diff options
| author | welinder@troll.com <welinder@troll.com> | 2004-08-31 23:31:24 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:02:58 -0700 |
| commit | 23ff06e17c298ecd8f0371bd97ad87ba03f63833 (patch) | |
| tree | b822ef196373cb0c402f8f0e2b915dc2cb695b43 | |
| parent | 2a07edfe82b08cec341cace8294990b359727a8a (diff) | |
| parent | 24945d604b9f97777b9878329e9a61318e3b2c1d (diff) | |
| download | sparse-dev-23ff06e17c298ecd8f0371bd97ad87ba03f63833.tar.gz | |
Merge troll.com:/scratch/welinder/linus-sparse
into troll.com:/scratch/welinder/sparse-for-linus
| -rw-r--r-- | parse.c | 47 |
1 files changed, 30 insertions, 17 deletions
@@ -1188,6 +1188,9 @@ struct token * statement_list(struct token *token, struct statement_list **list) static struct token *parameter_type_list(struct token *token, struct symbol *fn) { struct symbol_list **list = &fn->arguments; + + if (match_op(token, ')')) + return token; for (;;) { struct symbol *sym = alloc_symbol(token->pos, SYM_NODE); @@ -1346,28 +1349,38 @@ static struct token *parse_function_body(struct token *token, struct symbol *dec return expect(token, '}', "at end of function"); } -static void apply_kr_types(struct symbol_list *argtypes, struct symbol *fn) +static void promote_k_r_types(struct symbol *arg) +{ + struct symbol *base = arg->ctype.base_type; + if (base && base->ctype.base_type == &int_type && (base->ctype.modifiers & (MOD_CHAR | MOD_SHORT))) { + arg->ctype.base_type = &int_ctype; + } +} + +static void apply_k_r_types(struct symbol_list *argtypes, struct symbol *fn) { struct symbol_list *real_args = fn->ctype.base_type->arguments; - struct symbol *arg, *type; + struct symbol *arg; - PREPARE_PTR_LIST(argtypes, type); FOR_EACH_PTR(real_args, arg) { - if (!type) { - warn(arg->pos, "no K&R type for '%s'", show_ident(arg->ident)); - return; - } - if (type->ident != arg->ident) { - warn(arg->pos, "K&R declaration disagrees on name of %s", - show_ident(arg->ident)); - } + struct symbol *type; + + /* This is quadratic in the number of arguments. We _really_ don't care */ + FOR_EACH_PTR(argtypes, type) { + if (type->ident == arg->ident) + goto match; + } END_FOR_EACH_PTR; + warn(arg->pos, "no K&R type for '%s'", show_ident(arg->ident)); + return; +match: + /* "char" and "short" promote to "int" */ + promote_k_r_types(type); + arg->ctype = type->ctype; - NEXT_PTR_LIST(type); } END_FOR_EACH_PTR; - FINISH_PTR_LIST(type); } -static struct token *parse_kr_arguments(struct token *token, struct symbol *decl, +static struct token *parse_k_r_arguments(struct token *token, struct symbol *decl, struct symbol_list **list) { struct symbol_list *args = NULL; @@ -1377,13 +1390,13 @@ static struct token *parse_kr_arguments(struct token *token, struct symbol *decl token = external_declaration(token, &args); } while (lookup_type(token)); - apply_kr_types(args, decl); + apply_k_r_types(args, decl); if (!match_op(token, '{')) { warn(token->pos, "expected function body"); return token; } - return parse_function_body(token->next, decl, list); + return parse_function_body(token, decl, list); } @@ -1439,7 +1452,7 @@ static struct token *external_declaration(struct token *token, struct symbol_lis if (!is_typedef && base_type && base_type->type == SYM_FN) { /* K&R argument declaration? */ if (lookup_type(token)) - return parse_kr_arguments(token, decl, list); + return parse_k_r_arguments(token, decl, list); if (match_op(token, '{')) return parse_function_body(token, decl, list); |
