Improve error recovery in parse_asm_statement() and do not return an error statement.
[cparser] / ast2firm.c
index 543aa91..75b674c 100644 (file)
@@ -22,6 +22,7 @@
 #include <assert.h>
 #include <string.h>
 #include <stdbool.h>
+#include <unistd.h>
 #include <limits.h>
 
 #include <libfirm/firm.h>
@@ -128,14 +129,14 @@ static ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos)
        return new_r_Unknown(irg, mode);
 }
 
-static const char *dbg_retrieve(const dbg_info *dbg, unsigned *line)
+static src_loc_t dbg_retrieve(const dbg_info *dbg)
 {
-       const source_position_t *pos = (const source_position_t*) dbg;
-       if (pos == NULL)
-               return NULL;
-       if (line != NULL)
-               *line = pos->lineno;
-       return pos->input_name;
+       source_position_t const *const pos = (source_position_t const*)dbg;
+       if (pos) {
+               return (src_loc_t){ pos->input_name, pos->lineno, pos->colno };
+       } else {
+               return (src_loc_t){ NULL, 0, 0 };
+       }
 }
 
 static dbg_info *get_dbg_info(const source_position_t *pos)
@@ -519,8 +520,6 @@ static ir_type *create_bitfield_type(const entity_t *entity)
        }
 }
 
-#define INVALID_TYPE ((ir_type*)-1)
-
 enum {
        COMPOUND_IS_STRUCT = false,
        COMPOUND_IS_UNION  = true
@@ -651,7 +650,6 @@ static ir_type *get_ir_type_incomplete(type_t *type)
        type = skip_typeref(type);
 
        if (type->base.firm_type != NULL) {
-               assert(type->base.firm_type != INVALID_TYPE);
                return type->base.firm_type;
        }
 
@@ -672,7 +670,6 @@ ir_type *get_ir_type(type_t *type)
        type = skip_typeref(type);
 
        if (type->base.firm_type != NULL) {
-               assert(type->base.firm_type != INVALID_TYPE);
                return type->base.firm_type;
        }
 
@@ -723,14 +720,15 @@ ir_type *get_ir_type(type_t *type)
 
 static ir_mode *get_ir_mode_storage(type_t *type)
 {
-       ir_type *irtype = get_ir_type(type);
+       type = skip_typeref(type);
 
-       /* firm doesn't report a mode for arrays somehow... */
-       if (is_Array_type(irtype)) {
+       /* Firm doesn't report a mode for arrays and structs/unions. */
+       if (!is_type_scalar(type)) {
                return mode_P_data;
        }
 
-       ir_mode *mode = get_type_mode(irtype);
+       ir_type *const irtype = get_ir_type(type);
+       ir_mode *const mode   = get_type_mode(irtype);
        assert(mode != NULL);
        return mode;
 }
@@ -1864,9 +1862,9 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
 
                type_t *arg_type = skip_typeref(expression->base.type);
                if (!is_type_compound(arg_type)) {
-                       ir_mode *mode = get_ir_mode_storage(expression->base.type);
-                       arg_node      = create_conv(dbgi, arg_node, mode);
-                       arg_node      = do_strict_conv(dbgi, arg_node);
+                       ir_mode *const mode = get_ir_mode_storage(arg_type);
+                       arg_node = create_conv(dbgi, arg_node, mode);
+                       arg_node = do_strict_conv(dbgi, arg_node);
                }
 
                in[n] = arg_node;
@@ -1907,17 +1905,11 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
                }
 
                if (!is_type_void(return_type)) {
-                       ir_node *resproj = new_Proj(node, mode_T, pn_Call_T_result);
-
-                       if (is_type_scalar(return_type)) {
-                               ir_mode *mode       = get_ir_mode_storage(return_type);
-                               result              = new_Proj(resproj, mode, 0);
-                               ir_mode *mode_arith = get_ir_mode_arithmetic(return_type);
-                               result              = create_conv(NULL, result, mode_arith);
-                       } else {
-                               ir_mode *mode = mode_P_data;
-                               result        = new_Proj(resproj, mode, 0);
-                       }
+                       ir_node *const resproj    = new_Proj(node, mode_T, pn_Call_T_result);
+                       ir_mode *const mode       = get_ir_mode_storage(return_type);
+                       result                    = new_Proj(resproj, mode, 0);
+                       ir_mode *const mode_arith = get_ir_mode_arithmetic(return_type);
+                       result                    = create_conv(NULL, result, mode_arith);
                }
        }
 
@@ -2393,7 +2385,7 @@ static ir_node *create_cast(dbg_info *dbgi, ir_node *value_node,
                        if (from_var != NULL) {
                                ir_node *const addr = create_symconst(dbgi, from_var->v.entity);
                                ir_node *const base = deref_address(dbgi, from_var->base.type, addr);
-                               value_node = new_d_Add(dbgi, value_node, base, get_ir_mode_storage(from_type));
+                               value_node = new_d_Add(dbgi, value_node, base, mode);
                        }
                        if (to_var != NULL) {
                                ir_node *const addr = create_symconst(dbgi, to_var->v.entity);
@@ -2923,11 +2915,6 @@ static ir_node *sizeof_to_firm(const typeprop_expression_t *expression)
                        && expression->tp_expression != NULL) {
                expression_to_firm(expression->tp_expression);
        }
-       /* strange gnu extensions: sizeof(function) == 1 */
-       if (is_type_function(type)) {
-               ir_mode *mode = get_ir_mode_storage(type_size_t);
-               return new_Const(get_mode_one(mode));
-       }
 
        return get_type_size_node(type);
 }
@@ -3093,12 +3080,7 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression)
 
        ir_node *const in[2] = { true_val, false_val };
        type_t  *const type  = skip_typeref(expression->base.type);
-       ir_mode *mode;
-       if (is_type_compound(type)) {
-               mode = mode_P;
-       } else {
-               mode = get_ir_mode_arithmetic(type);
-       }
+       ir_mode *const mode  = get_ir_mode_arithmetic(type);
        ir_node *const val   = new_d_Phi(dbgi, lengthof(in), in, mode);
 
        return val;
@@ -4294,13 +4276,10 @@ static void create_variable_initializer(entity_t *entity)
        type_qualifiers_t  tq   = get_type_qualifier(type, true);
 
        if (initializer->kind == INITIALIZER_VALUE) {
-               initializer_value_t *initializer_value = &initializer->value;
-               dbg_info            *dbgi = get_dbg_info(&entity->base.source_position);
-               expression_t        *value     = initializer_value->value;
-               type_t              *init_type = value->base.type;
-               type_t              *skipped   = skip_typeref(init_type);
+               expression_t *      value     = initializer->value.value;
+               type_t       *const init_type = skip_typeref(value->base.type);
 
-               if (!is_type_scalar(skipped)) {
+               if (!is_type_scalar(init_type)) {
                        /* skip convs */
                        while (value->kind == EXPR_UNARY_CAST)
                                value = value->unary.value;
@@ -4311,9 +4290,9 @@ static void create_variable_initializer(entity_t *entity)
                        goto have_initializer;
                }
 
-               ir_node *node = expression_to_firm(initializer_value->value);
-
-               ir_mode *mode      = get_ir_mode_storage(init_type);
+               ir_node  *      node = expression_to_firm(value);
+               dbg_info *const dbgi = get_dbg_info(&entity->base.source_position);
+               ir_mode  *const mode = get_ir_mode_storage(init_type);
                node = create_conv(dbgi, node, mode);
                node = do_strict_conv(dbgi, node);
 
@@ -4460,44 +4439,27 @@ static ir_node *return_statement_to_firm(return_statement_t *statement)
        if (!currently_reachable())
                return NULL;
 
-       dbg_info *dbgi        = get_dbg_info(&statement->base.source_position);
-       type_t   *type        = current_function_entity->declaration.type;
-       ir_type  *func_irtype = get_ir_type(type);
-
-       ir_node *in[1];
-       int      in_len;
-       if (get_method_n_ress(func_irtype) > 0) {
-               ir_type *res_type = get_method_res_type(func_irtype, 0);
-
-               if (statement->value != NULL) {
-                       ir_node *node = expression_to_firm(statement->value);
-                       if (!is_compound_type(res_type)) {
-                               type_t  *ret_value_type = statement->value->base.type;
-                               ir_mode *mode           = get_ir_mode_storage(ret_value_type);
-                               node                    = create_conv(dbgi, node, mode);
-                               node                    = do_strict_conv(dbgi, node);
-                       }
-                       in[0] = node;
+       dbg_info *const dbgi = get_dbg_info(&statement->base.source_position);
+       type_t   *const type = skip_typeref(current_function_entity->declaration.type->function.return_type);
+       ir_node  *      res  = statement->value ? expression_to_firm(statement->value) : NULL;
+
+       int in_len;
+       if (!is_type_void(type)) {
+               ir_mode *const mode = get_ir_mode_storage(type);
+               if (res) {
+                       res = create_conv(dbgi, res, mode);
+                       res = do_strict_conv(dbgi, res);
                } else {
-                       ir_mode *mode;
-                       if (is_compound_type(res_type)) {
-                               mode = mode_P_data;
-                       } else {
-                               mode = get_type_mode(res_type);
-                       }
-                       in[0] = new_Unknown(mode);
+                       res = new_Unknown(mode);
                }
                in_len = 1;
        } else {
-               /* build return_value for its side effects */
-               if (statement->value != NULL) {
-                       expression_to_firm(statement->value);
-               }
                in_len = 0;
        }
 
-       ir_node  *store = get_store();
-       ir_node  *ret   = new_d_Return(dbgi, store, in_len, in);
+       ir_node *const in[1] = { res };
+       ir_node *const store = get_store();
+       ir_node *const ret   = new_d_Return(dbgi, store, in_len, in);
 
        ir_node *end_block = get_irg_end_block(current_ir_graph);
        add_immBlock_pred(end_block, ret);
@@ -5615,20 +5577,13 @@ static void create_function(entity_t *entity)
        if (currently_reachable()) {
                type_t *type = skip_typeref(entity->declaration.type);
                assert(is_type_function(type));
-               const function_type_t *func_type   = &type->function;
-               const type_t          *return_type
-                       = skip_typeref(func_type->return_type);
+               type_t *const return_type = skip_typeref(type->function.return_type);
 
                ir_node *ret;
                if (is_type_void(return_type)) {
                        ret = new_Return(get_store(), 0, NULL);
                } else {
-                       ir_mode *mode;
-                       if (is_type_scalar(return_type)) {
-                               mode = get_ir_mode_storage(func_type->return_type);
-                       } else {
-                               mode = mode_P_data;
-                       }
+                       ir_mode *const mode = get_ir_mode_storage(return_type);
 
                        ir_node *in[1];
                        /* ยง5.1.2.2.3 main implicitly returns 0 */
@@ -5802,8 +5757,27 @@ static void global_asm_to_firm(statement_t *s)
        }
 }
 
+static const char *get_cwd(void)
+{
+       static char buf[1024];
+       if (buf[0] == '\0')
+               getcwd(buf, sizeof(buf));
+       return buf;
+}
+
 void translation_unit_to_firm(translation_unit_t *unit)
 {
+       if (c_mode & _CXX) {
+               be_dwarf_set_source_language(DW_LANG_C_plus_plus);
+       } else if (c_mode & _C99) {
+               be_dwarf_set_source_language(DW_LANG_C99);
+       } else if (c_mode & _C89) {
+               be_dwarf_set_source_language(DW_LANG_C89);
+       } else {
+               be_dwarf_set_source_language(DW_LANG_C);
+       }
+       be_dwarf_set_compilation_directory(get_cwd());
+
        /* initialize firm arithmetic */
        tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP);
        ir_set_uninitialized_local_variable_func(uninitialized_local_var);