static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
{
assert(entity->kind == ENTITY_FUNCTION);
- if (entity->function.entity != NULL) {
- return entity->function.entity;
+ if (entity->function.irentity != NULL) {
+ return entity->function.irentity;
}
if (is_main(entity)) {
entitymap_insert(&entitymap, symbol, irentity);
entity_created:
- entity->declaration.kind = DECLARATION_KIND_FUNCTION;
- entity->function.entity = irentity;
+ entity->declaration.kind = DECLARATION_KIND_FUNCTION;
+ entity->function.irentity = irentity;
return irentity;
}
return res;
}
- return create_symconst(dbgi, mode, entity->function.entity);
+ return create_symconst(dbgi, mode, entity->function.irentity);
}
case DECLARATION_KIND_INNER_FUNCTION: {
ir_mode *const mode = get_ir_mode_storage(type);
if (!entity->function.goto_to_outer && !entity->function.need_closure) {
/* inner function not using the closure */
- return create_symconst(dbgi, mode, entity->function.entity);
+ return create_symconst(dbgi, mode, entity->function.irentity);
} else {
/* need trampoline here */
- return create_trampoline(dbgi, mode, entity->function.entity);
+ return create_trampoline(dbgi, mode, entity->function.irentity);
}
}
case DECLARATION_KIND_GLOBAL_VARIABLE: {
case DECLARATION_KIND_FUNCTION: {
type_t *const type = skip_typeref(entity->declaration.type);
ir_mode *const mode = get_ir_mode_storage(type);
- return create_symconst(dbgi, mode, entity->function.entity);
+ return create_symconst(dbgi, mode, entity->function.irentity);
}
case DECLARATION_KIND_INNER_FUNCTION: {
ir_mode *const mode = get_ir_mode_storage(type);
if (!entity->function.goto_to_outer && !entity->function.need_closure) {
/* inner function not using the closure */
- return create_symconst(dbgi, mode, entity->function.entity);
+ return create_symconst(dbgi, mode, entity->function.irentity);
} else {
/* need trampoline here */
- return create_trampoline(dbgi, mode, entity->function.entity);
+ return create_trampoline(dbgi, mode, entity->function.irentity);
}
}
const reference_expression_t *ref = &function->reference;
entity_t *entity = ref->entity;
- if (ref->entity->kind == ENTITY_FUNCTION &&
- ref->entity->function.btk != bk_none) {
- return process_builtin_call(call);
- }
+ if (entity->kind == ENTITY_FUNCTION) {
+ if (entity->function.btk != bk_none) {
+ return process_builtin_call(call);
+ }
- if (entity->kind == ENTITY_FUNCTION
- && entity->function.entity == rts_entities[rts_alloca]) {
- /* handle alloca() call */
- expression_t *argument = call->arguments->expression;
- ir_node *size = expression_to_firm(argument);
- ir_mode *mode = get_ir_mode_arithmetic(type_size_t);
+ ir_entity *irentity = entity->function.irentity;
+ if (irentity == NULL)
+ irentity = get_function_entity(entity, NULL);
- size = create_conv(dbgi, size, mode);
+ if (irentity == rts_entities[rts_alloca]) {
+ /* handle alloca() call */
+ expression_t *argument = call->arguments->expression;
+ ir_node *size = expression_to_firm(argument);
+ ir_mode *mode = get_ir_mode_arithmetic(type_size_t);
- ir_node *store = get_store();
- ir_node *alloca = new_d_Alloc(dbgi, store, size, firm_unknown_type,
- stack_alloc);
- ir_node *proj_m = new_Proj(alloca, mode_M, pn_Alloc_M);
- set_store(proj_m);
- ir_node *res = new_Proj(alloca, mode_P_data, pn_Alloc_res);
+ size = create_conv(dbgi, size, mode);
- return res;
+ ir_node *store = get_store();
+ ir_node *alloca = new_d_Alloc(dbgi, store, size,
+ firm_unknown_type, stack_alloc);
+ ir_node *proj_m = new_Proj(alloca, mode_M, pn_Alloc_M);
+ set_store(proj_m);
+ ir_node *res = new_Proj(alloca, mode_P_data, pn_Alloc_res);
+
+ return res;
+ }
}
}
ir_node *callee = expression_to_firm(function);
if (entity->function.statement == NULL)
return;
+ if (is_main(entity) && firm_opt.os_support == OS_SUPPORT_MINGW) {
+ prepare_main_collect2(entity);
+ }
+
inner_functions = NULL;
current_trampolines = NULL;
* @param decl the declaration to check
* @param type the function type of the declaration
*/
-static void check_type_of_main(const entity_t *entity)
+static void check_main(const entity_t *entity)
{
const source_position_t *pos = &entity->base.source_position;
if (entity->kind != ENTITY_FUNCTION) {
if (warning.main && current_scope == file_scope
&& is_sym_main(symbol)) {
- check_type_of_main(entity);
+ check_main(entity);
}
}
entity->base.symbol = symbol;
entity->base.source_position = *source_position;
- bool strict_prototypes_old = warning.strict_prototypes;
- warning.strict_prototypes = false;
- record_entity(entity, false);
- warning.strict_prototypes = strict_prototypes_old;
+ if (current_scope != NULL) {
+ bool strict_prototypes_old = warning.strict_prototypes;
+ warning.strict_prototypes = false;
+ record_entity(entity, false);
+ warning.strict_prototypes = strict_prototypes_old;
+ }
return entity;
}
}
}
+void prepare_main_collect2(entity_t *entity)
+{
+ // create call to __main
+ symbol_t *symbol = symbol_table_insert("__main");
+ entity_t *subsubmain_ent
+ = create_implicit_function(symbol, &builtin_source_position);
+
+ expression_t *ref = allocate_expression_zero(EXPR_REFERENCE);
+ type_t *ftype = subsubmain_ent->declaration.type;
+ ref->base.source_position = builtin_source_position;
+ ref->base.type = make_pointer_type(ftype, TYPE_QUALIFIER_NONE);
+ ref->reference.entity = subsubmain_ent;
+
+ expression_t *call = allocate_expression_zero(EXPR_CALL);
+ call->base.source_position = builtin_source_position;
+ call->base.type = type_void;
+ call->call.function = ref;
+
+ statement_t *expr_statement = allocate_statement_zero(STATEMENT_EXPRESSION);
+ expr_statement->base.source_position = builtin_source_position;
+ expr_statement->expression.expression = call;
+
+ statement_t *statement = entity->function.statement;
+ assert(statement->kind == STATEMENT_COMPOUND);
+ compound_statement_t *compounds = &statement->compound;
+
+ expr_statement->base.next = compounds->statements;
+ compounds->statements = expr_statement;
+}
+
void parse(void)
{
lookahead_bufpos = 0;