summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Loder <cloder@cvs.openbsd.org>2005-12-07 01:55:13 +0000
committerChad Loder <cloder@cvs.openbsd.org>2005-12-07 01:55:13 +0000
commit282b783746660f5ddca78fbeafa4c79416e81e34 (patch)
treea084ec76edffd907e71eac3b90632353de28cd45
parent509dd1e74df0f75272624065d0fbe78f1279ea0d (diff)
Refactor __attribute__ parsing a bit. This takes us further to being able
to not only consume, but also make sense of gcc __attribute__ syntax.
-rw-r--r--usr.bin/xlint/lint1/Makefile4
-rw-r--r--usr.bin/xlint/lint1/attr.c127
-rw-r--r--usr.bin/xlint/lint1/cgram.y56
-rw-r--r--usr.bin/xlint/lint1/externs1.h14
-rw-r--r--usr.bin/xlint/lint1/lint1.h13
-rw-r--r--usr.bin/xlint/lint1/scan.l45
6 files changed, 235 insertions, 24 deletions
diff --git a/usr.bin/xlint/lint1/Makefile b/usr.bin/xlint/lint1/Makefile
index b3e39dbac06..ccbe846cc44 100644
--- a/usr.bin/xlint/lint1/Makefile
+++ b/usr.bin/xlint/lint1/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.6 2005/11/29 19:57:28 cloder Exp $
+# $OpenBSD: Makefile,v 1.7 2005/12/07 01:55:12 cloder Exp $
# $NetBSD: Makefile,v 1.3 1995/07/04 01:53:05 cgd Exp $
PROG= lint1
SRCS= cgram.c scan.c mem1.c mem.c err.c main1.c decl.c tree.c func.c \
- init.c emit.c emit1.c
+ init.c emit.c emit1.c attr.c
NOMAN=
LDADD+= -ll
DPADD+= ${LIBL}
diff --git a/usr.bin/xlint/lint1/attr.c b/usr.bin/xlint/lint1/attr.c
new file mode 100644
index 00000000000..5296a822e9b
--- /dev/null
+++ b/usr.bin/xlint/lint1/attr.c
@@ -0,0 +1,127 @@
+/* $OpenBSD: attr.c,v 1.1 2005/12/07 01:55:12 cloder Exp $ */
+
+/*
+ * Copyright (c) 2005 Chad Loder
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char rcsid[] = "$OpenBSD: attr.c,v 1.1 2005/12/07 01:55:12 cloder Exp $";
+#endif
+
+#include "lint1.h"
+
+attr_t
+getattr(const char *attr)
+{
+ if (attr == NULL)
+ return AT_UNKNOWN;
+
+ if (!strcmp(attr, "__noreturn__")) {
+ return AT_NORETURN;
+ }
+ else if (!strcmp(attr, "noreturn"))
+ return AT_NORETURN;
+
+ return AT_UNKNOWN;
+}
+
+attr_t
+getqualattr(tqual_t q)
+{
+ if (q == VOLATILE)
+ return AT_VOLATILE;
+
+ return AT_UNKNOWN;
+}
+
+attrnode_t*
+newattrnode(attr_t a)
+{
+ attrnode_t *an = xcalloc(1, sizeof(attrnode_t));
+ an->an_attr = a;
+ return an;
+}
+
+void
+appendattr(attrnode_t *an, attr_t a)
+{
+ attrnode_t *nxt;
+
+ while (nxt != NULL) {
+ nxt = an->an_nxt;
+ if (nxt)
+ an = nxt;
+ }
+
+ an->an_nxt = newattrnode(a);
+}
+
+void
+appendattrnode(attrnode_t *an, attrnode_t *apn)
+{
+ attrnode_t *nxt;
+
+ while (nxt != NULL) {
+ nxt = an->an_nxt;
+ if (nxt)
+ an = nxt;
+ }
+
+ an->an_nxt = apn;
+}
+
+void
+addattr(type_t *t, attrnode_t *an)
+{
+ printf("adding attribute %p to type %p\n", an, t);
+ if (t->t_attr == NULL)
+ t->t_attr = an;
+ else
+ appendattrnode(t->t_attr, an);
+}
+
+int
+hasattr(type_t *t, attr_t a)
+{
+ attrnode_t *an = t->t_attr;
+
+ printf("seeing if type %p has attribute %d\n", t, a);
+
+ while (an != NULL) {
+ if (an->an_attr == a)
+ return 1;
+
+ an = an->an_nxt;
+ }
+
+ printf("subtypes of type %p are:\n", t);
+ while (t != NULL) {
+ t = t->t_subt;
+ printf("\ttype %p\n", t);
+ }
+
+ return 0;
+}
diff --git a/usr.bin/xlint/lint1/cgram.y b/usr.bin/xlint/lint1/cgram.y
index 39f98e756b1..7cc8c8db4b9 100644
--- a/usr.bin/xlint/lint1/cgram.y
+++ b/usr.bin/xlint/lint1/cgram.y
@@ -1,5 +1,5 @@
%{
-/* $OpenBSD: cgram.y,v 1.14 2005/12/03 00:27:54 cloder Exp $ */
+/* $OpenBSD: cgram.y,v 1.15 2005/12/07 01:55:12 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.14 2005/12/03 00:27:54 cloder Exp $";
+static char rcsid[] = "$OpenBSD: cgram.y,v 1.15 2005/12/07 01:55:12 cloder Exp $";
#endif
#include <stdlib.h>
@@ -72,6 +72,7 @@ static void ignuptorp(void);
tspec_t y_tspec;
tqual_t y_tqual;
attr_t y_attr;
+ attrnode_t *y_attrnode;
type_t *y_type;
tnode_t *y_tnode;
strg_t *y_strg;
@@ -213,6 +214,10 @@ static void ignuptorp(void);
%type <y_strg> string
%type <y_strg> string2
+%type <y_attr> attribute_name
+%type <y_attr> attribute_spec
+%type <y_attrnode> attribute_specs
+%type <y_attrnode> opt_attribute_specs
%%
@@ -473,22 +478,53 @@ declmod:
| attribute_spec
;
+attribute_name:
+ T_QUAL {
+ $$ = getkwattr(T_QUAL, $1);
+ }
+ | T_SCLASS {
+ $$ = getkwattr(T_SCLASS, $1);
+ }
+ | T_TYPENAME {
+ $$ = getattr($1->sb_name);
+ }
+ | T_NAME {
+ $$ = getattr($1->sb_name);
+ }
+ ;
+
attribute_spec:
- T_ATTRIBUTE T_LPARN T_LPARN T_ATTR T_RPARN T_RPARN {
- /* XXX: addattr($4) */
+ T_ATTRIBUTE T_LPARN T_LPARN attribute_name T_RPARN T_RPARN {
+ $$ = $4;
+ }
+ | T_ATTRIBUTE T_LPARN T_LPARN attribute_name T_COMMA read_until_rparn T_RPARN {
+ /* some other exotic syntax that we don't understand */
+ $$ = AT_UNKNOWN;
+ }
+ | T_ATTRIBUTE T_LPARN T_LPARN attribute_name T_LPARN read_until_rparn T_RPARN T_RPARN {
+ /* some other exotic syntax that we don't understand */
+ $$ = AT_UNKNOWN;
}
- | 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
+ attribute_spec {
+ /*$$ = newattrnode($1);*/
+ $$ = NULL;
+ }
+ | attribute_specs attribute_spec {
+ /*appendattr($1, $2);*/
+ $$ = $1;
+ }
;
opt_attribute_specs:
- /* EMPTY */
- | attribute_specs
+ /* EMPTY */ {
+ $$ = NULL;
+ }
+ | attribute_specs {
+ $$ = $1;
+ }
;
clrtyp_typespec:
diff --git a/usr.bin/xlint/lint1/externs1.h b/usr.bin/xlint/lint1/externs1.h
index dcc078dead3..66d81b2b6df 100644
--- a/usr.bin/xlint/lint1/externs1.h
+++ b/usr.bin/xlint/lint1/externs1.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: externs1.h,v 1.3 2002/02/16 21:27:59 millert Exp $ */
+/* $OpenBSD: externs1.h,v 1.4 2005/12/07 01:55:12 cloder Exp $ */
/* $NetBSD: externs1.h,v 1.7 1995/10/02 17:31:39 jpo Exp $ */
/*
@@ -72,6 +72,7 @@ extern pos_t csrc_pos;
extern symt_t symtyp;
extern FILE *yyin;
extern u_quad_t qbmasks[], qlmasks[], qumasks[];
+attr_t getkwattr(int, int);
extern void initscan(void);
extern int sign(quad_t, tspec_t, int);
@@ -260,6 +261,17 @@ extern void protolib(int);
extern void longlong(int);
/*
+ * attr.c
+ */
+extern attr_t getattr(const char *);
+extern attr_t getqualattr(tqual_t);
+extern attrnode_t *newattrnode(attr_t);
+extern void appendattr(attrnode_t*, attr_t);
+extern void appendattrnode(attrnode_t*, attrnode_t*);
+extern void addattr(type_t *, attrnode_t*);
+extern int hasattr(type_t *, attr_t);
+
+/*
* init.c
*/
extern int initerr;
diff --git a/usr.bin/xlint/lint1/lint1.h b/usr.bin/xlint/lint1/lint1.h
index c103e1904ec..dcce2425c0d 100644
--- a/usr.bin/xlint/lint1/lint1.h
+++ b/usr.bin/xlint/lint1/lint1.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: lint1.h,v 1.7 2005/12/03 01:14:39 cloder Exp $ */
+/* $OpenBSD: lint1.h,v 1.8 2005/12/07 01:55:12 cloder Exp $ */
/* $NetBSD: lint1.h,v 1.6 1995/10/02 17:31:41 jpo Exp $ */
/*
@@ -73,10 +73,18 @@ typedef enum {
* attributes
*/
typedef enum {
- NORETURN
+ AT_UNKNOWN, AT_NORETURN, AT_VOLATILE
} attr_t;
/*
+ * A node in an attribute list.
+ */
+typedef struct attrnode {
+ attr_t an_attr;
+ struct attrnode *an_nxt;
+} attrnode_t;
+
+/*
* Integer and floating point values are stored in this structure
*/
typedef struct {
@@ -146,6 +154,7 @@ typedef struct type {
u_int _t_foffs : 24; /* offset of bit-field */
} _t_u;
} t_u;
+ struct attrnode *t_attr; /* attributes */
struct type *t_subt; /* element type (arrays), return value
(functions), or type pointer points to */
} type_t;
diff --git a/usr.bin/xlint/lint1/scan.l b/usr.bin/xlint/lint1/scan.l
index d8022f1235d..7bc59f7b37e 100644
--- a/usr.bin/xlint/lint1/scan.l
+++ b/usr.bin/xlint/lint1/scan.l
@@ -1,5 +1,5 @@
%{
-/* $OpenBSD: scan.l,v 1.20 2005/12/03 01:14:39 cloder Exp $ */
+/* $OpenBSD: scan.l,v 1.21 2005/12/07 01:55:12 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.20 2005/12/03 01:14:39 cloder Exp $";
+static char rcsid[] = "$OpenBSD: scan.l,v 1.21 2005/12/07 01:55:12 cloder Exp $";
#endif
#include <stdlib.h>
@@ -184,7 +184,6 @@ 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 */
} kw_u;
u_int kw_stdc : 1; /* STDC keyword */
u_int kw_gcc : 1; /* GCC keyword */
@@ -218,7 +217,6 @@ 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 },
@@ -245,7 +243,6 @@ static struct kwtab {
#define kw_scl kw_u.kw_scl
#define kw_tspec kw_u.kw_tspec
#define kw_tqual kw_u.kw_tqual
-#define kw_attr kw_u.kw_attr
/* Symbol table */
static sym_t *symtab[HSHSIZ1];
@@ -293,8 +290,6 @@ 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)
@@ -447,8 +442,6 @@ 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);
}
@@ -1419,3 +1412,37 @@ freeyyv(void *sp, int tok)
free(strg);
}
}
+
+/*
+ * Return the corresponding attr_t constant for a particular C keyword,
+ * or AT_UNKNOWN if not known.
+ */
+attr_t
+getkwattr(int tok, int val)
+{
+ struct kwtab *kw;
+ int eq;
+
+ eq = 0;
+ for (kw = kwtab; !eq && kw->kw_name != NULL; kw++) {
+ if (kw->kw_token == tok) {
+ switch (tok) {
+ case T_QUAL:
+ eq = (val == kw->kw_tqual);
+ break;
+ case T_TYPE:
+ case T_SOU:
+ eq = (val == kw->kw_tspec);
+ break;
+ case T_SCLASS:
+ eq = (val == kw->kw_scl);
+ break;
+ }
+
+ if (eq)
+ return getattr(kw->kw_name);
+ }
+ }
+
+ return AT_UNKNOWN;
+}