X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=inline;f=parser.c;h=d9397d98992b4eca5a45fc8d01f09fb020dfce69;hb=6a2564eda2e886dba330454545f3c71e49be852b;hp=d2147ce65a26c4f3d20bf6f8cf9b22e830cb0534;hpb=e8bbfa9edcf76d64dcc1f037d83755a15153ff58;p=cparser diff --git a/parser.c b/parser.c index d2147ce..d9397d9 100644 --- a/parser.c +++ b/parser.c @@ -215,10 +215,6 @@ static void semantic_comparison(binary_expression_t *expression); TYPE_QUALIFIERS \ TYPE_SPECIFIERS -#define TYPENAME_START \ - TYPE_QUALIFIERS \ - TYPE_SPECIFIERS - #define EXPRESSION_START \ case '!': \ case '&': \ @@ -293,7 +289,7 @@ static size_t get_statement_struct_size(statement_kind_t kind) [STATEMENT_MS_TRY] = sizeof(ms_try_statement_t), [STATEMENT_LEAVE] = sizeof(leave_statement_t) }; - assert(kind < lengthof(sizes)); + assert((size_t)kind < lengthof(sizes)); assert(sizes[kind] != 0); return sizes[kind]; } @@ -345,7 +341,7 @@ static size_t get_expression_struct_size(expression_kind_t kind) if (kind >= EXPR_BINARY_FIRST && kind <= EXPR_BINARY_LAST) { return sizes[EXPR_BINARY_FIRST]; } - assert(kind < lengthof(sizes)); + assert((size_t)kind < lengthof(sizes)); assert(sizes[kind] != 0); return sizes[kind]; } @@ -431,7 +427,7 @@ static size_t get_initializer_size(initializer_kind_t kind) [INITIALIZER_LIST] = sizeof(initializer_list_t), [INITIALIZER_DESIGNATOR] = sizeof(initializer_designator_t) }; - assert(kind < lengthof(sizes)); + assert((size_t)kind < lengthof(sizes)); assert(sizes[kind] != 0); return sizes[kind]; } @@ -707,7 +703,7 @@ static entity_t *get_entity(const symbol_t *const symbol, assert(namespc != NAMESPACE_INVALID); entity_t *entity = symbol->entity; for (; entity != NULL; entity = entity->base.symbol_next) { - if (entity->base.namespc == namespc) + if ((namespace_tag_t)entity->base.namespc == namespc) return entity; } @@ -720,7 +716,7 @@ static entity_t *get_tag(symbol_t const *const symbol, entity_kind_tag_t const kind) { entity_t *entity = get_entity(symbol, NAMESPACE_TAG); - if (entity != NULL && entity->kind != kind) { + if (entity != NULL && (entity_kind_tag_t)entity->kind != kind) { errorf(HERE, "'%Y' defined as wrong kind of tag (previous definition %P)", symbol, &entity->base.source_position); @@ -1269,10 +1265,8 @@ static attribute_t *parse_attribute_gnu_single(void) return NULL; } - const char *name = symbol->string; - next_token(); - - attribute_kind_t kind; + attribute_kind_t kind; + char const *const name = symbol->string; for (kind = ATTRIBUTE_GNU_FIRST;; ++kind) { if (kind > ATTRIBUTE_GNU_LAST) { if (warning.attribute) { @@ -1289,6 +1283,8 @@ static attribute_t *parse_attribute_gnu_single(void) break; } + next_token(); + attribute_t *attribute = allocate_attribute_zero(kind); /* parse arguments */ @@ -1363,10 +1359,10 @@ static attribute_t *parse_attributes(attribute_t *first) break; case T___thiscall: - next_token(); /* TODO record modifier */ if (warning.other) warningf(HERE, "Ignoring declaration modifier %K", &token); + eat(T___thiscall); attribute = allocate_attribute_zero(ATTRIBUTE_MS_THISCALL); break; @@ -1736,13 +1732,12 @@ static initializer_t *initializer_from_expression(type_t *orig_type, } /** - * Checks if a given expression can be used as an constant initializer. + * Checks if a given expression can be used as a constant initializer. */ static bool is_initializer_constant(const expression_t *expression) { - return - is_constant_expression(expression) != EXPR_CLASS_VARIABLE || - is_address_constant(expression) != EXPR_CLASS_VARIABLE; + return is_constant_expression(expression) != EXPR_CLASS_VARIABLE || + is_linker_constant(expression) != EXPR_CLASS_VARIABLE; } /** @@ -2207,10 +2202,11 @@ finish_designator: } if (warning.other) { + source_position_t const* const pos = &expression->base.source_position; if (env->entity != NULL) { - warningf(HERE, "excess elements in initializer for '%Y'", env->entity->base.symbol); + warningf(pos, "excess elements in initializer for '%Y'", env->entity->base.symbol); } else { - warningf(HERE, "excess elements in initializer"); + warningf(pos, "excess elements in initializer"); } } goto error_parse_next; @@ -2437,9 +2433,8 @@ static compound_t *parse_compound_type_specifier(bool is_struct) * existing definition in outer scope */ entity = NULL; } else if (entity->compound.complete && token.type == '{') { - errorf(&pos, "multiple definitions of '%s %Y' (previous definition %P)", - is_struct ? "struct" : "union", symbol, - &entity->base.source_position); + source_position_t const *const ppos = &entity->base.source_position; + errorf(&pos, "multiple definitions of '%N' (previous definition %P)", entity, ppos); /* clear members in the hope to avoid further errors */ entity->compound.members.entities = NULL; } @@ -2544,8 +2539,8 @@ static type_t *parse_enum_specifier(void) * existing definition in outer scope */ entity = NULL; } else if (entity->enume.complete && token.type == '{') { - errorf(&pos, "multiple definitions of 'enum %Y' (previous definition %P)", - symbol, &entity->base.source_position); + source_position_t const *const ppos = &entity->base.source_position; + errorf(&pos, "multiple definitions of '%N' (previous definition %P)", entity, ppos); } } break; @@ -2624,7 +2619,7 @@ static type_t *parse_typeof(void) switch (token.type) { case T_IDENTIFIER: if (is_typedef_symbol(token.symbol)) { - TYPENAME_START + DECLARATION_START type = parse_typename(); } else { default: @@ -2698,7 +2693,6 @@ static attribute_t *parse_attribute_ms_property(attribute_t *attribute) symbol_t **prop; symbol_t *symbol = token.symbol; - next_token(); if (strcmp(symbol->string, "put") == 0) { prop = &property->put_symbol; } else if (strcmp(symbol->string, "get") == 0) { @@ -2707,6 +2701,7 @@ static attribute_t *parse_attribute_ms_property(attribute_t *attribute) errorf(HERE, "expected put or get in property declspec"); prop = NULL; } + eat(T_IDENTIFIER); expect('=', end_error); if (token.type != T_IDENTIFIER) { parse_error_expected("while parsing property declspec", @@ -2733,7 +2728,6 @@ static attribute_t *parse_microsoft_extended_decl_modifier_single(void) kind = ATTRIBUTE_MS_RESTRICT; } else if (token.type == T_IDENTIFIER) { const char *name = token.symbol->string; - next_token(); for (attribute_kind_t k = ATTRIBUTE_MS_FIRST; k <= ATTRIBUTE_MS_LAST; ++k) { const char *attribute_name = get_attribute_name(k); @@ -2746,6 +2740,7 @@ static attribute_t *parse_microsoft_extended_decl_modifier_single(void) if (kind == ATTRIBUTE_UNKNOWN && warning.attribute) { warningf(HERE, "unknown __declspec '%s' ignored", name); } + eat(T_IDENTIFIER); } else { parse_error_expected("while parsing __declspec", T_IDENTIFIER, NULL); return NULL; @@ -2952,8 +2947,10 @@ wrong_thread_storage_class: break; #define CHECK_DOUBLE_TYPE() \ + do { \ if ( type != NULL) \ - errorf(HERE, "multiple data types in declaration specifiers"); + errorf(HERE, "multiple data types in declaration specifiers"); \ + } while(0) case T_struct: CHECK_DOUBLE_TYPE(); @@ -3189,31 +3186,33 @@ warn_about_long_long: case SPECIFIER_LONG | SPECIFIER_DOUBLE | SPECIFIER_IMAGINARY: atomic_type = ATOMIC_TYPE_LONG_DOUBLE; break; - default: + default: { /* invalid specifier combination, give an error message */ + source_position_t const* const pos = &specifiers->source_position; if (type_specifiers == 0) { if (!saw_error) { /* ISO/IEC 14882:1998(E) §C.1.5:4 */ if (!(c_mode & _CXX) && !strict_mode) { if (warning.implicit_int) { - warningf(HERE, "no type specifiers in declaration, using 'int'"); + warningf(pos, "no type specifiers in declaration, using 'int'"); } atomic_type = ATOMIC_TYPE_INT; break; } else { - errorf(HERE, "no type specifiers given in declaration"); + errorf(pos, "no type specifiers given in declaration"); } } } else if ((type_specifiers & SPECIFIER_SIGNED) && (type_specifiers & SPECIFIER_UNSIGNED)) { - errorf(HERE, "signed and unsigned specifiers given"); + errorf(pos, "signed and unsigned specifiers given"); } else if (type_specifiers & (SPECIFIER_SIGNED | SPECIFIER_UNSIGNED)) { - errorf(HERE, "only integer types can be signed or unsigned"); + errorf(pos, "only integer types can be signed or unsigned"); } else { - errorf(HERE, "multiple datatypes in declaration"); + errorf(pos, "multiple datatypes in declaration"); } goto end_error; } + } if (type_specifiers & SPECIFIER_COMPLEX) { type = allocate_type_zero(TYPE_COMPLEX); @@ -3227,7 +3226,7 @@ warn_about_long_long: } newtype = true; } else if (type_specifiers != 0) { - errorf(HERE, "multiple datatypes in declaration"); + errorf(&specifiers->source_position, "multiple datatypes in declaration"); } /* FIXME: check type qualifiers here */ @@ -3308,9 +3307,7 @@ static void semantic_parameter_incomplete(const entity_t *entity) * incomplete type. */ type_t *type = skip_typeref(entity->declaration.type); if (is_type_incomplete(type)) { - errorf(&entity->base.source_position, - "parameter '%#T' has incomplete type", - entity->declaration.type, entity->base.symbol); + errorf(&entity->base.source_position, "'%N' has incomplete type", entity); } } @@ -3769,30 +3766,28 @@ static type_t *construct_declarator_type(construct_type_t *construct_list, if (size_expression != NULL) { switch (is_constant_expression(size_expression)) { - case EXPR_CLASS_CONSTANT: { - long const size = fold_constant_to_int(size_expression); - array_type->array.size = size; - array_type->array.size_constant = true; - /* §6.7.5.2:1 If the expression is a constant expression, it shall - * have a value greater than zero. */ - if (size <= 0) { - if (size < 0 || !GNU_MODE) { - errorf(&size_expression->base.source_position, - "size of array must be greater than zero"); - } else if (warning.other) { - warningf(&size_expression->base.source_position, - "zero length arrays are a GCC extension"); - } - } - break; + case EXPR_CLASS_CONSTANT: { + long const size = fold_constant_to_int(size_expression); + array_type->array.size = size; + array_type->array.size_constant = true; + /* §6.7.5.2:1 If the expression is a constant expression, + * it shall have a value greater than zero. */ + if (size < 0) { + errorf(&size_expression->base.source_position, + "size of array must be greater than zero"); + } else if (size == 0 && !GNU_MODE) { + errorf(&size_expression->base.source_position, + "size of array must be greater than zero (zero length arrays are a GCC extension)"); } + break; + } - case EXPR_CLASS_VARIABLE: - array_type->array.is_vla = true; - break; + case EXPR_CLASS_VARIABLE: + array_type->array.is_vla = true; + break; - case EXPR_CLASS_ERROR: - break; + case EXPR_CLASS_ERROR: + break; } } @@ -3818,7 +3813,7 @@ static type_t *automatic_type_conversion(type_t *orig_type); static type_t *semantic_parameter(const source_position_t *pos, type_t *type, const declaration_specifiers_t *specifiers, - symbol_t *symbol) + entity_t const *const param) { /* §6.7.5.3:7 A declaration of a parameter as ``array of type'' * shall be adjusted to ``qualified pointer to type'', @@ -3829,7 +3824,7 @@ static type_t *semantic_parameter(const source_position_t *pos, type = automatic_type_conversion(type); if (specifiers->is_inline && is_type_valid(type)) { - errorf(pos, "parameter '%#T' declared 'inline'", type, symbol); + errorf(pos, "'%N' declared 'inline'", param); } /* §6.9.1:6 The declarations in the declaration list shall contain @@ -3839,7 +3834,7 @@ static type_t *semantic_parameter(const source_position_t *pos, specifiers->storage_class != STORAGE_CLASS_NONE && specifiers->storage_class != STORAGE_CLASS_REGISTER) ) { - errorf(pos, "invalid storage class for parameter '%#T'", type, symbol); + errorf(pos, "invalid storage class for '%N'", param); } /* delay test for incomplete type, because we might have (void) @@ -3911,10 +3906,8 @@ static entity_t *parse_declarator(const declaration_specifiers_t *specifiers, } } } else if (flags & DECL_IS_PARAMETER) { - orig_type = semantic_parameter(&env.source_position, orig_type, - specifiers, env.symbol); - - entity = allocate_entity_zero(ENTITY_PARAMETER, NAMESPACE_NORMAL, env.symbol); + entity = allocate_entity_zero(ENTITY_PARAMETER, NAMESPACE_NORMAL, env.symbol); + orig_type = semantic_parameter(&env.source_position, orig_type, specifiers, entity); } else if (is_type_function(type)) { entity = allocate_entity_zero(ENTITY_FUNCTION, NAMESPACE_NORMAL, env.symbol); entity->function.is_inline = specifiers->is_inline; @@ -3930,8 +3923,7 @@ static entity_t *parse_declarator(const declaration_specifiers_t *specifiers, specifiers->storage_class != STORAGE_CLASS_NONE && (in_function_scope || specifiers->storage_class != STORAGE_CLASS_STATIC) )) { - errorf(&env.source_position, - "invalid storage class for function '%Y'", env.symbol); + errorf(&env.source_position, "invalid storage class for '%N'", entity); } } } else { @@ -3941,8 +3933,7 @@ static entity_t *parse_declarator(const declaration_specifiers_t *specifiers, if (env.symbol != NULL) { if (specifiers->is_inline && is_type_valid(type)) { - errorf(&env.source_position, - "variable '%Y' declared 'inline'", env.symbol); + errorf(&env.source_position, "'%N' declared 'inline'", entity); } bool invalid_storage_class = false; @@ -3959,8 +3950,7 @@ static entity_t *parse_declarator(const declaration_specifiers_t *specifiers, } } if (invalid_storage_class) { - errorf(&env.source_position, - "invalid storage class for variable '%Y'", env.symbol); + errorf(&env.source_position, "invalid storage class for variable '%N'", entity); } } } @@ -4083,9 +4073,9 @@ static bool is_sym_main(const symbol_t *const sym) static void error_redefined_as_different_kind(const source_position_t *pos, const entity_t *old, entity_kind_t new_kind) { - errorf(pos, "redeclaration of %s '%Y' as %s (declared %P)", - get_entity_kind_name(old->kind), old->base.symbol, - get_entity_kind_name(new_kind), &old->base.source_position); + char const *const what = get_entity_kind_name(new_kind); + source_position_t const *const ppos = &old->base.source_position; + errorf(pos, "redeclaration of '%N' as %s (declared %P)", old, what, ppos); } static bool is_entity_valid(entity_t *const ent) @@ -4163,10 +4153,10 @@ entity_t *record_entity(entity_t *entity, const bool is_definition) assert(is_type_function(type)); if (type->function.unspecified_parameters && - warning.strict_prototypes && - previous_entity == NULL) { - warningf(pos, "function declaration '%#T' is not a prototype", - orig_type, symbol); + warning.strict_prototypes && + previous_entity == NULL && + !entity->declaration.implicit) { + warningf(pos, "function declaration '%#N' is not a prototype", entity); } if (warning.main && current_scope == file_scope @@ -4175,23 +4165,21 @@ entity_t *record_entity(entity_t *entity, const bool is_definition) } } - if (is_declaration(entity) && - warning.nested_externs && - entity->declaration.storage_class == STORAGE_CLASS_EXTERN && - current_scope != file_scope) { - warningf(pos, "nested extern declaration of '%#T'", - entity->declaration.type, symbol); + if (is_declaration(entity) && + warning.nested_externs && + entity->declaration.storage_class == STORAGE_CLASS_EXTERN && + current_scope != file_scope && + !entity->declaration.implicit) { + warningf(pos, "nested extern declaration of '%#N'", entity); } if (previous_entity != NULL) { + source_position_t const *const ppos = &previous_entity->base.source_position; + if (previous_entity->base.parent_scope == ¤t_function->parameters && previous_entity->base.parent_scope->depth + 1 == current_scope->depth) { assert(previous_entity->kind == ENTITY_PARAMETER); - errorf(pos, - "declaration '%#T' redeclares the parameter '%#T' (declared %P)", - entity->declaration.type, symbol, - previous_entity->declaration.type, symbol, - &previous_entity->base.source_position); + errorf(pos, "declaration of '%N' redeclares the '%N' (declared %P)", entity, previous_entity, ppos); goto finish; } @@ -4204,14 +4192,12 @@ entity_t *record_entity(entity_t *entity, const bool is_definition) goto finish; } if (previous_entity->kind == ENTITY_ENUM_VALUE) { - errorf(pos, "redeclaration of enum entry '%Y' (declared %P)", - symbol, &previous_entity->base.source_position); + errorf(pos, "redeclaration of '%N' (declared %P)", entity, ppos); goto finish; } if (previous_entity->kind == ENTITY_TYPEDEF) { /* TODO: C++ allows this for exactly the same type */ - errorf(pos, "redefinition of typedef '%Y' (declared %P)", - symbol, &previous_entity->base.source_position); + errorf(pos, "redefinition of '%N' (declared %P)", entity, ppos); goto finish; } @@ -4232,16 +4218,11 @@ entity_t *record_entity(entity_t *entity, const bool is_definition) return previous_entity; } - type_t *const orig_type = decl->type; - assert(orig_type != NULL); - type_t *const type = skip_typeref(orig_type); + type_t *const type = skip_typeref(decl->type); type_t *const prev_type = skip_typeref(prev_decl->type); if (!types_compatible(type, prev_type)) { - errorf(pos, - "declaration '%#T' is incompatible with '%#T' (declared %P)", - orig_type, symbol, prev_decl->type, symbol, - &previous_entity->base.source_position); + errorf(pos, "declaration '%#N' is incompatible with '%#N' (declared %P)", entity, previous_entity, ppos); } else { unsigned old_storage_class = prev_decl->storage_class; @@ -4250,9 +4231,7 @@ entity_t *record_entity(entity_t *entity, const bool is_definition) !prev_decl->used && !(prev_decl->modifiers & DM_USED) && prev_decl->storage_class == STORAGE_CLASS_STATIC) { - warningf(&previous_entity->base.source_position, - "unnecessary static forward declaration for '%#T'", - prev_decl->type, symbol); + warningf(ppos, "unnecessary static forward declaration for '%#N'", previous_entity); } storage_class_t new_storage_class = decl->storage_class; @@ -4276,8 +4255,7 @@ entity_t *record_entity(entity_t *entity, const bool is_definition) if (warning.missing_prototypes && prev_type->function.unspecified_parameters && !is_sym_main(symbol)) { - warningf(pos, "no previous prototype for '%#T'", - orig_type, symbol); + warningf(pos, "no previous prototype for '%#N'", entity); } } else if (new_storage_class == STORAGE_CLASS_NONE) { new_storage_class = STORAGE_CLASS_EXTERN; @@ -4303,18 +4281,13 @@ warn_redundant_declaration: ; } else if (!is_definition && warning.redundant_decls && is_type_valid(prev_type) && - strcmp(previous_entity->base.source_position.input_name, - "") != 0) { - warningf(pos, - "redundant declaration for '%Y' (declared %P)", - symbol, &previous_entity->base.source_position); + strcmp(ppos->input_name, "") != 0) { + warningf(pos, "redundant declaration for '%Y' (declared %P)", symbol, ppos); } } else if (current_function == NULL) { if (old_storage_class != STORAGE_CLASS_STATIC && new_storage_class == STORAGE_CLASS_STATIC) { - errorf(pos, - "static declaration of '%Y' follows non-static declaration (declared %P)", - symbol, &previous_entity->base.source_position); + errorf(pos, "static declaration of '%Y' follows non-static declaration (declared %P)", symbol, ppos); } else if (old_storage_class == STORAGE_CLASS_EXTERN) { prev_decl->storage_class = STORAGE_CLASS_NONE; prev_decl->declared_storage_class = STORAGE_CLASS_NONE; @@ -4327,12 +4300,9 @@ warn_redundant_declaration: ; } else if (is_type_valid(prev_type)) { if (old_storage_class == new_storage_class) { error_redeclaration: - errorf(pos, "redeclaration of '%Y' (declared %P)", - symbol, &previous_entity->base.source_position); + errorf(pos, "redeclaration of '%Y' (declared %P)", symbol, ppos); } else { - errorf(pos, - "redeclaration of '%Y' with different linkage (declared %P)", - symbol, &previous_entity->base.source_position); + errorf(pos, "redeclaration of '%Y' with different linkage (declared %P)", symbol, ppos); } } } @@ -4346,10 +4316,8 @@ error_redeclaration: if (warning.shadow || (warning.shadow_local && previous_entity->base.parent_scope != file_scope)) { - warningf(pos, "%s '%Y' shadows %s (declared %P)", - get_entity_kind_name(entity->kind), symbol, - get_entity_kind_name(previous_entity->kind), - &previous_entity->base.source_position); + char const *const what = get_entity_kind_name(previous_entity->kind); + warningf(pos, "'%N' shadows %s (declared %P)", entity, what, ppos); } } @@ -4357,20 +4325,16 @@ error_redeclaration: if (is_definition && entity->declaration.storage_class != STORAGE_CLASS_STATIC) { if (warning.missing_prototypes && !is_sym_main(symbol)) { - warningf(pos, "no previous prototype for '%#T'", - entity->declaration.type, symbol); + warningf(pos, "no previous prototype for '%#N'", entity); } else if (warning.missing_declarations && !is_sym_main(symbol)) { - warningf(pos, "no previous declaration for '%#T'", - entity->declaration.type, symbol); + warningf(pos, "no previous declaration for '%#N'", entity); } } - } else if (warning.missing_declarations && - entity->kind == ENTITY_VARIABLE && - current_scope == file_scope) { - declaration_t *declaration = &entity->declaration; - if (declaration->storage_class == STORAGE_CLASS_NONE) { - warningf(pos, "no previous declaration for '%#T'", - declaration->type, symbol); + } else if (entity->kind == ENTITY_VARIABLE) { + if (warning.missing_declarations && + current_scope == file_scope && + entity->declaration.storage_class == STORAGE_CLASS_NONE) { + warningf(pos, "no previous declaration for '%#N'", entity); } } @@ -4392,20 +4356,14 @@ static void parser_error_multiple_definition(entity_t *entity, entity->base.symbol, &entity->base.source_position); } -static bool is_declaration_specifier(const token_t *token, - bool only_specifiers_qualifiers) +static bool is_declaration_specifier(const token_t *token) { switch (token->type) { - TYPE_SPECIFIERS - TYPE_QUALIFIERS + DECLARATION_START return true; case T_IDENTIFIER: return is_typedef_symbol(token->symbol); - case T___extension__: - STORAGE_CLASSES - return !only_specifiers_qualifiers; - default: return false; } @@ -4416,14 +4374,12 @@ static void parse_init_declarator_rest(entity_t *entity) type_t *orig_type = type_error_type; if (entity->base.kind == ENTITY_TYPEDEF) { - errorf(&entity->base.source_position, - "typedef '%Y' is initialized (use __typeof__ instead)", - entity->base.symbol); + source_position_t const *const pos = &entity->base.source_position; + errorf(pos, "'%N' is initialized (use __typeof__ instead)", entity); } else { assert(is_declaration(entity)); orig_type = entity->declaration.type; } - eat('='); type_t *type = skip_typeref(orig_type); @@ -4431,6 +4387,7 @@ static void parse_init_declarator_rest(entity_t *entity) && entity->variable.initializer != NULL) { parser_error_multiple_definition(entity, HERE); } + eat('='); declaration_t *const declaration = &entity->declaration; bool must_be_constant = false; @@ -4440,9 +4397,8 @@ static void parse_init_declarator_rest(entity_t *entity) } if (is_type_function(type)) { - errorf(&entity->base.source_position, - "function '%#T' is initialized like a variable", - orig_type, entity->base.symbol); + source_position_t const *const pos = &entity->base.source_position; + errorf(pos, "'%N' is initialized like a variable", entity); orig_type = type_error_type; } @@ -4510,8 +4466,7 @@ static void check_variable_type_complete(entity_t *ent) decl->storage_class == STORAGE_CLASS_STATIC) return; - type_t *const orig_type = decl->type; - type_t *const type = skip_typeref(orig_type); + type_t *const type = skip_typeref(decl->type); if (!is_type_incomplete(type)) return; @@ -4522,8 +4477,7 @@ static void check_variable_type_complete(entity_t *ent) return; } - errorf(&ent->base.source_position, "variable '%#T' has incomplete type", - orig_type, ent->base.symbol); + errorf(&ent->base.source_position, "variable '%#N' has incomplete type", ent); } @@ -4546,9 +4500,8 @@ static void parse_declaration_rest(entity_t *ndeclaration, if (decl->storage_class != STORAGE_CLASS_EXTERN) { type_t *type = decl->type; if (is_type_reference(skip_typeref(type))) { - errorf(&entity->base.source_position, - "reference '%#T' must be initialized", - type, entity->base.symbol); + source_position_t const *const pos = &entity->base.source_position; + errorf(pos, "reference '%#N' must be initialized", entity); } } } @@ -4586,7 +4539,7 @@ static entity_t *finished_kr_declaration(entity_t *entity, bool is_definition) } if (is_definition) { - errorf(HERE, "parameter '%Y' is initialised", entity->base.symbol); + errorf(HERE, "'%N' is initialised", entity); } return record_entity(entity, false); @@ -4703,14 +4656,13 @@ decl_list_end: type_t *parameter_type = parameter->declaration.type; if (parameter_type == NULL) { + source_position_t const* const pos = ¶meter->base.source_position; if (strict_mode) { - errorf(HERE, "no type specified for function parameter '%Y'", - parameter->base.symbol); + errorf(pos, "no type specified for function '%N'", parameter); parameter_type = type_error_type; } else { if (warning.implicit_int) { - warningf(HERE, "no type specified for function parameter '%Y', using 'int'", - parameter->base.symbol); + warningf(pos, "no type specified for function '%N', using 'int'", parameter); } parameter_type = type_int; } @@ -4736,25 +4688,22 @@ decl_list_end: parameter_type = not_promoted; } } - function_parameter_t *const parameter + function_parameter_t *const function_parameter = allocate_parameter(parameter_type); - *anchor = parameter; - anchor = ¶meter->next; + *anchor = function_parameter; + anchor = &function_parameter->next; } new_type->function.parameters = parameters; new_type = identify_new_type(new_type); if (warning.other && need_incompatible_warning) { - type_t *proto_type_type = proto_type->declaration.type; - warningf(HERE, - "declaration '%#T' is incompatible with '%#T' (declared %P)", - proto_type_type, proto_type->base.symbol, - new_type, entity->base.symbol, - &proto_type->base.source_position); + source_position_t const *const pos = &entity->base.source_position; + source_position_t const *const ppos = &proto_type->base.source_position; + symbol_t const *const sym = entity->base.symbol; + warningf(pos, "declaration '%#N' is incompatible with '%#T' (declared %P)", proto_type, new_type, sym, ppos); } - entity->declaration.type = new_type; rem_anchor_token('{'); @@ -4770,9 +4719,8 @@ static void print_in_function(void) { if (first_err) { first_err = false; - diagnosticf("%s: In function '%Y':\n", - current_function->base.base.source_position.input_name, - current_function->base.base.symbol); + char const *const file = current_function->base.base.source_position.input_name; + diagnosticf("%s: In '%N':\n", file, (entity_t const*)current_function); } } @@ -4790,12 +4738,10 @@ static void check_labels(void) continue; label_t *label = goto_statement->label; - - label->used = true; if (label->base.source_position.input_name == NULL) { print_in_function(); - errorf(&goto_statement->base.source_position, - "label '%Y' used but not defined", label->base.symbol); + source_position_t const *const pos = &goto_statement->base.source_position; + errorf(pos, "'%N' used but not defined", (entity_t const*)label); } } @@ -4807,8 +4753,8 @@ static void check_labels(void) if (! label->used) { print_in_function(); - warningf(&label_statement->base.source_position, - "label '%Y' defined but not used", label->base.symbol); + source_position_t const *const pos = &label_statement->base.source_position; + warningf(pos, "'%N' defined but not used", (entity_t const*)label); } } } @@ -4827,14 +4773,10 @@ static void warn_unused_entity(entity_t *entity, entity_t *last) if (!declaration->used) { print_in_function(); - const char *what = get_entity_kind_name(entity->kind); - warningf(&entity->base.source_position, "%s '%Y' is unused", - what, entity->base.symbol); + warningf(&entity->base.source_position, "'%N' is unused", entity); } else if (entity->kind == ENTITY_VARIABLE && !entity->variable.read) { print_in_function(); - const char *what = get_entity_kind_name(entity->kind); - warningf(&entity->base.source_position, "%s '%Y' is never read", - what, entity->base.symbol); + warningf(&entity->base.source_position, "'%N' is never read", entity); } } } @@ -5033,15 +4975,15 @@ static void check_reachable(statement_t *const stmt) case STATEMENT_DECLARATION: { declaration_statement_t const *const decl = &stmt->declaration; entity_t const * ent = decl->declarations_begin; - entity_t const *const last = decl->declarations_end; + entity_t const *const last_decl = decl->declarations_end; if (ent != NULL) { for (;; ent = ent->base.next) { if (ent->kind == ENTITY_VARIABLE && - ent->variable.initializer != NULL && - !initializer_returns(ent->variable.initializer)) { + ent->variable.initializer != NULL && + !initializer_returns(ent->variable.initializer)) { return; } - if (ent == last) + if (ent == last_decl) break; } } @@ -5539,30 +5481,27 @@ static void parse_external_declaration(void) if (!is_type_function(type)) { if (is_type_valid(type)) { - errorf(HERE, "declarator '%#T' has a body but is not a function type", - type, ndeclaration->base.symbol); + errorf(HERE, "declarator '%#N' has a body but is not a function type", ndeclaration); } eat_block(); return; - } else if (is_typeref(orig_type)) { + } + + source_position_t const *const pos = &ndeclaration->base.source_position; + if (is_typeref(orig_type)) { /* §6.9.1:2 */ - errorf(&ndeclaration->base.source_position, - "type of function definition '%#T' is a typedef", - orig_type, ndeclaration->base.symbol); + errorf(pos, "type of function definition '%#N' is a typedef", ndeclaration); } if (warning.aggregate_return && is_type_compound(skip_typeref(type->function.return_type))) { - warningf(&ndeclaration->base.source_position, "function '%Y' returns an aggregate", - ndeclaration->base.symbol); + warningf(pos, "'%N' returns an aggregate", ndeclaration); } if (warning.traditional && !type->function.unspecified_parameters) { - warningf(&ndeclaration->base.source_position, "traditional C rejects ISO C style function definition of function '%Y'", - ndeclaration->base.symbol); + warningf(pos, "traditional C rejects ISO C style definition of '%N'", ndeclaration); } if (warning.old_style_definition && type->function.unspecified_parameters) { - warningf(&ndeclaration->base.source_position, "old-style function definition '%Y'", - ndeclaration->base.symbol); + warningf(pos, "old-style definition of '%N'", ndeclaration); } /* §6.7.5.3:14 a function definition with () means no @@ -5639,9 +5578,8 @@ static void parse_external_declaration(void) if (warning.missing_noreturn && noreturn_candidate && !(function->base.modifiers & DM_NORETURN)) { - warningf(&body->base.source_position, - "function '%#T' is candidate for attribute 'noreturn'", - type, entity->base.symbol); + source_position_t const *const pos = &body->base.source_position; + warningf(pos, "function '%#N' is candidate for attribute 'noreturn'", entity); } } @@ -5670,8 +5608,7 @@ static type_t *make_bitfield_type(type_t *base_type, expression_t *size, il_size_t bit_size; type_t *skipped_type = skip_typeref(base_type); if (!is_type_integer(skipped_type)) { - errorf(HERE, "bitfield base type '%T' is not an integer type", - base_type); + errorf(source_position, "bitfield base type '%T' is not an integer type", base_type); bit_size = 0; } else { bit_size = get_type_size(base_type) * 8; @@ -5732,16 +5669,12 @@ static void check_deprecated(const source_position_t *source_position, if ((entity->declaration.modifiers & DM_DEPRECATED) == 0) return; - char const *const prefix = get_entity_kind_name(entity->kind); - const char *deprecated_string - = get_deprecated_string(entity->declaration.attributes); - if (deprecated_string != NULL) { - warningf(source_position, "%s '%Y' is deprecated (declared %P): \"%s\"", - prefix, entity->base.symbol, &entity->base.source_position, - deprecated_string); + source_position_t const *const pos = &entity->base.source_position; + char const* const msg = get_deprecated_string(entity->declaration.attributes); + if (msg != NULL) { + warningf(source_position, "'%N' is deprecated (declared %P): \"%s\"", entity, pos, msg); } else { - warningf(source_position, "%s '%Y' is deprecated (declared %P)", prefix, - entity->base.symbol, &entity->base.source_position); + warningf(source_position, "'%N' is deprecated (declared %P)", entity, pos); } } @@ -5850,9 +5783,9 @@ static void parse_compound_declarators(compound_t *compound, } else { entity = parse_declarator(specifiers, DECL_MAY_BE_ABSTRACT | DECL_CREATE_COMPOUND_MEMBER); + source_position_t const *const pos = &entity->base.source_position; if (entity->kind == ENTITY_TYPEDEF) { - errorf(&entity->base.source_position, - "typedef not allowed as compound member"); + errorf(pos, "typedef not allowed as compound member"); } else { assert(entity->kind == ENTITY_COMPOUND_MEMBER); @@ -5861,9 +5794,8 @@ static void parse_compound_declarators(compound_t *compound, if (symbol != NULL) { entity_t *prev = find_compound_entry(compound, symbol); if (prev != NULL) { - errorf(&entity->base.source_position, - "multiple declarations of symbol '%Y' (declared %P)", - symbol, &prev->base.source_position); + source_position_t const *const ppos = &prev->base.source_position; + errorf(pos, "multiple declarations of symbol '%Y' (declared %P)", symbol, ppos); } } @@ -5883,17 +5815,13 @@ static void parse_compound_declarators(compound_t *compound, type_t *orig_type = entity->declaration.type; type_t *type = skip_typeref(orig_type); if (is_type_function(type)) { - errorf(&entity->base.source_position, - "compound member '%Y' must not have function type '%T'", - entity->base.symbol, orig_type); + errorf(pos, "'%N' must not have function type '%T'", entity, orig_type); } else if (is_type_incomplete(type)) { /* §6.7.2.1:16 flexible array member */ if (!is_type_array(type) || token.type != ';' || look_ahead(1)->type != '}') { - errorf(&entity->base.source_position, - "compound member '%Y' has incomplete type '%T'", - entity->base.symbol, orig_type); + errorf(pos, "'%N' has incomplete type '%T'", entity, orig_type); } } } @@ -5938,7 +5866,7 @@ static type_t *parse_typename(void) /* TODO: improve error message, user does probably not know what a * storage class is... */ - errorf(HERE, "typename must not have a storage class"); + errorf(&specifiers.source_position, "typename must not have a storage class"); } type_t *result = parse_abstract_declarator(specifiers.type); @@ -5959,7 +5887,7 @@ struct expression_parser_function_t { parse_expression_infix_function infix_parser; }; -expression_parser_function_t expression_parsers[T_LAST_TOKEN]; +static expression_parser_function_t expression_parsers[T_LAST_TOKEN]; /** * Prints an error message if an expression was expected but not read @@ -6214,12 +6142,8 @@ static entity_t *create_implicit_function(symbol_t *symbol, entity->declaration.implicit = true; entity->base.source_position = *source_position; - if (current_scope != NULL) { - bool strict_prototypes_old = warning.strict_prototypes; - warning.strict_prototypes = false; + if (current_scope != NULL) record_entity(entity, false); - warning.strict_prototypes = strict_prototypes_old; - } return entity; } @@ -6323,7 +6247,8 @@ static entity_t *lookup_entity(const scope_t *scope, symbol_t *symbol, construct a hashmap here... */ entity_t *entity = scope->entities; for ( ; entity != NULL; entity = entity->base.next) { - if (entity->base.symbol == symbol && entity->base.namespc == namespc) + if (entity->base.symbol == symbol + && (namespace_tag_t)entity->base.namespc == namespc) break; } @@ -6368,7 +6293,11 @@ static entity_t *parse_qualified_identifier(void) default: errorf(&pos, "'%Y' must be a namespace, class, struct or union (but is a %s)", symbol, get_entity_kind_name(entity->kind)); - goto end_error; + + /* skip further qualifications */ + while (next_if(T_IDENTIFIER) && next_if(T_COLONCOLON)) {} + + return create_error_entity(sym_anonymous, ENTITY_VARIABLE); } } @@ -6389,12 +6318,6 @@ static entity_t *parse_qualified_identifier(void) } return entity; - -end_error: - /* skip further qualifications */ - while (next_if(T_IDENTIFIER) && next_if(T_COLONCOLON)) {} - - return create_error_entity(sym_anonymous, ENTITY_VARIABLE); } static expression_t *parse_reference(void) @@ -6442,13 +6365,12 @@ static expression_t *parse_reference(void) current_function->need_closure = true; } - check_deprecated(HERE, entity); + check_deprecated(&pos, entity); if (warning.init_self && entity == current_init_decl && !in_type_prop && entity->kind == ENTITY_VARIABLE) { current_init_decl = NULL; - warningf(&pos, "variable '%#T' is initialized by itself", - entity->declaration.type, entity->base.symbol); + warningf(&pos, "variable '%#N' is initialized by itself", entity); } return expression; @@ -6604,8 +6526,7 @@ static expression_t *parse_parenthesized_expression(void) case T_IDENTIFIER: if (is_typedef_symbol(la1->symbol)) { - TYPE_QUALIFIERS - TYPE_SPECIFIERS + DECLARATION_START return parse_cast(); } } @@ -6991,15 +6912,14 @@ end_error: } /** - * Return the declaration for a given label symbol or create a new one. - * - * @param symbol the symbol of the label + * Return the label for the current symbol or create a new one. */ -static label_t *get_label(symbol_t *symbol) +static label_t *get_label(void) { + assert(token.type == T_IDENTIFIER); assert(current_function != NULL); - entity_t *label = get_entity(symbol, NAMESPACE_LABEL); + entity_t *label = get_entity(token.symbol, NAMESPACE_LABEL); /* If we find a local label, we already created the declaration. */ if (label != NULL && label->kind == ENTITY_LOCAL_LABEL) { if (label->base.parent_scope != current_scope) { @@ -7008,10 +6928,11 @@ static label_t *get_label(symbol_t *symbol) } } else if (label == NULL || label->base.parent_scope != ¤t_function->parameters) { /* There is no matching label in the same function, so create a new one. */ - label = allocate_entity_zero(ENTITY_LABEL, NAMESPACE_LABEL, symbol); + label = allocate_entity_zero(ENTITY_LABEL, NAMESPACE_LABEL, token.symbol); label_push(label); } + eat(T_IDENTIFIER); return &label->label; } @@ -7024,24 +6945,20 @@ static expression_t *parse_label_address(void) eat(T_ANDAND); if (token.type != T_IDENTIFIER) { parse_error_expected("while parsing label address", T_IDENTIFIER, NULL); - goto end_error; + return create_invalid_expression(); } - symbol_t *symbol = token.symbol; - next_token(); - label_t *label = get_label(symbol); + label_t *const label = get_label(); label->used = true; label->address_taken = true; expression_t *expression = allocate_expression_zero(EXPR_LABEL_ADDRESS); expression->base.source_position = source_position; - /* label address is threaten as a void pointer */ + /* label address is treated as a void pointer */ expression->base.type = type_void_ptr; expression->label_address.label = label; return expression; -end_error: - return create_invalid_expression(); } /** @@ -7127,9 +7044,11 @@ static expression_t *parse_primary_expression(void) return parse_reference(); } /* FALLTHROUGH */ - TYPENAME_START { - source_position_t const pos = *HERE; - type_t const *const type = parse_typename(); + DECLARATION_START { + source_position_t const pos = *HERE; + declaration_specifiers_t specifiers; + parse_declaration_specifiers(&specifiers); + type_t const *const type = parse_abstract_declarator(specifiers.type); errorf(&pos, "encountered type '%T' while parsing expression", type); return create_invalid_expression(); } @@ -7181,9 +7100,7 @@ check_idx: } } else { if (is_type_valid(type_left) && is_type_valid(type_inside)) { - errorf(HERE, - "array access on object with non-pointer types '%T', '%T'", - orig_type_left, orig_type_inside); + errorf(&expr->base.source_position, "invalid types '%T[%T]' for array access", orig_type_left, orig_type_inside); } res_type = type_error_type; ref = left; @@ -7213,7 +7130,7 @@ static expression_t *parse_typeprop(expression_kind_t const kind) type_t *orig_type; expression_t *expression; - if (token.type == '(' && is_declaration_specifier(look_ahead(1), true)) { + if (token.type == '(' && is_declaration_specifier(look_ahead(1))) { next_token(); add_anchor_token(')'); orig_type = parse_typename(); @@ -7530,16 +7447,16 @@ static expression_t *parse_call_expression(expression_t *expression) /* do default promotion for other arguments */ for (; argument != NULL; argument = argument->next) { - type_t *type = argument->expression->base.type; - if (!is_type_object(skip_typeref(type))) { + type_t *argument_type = argument->expression->base.type; + if (!is_type_object(skip_typeref(argument_type))) { errorf(&argument->expression->base.source_position, "call argument '%E' must not be void", argument->expression); } - type = get_default_promoted_type(type); + argument_type = get_default_promoted_type(argument_type); argument->expression - = create_implicit_cast(argument->expression, type); + = create_implicit_cast(argument->expression, argument_type); } check_format(call); @@ -7607,9 +7524,9 @@ static void warn_reference_address_as_bool(expression_t const* expr) expr = get_reference_address(expr); if (expr != NULL) { - warningf(&expr->base.source_position, - "the address of '%Y' will always evaluate as 'true'", - expr->reference.entity->base.symbol); + source_position_t const *const pos = &expr->base.source_position; + entity_t const *const ent = expr->reference.entity; + warningf(pos, "the address of '%N' will always evaluate as 'true'", ent); } } @@ -7746,13 +7663,10 @@ end_error:; } result_type = pointer_type; } else { - if (is_type_valid(other_type)) { - type_error_incompatible("while parsing conditional", - &expression->base.source_position, true_type, false_type); - } - result_type = type_error_type; + goto types_incompatible; } } else { +types_incompatible: if (is_type_valid(true_type) && is_type_valid(false_type)) { type_error_incompatible("while parsing conditional", &conditional->base.source_position, true_type, @@ -8039,9 +7953,8 @@ static void set_address_taken(expression_t *expression, bool may_be_register) if (entity->declaration.storage_class == STORAGE_CLASS_REGISTER && !may_be_register) { - errorf(&expression->base.source_position, - "address of register %s '%Y' requested", - get_entity_kind_name(entity->kind), entity->base.symbol); + source_position_t const *const pos = &expression->base.source_position; + errorf(pos, "address of register '%N' requested", entity); } if (entity->kind == ENTITY_VARIABLE) { @@ -8433,25 +8346,6 @@ static void warn_string_literal_address(expression_t const* expr) } } -static void warn_comparison_in_comparison(const expression_t *const expr) -{ - if (expr->base.parenthesized) - return; - switch (expr->base.kind) { - case EXPR_BINARY_LESS: - case EXPR_BINARY_GREATER: - case EXPR_BINARY_LESSEQUAL: - case EXPR_BINARY_GREATEREQUAL: - case EXPR_BINARY_NOTEQUAL: - case EXPR_BINARY_EQUAL: - warningf(&expr->base.source_position, - "comparisons like 'x <= y < z' do not have their mathematical meaning"); - break; - default: - break; - } -} - static bool maybe_negative(expression_t const *const expr) { switch (is_constant_expression(expr)) { @@ -8461,39 +8355,47 @@ static bool maybe_negative(expression_t const *const expr) } } -/** - * Check the semantics of comparison expressions. - * - * @param expression The expression to check. - */ -static void semantic_comparison(binary_expression_t *expression) +static void warn_comparison(source_position_t const *const pos, expression_t const *const expr, expression_t const *const other) { - expression_t *left = expression->left; - expression_t *right = expression->right; - if (warning.address) { - warn_string_literal_address(left); - warn_string_literal_address(right); + warn_string_literal_address(expr); - expression_t const* const func_left = get_reference_address(left); - if (func_left != NULL && is_null_pointer_constant(right)) { - warningf(&expression->base.source_position, - "the address of '%Y' will never be NULL", - func_left->reference.entity->base.symbol); + expression_t const* const ref = get_reference_address(expr); + if (ref != NULL && is_null_pointer_constant(other)) { + entity_t const *const ent = ref->reference.entity; + warningf(pos, "the address of '%N' will never be NULL", ent); } + } - expression_t const* const func_right = get_reference_address(right); - if (func_right != NULL && is_null_pointer_constant(right)) { - warningf(&expression->base.source_position, - "the address of '%Y' will never be NULL", - func_right->reference.entity->base.symbol); + if (warning.parentheses && !expr->base.parenthesized) { + switch (expr->base.kind) { + case EXPR_BINARY_LESS: + case EXPR_BINARY_GREATER: + case EXPR_BINARY_LESSEQUAL: + case EXPR_BINARY_GREATEREQUAL: + case EXPR_BINARY_NOTEQUAL: + case EXPR_BINARY_EQUAL: + warningf(pos, "comparisons like 'x <= y < z' do not have their mathematical meaning"); + break; + default: + break; } } +} - if (warning.parentheses) { - warn_comparison_in_comparison(left); - warn_comparison_in_comparison(right); - } +/** + * Check the semantics of comparison expressions. + * + * @param expression The expression to check. + */ +static void semantic_comparison(binary_expression_t *expression) +{ + source_position_t const *const pos = &expression->base.source_position; + expression_t *const left = expression->left; + expression_t *const right = expression->right; + + warn_comparison(pos, left, right); + warn_comparison(pos, right, left); type_t *orig_type_left = left->base.type; type_t *orig_type_right = right->base.type; @@ -8513,8 +8415,7 @@ static void semantic_comparison(binary_expression_t *expression) /* TODO check whether constant value can be represented by other type */ if ((signed_left && maybe_negative(left)) || (signed_right && maybe_negative(right))) { - warningf(&expression->base.source_position, - "comparison between signed and unsigned"); + warningf(pos, "comparison between signed and unsigned"); } } } @@ -8526,8 +8427,7 @@ static void semantic_comparison(binary_expression_t *expression) (expression->base.kind == EXPR_BINARY_EQUAL || expression->base.kind == EXPR_BINARY_NOTEQUAL) && is_type_float(arithmetic_type)) { - warningf(&expression->base.source_position, - "comparing floating point with == or != is unsafe"); + warningf(pos, "comparing floating point with == or != is unsafe"); } } else if (is_type_pointer(type_left) && is_type_pointer(type_right)) { /* TODO check compatibility */ @@ -8536,9 +8436,7 @@ static void semantic_comparison(binary_expression_t *expression) } else if (is_type_pointer(type_right)) { expression->left = create_implicit_cast(left, type_right); } else if (is_type_valid(type_left) && is_type_valid(type_right)) { - type_error_incompatible("invalid operands in comparison", - &expression->base.source_position, - type_left, type_right); + type_error_incompatible("invalid operands in comparison", pos, type_left, type_right); } expression->base.type = c_mode & _CXX ? type_bool : type_int; } @@ -9428,8 +9326,7 @@ end_error: if (current_switch != NULL) { const case_label_statement_t *def_label = current_switch->default_label; if (def_label != NULL) { - errorf(HERE, "multiple default labels in one switch (previous declared %P)", - &def_label->base.source_position); + errorf(&statement->base.source_position, "multiple default labels in one switch (previous declared %P)", &def_label->base.source_position); } else { current_switch->default_label = &statement->case_label; @@ -9457,25 +9354,20 @@ end_error: */ static statement_t *parse_label_statement(void) { - assert(token.type == T_IDENTIFIER); - symbol_t *symbol = token.symbol; - label_t *label = get_label(symbol); - statement_t *const statement = allocate_statement_zero(STATEMENT_LABEL); - statement->label.label = label; - - next_token(); + label_t *const label = get_label(); + statement->label.label = label; PUSH_PARENT(statement); /* if statement is already set then the label is defined twice, * otherwise it was just mentioned in a goto/local label declaration so far */ + source_position_t const* const pos = &statement->base.source_position; if (label->statement != NULL) { - errorf(HERE, "duplicate label '%Y' (declared %P)", - symbol, &label->base.source_position); + errorf(pos, "duplicate '%N' (declared %P)", (entity_t const*)label, &label->base.source_position); } else { - label->base.source_position = token.source_position; + label->base.source_position = *pos; label->statement = statement; } @@ -9569,10 +9461,8 @@ static void check_enum_cases(const switch_statement_t *statement) break; } } - if (! found) { - warningf(&statement->base.source_position, - "enumeration value '%Y' not handled in switch", - entry->base.symbol); + if (!found) { + warningf(&statement->base.source_position, "'%N' not handled in switch", entry); } last_value = value; } @@ -9731,7 +9621,7 @@ static statement_t *parse_for(void) } if (next_if(';')) { - } else if (is_declaration_specifier(&token, false)) { + } else if (is_declaration_specifier(&token)) { parse_declaration(record_entity, DECL_FLAGS_NONE); } else { add_anchor_token(';'); @@ -9819,9 +9709,9 @@ static statement_t *parse_goto(void) statement->gotos.expression = expression; } else if (token.type == T_IDENTIFIER) { - symbol_t *symbol = token.symbol; - next_token(); - statement->gotos.label = get_label(symbol); + label_t *const label = get_label(); + label->used = true; + statement->gotos.label = label; } else { if (GNU_MODE) parse_error_expected("while parsing goto", T_IDENTIFIER, '*', NULL); @@ -10136,8 +10026,8 @@ static statement_t *parse_local_label_declaration(void) symbol_t *symbol = token.symbol; entity_t *entity = get_entity(symbol, NAMESPACE_LABEL); if (entity != NULL && entity->base.parent_scope == current_scope) { - errorf(HERE, "multiple definitions of '__label__ %Y' (previous definition %P)", - symbol, &entity->base.source_position); + source_position_t const *const ppos = &entity->base.source_position; + errorf(HERE, "multiple definitions of '%N' (previous definition %P)", entity, ppos); } else { entity = allocate_entity_zero(ENTITY_LOCAL_LABEL, NAMESPACE_LABEL, symbol); entity->base.parent_scope = current_scope; @@ -10600,7 +10490,6 @@ static void check_unused_globals(void) declaration->storage_class != STORAGE_CLASS_STATIC) continue; - type_t *const type = declaration->type; const char *s; if (entity->kind == ENTITY_FUNCTION) { /* inhibit warning for static inline functions */ @@ -10612,8 +10501,7 @@ static void check_unused_globals(void) s = "defined"; } - warningf(&declaration->base.source_position, "'%#T' %s but not used", - type, declaration->base.symbol, s); + warningf(&declaration->base.source_position, "'%#N' %s but not used", entity); } } @@ -10638,7 +10526,8 @@ static void parse_linkage_specification(void) { eat(T_extern); - const char *linkage = parse_string_literals().begin; + source_position_t const pos = *HERE; + char const *const linkage = parse_string_literals().begin; linkage_kind_t old_linkage = current_linkage; linkage_kind_t new_linkage; @@ -10647,7 +10536,7 @@ static void parse_linkage_specification(void) } else if (strcmp(linkage, "C++") == 0) { new_linkage = LINKAGE_CXX; } else { - errorf(HERE, "linkage string \"%s\" not recognized", linkage); + errorf(&pos, "linkage string \"%s\" not recognized", linkage); new_linkage = LINKAGE_INVALID; } current_linkage = new_linkage; @@ -10725,23 +10614,17 @@ static void parse_externals(void) while (token.type != T_EOF && token.type != '}') { #ifndef NDEBUG - bool anchor_leak = false; for (int i = 0; i < T_LAST_TOKEN; ++i) { unsigned char count = token_anchor_set[i] - token_anchor_copy[i]; if (count != 0) { /* the anchor set and its copy differs */ internal_errorf(HERE, "Leaked anchor token %k %d times", i, count); - anchor_leak = true; } } if (in_gcc_extension) { /* an gcc extension scope was not closed */ internal_errorf(HERE, "Leaked __extension__"); - anchor_leak = true; } - - if (anchor_leak) - abort(); #endif parse_external(); @@ -10828,17 +10711,15 @@ static void complete_incomplete_arrays(void) { size_t n = ARR_LEN(incomplete_arrays); for (size_t i = 0; i != n; ++i) { - declaration_t *const decl = incomplete_arrays[i]; - type_t *const orig_type = decl->type; - type_t *const type = skip_typeref(orig_type); + declaration_t *const decl = incomplete_arrays[i]; + type_t *const type = skip_typeref(decl->type); if (!is_type_incomplete(type)) continue; if (warning.other) { - warningf(&decl->base.source_position, - "array '%#T' assumed to have one element", - orig_type, decl->base.symbol); + source_position_t const *const pos = &decl->base.source_position; + warningf(pos, "array '%#N' assumed to have one element", (entity_t const*)decl); } type_t *const new_type = duplicate_type(type);