simple support for __attribute__((alias("symbol")))
[cparser] / ast2firm.c
index 28b5f31..8d24dd7 100644 (file)
@@ -193,9 +193,7 @@ static unsigned decide_modulo_shift(unsigned type_size)
 {
        if (architecture_modulo_shift == 0)
                return 0;
-       if (type_size < architecture_modulo_shift)
-               return architecture_modulo_shift;
-       return type_size;
+       return MAX(type_size, architecture_modulo_shift);
 }
 
 static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
@@ -896,6 +894,8 @@ static bool declaration_is_definition(const entity_t *entity)
        switch (entity->kind) {
        case ENTITY_VARIABLE:
                return entity->declaration.storage_class != STORAGE_CLASS_EXTERN;
+// TODO: alias provides a definition
+//                    || entity->variable.alias != NULL;
        case ENTITY_FUNCTION:
                return entity->function.body != NULL;
        case ENTITY_PARAMETER:
@@ -941,8 +941,10 @@ static void handle_decl_modifiers(ir_entity *irentity, entity_t *entity)
        if ((modifiers & DM_USED) && declaration_is_definition(entity)) {
                add_entity_linkage(irentity, IR_LINKAGE_HIDDEN_USER);
        }
-       if ((modifiers & DM_WEAK) && declaration_is_definition(entity)
-           && entity->declaration.storage_class != STORAGE_CLASS_EXTERN) {
+// TODO: i dont understand this logic
+//     if ((modifiers & DM_WEAK) && declaration_is_definition(entity)
+//         && entity->declaration.storage_class != STORAGE_CLASS_EXTERN) {
+       if (modifiers & DM_WEAK) {
                add_entity_linkage(irentity, IR_LINKAGE_WEAK);
        }
 }
@@ -2688,28 +2690,31 @@ static ir_node *sizeof_to_firm(const typeprop_expression_t *expression)
        return get_type_size_node(type);
 }
 
-static entity_t *get_expression_entity(const expression_t *expression)
-{
-       if (expression->kind != EXPR_REFERENCE)
-               return NULL;
+static unsigned get_object_alignment(expression_t const *expr);
 
-       return expression->reference.entity;
+static unsigned get_address_alignment(expression_t const *const expr)
+{
+       if (expr->kind == EXPR_UNARY_TAKE_ADDRESS) {
+               return get_object_alignment(expr->unary.value);
+       } else {
+               type_t *const type = skip_typeref(expr->base.type);
+               assert(is_type_pointer(type));
+               return get_type_alignment(type->pointer.points_to);
+       }
 }
 
-static unsigned get_cparser_entity_alignment(const entity_t *entity)
+static unsigned get_object_alignment(expression_t const *const expr)
 {
-       switch (entity->kind) {
-       case DECLARATION_KIND_CASES:
-               return entity->declaration.alignment;
-       case ENTITY_STRUCT:
-       case ENTITY_UNION:
-               return entity->compound.alignment;
-       case ENTITY_TYPEDEF:
-               return entity->typedefe.alignment;
-       default:
-               break;
+       entity_t *ent;
+       switch (expr->kind) {
+       case EXPR_ARRAY_ACCESS:      return get_address_alignment(expr->array_access.array_ref);
+       case EXPR_UNARY_DEREFERENCE: return get_address_alignment(expr->unary.value);
+       case EXPR_REFERENCE:         ent = expr->reference.entity;      break;
+       case EXPR_SELECT:            ent = expr->select.compound_entry; break;
+       default:                     return get_type_alignment(expr->base.type);
        }
-       return 0;
+       assert(is_declaration(ent));
+       return ent->declaration.alignment;
 }
 
 /**
@@ -2717,20 +2722,9 @@ static unsigned get_cparser_entity_alignment(const entity_t *entity)
  */
 static ir_node *alignof_to_firm(const typeprop_expression_t *expression)
 {
-       unsigned alignment = 0;
-
-       const expression_t *tp_expression = expression->tp_expression;
-       if (tp_expression != NULL) {
-               entity_t *entity = get_expression_entity(tp_expression);
-               if (entity != NULL) {
-                       alignment = get_cparser_entity_alignment(entity);
-               }
-       }
-
-       if (alignment == 0) {
-               type_t *type = expression->type;
-               alignment = get_type_alignment(type);
-       }
+       unsigned const alignment = expression->tp_expression
+               ? get_object_alignment(expression->tp_expression)
+               : get_type_alignment(expression->type);
 
        dbg_info  *dbgi = get_dbg_info(&expression->base.pos);
        ir_mode   *mode = get_ir_mode_storage(expression->base.type);
@@ -4685,6 +4679,18 @@ static void create_variable_initializer(entity_t *entity)
 {
        assert(entity->kind == ENTITY_VARIABLE);
        initializer_t *initializer = entity->variable.initializer;
+       if (entity->variable.alias != NULL) {
+               const namespace_tag_t namespc = (namespace_tag_t)entity->base.namespc;
+               entity_t *a = entity->variable.alias->entity;
+               for (; a != NULL; a = a->base.symbol_next) {
+                       if ((namespace_tag_t)a->base.namespc == namespc)
+                               break;
+               }
+               assert(a != NULL && a->kind == ENTITY_VARIABLE && a->variable.v.entity != NULL);
+               set_entity_alias(entity->variable.v.entity, a->variable.v.entity);
+               /* prevent usage assumption to be made about aliased variables */
+               add_entity_linkage(a->variable.v.entity, IR_LINKAGE_HIDDEN_USER);
+       }
        if (initializer == NULL)
                return;
 
@@ -5805,6 +5811,21 @@ static void create_function(entity_t *entity)
        assert(entity->kind == ENTITY_FUNCTION);
        ir_entity *function_entity = get_function_entity(entity, current_outer_frame);
 
+       if (entity->function.alias != NULL) {
+               const namespace_tag_t namespc = (namespace_tag_t)entity->base.namespc;
+               entity_t *a = entity->function.alias->entity;
+               for (; a != NULL; a = a->base.symbol_next) {
+                       if ((namespace_tag_t)a->base.namespc == namespc)
+                               break;
+               }
+// TODO: or use entitymap
+//             ir_entity *a = entitymap_get(&entitymap, entity->function.alias);
+               assert(a != NULL && a->kind == ENTITY_VARIABLE && a->function.irentity != NULL);
+               set_entity_alias(entity->function.irentity, a->function.irentity);
+               /* prevent usage assumption to be made about aliased functions */
+               add_entity_linkage(a->function.irentity, IR_LINKAGE_HIDDEN_USER);
+       }
+
        if (entity->function.body == NULL)
                return;
 
@@ -5895,32 +5916,6 @@ static void create_function(entity_t *entity)
 
        irg_finalize_cons(irg);
 
-       /* finalize the frame type */
-       ir_type *frame_type = get_irg_frame_type(irg);
-       int      n          = get_compound_n_members(frame_type);
-       int      align_all  = 4;
-       int      offset     = 0;
-       for (int i = 0; i < n; ++i) {
-               ir_entity *member      = get_compound_member(frame_type, i);
-               ir_type   *entity_type = get_entity_type(member);
-
-               int align = get_type_alignment_bytes(entity_type);
-               if (align > align_all)
-                       align_all = align;
-               int misalign = 0;
-               if (align > 0) {
-                       misalign  = offset % align;
-                       if (misalign > 0) {
-                               offset += align - misalign;
-                       }
-               }
-
-               set_entity_offset(member, offset);
-               offset += get_type_size_bytes(entity_type);
-       }
-       set_type_size_bytes(frame_type, offset);
-       set_type_alignment_bytes(frame_type, align_all);
-
        irg_verify(irg, VERIFY_ENFORCE_SSA);
        current_vararg_entity = old_current_vararg_entity;
        current_function      = old_current_function;