top->type = top_type;
if (is_type_compound(top_type)) {
- compound_t *compound = top_type->compound.compound;
- entity_t *entry = compound->members.entities;
+ compound_t *const compound = top_type->compound.compound;
+ entity_t *const entry = skip_unnamed_bitfields(compound->members.entities);
if (entry != NULL) {
- assert(entry->kind == ENTITY_COMPOUND_MEMBER);
top->v.compound_entry = &entry->declaration;
path->top_type = entry->declaration.type;
} else {
} else if (is_type_struct(type)) {
declaration_t *entry = top->v.compound_entry;
- entity_t *next_entity = entry->base.next;
+ entity_t *const next_entity = skip_unnamed_bitfields(entry->base.next);
if (next_entity != NULL) {
assert(is_declaration(next_entity));
entry = &next_entity->declaration;
goto finish;
}
if (previous_entity->kind == ENTITY_TYPEDEF) {
- /* TODO: C++ allows this for exactly the same type */
- errorf(pos, "redefinition of '%N' (declared %P)", entity, ppos);
+ type_t *const type = skip_typeref(entity->typedefe.type);
+ type_t *const prev_type
+ = skip_typeref(previous_entity->typedefe.type);
+ /* gcc extension redef in system headers is allowed */
+ if ((!(c_mode & _CXX) && !pos->is_system_header)
+ || !types_compatible(type, prev_type)) {
+ errorf(pos, "redefinition of '%N' (declared %P)",
+ entity, ppos);
+ }
goto finish;
}
merge_in_attributes(decl, prev_decl->attributes);
} else if (!is_definition &&
is_type_valid(prev_type) &&
- strcmp(ppos->input_name, "<builtin>") != 0) {
+ !pos->is_system_header) {
warningf(WARN_REDUNDANT_DECLS, pos, "redundant declaration for '%Y' (declared %P)", symbol, ppos);
}
} else if (current_function == NULL) {
if (entity == NULL) {
if (!strict_mode && token.kind == '(') {
/* an implicitly declared function */
- warningf(WARN_IMPLICIT_FUNCTION_DECLARATION, &pos, "implicit declaration of function '%Y'", symbol);
+ warningf(WARN_IMPLICIT_FUNCTION_DECLARATION, &pos,
+ "implicit declaration of function '%Y'", symbol);
entity = create_implicit_function(symbol, &pos);
} else {
errorf(&pos, "unknown identifier '%Y' found.", symbol);
/**
* Handle the semantic restrictions of builtin calls
*/
-static void handle_builtin_argument_restrictions(call_expression_t *call) {
- switch (call->function->reference.entity->function.btk) {
- case bk_gnu_builtin_return_address:
- case bk_gnu_builtin_frame_address: {
+static void handle_builtin_argument_restrictions(call_expression_t *call)
+{
+ entity_t *entity = call->function->reference.entity;
+ switch (entity->function.btk) {
+ case BUILTIN_FIRM:
+ switch (entity->function.b.firm_builtin_kind) {
+ case ir_bk_return_address:
+ case ir_bk_frame_address: {
/* argument must be constant */
call_argument_t *argument = call->arguments;
if (is_constant_expression(argument->expression) == EXPR_CLASS_VARIABLE) {
errorf(&call->base.source_position,
- "argument of '%Y' must be a constant expression",
- call->function->reference.entity->base.symbol);
- }
- break;
- }
- case bk_gnu_builtin_object_size:
- if (call->arguments == NULL)
- break;
-
- call_argument_t *arg = call->arguments->next;
- if (arg != NULL && is_constant_expression(arg->expression) == EXPR_CLASS_VARIABLE) {
- errorf(&call->base.source_position,
- "second argument of '%Y' must be a constant expression",
+ "argument of '%Y' must be a constant expression",
call->function->reference.entity->base.symbol);
}
break;
- case bk_gnu_builtin_prefetch:
+ }
+ case ir_bk_prefetch:
/* second and third argument must be constant if existent */
if (call->arguments == NULL)
break;
if (rw != NULL) {
if (is_constant_expression(rw->expression) == EXPR_CLASS_VARIABLE) {
errorf(&call->base.source_position,
- "second argument of '%Y' must be a constant expression",
- call->function->reference.entity->base.symbol);
+ "second argument of '%Y' must be a constant expression",
+ call->function->reference.entity->base.symbol);
}
locality = rw->next;
}
if (locality != NULL) {
if (is_constant_expression(locality->expression) == EXPR_CLASS_VARIABLE) {
errorf(&call->base.source_position,
- "third argument of '%Y' must be a constant expression",
- call->function->reference.entity->base.symbol);
+ "third argument of '%Y' must be a constant expression",
+ call->function->reference.entity->base.symbol);
}
locality = rw->next;
}
break;
default:
break;
+ }
+
+ case BUILTIN_OBJECT_SIZE:
+ if (call->arguments == NULL)
+ break;
+
+ call_argument_t *arg = call->arguments->next;
+ if (arg != NULL && is_constant_expression(arg->expression) == EXPR_CLASS_VARIABLE) {
+ errorf(&call->base.source_position,
+ "second argument of '%Y' must be a constant expression",
+ call->function->reference.entity->base.symbol);
+ }
+ break;
+ default:
+ break;
}
}
if (expression->kind == EXPR_REFERENCE) {
reference_expression_t *reference = &expression->reference;
if (reference->entity->kind == ENTITY_FUNCTION &&
- reference->entity->function.btk != bk_none)
+ reference->entity->function.btk != BUILTIN_NONE)
handle_builtin_argument_restrictions(call);
}