X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=c0a0d983ef59ca54650b402fbeb3b57b2e32b3b7;hb=2b69f877f5c1709b02a0bd6ec374bdf6484dd751;hp=eb68d0f3d0ef870538bab701d980349ac094e268;hpb=ba19ec2de61d3edff9134fcc8c814e0ef3377be3;p=cparser diff --git a/ast2firm.c b/ast2firm.c index eb68d0f..c0a0d98 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -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" @@ -94,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) { @@ -176,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; @@ -217,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); @@ -319,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); @@ -335,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; @@ -352,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); @@ -385,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); @@ -431,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; @@ -441,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; } @@ -454,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); @@ -608,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); @@ -1450,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: { @@ -1533,7 +1521,12 @@ 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: + 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: @@ -1578,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); @@ -1586,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); @@ -1784,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); @@ -1823,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); } @@ -1896,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; } } @@ -2536,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); @@ -2640,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; @@ -3219,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); @@ -3306,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-"); } @@ -3451,7 +3450,6 @@ 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); @@ -3709,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: { @@ -3717,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); @@ -3729,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); @@ -3756,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; } @@ -3791,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, @@ -4554,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) { @@ -4573,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: @@ -4583,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); @@ -4695,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); } @@ -4795,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; @@ -5032,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) { @@ -5045,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; + int *const count = env; - 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; - } - - 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) @@ -5267,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; }