if( to if (
[cparser] / ast2firm.c
index 509f302..e9d4267 100644 (file)
@@ -219,8 +219,6 @@ static unsigned get_array_type_size(array_type_t *type)
 
 static unsigned get_type_size_const(type_t *type)
 {
-       type = skip_typeref(type);
-
        switch(type->kind) {
        case TYPE_ERROR:
                panic("error type occurred");
@@ -339,6 +337,21 @@ static ir_type *create_imaginary_type(const imaginary_type_t *type)
        return irtype;
 }
 
+/**
+ * return type of a parameter (and take transparent union gnu extension into
+ * account)
+ */
+static type_t *get_parameter_type(type_t *type)
+{
+       type = skip_typeref(type);
+       if (type->base.modifiers & TYPE_MODIFIER_TRANSPARENT_UNION) {
+               declaration_t *decl = type->compound.declaration;
+               type                = decl->scope.declarations->type;
+       }
+
+       return type;
+}
+
 static ir_type *create_method_type(const function_type_t *function_type)
 {
        type_t  *return_type  = function_type->return_type;
@@ -357,7 +370,8 @@ static ir_type *create_method_type(const function_type_t *function_type)
        function_parameter_t *parameter = function_type->parameters;
        int                   n         = 0;
        for ( ; parameter != NULL; parameter = parameter->next) {
-               ir_type *p_irtype = get_ir_type(parameter->type);
+               type_t  *type     = get_parameter_type(parameter->type);
+               ir_type *p_irtype = get_ir_type(type);
                set_method_param_type(irtype, n, p_irtype);
                ++n;
        }
@@ -484,7 +498,7 @@ static ir_type *get_unsigned_int_type_for_bit_size(ir_type *base_tp,
 static ir_type *create_bitfield_type(bitfield_type_t *const type)
 {
        type_t *base = skip_typeref(type->base_type);
-       assert(base->kind == TYPE_ATOMIC);
+       assert(base->kind == TYPE_ATOMIC || base->kind == TYPE_ENUM);
        ir_type *irbase = get_ir_type(base);
 
        unsigned size = fold_constant(type->size);
@@ -998,14 +1012,23 @@ 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));
 
-       if (declaration->storage_class == STORAGE_CLASS_STATIC
-                       || declaration->is_inline) {
-               if (declaration->init.statement == NULL) {
+       /* static inline             => local
+        * extern inline             => local
+        * inline without definition => local
+        * inline with definition    => external_visible */
+       storage_class_tag_t const storage_class = declaration->storage_class;
+       bool                const is_inline     = declaration->is_inline;
+       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 && has_body)) {
+               if (!has_body) {
                        /* this entity was declared, but is defined nowhere */
                        set_entity_peculiarity(entity, peculiarity_description);
                }
                set_entity_visibility(entity, visibility_local);
-       } else if (declaration->init.statement != NULL) {
+       } else if (has_body) {
                set_entity_visibility(entity, visibility_external_visible);
        } else {
                set_entity_visibility(entity, visibility_external_allocated);
@@ -1472,9 +1495,10 @@ static ir_node *process_builtin_call(const call_expression_t *call)
 
 /**
  * Transform a call expression.
- * Handles some special cases, like alloca() calls, which must be resolved BEFORE the inlines runs.
- * Inlining routines calling alloca() is dangerous, 176.gcc for instance might allocate 2GB instead of
- * 256 MB if alloca is not handled right...
+ * Handles some special cases, like alloca() calls, which must be resolved
+ * BEFORE the inlines runs. Inlining routines calling alloca() is dangerous,
+ * 176.gcc for instance might allocate 2GB instead of 256 MB if alloca is not
+ * handled right...
  */
 static ir_node *call_expression_to_firm(const call_expression_t *call)
 {
@@ -2072,7 +2096,7 @@ static ir_node *adjust_for_pointer_arithmetic(dbg_info *dbgi,
                ir_node *value, type_t *type)
 {
        pointer_type_t *const pointer_type = &type->pointer;
-       type_t         *const points_to    = pointer_type->points_to;
+       type_t         *const points_to    = skip_typeref(pointer_type->points_to);
        unsigned              elem_size    = get_type_size_const(points_to);
 
        /* gcc extension */
@@ -3399,7 +3423,7 @@ static ir_initializer_t *create_ir_initializer_string(
        ir_initializer_t *irinitializer = create_initializer_compound(len);
 
        const char *string = initializer->string.begin;
-       ir_mode    *mode   = get_type_mode(ir_type_const_char);
+       ir_mode    *mode   = get_ir_mode(type->array.element_type);
 
        for(size_t i = 0; i < len; ++i) {
                char c = 0;
@@ -3671,6 +3695,8 @@ static void create_declaration_initializer(declaration_t *declaration)
                return;
        }
 
+       type_t *type = skip_typeref(declaration->type);
+
        if (initializer->kind == INITIALIZER_VALUE) {
                initializer_value_t *initializer_value = &initializer->value;
                dbg_info            *dbgi
@@ -3686,7 +3712,11 @@ static void create_declaration_initializer(declaration_t *declaration)
 
                        ir_entity *entity = declaration->v.entity;
 
-                       set_entity_variability(entity, variability_initialized);
+                       if (type->base.qualifiers & TYPE_QUALIFIER_CONST) {
+                               set_entity_variability(entity, variability_constant);
+                       } else {
+                               set_entity_variability(entity, variability_initialized);
+                       }
                        set_atomic_ent_value(entity, value);
                }
        } else {
@@ -3695,9 +3725,13 @@ static void create_declaration_initializer(declaration_t *declaration)
 
                ir_entity        *entity        = declaration->v.entity;
                ir_initializer_t *irinitializer
-                       = create_ir_initializer(initializer, declaration->type);
+                       = create_ir_initializer(initializer, type);
 
-               set_entity_variability(entity, variability_initialized);
+               if (type->base.qualifiers & TYPE_QUALIFIER_CONST) {
+                       set_entity_variability(entity, variability_constant);
+               } else {
+                       set_entity_variability(entity, variability_initialized);
+               }
                set_entity_initializer(entity, irinitializer);
        }
 }
@@ -4680,6 +4714,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];
@@ -4690,10 +4729,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) {
@@ -4786,7 +4821,8 @@ static int count_local_declarations(const declaration_t *      decl,
        for (; decl != end; decl = decl->next) {
                if (decl->namespc != NAMESPACE_NORMAL)
                        continue;
-               const type_t *type = skip_typeref(decl->type);
+               type_t *type = skip_typeref(decl->type);
+
                if (!decl->address_taken && is_type_scalar(type))
                        ++count;
                const initializer_t *initializer = decl->init.initializer;
@@ -5051,7 +5087,7 @@ static void initialize_function_parameters(declaration_t *declaration)
                long     pn    = n;
                ir_node *value = new_r_Proj(irg, start_block, args, param_mode, pn);
 
-               ir_mode *mode = get_ir_mode(parameter->type);
+               ir_mode *mode = get_ir_mode(type);
                value = create_conv(NULL, value, mode);
                value = do_strict_conv(NULL, value);