From: Christoph Mallon Date: Wed, 16 May 2012 05:05:40 +0000 (+0200) Subject: Implement reference_expression_to_firm() by using reference_addr() in most cases. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=599f3e2bf39b65bebc51971f5b01a50fc41410b3;p=cparser Implement reference_expression_to_firm() by using reference_addr() in most cases. - Correct the problem, that implicitly taking the address of a builtin function (without &) works, but using & panics by moving the special case handling to reference_addr(). - Reduces code duplication. --- diff --git a/ast2firm.c b/ast2firm.c index 93360ef..8a02168 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -1515,15 +1515,11 @@ static ir_node *enum_constant_to_firm(reference_expression_t const *const ref) return new_Const(entity->enum_value.tv); } -static ir_node *reference_expression_to_firm(const reference_expression_t *ref) +static ir_node *reference_addr(const reference_expression_t *ref) { dbg_info *dbgi = get_dbg_info(&ref->base.source_position); entity_t *entity = ref->entity; assert(is_declaration(entity)); - type_t *type = skip_typeref(entity->declaration.type); - - /* make sure the type is constructed */ - (void) get_ir_type(type); if (entity->kind == ENTITY_FUNCTION && entity->function.btk != BUILTIN_NONE) { @@ -1542,60 +1538,6 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref) } } - switch ((declaration_kind_t) entity->declaration.kind) { - case DECLARATION_KIND_UNKNOWN: - break; - - case DECLARATION_KIND_LOCAL_VARIABLE: - case DECLARATION_KIND_PARAMETER: { - ir_mode *const mode = get_ir_mode_storage(type); - ir_node *const value = get_value(entity->variable.v.value_number, mode); - return create_conv(NULL, value, get_ir_mode_arithmetic(type)); - } - - case DECLARATION_KIND_FUNCTION: { - return create_symconst(dbgi, 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, entity->function.irentity); - } else { - /* need trampoline here */ - return create_trampoline(dbgi, mode, entity->function.irentity); - } - } - case DECLARATION_KIND_GLOBAL_VARIABLE: { - const variable_t *variable = &entity->variable; - ir_node *const addr = create_symconst(dbgi, variable->v.entity); - return deref_address(dbgi, variable->base.type, addr); - } - - case DECLARATION_KIND_LOCAL_VARIABLE_ENTITY: - case DECLARATION_KIND_PARAMETER_ENTITY: { - ir_entity *irentity = entity->variable.v.entity; - ir_node *frame = get_local_frame(irentity); - ir_node *sel = new_d_simpleSel(dbgi, new_NoMem(), frame, irentity); - return deref_address(dbgi, entity->declaration.type, sel); - } - - case DECLARATION_KIND_VARIABLE_LENGTH_ARRAY: - return entity->variable.v.vla_base; - - case DECLARATION_KIND_COMPOUND_MEMBER: - panic("not implemented reference type"); - } - - panic("reference to declaration with unknown type found"); -} - -static ir_node *reference_addr(const reference_expression_t *ref) -{ - dbg_info *dbgi = get_dbg_info(&ref->base.source_position); - entity_t *entity = ref->entity; - assert(is_declaration(entity)); - switch((declaration_kind_t) entity->declaration.kind) { case DECLARATION_KIND_UNKNOWN: break; @@ -1643,6 +1585,28 @@ static ir_node *reference_addr(const reference_expression_t *ref) panic("reference to declaration with unknown type found"); } +static ir_node *reference_expression_to_firm(const reference_expression_t *ref) +{ + dbg_info *const dbgi = get_dbg_info(&ref->base.source_position); + entity_t *const entity = ref->entity; + assert(is_declaration(entity)); + + switch ((declaration_kind_t)entity->declaration.kind) { + case DECLARATION_KIND_LOCAL_VARIABLE: + case DECLARATION_KIND_PARAMETER: { + type_t *const type = skip_typeref(entity->declaration.type); + ir_mode *const mode = get_ir_mode_storage(type); + ir_node *const value = get_value(entity->variable.v.value_number, mode); + return create_conv(dbgi, value, get_ir_mode_arithmetic(type)); + } + + default: { + ir_node *const addr = reference_addr(ref); + return deref_address(dbgi, entity->declaration.type, addr); + } + } +} + /** * Transform calls to builtin functions. */