From 953a820405dfd857ff9f5e24f3b630b6103dad46 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Tue, 16 Sep 2008 02:09:35 +0000 Subject: [PATCH] - when parsing compound types, do NOT destroy old declarations if a new one with the same name is found, always create a new one - handle enums analog - do not record "anonymous declarations" in the AST [r21986] --- parser.c | 82 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/parser.c b/parser.c index 1ccaffa..c4523d8 100644 --- a/parser.c +++ b/parser.c @@ -2697,7 +2697,6 @@ static declaration_t *parse_compound_type_specifier(bool is_struct) errorf(HERE, "multiple definitions of '%s %Y' (previous definition at %P)", is_struct ? "struct" : "union", symbol, &declaration->source_position); - declaration->scope.declarations = NULL; } } } else if (token.type != '{') { @@ -2712,18 +2711,17 @@ static declaration_t *parse_compound_type_specifier(bool is_struct) return NULL; } - if (declaration == NULL) { - declaration = allocate_declaration_zero(); - declaration->namespc = - (is_struct ? NAMESPACE_STRUCT : NAMESPACE_UNION); - declaration->source_position = token.source_position; - declaration->symbol = symbol; - declaration->parent_scope = scope; - if (symbol != NULL) { - environment_push(declaration); - } - append_declaration(declaration); + /* always create a new declaration, do NOT modify old one */ + declaration = allocate_declaration_zero(); + declaration->namespc = + (is_struct ? NAMESPACE_STRUCT : NAMESPACE_UNION); + declaration->source_position = token.source_position; + declaration->symbol = symbol; + declaration->parent_scope = scope; + if (symbol != NULL) { + environment_push(declaration); } + append_declaration(declaration); if (token.type == '{') { declaration->init.complete = true; @@ -2786,11 +2784,14 @@ end_error: ; } +/** + * Parse enum specifier and return the enum type or NULL on error. + */ static type_t *parse_enum_specifier(void) { - gnu_attribute_t *attributes = NULL; - declaration_t *declaration; - symbol_t *symbol; + gnu_attribute_t *attributes = NULL; + declaration_t *declaration = NULL; + symbol_t *symbol = NULL; eat(T_enum); if (token.type == T_IDENTIFIER) { @@ -2802,30 +2803,31 @@ static type_t *parse_enum_specifier(void) parse_error_expected("while parsing enum type specifier", T_IDENTIFIER, '{', NULL); return NULL; - } else { - declaration = NULL; - symbol = NULL; } - if (declaration == NULL) { - declaration = allocate_declaration_zero(); - declaration->namespc = NAMESPACE_ENUM; - declaration->source_position = token.source_position; - declaration->symbol = symbol; - declaration->parent_scope = scope; + if (token.type == '{' && declaration != NULL && declaration->init.complete) { + errorf(HERE, "multiple definitions of enum '%Y' (previous definition at %P)", + symbol, &declaration->source_position); } + declaration = allocate_declaration_zero(); + declaration->namespc = NAMESPACE_ENUM; + declaration->source_position = token.source_position; + declaration->symbol = symbol; + declaration->parent_scope = scope; + if (symbol != NULL) { + environment_push(declaration); + } + append_declaration(declaration); + type_t *const type = allocate_type_zero(TYPE_ENUM, &declaration->source_position); type->enumt.declaration = declaration; if (token.type == '{') { if (declaration->init.complete) { - errorf(HERE, "multiple definitions of enum %Y", symbol); + errorf(HERE, "multiple definitions of enum '%Y' (previous definition at %P)", + symbol, &declaration->source_position); } - if (symbol != NULL) { - environment_push(declaration); - } - append_declaration(declaration); declaration->init.complete = true; parse_enum_entries(type); @@ -4601,24 +4603,26 @@ static void parse_anonymous_declaration_rest( { eat(';'); + if (specifiers->declared_storage_class != STORAGE_CLASS_NONE) { + warningf(&specifiers->source_position, + "useless storage class in empty declaration"); + } + +#ifdef RECORD_EMPTY_DECLARARTIONS declaration_t *const declaration = allocate_declaration_zero(); declaration->type = specifiers->type; declaration->declared_storage_class = specifiers->declared_storage_class; declaration->source_position = specifiers->source_position; declaration->modifiers = specifiers->modifiers; + declaration->storage_class = STORAGE_CLASS_NONE; +#endif - if (declaration->declared_storage_class != STORAGE_CLASS_NONE) { - warningf(&declaration->source_position, - "useless storage class in empty declaration"); - } - declaration->storage_class = STORAGE_CLASS_NONE; - - type_t *type = declaration->type; + type_t *type = specifiers->type; switch (type->kind) { case TYPE_COMPOUND_STRUCT: case TYPE_COMPOUND_UNION: { if (type->compound.declaration->symbol == NULL) { - warningf(&declaration->source_position, + warningf(&specifiers->source_position, "unnamed struct/union that defines no instances"); } break; @@ -4628,11 +4632,13 @@ static void parse_anonymous_declaration_rest( break; default: - warningf(&declaration->source_position, "empty declaration"); + warningf(&specifiers->source_position, "empty declaration"); break; } +#ifdef RECORD_EMPTY_DECLARARTIONS append_declaration(declaration); +#endif } static void parse_declaration_rest(declaration_t *ndeclaration, -- 2.20.1