attempt to fix bug #40
authorMatthias Braun <matze@braunis.de>
Mon, 9 Mar 2009 20:01:48 +0000 (20:01 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 9 Mar 2009 20:01:48 +0000 (20:01 +0000)
[r25652]

ast2firm.c
entity_t.h
parser.c
parser.h

index 0fa1e3e..634bb79 100644 (file)
@@ -934,8 +934,8 @@ static bool is_main(entity_t *entity)
 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)) {
@@ -1037,8 +1037,8 @@ static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
        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;
 }
@@ -1484,16 +1484,16 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
 
                        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: {
@@ -1564,7 +1564,7 @@ static ir_node *reference_addr(const reference_expression_t *ref)
        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: {
@@ -1572,10 +1572,10 @@ static ir_node *reference_addr(const reference_expression_t *ref)
                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);
                }
        }
 
@@ -1853,28 +1853,32 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
                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);
@@ -5700,6 +5704,10 @@ static void create_function(entity_t *entity)
        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;
 
index ee19b7b..5003cbc 100644 (file)
@@ -303,7 +303,7 @@ struct function_t {
        statement_t   *statement;
 
        /* ast2firm info */
-       ir_entity     *entity;
+       ir_entity     *irentity;
        ir_node       *static_link;        /**< if need_closure is set, the node representing
                                                                                    the static link. */
 };
index 1f3173f..93c338f 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -4203,7 +4203,7 @@ static type_t *parse_abstract_declarator(type_t *base_type)
  * @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) {
@@ -4312,7 +4312,7 @@ static entity_t *record_entity(entity_t *entity, const bool is_definition)
 
                if (warning.main && current_scope == file_scope
                                && is_sym_main(symbol)) {
-                       check_type_of_main(entity);
+                       check_main(entity);
                }
        }
 
@@ -6237,10 +6237,12 @@ static entity_t *create_implicit_function(symbol_t *symbol,
        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;
 }
@@ -10878,6 +10880,36 @@ static void complete_incomplete_arrays(void)
        }
 }
 
+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;
index 1bc004d..4bc63fb 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -35,4 +35,6 @@ translation_unit_t *finish_parsing(void);
 type_t   *revert_automatic_type_conversion(const expression_t *expression);
 entity_t *expression_is_variable(const expression_t *expression);
 
+void prepare_main_collect2(entity_t *entity);
+
 #endif