diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-06-14 20:15:46 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:00:52 -0700 |
| commit | b020fece6e9b85066d4a6c306e6d2208c61e22f1 (patch) | |
| tree | f74d08b396bc59e6737d3c707fbce5b34239b0e8 | |
| parent | 6615981184a97439c2ebd9eeae6704c402f35ca8 (diff) | |
| download | sparse-dev-b020fece6e9b85066d4a6c306e6d2208c61e22f1.tar.gz | |
Clean up function inlining some, and fix the type of the
argument symbols that got corrupted by the incorrect
partial symbol copy when creating the new argument symbols.
| -rw-r--r-- | evaluate.c | 66 | ||||
| -rw-r--r-- | inline.c | 75 | ||||
| -rw-r--r-- | parse.h | 1 |
3 files changed, 80 insertions, 62 deletions
@@ -1389,62 +1389,6 @@ static struct symbol *evaluate_cast(struct expression *expr) return ctype; } -static int inline_function(struct expression *expr, struct symbol *sym) -{ - struct symbol *curr; - struct symbol *fn = sym->ctype.base_type; - struct expression_list *arg_list = expr->args; - struct statement *stmt = alloc_statement(expr->pos, STMT_COMPOUND); - struct symbol_list *name_list = sym->ctype.base_type->arguments; - struct symbol *name; - struct expression *arg; - - if (!fn->stmt) { - warn(fn->pos, "marked inline, but without a definition"); - return 0; - } - - stmt = alloc_statement(expr->pos, STMT_COMPOUND); - expr->type = EXPR_STATEMENT; - expr->statement = stmt; - expr->ctype = fn->ctype.base_type; - - /* - * FIXME! On expansion, we'll need to replace the original return - * symbol with this local one! - */ - stmt->ret = alloc_symbol(sym->pos, SYM_NODE); - - /* - * FIXME! On expansion, we'll also need to replace the original - * argument symbols with these! - */ - PREPARE_PTR_LIST(name_list, name); - FOR_EACH_PTR(arg_list, arg) { - struct symbol *a = alloc_symbol(arg->pos, SYM_NODE); - - if (name) { - a->ident = name->ident; - a->ctype.modifiers = name->ctype.modifiers; - name->replace = a; - } - a->ctype.base_type = arg->ctype; - a->initializer = arg; - add_symbol(&stmt->syms, a); - - NEXT_PTR_LIST(name); - } END_FOR_EACH_PTR; - FINISH_PTR_LIST(name); - - copy_statement(fn->stmt, stmt); - - curr = current_fn; - current_fn = fn; - evaluate_statement(stmt); - current_fn = curr; - return 1; -} - /* * Evaluate a call expression with a symbol. This * should expand inline functions, and evaluate @@ -1466,8 +1410,14 @@ static int evaluate_symbol_call(struct expression *expr) * For now we just mark them accessed so that they show * up on the list of used symbols. */ - if (ctype->ctype.modifiers & MOD_INLINE) - return inline_function(expr, ctype); + if (ctype->ctype.modifiers & MOD_INLINE) { + int ret; + struct symbol *curr = current_fn; + current_fn = ctype->ctype.base_type; + ret = inline_function(expr, ctype); + current_fn = curr; + return ret; + } return 0; } @@ -240,6 +240,20 @@ static struct statement *copy_one_statement(struct statement *stmt) return stmt; } +void set_replace(struct symbol *old, struct symbol *new) +{ + new->replace = old; + old->replace = new; +} + +void unset_replace(struct symbol *sym) +{ + struct symbol *r = sym->replace; + if (r) { + r->replace = NULL; + sym->replace = NULL; + } +} /* * Copy a stateemnt tree from 'src' to 'dst', where both @@ -257,18 +271,71 @@ void copy_statement(struct statement *src, struct statement *dst) FOR_EACH_PTR(src->syms, sym) { struct symbol *newsym = alloc_symbol(sym->pos, sym->type); - newsym->replace = sym; - sym->replace = newsym; newsym->ctype = sym->ctype; newsym->initializer = copy_expression(sym->initializer); add_symbol(&dst->syms, newsym); + + set_replace(sym, newsym); } END_FOR_EACH_PTR; FOR_EACH_PTR(src->stmts, stmt) { add_statement(&dst->stmts, copy_one_statement(stmt)); } END_FOR_EACH_PTR; - FOR_EACH_PTR(src->syms, sym) { - sym->replace = NULL; + FOR_EACH_PTR(dst->syms, sym) { + unset_replace(sym); + } END_FOR_EACH_PTR; +} + +int inline_function(struct expression *expr, struct symbol *sym) +{ + struct symbol *fn = sym->ctype.base_type; + struct expression_list *arg_list = expr->args; + struct statement *stmt = alloc_statement(expr->pos, STMT_COMPOUND); + struct symbol_list *name_list = sym->ctype.base_type->arguments; + struct symbol *name; + struct expression *arg; + + if (!fn->stmt) { + warn(fn->pos, "marked inline, but without a definition"); + return 0; + } + + stmt = alloc_statement(expr->pos, STMT_COMPOUND); + + expr->type = EXPR_STATEMENT; + expr->statement = stmt; + expr->ctype = fn->ctype.base_type; + + /* + * FIXME! On expansion, we'll need to replace the original return + * symbol with this local one! + */ + stmt->ret = alloc_symbol(sym->pos, SYM_NODE); + + /* + * FIXME! On expansion, we'll also need to replace the original + * argument symbols with these! + */ + PREPARE_PTR_LIST(name_list, name); + FOR_EACH_PTR(arg_list, arg) { + struct symbol *a = alloc_symbol(arg->pos, SYM_NODE); + + a->ctype.base_type = arg->ctype; + if (name) { + a->ident = name->ident; + a->ctype = name->ctype; + set_replace(name, a); + } + a->initializer = arg; + add_symbol(&stmt->syms, a); + + NEXT_PTR_LIST(name); } END_FOR_EACH_PTR; + FINISH_PTR_LIST(name); + + copy_statement(fn->stmt, stmt); + evaluate_statement(stmt); + + return 1; } @@ -95,5 +95,6 @@ extern struct symbol *ctype_fp(unsigned int spec); extern int match_string_ident(struct ident *, const char *); extern void copy_statement(struct statement *src, struct statement *dst); +extern int inline_function(struct expression *expr, struct symbol *sym); #endif /* PARSE_H */ |
