X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=3a2e22078c2d92f66a5a880125317918851b5689;hb=4108d31ed34aee3c0841ae01b844420da8a3cdf1;hp=7a0ca4dc1be2e4f840deb6fb4de5602f7631280c;hpb=3a0d95404de6b0a97994658d0cd3b59180504b4f;p=cparser diff --git a/ast2firm.c b/ast2firm.c index 7a0ca4d..3a2e220 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -96,9 +96,11 @@ ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos) { const declaration_t *declaration = get_irg_loc_description(irg, pos); - warningf(&declaration->source_position, - "variable '%#T' might be used uninitialized", - declaration->type, declaration->symbol); + if (declaration != NULL) { + warningf(&declaration->source_position, + "variable '%#T' might be used uninitialized", + declaration->type, declaration->symbol); + } return new_r_Unknown(irg, mode); } @@ -380,6 +382,34 @@ static ir_type *create_method_type(const function_type_t *function_type) set_method_variadicity(irtype, variadicity_variadic); } + unsigned cc = get_method_calling_convention(irtype); + switch (function_type->calling_convention) { + case CC_DEFAULT: /* unspecified calling convention, equal to one of the other, typically cdecl */ + case CC_CDECL: +is_cdecl: + set_method_calling_convention(irtype, SET_CDECL(cc)); + break; + + case CC_STDCALL: + if (function_type->variadic || function_type->unspecified_parameters) + goto is_cdecl; + + /* only non-variadic function can use stdcall, else use cdecl */ + set_method_calling_convention(irtype, SET_STDCALL(cc)); + break; + + case CC_FASTCALL: + if (function_type->variadic || function_type->unspecified_parameters) + goto is_cdecl; + /* only non-variadic function can use fastcall, else use cdecl */ + set_method_calling_convention(irtype, SET_FASTCALL(cc)); + break; + + case CC_THISCALL: + /* Hmm, leave default, not accepted by the parser yet. */ + warningf(&function_type->base.source_position, "THISCALL calling convention not supported yet"); + break; + } return irtype; } @@ -980,6 +1010,26 @@ typedef ident* (*create_ld_ident_func)(ir_entity *entity, declaration_t *declaration); create_ld_ident_func create_ld_ident = create_ld_ident_linux_elf; +/** + * Handle GNU attributes for entities + * + * @param ent the entity + * @param decl the routine declaration + */ +static void handle_gnu_attributes_ent(ir_entity *ent, declaration_t *decl) +{ + if (decl->modifiers & DM_PURE) { + /* TRUE if the declaration includes the GNU + __attribute__((pure)) specifier. */ + set_entity_additional_property(ent, mtp_property_pure); + } + if (decl->modifiers & DM_USED) { + /* TRUE if the declaration includes the GNU + __attribute__((used)) specifier. */ + set_entity_stickyness(ent, stickyness_sticky); + } +} + /** * Creates an entity representing a function. * @@ -1012,6 +1062,8 @@ static ir_entity *get_function_entity(declaration_t *declaration) entity = new_d_entity(global_type, id, ir_type_method, dbgi); set_entity_ld_ident(entity, create_ld_ident(entity, declaration)); + handle_gnu_attributes_ent(entity, declaration); + /* static inline => local * extern inline => local * inline without definition => local @@ -1021,7 +1073,8 @@ static ir_entity *get_function_entity(declaration_t *declaration) bool const has_body = declaration->init.statement != NULL; if (is_inline && storage_class == STORAGE_CLASS_NONE && has_body) { set_entity_visibility(entity, visibility_external_visible); - } else if (storage_class == STORAGE_CLASS_STATIC || is_inline) { + } else if (storage_class == STORAGE_CLASS_STATIC || + (is_inline && has_body)) { if (!has_body) { /* this entity was declared, but is defined nowhere */ set_entity_peculiarity(entity, peculiarity_description); @@ -4713,6 +4766,11 @@ static void asm_statement_to_firm(const asm_statement_t *statement) } /* create output projs & connect them */ + if (needs_memory) { + ir_node *projm = new_Proj(node, mode_M, out_size+1); + set_store(projm); + } + size_t i; for (i = 0; i < out_size; ++i) { const expression_t *out_expr = out_exprs[i]; @@ -4723,10 +4781,6 @@ static void asm_statement_to_firm(const asm_statement_t *statement) set_value_for_expression_addr(out_expr, proj, addr); } - if (needs_memory) { - ir_node *projm = new_Proj(node, mode_M, i); - set_store(projm); - } } static void ms_try_statement_to_firm(ms_try_statement_t *statement) { @@ -5377,6 +5431,23 @@ void exit_ast2firm(void) obstack_free(&asm_obst, NULL); } +static void global_asm_to_firm(statement_t *s) +{ + for (; s != NULL; s = s->base.next) { + assert(s->kind == STATEMENT_ASM); + + char const *const text = s->asms.asm_text.begin; + size_t size = s->asms.asm_text.size; + + /* skip the last \0 */ + if (text[size - 1] == '\0') + --size; + + ident *const id = new_id_from_chars(text, size); + add_irp_asm(id); + } +} + void translation_unit_to_firm(translation_unit_t *unit) { /* just to be sure */ @@ -5387,4 +5458,5 @@ void translation_unit_to_firm(translation_unit_t *unit) init_ir_types(); scope_to_firm(&unit->scope); + global_asm_to_firm(unit->global_asm); }