+ if (previous_entity->kind != entity->kind) {
+ error_redefined_as_different_kind(pos, previous_entity,
+ entity->kind);
+ goto finish;
+ }
+ if (previous_entity->kind == ENTITY_ENUM_VALUE) {
+ errorf(pos,
+ "redeclaration of enum entry '%Y' (declared %P)",
+ symbol, &previous_entity->base.source_position);
+ 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);
+ goto finish;
+ }
+
+ /* at this point we should have only VARIABLES or FUNCTIONS */
+ assert(is_declaration(previous_entity) && is_declaration(entity));
+
+ /* can happen for K&R style declarations */
+ if (previous_entity->kind == ENTITY_VARIABLE
+ && previous_entity->declaration.type == NULL
+ && entity->kind == ENTITY_VARIABLE) {
+ previous_entity->declaration.type = entity->declaration.type;
+ previous_entity->declaration.storage_class
+ = entity->declaration.storage_class;
+ previous_entity->declaration.declared_storage_class
+ = entity->declaration.declared_storage_class;
+ previous_entity->declaration.modifiers
+ = entity->declaration.modifiers;
+ previous_entity->declaration.deprecated_string
+ = entity->declaration.deprecated_string;
+ }
+ assert(entity->declaration.type != NULL);
+
+ declaration_t *const previous_declaration
+ = &previous_entity->declaration;
+ declaration_t *const declaration = &entity->declaration;
+ type_t *const orig_type = entity->declaration.type;
+ type_t *const type = skip_typeref(orig_type);
+
+ type_t *prev_type = skip_typeref(previous_declaration->type);
+
+ if (!types_compatible(type, prev_type)) {
+ errorf(pos,
+ "declaration '%#T' is incompatible with '%#T' (declared %P)",
+ orig_type, symbol, previous_declaration->type, symbol,
+ &previous_entity->base.source_position);
+ } else {
+ unsigned old_storage_class = previous_declaration->storage_class;
+ if (warning.redundant_decls && is_definition
+ && previous_declaration->storage_class == STORAGE_CLASS_STATIC
+ && !(previous_declaration->modifiers & DM_USED)
+ && !previous_declaration->used) {
+ warningf(&previous_entity->base.source_position,
+ "unnecessary static forward declaration for '%#T'",
+ previous_declaration->type, symbol);
+ }
+
+ unsigned new_storage_class = declaration->storage_class;