support compound literals as initializers
[cparser] / ast2firm.c
index d79075f..de449ff 100644 (file)
@@ -2912,8 +2912,6 @@ bool fold_constant_to_bool(const expression_t *expression)
 
 static ir_node *conditional_to_firm(const conditional_expression_t *expression)
 {
-       dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
-
        /* first try to fold a constant condition */
        if (is_constant_expression(expression->condition) == EXPR_CLASS_CONSTANT) {
                bool val = fold_constant_to_bool(expression->condition);
@@ -2954,7 +2952,8 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression)
                ir_node *const false_val = expression_to_firm(expression->false_expression);
                jump_to_target(&exit_target);
                if (val) {
-                       ir_node *const in[] = { val, false_val };
+                       ir_node  *const in[] = { val, false_val };
+                       dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
                        val = new_rd_Phi(dbgi, exit_target.block, lengthof(in), in, get_irn_mode(val));
                } else {
                        val = false_val;
@@ -3425,26 +3424,33 @@ static ir_node *create_condition_evaluation(expression_t const *const expression
                break;
        }
 
-       dbg_info *dbgi       = get_dbg_info(&expression->base.source_position);
-       ir_node  *cond_expr  = _expression_to_firm(expression);
-       ir_node  *condition  = create_conv(dbgi, cond_expr, mode_b);
-       ir_node  *cond       = new_d_Cond(dbgi, condition);
-       ir_node  *true_proj  = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
-       ir_node  *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false);
-
-       /* set branch prediction info based on __builtin_expect */
-       if (is_builtin_expect(expression) && is_Cond(cond)) {
-               call_argument_t *argument = expression->call.arguments->next;
-               if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
-                       bool               const cnst = fold_constant_to_bool(argument->expression);
-                       cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
-                       set_Cond_jmp_pred(cond, pred);
+       ir_node *cond_expr = _expression_to_firm(expression);
+       if (is_Const(cond_expr)) {
+               if (tarval_is_null(get_Const_tarval(cond_expr))) {
+                       jump_to_target(false_target);
+               } else {
+                       jump_to_target(true_target);
+               }
+       } else {
+               dbg_info *dbgi       = get_dbg_info(&expression->base.source_position);
+               ir_node  *condition  = create_conv(dbgi, cond_expr, mode_b);
+               ir_node  *cond       = new_d_Cond(dbgi, condition);
+               ir_node  *true_proj  = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
+               ir_node  *false_proj = new_d_Proj(dbgi, cond, mode_X, pn_Cond_false);
+
+               /* set branch prediction info based on __builtin_expect */
+               if (is_builtin_expect(expression) && is_Cond(cond)) {
+                       call_argument_t *argument = expression->call.arguments->next;
+                       if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
+                               bool               const cnst = fold_constant_to_bool(argument->expression);
+                               cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
+                               set_Cond_jmp_pred(cond, pred);
+                       }
                }
-       }
-
-       add_pred_to_jump_target(true_target,  true_proj);
-       add_pred_to_jump_target(false_target, false_proj);
 
+               add_pred_to_jump_target(true_target,  true_proj);
+               add_pred_to_jump_target(false_target, false_proj);
+       }
        set_unreachable_now();
        return cond_expr;
 }
@@ -3731,11 +3737,20 @@ static void advance_current_object(type_path_t *path)
 static ir_initializer_t *create_ir_initializer_value(
                const initializer_value_t *initializer)
 {
-       if (is_type_compound(initializer->value->base.type)) {
-               panic("initializer creation for compounds not implemented yet");
-       }
-       type_t       *type = initializer->value->base.type;
        expression_t *expr = initializer->value;
+       type_t       *type = expr->base.type;
+
+       if (is_type_compound(type)) {
+               if (expr->kind == EXPR_UNARY_CAST) {
+                       expr = expr->unary.value;
+                       type = expr->base.type;
+               }
+               /* must be a compound literal... */
+               if (expr->kind != EXPR_COMPOUND_LITERAL)
+                       panic("initializer creation for compounds needs compound literals");
+               return create_ir_initializer(expr->compound_literal.initializer, type);
+       }
+
        ir_node *value = expression_to_firm(expr);
        ir_mode *mode  = get_ir_mode_storage(type);
        value          = create_conv(NULL, value, mode);
@@ -3771,13 +3786,14 @@ static ir_initializer_t *create_ir_initializer_list(
                }
 
                if (sub_initializer->kind == INITIALIZER_VALUE) {
-                       /* we might have to descend into types until we're at a scalar
-                        * type */
+                       const expression_t *expr      = sub_initializer->value.value;
+                       const type_t       *expr_type = skip_typeref(expr->base.type);
+                       /* we might have to descend into types until the types match */
                        while(true) {
                                type_t *orig_top_type = path.top_type;
                                type_t *top_type      = skip_typeref(orig_top_type);
 
-                               if (is_type_scalar(top_type))
+                               if (types_compatible(top_type, expr_type))
                                        break;
                                descend_into_subtype(&path);
                        }
@@ -5219,6 +5235,7 @@ static void create_function(entity_t *entity)
        }
 
        if (enter_jump_target(&ijmp_target)) {
+               keep_loop();
                size_t   const n    = ARR_LEN(ijmp_ops);
                ir_node *const op   = n == 1 ? ijmp_ops[0] : new_Phi(n, ijmp_ops, get_irn_mode(ijmp_ops[0]));
                ir_node *const ijmp = new_IJmp(op);