diff options
author | Chad Loder <cloder@cvs.openbsd.org> | 2005-12-07 01:55:13 +0000 |
---|---|---|
committer | Chad Loder <cloder@cvs.openbsd.org> | 2005-12-07 01:55:13 +0000 |
commit | 282b783746660f5ddca78fbeafa4c79416e81e34 (patch) | |
tree | a084ec76edffd907e71eac3b90632353de28cd45 | |
parent | 509dd1e74df0f75272624065d0fbe78f1279ea0d (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/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/attr.c | 127 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/cgram.y | 56 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/externs1.h | 14 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/lint1.h | 13 | ||||
-rw-r--r-- | usr.bin/xlint/lint1/scan.l | 45 |
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; +} |