aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Viro <viro@www.linux.org.uk>2004-09-04 19:45:26 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:03:05 -0700
commitee33e420fcfc7ddb359df8ca79316d8fe2084452 (patch)
tree620c9aa9e90f34a3f4b4e588d732adb8d115f0ec /inline.c
parent[PATCH] more on fixing dependency (diff)
downloadsparse-ee33e420fcfc7ddb359df8ca79316d8fe2084452.tar.gz
sparse-ee33e420fcfc7ddb359df8ca79316d8fe2084452.tar.bz2
sparse-ee33e420fcfc7ddb359df8ca79316d8fe2084452.zip
[PATCH] uninlining inline functions
When we take the address of an inline function or otherwise refusing to inline it, we need to output the now non-inline function properly. What we do is a) keeping body and symbol list of inlined function in new fields b) when expanding inlined call use these fields c) when evaluating the function itself (which happens if sparse decides that it can't be [always] inlined) uninline the sucker. I.e. create ->stmt and ->symbol_list by copying the ->inline_stmt and ->inline_symbol_list same as we would do while expanding a call. That guarantees that we won't run into trouble with inlined calls coming afterwards - evaluation doesn't mangle ->inline_stmt anymore.
Diffstat (limited to 'inline.c')
-rw-r--r--inline.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/inline.c b/inline.c
index f5a04d1..a7f6176 100644
--- a/inline.c
+++ b/inline.c
@@ -418,7 +418,7 @@ int inline_function(struct expression *expr, struct symbol *sym)
struct symbol *name;
struct expression *arg;
- if (!fn->stmt) {
+ if (!fn->inline_stmt) {
warn(fn->pos, "marked inline, but without a definition");
return 0;
}
@@ -428,13 +428,11 @@ int inline_function(struct expression *expr, struct symbol *sym)
name_list = fn->arguments;
- stmt = alloc_statement(expr->pos, STMT_COMPOUND);
-
expr->type = EXPR_STATEMENT;
expr->statement = stmt;
expr->ctype = fn->ctype.base_type;
- fn_symbol_list = create_symbol_list(sym->symbol_list);
+ fn_symbol_list = create_symbol_list(sym->inline_symbol_list);
PREPARE_PTR_LIST(name_list, name);
FOR_EACH_PTR(arg_list, arg) {
@@ -453,7 +451,7 @@ int inline_function(struct expression *expr, struct symbol *sym)
} END_FOR_EACH_PTR;
FINISH_PTR_LIST(name);
- copy_statement(fn->stmt, stmt);
+ copy_statement(fn->inline_stmt, stmt);
unset_replace_list(fn_symbol_list);
@@ -462,3 +460,19 @@ int inline_function(struct expression *expr, struct symbol *sym)
fn->expanding = 0;
return 1;
}
+
+void uninline(struct symbol *sym)
+{
+ struct symbol *fn = sym->ctype.base_type;
+ struct symbol_list *arg_list = fn->arguments;
+ struct symbol *p;
+
+ sym->symbol_list = create_symbol_list(sym->inline_symbol_list);
+ FOR_EACH_PTR(arg_list, p) {
+ p->replace = p;
+ } END_FOR_EACH_PTR;
+ fn->stmt = alloc_statement(fn->pos, STMT_COMPOUND);
+ copy_statement(fn->inline_stmt, fn->stmt);
+ unset_replace_list(sym->symbol_list);
+ unset_replace_list(arg_list);
+}