In C++ (most) character literals are of type char.
[cparser] / ast2firm.c
index 72e9d5a..c0a0d98 100644 (file)
@@ -22,6 +22,7 @@
 #include <assert.h>
 #include <string.h>
 #include <stdbool.h>
+#include <limits.h>
 
 #include <libfirm/firm.h>
 #include <libfirm/adt/obst.h>
@@ -39,6 +40,7 @@
 #include "diagnostic.h"
 #include "lang_features.h"
 #include "types.h"
+#include "walk_statements.h"
 #include "warning.h"
 #include "entitymap_t.h"
 #include "driver/firm_opt.h"
@@ -64,6 +66,8 @@ static int             inner_function_idx;
 static ir_node        *ijmp_list;
 static bool            constant_folding;
 
+extern bool            have_const_functions;
+
 static const declaration_t *current_function_decl;
 static ir_node             *current_function_name;
 static ir_node             *current_funcsig;
@@ -92,7 +96,6 @@ typedef enum declaration_kind_t {
 
 static ir_type *get_ir_type(type_t *type);
 static ir_type *get_ir_type_incomplete(type_t *type);
-static int count_decls_in_stmts(const statement_t *stmt);
 
 static void enqueue_inner_function(declaration_t *declaration) {
        if (inner_functions == NULL) {
@@ -174,13 +177,13 @@ static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
 
                if (flags & ATOMIC_TYPE_FLAG_INTEGER) {
                        assert(! (flags & ATOMIC_TYPE_FLAG_FLOAT));
-                       snprintf(name, sizeof(name), "i%s%d", is_signed?"":"u", bit_size);
+                       snprintf(name, sizeof(name), "i%s%u", is_signed ? "" : "u", bit_size);
                        sort         = irms_int_number;
                        arithmetic   = irma_twos_complement;
                        modulo_shift = bit_size < machine_size ? machine_size : bit_size;
                } else {
                        assert(flags & ATOMIC_TYPE_FLAG_FLOAT);
-                       snprintf(name, sizeof(name), "f%d", bit_size);
+                       snprintf(name, sizeof(name), "f%u", bit_size);
                        sort         = irms_float_number;
                        arithmetic   = irma_ieee754;
                        modulo_shift = 0;
@@ -215,7 +218,7 @@ static void init_atomic_modes(void)
        unsigned        modulo_shift
                = bit_size < machine_size ? machine_size : bit_size;
 
-       snprintf(name, sizeof(name), "p%d", machine_size);
+       snprintf(name, sizeof(name), "p%u", machine_size);
        ir_mode *ptr_mode = new_ir_mode(name, sort, bit_size, is_signed, arithmetic,
                                        modulo_shift);
 
@@ -317,11 +320,10 @@ static unsigned count_parameters(const function_type_t *function_type)
  */
 static ir_type *create_atomic_type(const atomic_type_t *type)
 {
-       dbg_info           *dbgi      = get_dbg_info(&type->base.source_position);
-       atomic_type_kind_t  kind      = type->akind;
-       ir_mode            *mode      = _atomic_modes[kind];
-       ident              *id        = get_mode_ident(mode);
-       ir_type            *irtype    = new_d_type_primitive(id, mode, dbgi);
+       atomic_type_kind_t  kind   = type->akind;
+       ir_mode            *mode   = _atomic_modes[kind];
+       ident              *id     = get_mode_ident(mode);
+       ir_type            *irtype = new_type_primitive(id, mode);
 
        set_type_alignment_bytes(irtype, type->base.alignment);
 
@@ -333,13 +335,11 @@ static ir_type *create_atomic_type(const atomic_type_t *type)
  */
 static ir_type *create_complex_type(const complex_type_t *type)
 {
-       dbg_info           *dbgi      = get_dbg_info(&type->base.source_position);
-       atomic_type_kind_t  kind      = type->akind;
-       ir_mode            *mode      = _atomic_modes[kind];
-       ident              *id        = get_mode_ident(mode);
+       atomic_type_kind_t  kind = type->akind;
+       ir_mode            *mode = _atomic_modes[kind];
+       ident              *id   = get_mode_ident(mode);
 
        (void) id;
-       (void) dbgi;
 
        /* FIXME: finish the array */
        return NULL;
@@ -350,11 +350,10 @@ static ir_type *create_complex_type(const complex_type_t *type)
  */
 static ir_type *create_imaginary_type(const imaginary_type_t *type)
 {
-       dbg_info           *dbgi      = get_dbg_info(&type->base.source_position);
        atomic_type_kind_t  kind      = type->akind;
        ir_mode            *mode      = _atomic_modes[kind];
        ident              *id        = get_mode_ident(mode);
-       ir_type            *irtype    = new_d_type_primitive(id, mode, dbgi);
+       ir_type            *irtype    = new_type_primitive(id, mode);
 
        set_type_alignment_bytes(irtype, type->base.alignment);
 
@@ -383,8 +382,7 @@ static ir_type *create_method_type(const function_type_t *function_type)
        ident   *id           = id_unique("functiontype.%u");
        int      n_parameters = count_parameters(function_type);
        int      n_results    = return_type == type_void ? 0 : 1;
-       dbg_info *dbgi        = get_dbg_info(&function_type->base.source_position);
-       ir_type *irtype       = new_d_type_method(id, n_parameters, n_results, dbgi);
+       ir_type *irtype       = new_type_method(id, n_parameters, n_results);
 
        if (return_type != type_void) {
                ir_type *restype = get_ir_type(return_type);
@@ -429,7 +427,6 @@ is_cdecl:
 
        case CC_THISCALL:
                /* Hmm, leave default, not accepted by the parser yet. */
-               warningf(&function_type->base.source_position, "THISCALL calling convention not supported yet");
                break;
        }
        return irtype;
@@ -439,9 +436,8 @@ static ir_type *create_pointer_type(pointer_type_t *type)
 {
        type_t   *points_to    = type->points_to;
        ir_type  *ir_points_to = get_ir_type_incomplete(points_to);
-       dbg_info *dbgi         = get_dbg_info(&type->base.source_position);
-       ir_type  *ir_type      = new_d_type_pointer(id_unique("pointer.%u"),
-                                                   ir_points_to, mode_P_data, dbgi);
+       ir_type  *ir_type      = new_type_pointer(id_unique("pointer.%u"),
+                                                 ir_points_to, mode_P_data);
 
        return ir_type;
 }
@@ -452,8 +448,7 @@ static ir_type *create_array_type(array_type_t *type)
        ir_type *ir_element_type = get_ir_type(element_type);
 
        ident    *id      = id_unique("array.%u");
-       dbg_info *dbgi    = get_dbg_info(&type->base.source_position);
-       ir_type  *ir_type = new_d_type_array(id, 1, ir_element_type, dbgi);
+       ir_type  *ir_type = new_type_array(id, 1, ir_element_type);
 
        const int align = get_type_alignment_bytes(ir_element_type);
        set_type_alignment_bytes(ir_type, align);
@@ -606,7 +601,7 @@ static ir_type *create_compound_type(compound_type_t *type, ir_type *irtype,
                                id = id_unique("__anonymous_struct.%u");
                        }
                }
-               dbg_info *dbgi  = get_dbg_info(&type->base.source_position);
+               dbg_info *dbgi = get_dbg_info(&declaration->source_position);
 
                if (is_union) {
                        irtype = new_d_type_union(id, dbgi);
@@ -1047,6 +1042,10 @@ static void handle_gnu_attributes_ent(ir_entity *ent, declaration_t *decl)
                   __attribute__((pure)) specifier. */
                set_entity_additional_property(ent, mtp_property_pure);
        }
+       if (decl->modifiers & DM_CONST) {
+               set_entity_additional_property(ent, mtp_property_const);
+               have_const_functions = true;
+       }
        if (decl->modifiers & DM_USED) {
                /* TRUE if the declaration includes the GNU
                   __attribute__((used)) specifier. */
@@ -1444,12 +1443,7 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
 
        case DECLARATION_KIND_ENUM_ENTRY: {
                ir_mode *const mode = get_ir_mode(type);
-               if (ref->is_outer_ref) {
-                       /* reference to an outer variable */
-                       panic("Outer variable reference not implemented");
-               } else {
-                       return new_Const(mode, declaration->v.enum_val);
-               }
+               return new_Const(mode, declaration->v.enum_val);
        }
 
        case DECLARATION_KIND_LOCAL_VARIABLE: {
@@ -1470,7 +1464,7 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
                        panic("Trampoline code not implemented");
                        return create_symconst(dbgi, mode, declaration->v.entity);
                }
-                                                                       }
+       }
        case DECLARATION_KIND_GLOBAL_VARIABLE: {
                ir_node *const addr   = get_global_var_address(dbgi, declaration);
                return deref_address(dbgi, declaration->type, addr);
@@ -1509,11 +1503,6 @@ static ir_node *reference_addr(const reference_expression_t *ref)
                /* you can store to a local variable (so we don't panic but return NULL
                 * as an indicator for no real address) */
                return NULL;
-       case DECLARATION_KIND_FUNCTION: {
-               type_t *const  type = skip_typeref(ref->base.type);
-               ir_mode *const mode = get_ir_mode(type);
-               return create_symconst(dbgi, mode, declaration->v.entity);
-       }
        case DECLARATION_KIND_GLOBAL_VARIABLE: {
                ir_node *const addr = get_global_var_address(dbgi, declaration);
                return addr;
@@ -1532,6 +1521,13 @@ static ir_node *reference_addr(const reference_expression_t *ref)
        case DECLARATION_KIND_ENUM_ENTRY:
                panic("trying to reference enum entry");
 
+       case DECLARATION_KIND_FUNCTION: {
+               type_t  *const type = skip_typeref(declaration->type);
+               ir_mode *const mode = get_ir_mode(type);
+               return create_symconst(dbgi, mode, declaration->v.entity);
+       }
+
+       case DECLARATION_KIND_INNER_FUNCTION:
        case DECLARATION_KIND_COMPOUND_TYPE_INCOMPLETE:
        case DECLARATION_KIND_COMPOUND_TYPE_COMPLETE:
        case DECLARATION_KIND_COMPOUND_MEMBER:
@@ -1575,7 +1571,11 @@ static ir_node *process_builtin_call(const call_expression_t *call)
 
                return res;
        }
-       case T___builtin_huge_val: {
+
+       case T___builtin_huge_val:
+       case T___builtin_inf:
+       case T___builtin_inff:
+       case T___builtin_infl: {
                ir_mode *mode = get_ir_mode(function_type->function.return_type);
                tarval  *tv   = get_mode_infinite(mode);
                ir_node *res  = new_d_Const(dbgi, mode, tv);
@@ -1583,7 +1583,7 @@ static ir_node *process_builtin_call(const call_expression_t *call)
        }
        case T___builtin_nan:
        case T___builtin_nanf:
-       case T___builtin_nand: {
+       case T___builtin_nanl: {
                /* Ignore string for now... */
                assert(is_type_function(function_type));
                ir_mode *mode = get_ir_mode(function_type->function.return_type);
@@ -1781,21 +1781,19 @@ static tarval *create_bitfield_mask(ir_mode *mode, int offset, int size)
        return mask1;
 }
 
-static void bitfield_store_to_firm(const select_expression_t *expression,
-                                   ir_node *addr, ir_node *value)
+static void bitfield_store_to_firm(dbg_info *dbgi,
+               ir_entity *entity, ir_node *addr, ir_node *value, bool set_volatile)
 {
-       type_t       *type   = expression->base.type;
-       ir_mode      *mode   = get_ir_mode(type);
+       ir_type *entity_type = get_entity_type(entity);
+       ir_type *base_type   = get_primitive_base_type(entity_type);
+       assert(base_type != NULL);
+       ir_mode *mode        = get_type_mode(base_type);
 
-       assert(get_irn_mode(value) == mode || is_Bad(value));
-
-       dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+       value = create_conv(dbgi, value, mode);
 
        /* kill upper bits of value and shift to right position */
-       ir_entity *entity       = expression->compound_entry->v.entity;
-       int        bitoffset    = get_entity_offset_bits_remainder(entity);
-       ir_type   *entity_type  = get_entity_type(entity);
-       int        bitsize      = get_mode_size_bits(get_type_mode(entity_type));
+       int      bitoffset    = get_entity_offset_bits_remainder(entity);
+       int      bitsize      = get_mode_size_bits(get_type_mode(entity_type));
 
        tarval  *mask            = create_bitfield_mask(mode, 0, bitsize);
        ir_node *mask_node       = new_d_Const(dbgi, mode, mask);
@@ -1820,7 +1818,7 @@ static void bitfield_store_to_firm(const select_expression_t *expression,
        ir_node *store_mem = new_d_Proj(dbgi, store, mode_M, pn_Store_M);
        set_store(store_mem);
 
-       if (type->base.qualifiers & TYPE_QUALIFIER_VOLATILE) {
+       if (set_volatile) {
                set_Load_volatility(load, volatility_is_volatile);
                set_Store_volatility(store, volatility_is_volatile);
        }
@@ -1893,7 +1891,10 @@ static void set_value_for_expression_addr(const expression_t *expression,
 
                declaration_t *declaration = select->compound_entry;
                if (declaration->type->kind == TYPE_BITFIELD) {
-                       bitfield_store_to_firm(select, addr, value);
+                       ir_entity *entity = select->compound_entry->v.entity;
+                       bool       set_volatile
+                               = select->base.type->base.qualifiers & TYPE_QUALIFIER_VOLATILE;
+                       bitfield_store_to_firm(dbgi, entity, addr, value, set_volatile);
                        return;
                }
        }
@@ -2533,7 +2534,6 @@ static long get_offsetof_offset(const offsetof_expression_t *expression)
                        expression_t *array_index = designator->array_index;
                        assert(designator->array_index != NULL);
                        assert(is_type_array(type));
-                       assert(is_type_valid(array_index->base.type));
 
                        long index         = fold_constant(array_index);
                        ir_type *arr_type  = get_ir_type(type);
@@ -2637,6 +2637,8 @@ static void init_ir_types(void);
 
 long fold_constant(const expression_t *expression)
 {
+       assert(is_type_valid(skip_typeref(expression->base.type)));
+
        bool constant_folding_old = constant_folding;
        constant_folding = true;
 
@@ -3216,7 +3218,7 @@ static ir_node *create_condition_evaluation(const expression_t *expression,
 
        dbg_info *dbgi       = get_dbg_info(&expression->base.source_position);
        ir_node  *cond_expr  = _expression_to_firm(expression);
-       ir_node  *condition  = create_conv(NULL, cond_expr, mode_b);
+       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);
@@ -3260,6 +3262,8 @@ static void create_declaration_entity(declaration_t *declaration,
        dbg_info  *const dbgi   = get_dbg_info(&declaration->source_position);
        ir_entity *const entity = new_d_entity(parent_type, id, irtype, dbgi);
 
+       handle_gnu_attributes_ent(entity, declaration);
+
        declaration->declaration_kind = (unsigned char) declaration_kind;
        declaration->v.entity         = entity;
        set_entity_variability(entity, variability_uninitialized);
@@ -3301,7 +3305,7 @@ static __attribute__((unused)) void debug_print_type_path(const type_path_t *pat
                if (is_type_compound(type)) {
                        fprintf(stderr, ".%s", entry->compound_entry->symbol->string);
                } else if (is_type_array(type)) {
-                       fprintf(stderr, "[%zd]", entry->index);
+                       fprintf(stderr, "[%zu]", entry->index);
                } else {
                        fprintf(stderr, "-INVALID-");
                }
@@ -3446,12 +3450,11 @@ static void walk_designator(type_path_t *path, const designator_t *designator)
                        expression_t *array_index = designator->array_index;
                        assert(designator->array_index != NULL);
                        assert(is_type_array(type));
-                       assert(is_type_valid(array_index->base.type));
 
                        long index = fold_constant(array_index);
                        assert(index >= 0);
 #ifndef NDEBUG
-                       if (type->array.size_constant == 1) {
+                       if (type->array.size_constant) {
                                long array_size = type->array.size;
                                assert(index < array_size);
                        }
@@ -3704,7 +3707,7 @@ static void create_dynamic_null_initializer(ir_type *type, dbg_info *dbgi,
 }
 
 static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
-               ir_type *type, dbg_info *dbgi, ir_node *base_addr)
+               ir_entity *entity, ir_type *type, dbg_info *dbgi, ir_node *base_addr)
 {
        switch(get_initializer_kind(initializer)) {
        case IR_INITIALIZER_NULL: {
@@ -3712,11 +3715,18 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
                return;
        }
        case IR_INITIALIZER_CONST: {
-               ir_node *node = get_initializer_const_value(initializer);
-               ir_mode *mode = get_irn_mode(node);
-               assert(get_type_mode(type) == mode);
+               ir_node *node     = get_initializer_const_value(initializer);
+               ir_mode *mode     = get_irn_mode(node);
+               ir_type *ent_type = get_entity_type(entity);
+
+               /* is it a bitfield type? */
+               if (is_Primitive_type(ent_type) &&
+                               get_primitive_base_type(ent_type) != NULL) {
+                       bitfield_store_to_firm(dbgi, entity, base_addr, node, false);
+                       return;
+               }
 
-               /* TODO: bitfields... */
+               assert(get_type_mode(type) == mode);
                ir_node *mem    = get_store();
                ir_node *store  = new_d_Store(dbgi, mem, base_addr, node);
                ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
@@ -3724,12 +3734,19 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
                return;
        }
        case IR_INITIALIZER_TARVAL: {
-               tarval  *tv   = get_initializer_tarval_value(initializer);
-               ir_mode *mode = get_tarval_mode(tv);
-               ir_node *cnst = new_d_Const(dbgi, mode, tv);
-               assert(get_type_mode(type) == mode);
+               tarval  *tv       = get_initializer_tarval_value(initializer);
+               ir_mode *mode     = get_tarval_mode(tv);
+               ir_node *cnst     = new_d_Const(dbgi, mode, tv);
+               ir_type *ent_type = get_entity_type(entity);
+
+               /* is it a bitfield type? */
+               if (is_Primitive_type(ent_type) &&
+                               get_primitive_base_type(ent_type) != NULL) {
+                       bitfield_store_to_firm(dbgi, entity, base_addr, cnst, false);
+                       return;
+               }
 
-               /* TODO: bitfields... */
+               assert(get_type_mode(type) == mode);
                ir_node *mem    = get_store();
                ir_node *store  = new_d_Store(dbgi, mem, base_addr, cnst);
                ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
@@ -3751,26 +3768,29 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
                        panic("initializer doesn't match compound type");
 
                for(int i = 0; i < n_members; ++i) {
-                       ir_node *addr;
-                       ir_type *irtype;
+                       ir_node   *addr;
+                       ir_type   *irtype;
+                       ir_entity *sub_entity;
                        if (is_Array_type(type)) {
-                               ir_entity *entity   = get_array_element_entity(type);
                                tarval    *index_tv = new_tarval_from_long(i, mode_uint);
                                ir_node   *cnst     = new_d_Const(dbgi, mode_uint, index_tv);
                                ir_node   *in[1]    = { cnst };
-                               irtype = get_array_element_type(type);
-                               addr   = new_d_Sel(dbgi, new_NoMem(), base_addr, 1, in, entity);
+                               irtype     = get_array_element_type(type);
+                               sub_entity = get_array_element_entity(type);
+                               addr       = new_d_Sel(dbgi, new_NoMem(), base_addr, 1, in,
+                                                      sub_entity);
                        } else {
-                               ir_entity *member = get_compound_member(type, i);
-
-                               irtype = get_entity_type(member);
-                               addr   = new_d_simpleSel(dbgi, new_NoMem(), base_addr, member);
+                               sub_entity = get_compound_member(type, i);
+                               irtype     = get_entity_type(sub_entity);
+                               addr       = new_d_simpleSel(dbgi, new_NoMem(), base_addr,
+                                                            sub_entity);
                        }
 
                        ir_initializer_t *sub_init
                                = get_initializer_compound_value(initializer, i);
 
-                       create_dynamic_initializer_sub(sub_init, irtype, dbgi, addr);
+                       create_dynamic_initializer_sub(sub_init, sub_entity, irtype, dbgi,
+                                                      addr);
                }
                return;
        }
@@ -3786,7 +3806,7 @@ static void create_dynamic_initializer(ir_initializer_t *initializer,
        ir_node *base_addr = new_d_simpleSel(dbgi, new_NoMem(), frame, entity);
        ir_type *type      = get_entity_type(entity);
 
-       create_dynamic_initializer_sub(initializer, type, dbgi, base_addr);
+       create_dynamic_initializer_sub(initializer, entity, type, dbgi, base_addr);
 }
 
 static void create_local_initializer(initializer_t *initializer, dbg_info *dbgi,
@@ -3865,7 +3885,8 @@ static void create_declaration_initializer(declaration_t *declaration)
                return;
        }
 
-       type_t *type = skip_typeref(declaration->type);
+       type_t            *type = declaration->type;
+       type_qualifiers_t  tq   = get_type_qualifier(type, true);
 
        if (initializer->kind == INITIALIZER_VALUE) {
                initializer_value_t *initializer_value = &initializer->value;
@@ -3882,7 +3903,7 @@ static void create_declaration_initializer(declaration_t *declaration)
 
                        ir_entity *entity = declaration->v.entity;
 
-                       if (type->base.qualifiers & TYPE_QUALIFIER_CONST) {
+                       if (tq & TYPE_QUALIFIER_CONST) {
                                set_entity_variability(entity, variability_constant);
                        } else {
                                set_entity_variability(entity, variability_initialized);
@@ -3890,14 +3911,14 @@ static void create_declaration_initializer(declaration_t *declaration)
                        set_atomic_ent_value(entity, value);
                }
        } else {
-               assert(declaration_kind == DECLARATION_KIND_LOCAL_VARIABLE_ENTITY
-                               || declaration_kind == DECLARATION_KIND_GLOBAL_VARIABLE);
+               assert(declaration_kind == DECLARATION_KIND_LOCAL_VARIABLE_ENTITY ||
+                      declaration_kind == DECLARATION_KIND_GLOBAL_VARIABLE);
 
                ir_entity        *entity        = declaration->v.entity;
                ir_initializer_t *irinitializer
                        = create_ir_initializer(initializer, type);
 
-               if (type->base.qualifiers & TYPE_QUALIFIER_CONST) {
+               if (tq & TYPE_QUALIFIER_CONST) {
                        set_entity_variability(entity, variability_constant);
                } else {
                        set_entity_variability(entity, variability_initialized);
@@ -4548,18 +4569,17 @@ static void switch_statement_to_firm(switch_statement_t *statement)
                        continue;
                }
                if (l->last_case >= l->first_case)
-                       num_cases += l->last_case - l->first_case;
+                       num_cases += l->last_case - l->first_case + 1;
                if (l->last_case > def_nr)
                        def_nr = l->last_case;
        }
 
-       if (def_nr + 1 < 0) {
-               /* Bad: an overflow occurred, we cannot be sure that the
-        * maximum + 1 is a free number. Scan the values a second
-        * time to find a free number.
-        */
+       if (def_nr == INT_MAX) {
+               /* Bad: an overflow will occurr, we cannot be sure that the
+                * maximum + 1 is a free number. Scan the values a second
+                * time to find a free number.
+                */
                unsigned char *bits = xmalloc((num_cases + 7) >> 3);
-               unsigned long i;
 
                memset(bits, 0, (num_cases + 7) >> 3);
                for (case_label_statement_t *l = statement->first_case; l != NULL; l = l->next) {
@@ -4567,9 +4587,13 @@ static void switch_statement_to_firm(switch_statement_t *statement)
                                /* default case */
                                continue;
                        }
-                       for (long cns = l->first_case; cns <= l->last_case; ++cns) {
-                               if (cns >= 0 && (unsigned long)cns < num_cases)
+                       unsigned long start = l->first_case > 0 ? (unsigned long)l->first_case : 0;
+                       if (start < num_cases && l->last_case >= 0) {
+                               unsigned long end  = (unsigned long)l->last_case < num_cases ?
+                                       (unsigned long)l->last_case : num_cases - 1;
+                               for (unsigned long cns = start; cns <= end; ++cns) {
                                        bits[cns >> 3] |= (1 << (cns & 7));
+                               }
                        }
                }
                /* We look at the first num_cases constants:
@@ -4577,8 +4601,9 @@ static void switch_statement_to_firm(switch_statement_t *statement)
                 * one, or they are non densed, so we will find one free
                 * there...
                 */
+               unsigned long i;
                for (i = 0; i < num_cases; ++i)
-                       if ((bits[i >> 3] & (i & 7)) == 0)
+                       if ((bits[i >> 3] & (1 << (i & 7))) == 0)
                                break;
 
                free(bits);
@@ -4689,14 +4714,9 @@ static void goto_to_firm(const goto_statement_t *statement)
                set_irn_link(ijmp, ijmp_list);
                ijmp_list = ijmp;
        } else {
-               if (statement->outer_fkt_jmp) {
-                       /* TODO: this is a outer function jmp */
-                       panic("outer function jump not implemented");
-               } else {
-                       ir_node *block = get_label_block(statement->label);
-                       ir_node *jmp   = new_Jmp();
-                       add_immBlock_pred(block, jmp);
-               }
+               ir_node *block = get_label_block(statement->label);
+               ir_node *jmp   = new_Jmp();
+               add_immBlock_pred(block, jmp);
        }
        set_cur_block(NULL);
 }
@@ -4789,7 +4809,7 @@ static void asm_statement_to_firm(const asm_statement_t *statement)
                                char     buf[64];
                                ir_node *value = get_value_from_lvalue(expr, addr);
 
-                               snprintf(buf, sizeof(buf), "%d", pos);
+                               snprintf(buf, sizeof(buf), "%u", pos);
 
                                ir_asm_constraint constraint;
                                constraint.pos              = pos;
@@ -5026,8 +5046,6 @@ static void statement_to_firm(statement_t *statement)
        panic("Statement not implemented\n");
 }
 
-static int count_decls_in_expression(const expression_t *expression);
-
 static int count_local_declarations(const declaration_t *      decl,
                                     const declaration_t *const end)
 {
@@ -5039,218 +5057,29 @@ static int count_local_declarations(const declaration_t *      decl,
 
                if (!decl->address_taken && is_type_scalar(type))
                        ++count;
-               const initializer_t *initializer = decl->init.initializer;
-               /* FIXME: should walk initializer hierarchies... */
-               if (initializer != NULL && initializer->kind == INITIALIZER_VALUE) {
-                       count += count_decls_in_expression(initializer->value.value);
-               }
        }
        return count;
 }
 
-static int count_decls_in_expression(const expression_t *expression) {
-       int count = 0;
-
-       if (expression == NULL)
-               return 0;
-
-       switch((expression_kind_t) expression->base.kind) {
-       case EXPR_STATEMENT:
-               return count_decls_in_stmts(expression->statement.statement);
-       EXPR_BINARY_CASES {
-               int count_left  = count_decls_in_expression(expression->binary.left);
-               int count_right = count_decls_in_expression(expression->binary.right);
-               return count_left + count_right;
-       }
-       EXPR_UNARY_CASES
-               return count_decls_in_expression(expression->unary.value);
-       case EXPR_CALL: {
-               call_argument_t *argument = expression->call.arguments;
-               for( ; argument != NULL; argument = argument->next) {
-                       count += count_decls_in_expression(argument->expression);
-               }
-               return count;
-       }
-
-       case EXPR_UNKNOWN:
-       case EXPR_INVALID:
-               panic("unexpected expression kind");
-
-       case EXPR_COMPOUND_LITERAL:
-               /* TODO... */
-               break;
-
-       case EXPR_CONDITIONAL:
-               count += count_decls_in_expression(expression->conditional.condition);
-               count += count_decls_in_expression(expression->conditional.true_expression);
-               count += count_decls_in_expression(expression->conditional.false_expression);
-               return count;
-
-       case EXPR_BUILTIN_PREFETCH:
-               count += count_decls_in_expression(expression->builtin_prefetch.adr);
-               count += count_decls_in_expression(expression->builtin_prefetch.rw);
-               count += count_decls_in_expression(expression->builtin_prefetch.locality);
-               return count;
-
-       case EXPR_BUILTIN_CONSTANT_P:
-               count += count_decls_in_expression(expression->builtin_constant.value);
-               return count;
-
-       case EXPR_SELECT:
-               count += count_decls_in_expression(expression->select.compound);
-               return count;
-
-       case EXPR_ARRAY_ACCESS:
-               count += count_decls_in_expression(expression->array_access.array_ref);
-               count += count_decls_in_expression(expression->array_access.index);
-               return count;
-
-       case EXPR_CLASSIFY_TYPE:
-               count += count_decls_in_expression(expression->classify_type.type_expression);
-               return count;
-
-       case EXPR_SIZEOF:
-       case EXPR_ALIGNOF: {
-               expression_t *tp_expression = expression->typeprop.tp_expression;
-               if (tp_expression != NULL) {
-                       count += count_decls_in_expression(tp_expression);
-               }
-               return count;
-       }
-
-       case EXPR_OFFSETOF:
-       case EXPR_REFERENCE:
-       case EXPR_CONST:
-       case EXPR_CHARACTER_CONSTANT:
-       case EXPR_WIDE_CHARACTER_CONSTANT:
-       case EXPR_STRING_LITERAL:
-       case EXPR_WIDE_STRING_LITERAL:
-       case EXPR_FUNCNAME:
-       case EXPR_BUILTIN_SYMBOL:
-       case EXPR_VA_START:
-       case EXPR_VA_ARG:
-       case EXPR_LABEL_ADDRESS:
-               break;
-       }
-
-       /* TODO FIXME: finish/fix that firm patch that allows dynamic value numbers
-        * (or implement all the missing expressions here/implement a walker)
-        */
-
-       return 0;
-}
-
-static int count_decls_in_stmts(const statement_t *stmt)
+static void count_decls_in_stmt(statement_t *stmt, void *const env)
 {
-       int count = 0;
-       for (; stmt != NULL; stmt = stmt->base.next) {
-               switch (stmt->kind) {
-                       case STATEMENT_EMPTY:
-                               break;
-
-                       case STATEMENT_DECLARATION: {
-                               const declaration_statement_t *const decl_stmt = &stmt->declaration;
-                               count += count_local_declarations(decl_stmt->declarations_begin,
-                                                                 decl_stmt->declarations_end->next);
-                               break;
-                       }
-
-                       case STATEMENT_COMPOUND: {
-                               const compound_statement_t *const comp =
-                                       &stmt->compound;
-                               count += count_decls_in_stmts(comp->statements);
-                               break;
-                       }
-
-                       case STATEMENT_IF: {
-                               const if_statement_t *const if_stmt = &stmt->ifs;
-                               count += count_decls_in_expression(if_stmt->condition);
-                               count += count_decls_in_stmts(if_stmt->true_statement);
-                               count += count_decls_in_stmts(if_stmt->false_statement);
-                               break;
-                       }
-
-                       case STATEMENT_SWITCH: {
-                               const switch_statement_t *const switch_stmt = &stmt->switchs;
-                               count += count_decls_in_expression(switch_stmt->expression);
-                               count += count_decls_in_stmts(switch_stmt->body);
-                               break;
-                       }
-
-                       case STATEMENT_LABEL: {
-                               const label_statement_t *const label_stmt = &stmt->label;
-                               if (label_stmt->statement != NULL) {
-                                       count += count_decls_in_stmts(label_stmt->statement);
-                               }
-                               break;
-                       }
-
-                       case STATEMENT_WHILE: {
-                               const while_statement_t *const while_stmt = &stmt->whiles;
-                               count += count_decls_in_expression(while_stmt->condition);
-                               count += count_decls_in_stmts(while_stmt->body);
-                               break;
-                       }
-
-                       case STATEMENT_DO_WHILE: {
-                               const do_while_statement_t *const do_while_stmt = &stmt->do_while;
-                               count += count_decls_in_expression(do_while_stmt->condition);
-                               count += count_decls_in_stmts(do_while_stmt->body);
-                               break;
-                       }
-
-                       case STATEMENT_FOR: {
-                               const for_statement_t *const for_stmt = &stmt->fors;
-                               count += count_local_declarations(for_stmt->scope.declarations, NULL);
-                               count += count_decls_in_expression(for_stmt->initialisation);
-                               count += count_decls_in_expression(for_stmt->condition);
-                               count += count_decls_in_expression(for_stmt->step);
-                               count += count_decls_in_stmts(for_stmt->body);
-                               break;
-                       }
-
-                       case STATEMENT_CASE_LABEL: {
-                               const case_label_statement_t *label = &stmt->case_label;
-                               count += count_decls_in_expression(label->expression);
-                               if (label->statement != NULL) {
-                                       count += count_decls_in_stmts(label->statement);
-                               }
-                               break;
-                       }
-
-                       case STATEMENT_ASM:
-                       case STATEMENT_BREAK:
-                       case STATEMENT_CONTINUE:
-                               break;
-
-                       case STATEMENT_EXPRESSION: {
-                               const expression_statement_t *expr_stmt = &stmt->expression;
-                               count += count_decls_in_expression(expr_stmt->expression);
-                               break;
-                       }
+       int *const count = env;
 
-                       case STATEMENT_GOTO:
-                       case STATEMENT_LEAVE:
-                       case STATEMENT_INVALID:
-                               break;
+       switch (stmt->kind) {
+               case STATEMENT_DECLARATION: {
+                       const declaration_statement_t *const decl_stmt = &stmt->declaration;
+                       *count += count_local_declarations(decl_stmt->declarations_begin,
+                                                                                                                                                                decl_stmt->declarations_end->next);
+                       break;
+               }
 
-                       case STATEMENT_RETURN: {
-                               const return_statement_t *ret_stmt = &stmt->returns;
-                               count += count_decls_in_expression(ret_stmt->value);
-                               break;
-                       }
+               case STATEMENT_FOR:
+                       *count += count_local_declarations(stmt->fors.scope.declarations, NULL);
+                       break;
 
-                       case STATEMENT_MS_TRY: {
-                               const ms_try_statement_t *const try_stmt = &stmt->ms_try;
-                               count += count_decls_in_stmts(try_stmt->try_statement);
-                               if (try_stmt->except_expression != NULL)
-                                       count += count_decls_in_expression(try_stmt->except_expression);
-                               count += count_decls_in_stmts(try_stmt->final_statement);
-                               break;
-                       }
-               }
+               default:
+                       break;
        }
-       return count;
 }
 
 static int get_function_n_local_vars(declaration_t *declaration)
@@ -5261,8 +5090,7 @@ static int get_function_n_local_vars(declaration_t *declaration)
        count += count_local_declarations(declaration->scope.declarations, NULL);
 
        /* count local variables declared in body */
-       count += count_decls_in_stmts(declaration->init.statement);
-
+       walk_statements(declaration->init.statement, count_decls_in_stmt, &count);
        return count;
 }