summaryrefslogtreecommitdiff
path: root/usr.bin/xlint
diff options
context:
space:
mode:
authorChad Loder <cloder@cvs.openbsd.org>2005-12-03 00:27:55 +0000
committerChad Loder <cloder@cvs.openbsd.org>2005-12-03 00:27:55 +0000
commit1c6cd252eaeaeedbd87c69d5843ae9550b20ee91 (patch)
treefaf71d00f151426fb577354f266f17fcf8ec09fb /usr.bin/xlint
parentb6d67a9b2dd73b1e8e23240c4212871b40b3d4fc (diff)
Lint can now parse every variation of gcc's __attribute__ that I could find
either in our tree or in the gcc docs. See regression test 11 for examples of this. Right now, our cdefs.h actually defines __attribute__(x) to blank when lint runs. We can change this whenever we choose.
Diffstat (limited to 'usr.bin/xlint')
-rw-r--r--usr.bin/xlint/lint1/cgram.y67
-rw-r--r--usr.bin/xlint/lint1/lint1.h11
-rw-r--r--usr.bin/xlint/lint1/scan.l11
3 files changed, 62 insertions, 27 deletions
diff --git a/usr.bin/xlint/lint1/cgram.y b/usr.bin/xlint/lint1/cgram.y
index 70d9c649889..39f98e756b1 100644
--- a/usr.bin/xlint/lint1/cgram.y
+++ b/usr.bin/xlint/lint1/cgram.y
@@ -1,5 +1,5 @@
%{
-/* $OpenBSD: cgram.y,v 1.13 2005/11/30 18:47:11 deraadt Exp $ */
+/* $OpenBSD: cgram.y,v 1.14 2005/12/03 00:27:54 cloder Exp $ */
/* $NetBSD: cgram.y,v 1.8 1995/10/02 17:31:35 jpo Exp $ */
/*
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: cgram.y,v 1.13 2005/11/30 18:47:11 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: cgram.y,v 1.14 2005/12/03 00:27:54 cloder Exp $";
#endif
#include <stdlib.h>
@@ -71,6 +71,7 @@ static void ignuptorp(void);
scl_t y_scl;
tspec_t y_tspec;
tqual_t y_tqual;
+ attr_t y_attr;
type_t *y_type;
tnode_t *y_tnode;
strg_t *y_strg;
@@ -110,6 +111,9 @@ static void ignuptorp(void);
/* qualifiers (const, volatile, restrict) */
%token <y_tqual> T_QUAL
+/* attributes (noreturn, format, etc.) */
+%token <y_attr> T_ATTR
+
/* struct or union */
%token <y_tspec> T_SOU
@@ -306,7 +310,7 @@ data_def: T_SEMI
warning(2);
}
}
- | declspecs deftyp type_init_decls opt_attribute_spec T_SEMI
+ | declspecs deftyp type_init_decls T_SEMI
| error T_SEMI {
globclup();
}
@@ -341,11 +345,6 @@ func_def:
}
;
-opt_attribute_spec:
- /* empty */
- | T_ATTRIBUTE T_LPARN T_LPARN read_until_rparn T_RPARN
- ;
-
func_decl:
clrtyp deftyp notype_decl {
$$ = $3;
@@ -460,6 +459,7 @@ declmods:
| clrtyp T_SCLASS {
addscl($2);
}
+ | clrtyp attribute_spec
| declmods declmod
;
@@ -470,6 +470,25 @@ declmod:
| T_SCLASS {
addscl($1);
}
+ | attribute_spec
+ ;
+
+attribute_spec:
+ T_ATTRIBUTE T_LPARN T_LPARN T_ATTR T_RPARN T_RPARN {
+ /* XXX: addattr($4) */
+ }
+ | T_ATTRIBUTE T_LPARN T_LPARN T_NAME read_until_rparn T_RPARN
+ | T_ATTRIBUTE T_LPARN T_LPARN T_QUAL read_until_rparn T_RPARN
+ ;
+
+attribute_specs:
+ attribute_spec
+ | attribute_specs attribute_spec
+ ;
+
+opt_attribute_specs:
+ /* EMPTY */
+ | attribute_specs
;
clrtyp_typespec:
@@ -579,10 +598,10 @@ member_declaration_list_with_rbrace:
;
member_declaration_list:
- member_declaration {
+ member_declaration opt_attribute_specs {
$$ = $1;
}
- | member_declaration_list T_SEMI member_declaration {
+ | member_declaration_list T_SEMI member_declaration opt_attribute_specs {
$$ = lnklst($1, $3);
}
;
@@ -792,7 +811,7 @@ type_init_decls:
;
notype_init_decl:
- notype_decl opt_attribute_spec opt_asm_spec {
+ notype_decl opt_asm_spec {
idecl($1, 0);
chksz($1);
}
@@ -816,10 +835,10 @@ type_init_decl:
;
notype_decl:
- notype_direct_decl {
+ notype_direct_decl opt_attribute_specs {
$$ = $1;
}
- | pointer notype_direct_decl {
+ | pointer notype_direct_decl opt_attribute_specs {
$$ = addptr($2, $1);
}
;
@@ -845,10 +864,10 @@ notype_direct_decl:
;
type_decl:
- type_direct_decl {
+ type_direct_decl opt_attribute_specs {
$$ = $1;
}
- | pointer type_direct_decl {
+ | pointer type_direct_decl opt_attribute_specs {
$$ = addptr($2, $1);
}
;
@@ -939,17 +958,17 @@ direct_notype_param_decl:
;
pointer:
- asterisk {
+ asterisk opt_attribute_specs {
$$ = $1;
}
- | asterisk type_qualifier_list {
- $$ = mergepq($1, $2);
+ | asterisk opt_attribute_specs type_qualifier_list {
+ $$ = mergepq($1, $3);
}
- | asterisk pointer {
- $$ = mergepq($1, $2);
+ | asterisk opt_attribute_specs pointer {
+ $$ = mergepq($1, $3);
}
- | asterisk type_qualifier_list pointer {
- $$ = mergepq(mergepq($1, $2), $3);
+ | asterisk opt_attribute_specs type_qualifier_list pointer {
+ $$ = mergepq(mergepq($1, $3), $4);
}
;
@@ -1050,10 +1069,10 @@ vararg_parameter_type_list:
;
parameter_type_list:
- parameter_declaration opt_asm_spec {
+ parameter_declaration opt_attribute_specs opt_asm_spec {
$$ = $1;
}
- | parameter_type_list T_COMMA parameter_declaration opt_asm_spec {
+ | parameter_type_list T_COMMA parameter_declaration opt_attribute_specs opt_asm_spec {
$$ = lnklst($1, $3);
}
;
diff --git a/usr.bin/xlint/lint1/lint1.h b/usr.bin/xlint/lint1/lint1.h
index 2417d2feaf2..38478f01b56 100644
--- a/usr.bin/xlint/lint1/lint1.h
+++ b/usr.bin/xlint/lint1/lint1.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lint1.h,v 1.5 2005/11/29 19:38:09 cloder Exp $ */
+/* $OpenBSD: lint1.h,v 1.6 2005/12/03 00:27:54 cloder Exp $ */
/* $NetBSD: lint1.h,v 1.6 1995/10/02 17:31:41 jpo Exp $ */
/*
@@ -70,6 +70,13 @@ typedef enum {
} tqual_t;
/*
+ * attributes
+ */
+typedef enum {
+ NORETURN
+} attr_t;
+
+/*
* Integer and floating point values are stored in this structure
*/
typedef struct {
@@ -220,6 +227,7 @@ typedef struct sym {
enum_t *_s_et; /* tag, if it is a enumerator */
tspec_t _s_tsp; /* type (only for keywords) */
tqual_t _s_tqu; /* qualifier (only for keywords) */
+ tqual_t _s_att; /* attribute (only for keywords) */
struct sym *_s_args; /* arguments in old style function
definitions */
} u;
@@ -234,6 +242,7 @@ typedef struct sym {
#define s_etyp u._s_et
#define s_tspec u._s_tsp
#define s_tqual u._s_tqu
+#define s_attr u._s_att
#define s_args u._s_args
/*
diff --git a/usr.bin/xlint/lint1/scan.l b/usr.bin/xlint/lint1/scan.l
index 406b8cc1985..3b0ee0ed0b7 100644
--- a/usr.bin/xlint/lint1/scan.l
+++ b/usr.bin/xlint/lint1/scan.l
@@ -1,5 +1,5 @@
%{
-/* $OpenBSD: scan.l,v 1.18 2005/12/02 18:03:09 cloder Exp $ */
+/* $OpenBSD: scan.l,v 1.19 2005/12/03 00:27:54 cloder Exp $ */
/* $NetBSD: scan.l,v 1.8 1995/10/23 13:38:51 jpo Exp $ */
/*
@@ -34,7 +34,7 @@
*/
#ifndef lint
-static char rcsid[] = "$OpenBSD: scan.l,v 1.18 2005/12/02 18:03:09 cloder Exp $";
+static char rcsid[] = "$OpenBSD: scan.l,v 1.19 2005/12/03 00:27:54 cloder Exp $";
#endif
#include <stdlib.h>
@@ -184,6 +184,7 @@ static struct kwtab {
scl_t kw_scl; /* storage class if kw_token T_SCLASS */
tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */
tqual_t kw_tqual; /* type qual. if kw_token T_QUAL */
+ attr_t kw_attr; /* attribute spec. if kw_token T_ATTR */
};
u_int kw_stdc : 1; /* STDC keyword */
u_int kw_gcc : 1; /* GCC keyword */
@@ -191,6 +192,7 @@ static struct kwtab {
{ "asm", T_ASM, { 0 }, 0, 1 },
{ "__asm", T_ASM, { 0 }, 0, 0 },
{ "__asm__", T_ASM, { 0 }, 0, 0 },
+ { "__attribute", T_ATTRIBUTE, { 0 }, 0, 0 },
{ "__attribute__", T_ATTRIBUTE, { 0 }, 0, 0 },
{ "auto", T_SCLASS, { AUTO }, 0, 0 },
{ "break", T_BREAK, { 0 }, 0, 0 },
@@ -216,6 +218,7 @@ static struct kwtab {
{ "int", T_TYPE, { INT }, 0, 0 },
{ "__lint_equal__", T_LEQUAL, { 0 }, 0, 0 },
{ "long", T_TYPE, { LONG }, 0, 0 },
+ { "__noreturn__", T_ATTR, { NORETURN }, 0, 1 },
{ "register", T_SCLASS, { REG }, 0, 0 },
{ "__restrict", T_QUAL, { RESTRICT }, 0, 0 },
{ "__restrict__", T_QUAL, { RESTRICT }, 0, 0 },
@@ -285,6 +288,8 @@ initscan(void)
sym->s_scl = kw->kw_scl;
} else if (kw->kw_token == T_QUAL) {
sym->s_tqual = kw->kw_tqual;
+ } else if (kw->kw_token == T_ATTR) {
+ sym->s_attr = kw->kw_attr;
}
h = hash(sym->s_name);
if ((sym->s_link = symtab[h]) != NULL)
@@ -437,6 +442,8 @@ keyw(sym_t *sym)
yylval.y_tspec = sym->s_tspec;
} else if (t == T_QUAL) {
yylval.y_tqual = sym->s_tqual;
+ } else if (t == T_ATTR) {
+ yylval.y_attr = sym->s_attr;
}
return (t);
}