aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
-rw-r--r--Makefile2
-rw-r--r--evaluate.c19
-rw-r--r--inline.c43
-rw-r--r--parse.h1
4 files changed, 58 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index 7d56a18e..41e4485c 100644
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ PROGRAMS=test-lexing test-parsing obfuscate check
LIB_H= token.h parse.h lib.h symbol.h scope.h expression.h target.h
LIB_OBJS= parse.o tokenize.o pre-process.o symbol.o lib.o scope.o \
- expression.o show-parse.o evaluate.o
+ expression.o show-parse.o evaluate.o inline.o
LIB_FILE= sparse.a
diff --git a/evaluate.c b/evaluate.c
index d0f5c28a..7e449def 100644
--- a/evaluate.c
+++ b/evaluate.c
@@ -1370,6 +1370,7 @@ static struct symbol *evaluate_cast(struct expression *expr)
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);
@@ -1377,6 +1378,12 @@ static int inline_function(struct expression *expr, struct symbol *sym)
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;
@@ -1407,12 +1414,12 @@ static int inline_function(struct expression *expr, struct symbol *sym)
} END_FOR_EACH_PTR;
FINISH_PTR_LIST(name);
- /*
- * FIXME!
- *
- * This is bogus, we should expand it, not just access it!
- */
- access_symbol(sym);
+ copy_statement(fn->stmt, stmt);
+
+ curr = current_fn;
+ current_fn = fn;
+ evaluate_statement(stmt);
+ current_fn = curr;
return 1;
}
diff --git a/inline.c b/inline.c
new file mode 100644
index 00000000..7b80f5ce
--- /dev/null
+++ b/inline.c
@@ -0,0 +1,43 @@
+/*
+ * Sparse - a semantic source parser.
+ *
+ * Copyright (C) 2003 Transmeta Corp.
+ *
+ * Licensed under the Open Software License version 1.1
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "lib.h"
+#include "token.h"
+#include "parse.h"
+#include "symbol.h"
+
+#define copy_one_statement(stmt) (stmt)
+#define copy_expression(expr) (expr)
+
+/*
+ * Copy a stateemnt tree from 'src' to 'dst', where both
+ * source and destination are of type STMT_COMPOUND.
+ *
+ * We do this for the tree-level inliner.
+ *
+ * This doesn't do the symbol replacements right, duh.
+ */
+void copy_statement(struct statement *src, struct statement *dst)
+{
+ struct statement *stmt;
+ struct symbol *sym;
+
+ FOR_EACH_PTR(src->syms, sym) {
+ struct symbol *newsym = alloc_symbol(sym->pos, sym->type);
+ newsym->ctype = sym->ctype;
+ newsym->initializer = copy_expression(sym->initializer);
+ add_symbol(&dst->syms, newsym);
+ } END_FOR_EACH_PTR;
+
+ FOR_EACH_PTR(src->stmts, stmt) {
+ add_statement(&dst->stmts, copy_one_statement(stmt));
+ } END_FOR_EACH_PTR;
+}
diff --git a/parse.h b/parse.h
index 8dee1939..ea8b93c6 100644
--- a/parse.h
+++ b/parse.h
@@ -94,5 +94,6 @@ extern struct symbol *ctype_integer(unsigned int spec);
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);
#endif /* PARSE_H */