This change using symbol_op to contain the specifier parsing
function. It is easier to add new specifiers. We don't need
special bits any more.

Signed-Off-By: Christopher Li <[EMAIL PROTECTED]>

Index: sparse/parse.h
===================================================================
--- sparse.orig/parse.h 2007-03-05 00:27:18.000000000 -0800
+++ sparse/parse.h      2007-03-05 00:33:03.000000000 -0800
@@ -133,5 +133,6 @@ extern struct symbol *ctype_fp(unsigned 
 extern void copy_statement(struct statement *src, struct statement *dst);
 extern int inline_function(struct expression *expr, struct symbol *sym);
 extern void uninline(struct symbol *sym);
+extern void init_parser(int);
 
 #endif /* PARSE_H */
Index: sparse/symbol.c
===================================================================
--- sparse.orig/symbol.c        2007-03-05 00:27:18.000000000 -0800
+++ sparse/symbol.c     2007-03-05 00:33:03.000000000 -0800
@@ -678,43 +678,9 @@ static struct sym_init {
        { "__label__",  &label_ctype,   MOD_LABEL | MOD_UNSIGNED },
        { "_Bool",      &bool_ctype,    MOD_UNSIGNED },
 
-       /* Type qualifiers */
-       { "const",      NULL,           MOD_CONST },
-       { "__const",    NULL,           MOD_CONST },
-       { "__const__",  NULL,           MOD_CONST },
-       { "volatile",   NULL,           MOD_VOLATILE },
-       { "__volatile", NULL,           MOD_VOLATILE },
-       { "__volatile__", NULL,         MOD_VOLATILE },
-
        /* Predeclared types */
        { "__builtin_va_list", &int_type, 0 },
 
-       /* Typedef.. */
-       { "typedef",    NULL,           MOD_TYPEDEF },
-
-       /* Extended types */
-       { "typeof",     NULL,           MOD_TYPEOF },
-       { "__typeof",   NULL,           MOD_TYPEOF },
-       { "__typeof__", NULL,           MOD_TYPEOF },
-
-#if 0
-       { "attribute",  NULL,           MOD_ATTRIBUTE },
-#endif
-       { "__attribute", NULL,          MOD_ATTRIBUTE },
-       { "__attribute__", NULL,        MOD_ATTRIBUTE },
-
-       { "struct",     NULL,           MOD_STRUCTOF },
-       { "union",      NULL,           MOD_UNIONOF },
-       { "enum",       NULL,           MOD_ENUMOF },
-
-       { "inline",     NULL,           MOD_INLINE },
-       { "__inline",   NULL,           MOD_INLINE },
-       { "__inline__", NULL,           MOD_INLINE },
-
-       /* Ignored for now.. */
-       { "restrict",   NULL,           0 },
-       { "__restrict", NULL,           0 },
-
        { NULL,         NULL,           0 }
 };
 
@@ -794,6 +760,7 @@ void init_symbols(void)
        hash_ident(&n)
 #include "ident-list.h"
 
+       init_parser(stream);
        for (ptr = symbol_init_table; ptr->name; ptr++) {
                struct symbol *sym;
                sym = create_symbol(stream, ptr->name, SYM_NODE, NS_TYPEDEF);
Index: sparse/parse.c
===================================================================
--- sparse.orig/parse.c 2007-03-05 00:32:57.000000000 -0800
+++ sparse/parse.c      2007-03-05 00:33:21.000000000 -0800
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 2003 Transmeta Corp.
  *               2003-2004 Linus Torvalds
+ * Copyright (C) 2004 Christopher Li
  *
  *  Licensed under the Open Software License version 1.1
  */
@@ -36,6 +37,96 @@ struct statement_list *function_computed
 static struct token *statement(struct token *token, struct statement **tree);
 static struct token *handle_attributes(struct token *token, struct ctype 
*ctype);
 
+static struct token *struct_specifier(struct token *token, struct ctype 
*ctype);
+static struct token *union_specifier(struct token *token, struct ctype *ctype);
+static struct token *enum_specifier(struct token *token, struct ctype *ctype);
+static struct token *attribute_specifier(struct token *token, struct ctype 
*ctype);
+static struct token *typeof_specifier(struct token *token, struct ctype 
*ctype);
+
+
+static struct symbol_op modifier_op = {
+       .type = KW_MODIFIER,
+};
+
+static struct symbol_op qualifier_op = {
+       .type = KW_QUALIFIER,
+};
+
+static struct symbol_op typeof_op = {
+       .type = KW_TYPEOF,
+       .declarator = typeof_specifier,
+};
+
+static struct symbol_op attribute_op = {
+       .type = KW_ATTRIBUTE,
+       .declarator = attribute_specifier,
+};
+
+static struct symbol_op struct_op = {
+       .type = KW_SPECIFIER,
+       .declarator = struct_specifier, 
+};
+
+static struct symbol_op union_op = {
+       .type = KW_SPECIFIER,
+       .declarator = union_specifier,
+};
+
+static struct symbol_op enum_op = {
+       .type = KW_SPECIFIER,
+       .declarator = enum_specifier,
+};
+
+static struct init_keyword {
+       const char *name;
+       enum namespace ns;
+       unsigned long modifiers;
+       struct symbol_op *op;
+} keyword_table[] = {
+       /* Type qualifiers */
+       { "const",      NS_TYPEDEF, MOD_CONST, .op = &qualifier_op },
+       { "__const",    NS_TYPEDEF, MOD_CONST, .op = &qualifier_op },
+       { "__const__",  NS_TYPEDEF, MOD_CONST, .op = &qualifier_op },
+       { "volatile",   NS_TYPEDEF, MOD_VOLATILE, .op = &qualifier_op },
+       { "__volatile",         NS_TYPEDEF, MOD_VOLATILE, .op = &qualifier_op },
+       { "__volatile__",       NS_TYPEDEF, MOD_VOLATILE, .op = &qualifier_op },
+
+       /* Typedef.. */
+       { "typedef",    NS_TYPEDEF, MOD_TYPEDEF, .op = &modifier_op },
+
+       /* Extended types */
+       { "typeof",     NS_TYPEDEF, .op = &typeof_op },
+       { "__typeof",   NS_TYPEDEF, .op = &typeof_op },
+       { "__typeof__", NS_TYPEDEF, .op = &typeof_op },
+
+       { "__attribute",   NS_TYPEDEF, .op = &attribute_op },
+       { "__attribute__", NS_TYPEDEF, .op = &attribute_op },
+
+       { "struct",     NS_TYPEDEF, .op = &struct_op },
+       { "union",      NS_TYPEDEF, .op = &union_op },
+       { "enum",       NS_TYPEDEF, .op = &enum_op },
+
+       { "inline",     NS_TYPEDEF, MOD_INLINE, .op = &modifier_op },
+       { "__inline",   NS_TYPEDEF, MOD_INLINE, .op = &modifier_op },
+       { "__inline__", NS_TYPEDEF, MOD_INLINE, .op = &modifier_op },
+
+       /* Ignored for now.. */
+       { "restrict",   NS_TYPEDEF, .op = &qualifier_op},
+       { "__restrict", NS_TYPEDEF, .op = &qualifier_op},
+};
+
+void init_parser(int stream)
+{
+       int i;
+       for (i = 0; i < sizeof keyword_table/sizeof keyword_table[0]; i++) {
+               struct init_keyword *ptr = keyword_table + i;
+               struct symbol *sym = create_symbol(stream, ptr->name, 
SYM_KEYWORD, ptr->ns);
+               sym->ident->keyword = 1;
+               sym->ctype.modifiers = ptr->modifiers;
+               sym->op = ptr->op;
+       }
+}
+
 // Add a symbol to the list of function-local symbols
 static void fn_local_symbol(struct symbol *sym)
 {
@@ -115,7 +206,7 @@ static int apply_modifiers(struct positi
        return 0;
 }
 
-static struct symbol * indirect(struct position pos, struct ctype *ctype, int 
type)
+static struct symbol * alloc_indirect_symbol(struct position pos, struct ctype 
*ctype, int type)
 {
        struct symbol *sym = alloc_symbol(pos, type);
 
@@ -207,11 +298,17 @@ static struct token *parse_struct_declar
        return struct_declaration_list(token, &sym->symbol_list);
 }
 
-static struct token *struct_or_union_specifier(enum type type, struct token 
*token, struct ctype *ctype)
+static struct token *struct_specifier(struct token *token, struct ctype *ctype)
+{
+       return struct_union_enum_specifier(SYM_STRUCT, token, ctype, 
parse_struct_declaration);
+}
+
+static struct token *union_specifier(struct token *token, struct ctype *ctype)
 {
-       return struct_union_enum_specifier(type, token, ctype, 
parse_struct_declaration);
+       return struct_union_enum_specifier(SYM_UNION, token, ctype, 
parse_struct_declaration);
 }
 
+
 typedef struct {
        int x;
        unsigned long long y;
@@ -744,14 +841,11 @@ static void apply_ctype(struct position 
 static void check_modifiers(struct position *pos, struct symbol *s, unsigned 
long mod)
 {
        unsigned long banned, wrong;
-       unsigned long this_mod = s->ctype.modifiers;
        const unsigned long BANNED_SIZE = MOD_LONG | MOD_LONGLONG | MOD_SHORT;
        const unsigned long BANNED_SIGN = MOD_SIGNED | MOD_UNSIGNED;
 
-       if (this_mod & (MOD_STRUCTOF | MOD_UNIONOF | MOD_ENUMOF))
-               banned = BANNED_SIZE | BANNED_SIGN;
-       else if (this_mod & MOD_SPECIALBITS)
-               banned = 0;
+       if (s->type == SYM_KEYWORD)
+               banned = s->op->type == KW_SPECIFIER ? (BANNED_SIZE | 
BANNED_SIGN) : 0;
        else if (s->ctype.base_type == &fp_type)
                banned = BANNED_SIGN;
        else if (s->ctype.base_type == &int_type || !s->ctype.base_type || 
is_int_type (s))
@@ -790,19 +884,14 @@ static struct token *declaration_specifi
                        break;
                thistype = s->ctype;
                mod = thistype.modifiers;
-               if (qual && (mod & ~(MOD_ATTRIBUTE | MOD_CONST | MOD_VOLATILE)))
-                       break;
-               if (mod & MOD_SPECIALBITS) {
-                       if (mod & MOD_STRUCTOF)
-                               next = struct_or_union_specifier(SYM_STRUCT, 
next, &thistype);
-                       else if (mod & MOD_UNIONOF)
-                               next = struct_or_union_specifier(SYM_UNION, 
next, &thistype);
-                       else if (mod & MOD_ENUMOF)
-                               next = enum_specifier(next, &thistype);
-                       else if (mod & MOD_ATTRIBUTE)
-                               next = attribute_specifier(next, &thistype);
-                       else if (mod & MOD_TYPEOF)
-                               next = typeof_specifier(next, &thistype);
+               if (qual) {
+                       if (s->type != SYM_KEYWORD)
+                               break;
+                       if (!(s->op->type & (KW_ATTRIBUTE | KW_QUALIFIER)))
+                               break;
+               }
+               if (s->type == SYM_KEYWORD && s->op->declarator) {
+                       next = s->op->declarator(next, &thistype);
                        mod = thistype.modifiers;
                }
                type = thistype.base_type;
@@ -910,13 +999,13 @@ static struct token *direct_declarator(s
                                continue;
                        }
 
-                       sym = indirect(token->pos, ctype, SYM_FN);
+                       sym = alloc_indirect_symbol(token->pos, ctype, SYM_FN);
                        token = parameter_type_list(next, sym, p);
                        token = expect(token, ')', "in function declarator");
                        continue;
                }
                if (token->special == '[') {
-                       struct symbol *array = indirect(token->pos, ctype, 
SYM_ARRAY);
+                       struct symbol *array = 
alloc_indirect_symbol(token->pos, ctype, SYM_ARRAY);
                        token = abstract_array_declarator(token->next, array);
                        token = expect(token, ']', "in 
abstract_array_declarator");
                        ctype = &array->ctype;
@@ -932,7 +1021,7 @@ static struct token *pointer(struct toke
        unsigned long modifiers;
        struct symbol *base_type;
 
-       modifiers = ctype->modifiers & ~(MOD_TYPEDEF | MOD_ATTRIBUTE);
+       modifiers = ctype->modifiers & ~MOD_TYPEDEF;
        base_type = ctype->base_type;
        ctype->modifiers = modifiers;
        
@@ -976,7 +1065,7 @@ static struct token *handle_bitfield(str
                return conditional_expression(token->next, &expr);
        }
 
-       bitfield = indirect(token->pos, ctype, SYM_BITFIELD);
+       bitfield = alloc_indirect_symbol(token->pos, ctype, SYM_BITFIELD);
        token = conditional_expression(token->next, &expr);
        width = get_expression_value(expr);
        bitfield->bit_size = width;
Index: sparse/symbol.h
===================================================================
--- sparse.orig/symbol.h        2007-03-05 00:27:18.000000000 -0800
+++ sparse/symbol.h     2007-03-05 00:33:21.000000000 -0800
@@ -33,6 +33,7 @@ enum namespace {
        NS_ITERATOR = 32,
        NS_PREPROCESSOR = 64,
        NS_UNDEF = 128,
+       NS_KEYWORD = 256,
 };
 
 enum type {
@@ -53,9 +54,18 @@ enum type {
        SYM_LABEL,
        SYM_RESTRICT,
        SYM_FOULED,
+       SYM_KEYWORD,
        SYM_BAD,
 };
 
+enum keyword {
+       KW_SPECIFIER    = 1 << 0,
+       KW_MODIFIER     = 1 << 1,
+       KW_QUALIFIER    = 1 << 2,
+       KW_ATTRIBUTE    = 1 << 3,
+       KW_TYPEOF       = 1 << 4,
+};
+
 struct context {
        struct expression *context;
        unsigned int in, out;
@@ -74,9 +84,13 @@ struct ctype {
 };
 
 struct symbol_op {
+       enum keyword type;
        int (*evaluate)(struct expression *);
        int (*expand)(struct expression *, int);
        int (*args)(struct expression *);
+
+       /* keywrods */
+       struct token *(*declarator)(struct token *token, struct ctype *ctype);
 };     
 
 extern int expand_safe_p(struct expression *expr, int cost);
@@ -87,8 +101,8 @@ extern int expand_constant_p(struct expr
 #define SYM_ATTR_STRONG                2
 
 struct symbol {
-       enum namespace namespace:8;
        enum type type:8;
+       enum namespace namespace:9;
        unsigned char used:1, attr:2;
        struct position pos;            /* Where this symbol was declared */
        struct ident *ident;            /* What identifier this symbol is 
associated with */
@@ -159,12 +173,7 @@ struct symbol {
 #define MOD_LONGLONG   0x0800
 
 #define MOD_TYPEDEF    0x1000
-#define MOD_STRUCTOF   0x2000
-#define MOD_UNIONOF    0x4000
-#define MOD_ENUMOF     0x8000
 
-#define MOD_TYPEOF     0x10000
-#define MOD_ATTRIBUTE  0x20000
 #define MOD_INLINE     0x40000
 #define MOD_ADDRESSABLE        0x80000
 
@@ -185,7 +194,6 @@ struct symbol {
 
 #define MOD_NONLOCAL   (MOD_EXTERN | MOD_TOPLEVEL)
 #define MOD_STORAGE    (MOD_AUTO | MOD_REGISTER | MOD_STATIC | MOD_EXTERN | 
MOD_INLINE | MOD_TOPLEVEL)
-#define MOD_SPECIALBITS (MOD_STRUCTOF | MOD_UNIONOF | MOD_ENUMOF | 
MOD_ATTRIBUTE | MOD_TYPEOF)
 #define MOD_SIGNEDNESS (MOD_SIGNED | MOD_UNSIGNED | MOD_EXPLICITLY_SIGNED)
 #define MOD_SPECIFIER  (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG | 
MOD_SIGNEDNESS)
 #define MOD_SIZE       (MOD_CHAR | MOD_SHORT | MOD_LONG | MOD_LONGLONG)
Index: sparse/lib.c
===================================================================
Index: sparse/token.h
===================================================================
--- sparse.orig/token.h 2007-03-05 00:27:18.000000000 -0800
+++ sparse/token.h      2007-03-05 00:33:03.000000000 -0800
@@ -54,7 +54,8 @@ struct ident {
        struct symbol *symbols; /* Pointer to semantic meaning list */
        unsigned char len;      /* Length of identifier name */
        unsigned char tainted:1,
-                     reserved:1;
+                     reserved:1,
+                     keyword:1;
        char name[];            /* Actual identifier */
 };
 
-
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to