From: Michael Beck Date: Tue, 16 Sep 2008 02:51:35 +0000 (+0000) Subject: reverted 21986-21986, spec failed X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=f5a27af44212805f4a00d645e8b8b9c868846a39;p=cparser reverted 21986-21986, spec failed [r21988] --- diff --git a/parser.c b/parser.c index 060c145..1ccaffa 100644 --- a/parser.c +++ b/parser.c @@ -2687,12 +2687,18 @@ static declaration_t *parse_compound_type_specifier(bool is_struct) namespace_t const namespc = is_struct ? NAMESPACE_STRUCT : NAMESPACE_UNION; declaration = get_declaration(symbol, namespc); - if (declaration != NULL && - declaration->init.complete && token.type == '{') { - assert(symbol != NULL); - errorf(HERE, "multiple definitions of '%s %Y' (previous definition at %P)", - is_struct ? "struct" : "union", symbol, - &declaration->source_position); + if (declaration != NULL) { + if (declaration->parent_scope != scope && + (token.type == '{' || token.type == ';')) { + declaration = NULL; + } else if (declaration->init.complete && + token.type == '{') { + assert(symbol != NULL); + 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 != '{') { if (is_struct) { @@ -2706,17 +2712,18 @@ static declaration_t *parse_compound_type_specifier(bool is_struct) return NULL; } - /* 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); + 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); } - append_declaration(declaration); if (token.type == '{') { declaration->init.complete = true; @@ -2779,14 +2786,11 @@ 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 = NULL; - symbol_t *symbol = NULL; + gnu_attribute_t *attributes = NULL; + declaration_t *declaration; + symbol_t *symbol; eat(T_enum); if (token.type == T_IDENTIFIER) { @@ -2794,36 +2798,34 @@ static type_t *parse_enum_specifier(void) next_token(); declaration = get_declaration(symbol, NAMESPACE_ENUM); - if (declaration != NULL && - declaration->init.complete && token.type == '{') { - assert(symbol != NULL); - errorf(HERE, "multiple definitions of 'enum %Y' (previous definition at %P)", - symbol, &declaration->source_position); - } } else if (token.type != '{') { parse_error_expected("while parsing enum type specifier", T_IDENTIFIER, '{', NULL); return NULL; + } else { + declaration = NULL; + symbol = NULL; } - 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); + if (declaration == NULL) { + declaration = allocate_declaration_zero(); + declaration->namespc = NAMESPACE_ENUM; + declaration->source_position = token.source_position; + declaration->symbol = symbol; + declaration->parent_scope = scope; } - 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' (previous definition at %P)", - symbol, &declaration->source_position); + errorf(HERE, "multiple definitions of enum %Y", symbol); + } + if (symbol != NULL) { + environment_push(declaration); } + append_declaration(declaration); declaration->init.complete = true; parse_enum_entries(type); @@ -4599,26 +4601,24 @@ 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 - type_t *type = specifiers->type; + 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; switch (type->kind) { case TYPE_COMPOUND_STRUCT: case TYPE_COMPOUND_UNION: { if (type->compound.declaration->symbol == NULL) { - warningf(&specifiers->source_position, + warningf(&declaration->source_position, "unnamed struct/union that defines no instances"); } break; @@ -4628,13 +4628,11 @@ static void parse_anonymous_declaration_rest( break; default: - warningf(&specifiers->source_position, "empty declaration"); + warningf(&declaration->source_position, "empty declaration"); break; } -#ifdef RECORD_EMPTY_DECLARARTIONS append_declaration(declaration); -#endif } static void parse_declaration_rest(declaration_t *ndeclaration,