aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorwelinder@troll.com <welinder@troll.com>2004-08-31 23:31:24 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:02:58 -0700
commit23ff06e17c298ecd8f0371bd97ad87ba03f63833 (patch)
treeb822ef196373cb0c402f8f0e2b915dc2cb695b43
parent2a07edfe82b08cec341cace8294990b359727a8a (diff)
parent24945d604b9f97777b9878329e9a61318e3b2c1d (diff)
downloadsparse-dev-23ff06e17c298ecd8f0371bd97ad87ba03f63833.tar.gz
Merge troll.com:/scratch/welinder/linus-sparse
into troll.com:/scratch/welinder/sparse-for-linus
-rw-r--r--parse.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/parse.c b/parse.c
index dcfc33f7..29150e50 100644
--- a/parse.c
+++ b/parse.c
@@ -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);