#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"
static ir_node *current_switch_cond;
static bool saw_default_label;
static declaration_t **all_labels;
+static declaration_t **inner_functions;
+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;
DECLARATION_KIND_ENUM_ENTRY,
DECLARATION_KIND_COMPOUND_TYPE_INCOMPLETE,
DECLARATION_KIND_COMPOUND_TYPE_COMPLETE,
- DECLARATION_KIND_TYPE
+ DECLARATION_KIND_TYPE,
+ DECLARATION_KIND_INNER_FUNCTION
} 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) {
+ inner_functions = NEW_ARR_F(declaration_t *, 16);
+ inner_functions[0] = declaration;
+ inner_function_idx = 1;
+ } else {
+ int size = ARR_LEN(inner_functions);
+ if (inner_function_idx >= size) {
+ ARR_RESIZE(declaration_t *, inner_functions, size + 16);
+ }
+ inner_functions[inner_function_idx++] = declaration;
+ }
+}
+
+static declaration_t *next_inner_function(void) {
+ if (inner_function_idx == 0)
+ return 0;
+ return inner_functions[--inner_function_idx];
+}
ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos)
{
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;
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);
__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. */
*/
static ir_entity *get_function_entity(declaration_t *declaration)
{
- if (declaration->declaration_kind == DECLARATION_KIND_FUNCTION)
+ if (declaration->declaration_kind == DECLARATION_KIND_FUNCTION ||
+ declaration->declaration_kind == DECLARATION_KIND_INNER_FUNCTION)
return declaration->v.entity;
assert(declaration->declaration_kind == DECLARATION_KIND_UNKNOWN);
ir_mode *const mode = get_ir_mode(type);
return create_symconst(dbgi, mode, declaration->v.entity);
}
+ case DECLARATION_KIND_INNER_FUNCTION: {
+ ir_mode *const mode = get_ir_mode(type);
+ if (! declaration->goto_to_outer && !declaration->need_closure) {
+ /* inner function not using the closure */
+ return create_symconst(dbgi, mode, declaration->v.entity);
+ } else {
+ /* TODO: need trampoline here */
+ 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);
/* 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;
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:
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);
}
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);
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);
-
- assert(get_irn_mode(value) == mode || is_Bad(value));
+ 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);
- 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);
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);
}
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;
}
}
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);
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;
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);
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);
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-");
}
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);
}
}
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: {
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);
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);
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;
}
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,
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;
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);
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);
case STORAGE_CLASS_REGISTER:
if (is_type_function(type)) {
if (declaration->init.statement != NULL) {
- panic("nested functions not supported yet");
+ get_function_entity(declaration);
+ declaration->declaration_kind = DECLARATION_KIND_INNER_FUNCTION;
+ enqueue_inner_function(declaration);
} else {
get_function_entity(declaration);
}
case DECLARATION_KIND_FUNCTION:
case DECLARATION_KIND_TYPE:
case DECLARATION_KIND_ENUM_ENTRY:
+ case DECLARATION_KIND_INNER_FUNCTION:
return;
case DECLARATION_KIND_UNKNOWN:
- panic("can't initialize unknwon declaration");
+ panic("can't initialize unknown declaration");
}
panic("invalid declaration kind");
}
static void case_label_to_firm(const case_label_statement_t *statement)
{
- if (statement->is_empty)
+ if (statement->is_empty_range)
return;
dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
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;
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)
{
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;
- }
+ int *const count = env;
- 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)
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;
}
type_t *type = declaration->type;
if (type->kind == TYPE_FUNCTION) {
create_function(declaration);
+ declaration_t *inner;
+ for (inner = next_inner_function(); inner != NULL;
+ inner = next_inner_function())
+ create_function(inner);
} else {
assert(declaration->declaration_kind
== DECLARATION_KIND_GLOBAL_VARIABLE);