aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLinus Torvalds <torvalds@home.transmeta.com>2003-03-17 13:01:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 20:59:21 -0700
commit82599b4ccfec1804e6fc976b25a505391d8275d4 (patch)
treec5f3f69b71d1b3947868a297dc4618b375f7515c
parent2540f9d534d34a6e4b018f94314d006ef3209d4c (diff)
downloadsparse-dev-82599b4ccfec1804e6fc976b25a505391d8275d4.tar.gz
Preprocessor symbol handling: handle simple cases of #define and
symbol expansion (ie no argument-handling yet). Mark the EOF token as being on a new line, to make preprocessing simpler.
-rw-r--r--Makefile4
-rw-r--r--pre-process.c91
-rw-r--r--symbol.h22
-rw-r--r--tokenize.c1
4 files changed, 101 insertions, 17 deletions
diff --git a/Makefile b/Makefile
index 061b8b40..af4602f5 100644
--- a/Makefile
+++ b/Makefile
@@ -4,8 +4,8 @@ PROGRAMS=test-lexing test-parsing
all: $(PROGRAMS)
-test-lexing: test-lexing.o tokenize.o pre-process.o lib.o
- gcc -o $@ test-lexing.o tokenize.o pre-process.o lib.o
+test-lexing: test-lexing.o tokenize.o pre-process.o symbol.o lib.o
+ gcc -o $@ test-lexing.o tokenize.o pre-process.o symbol.o lib.o
test-parsing: test-parsing.o parse.o tokenize.o symbol.o pre-process.o lib.o
gcc -o $@ test-parsing.o parse.o tokenize.o symbol.o pre-process.o lib.o
diff --git a/pre-process.c b/pre-process.c
index 7a7a7db0..ae8c84ee 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -16,17 +16,87 @@
#include "token.h"
#include "symbol.h"
-static struct token *preprocessor_line(struct token * head)
+static void expand(struct token *head, struct symbol *sym)
{
- struct token *token = head->next; // hash-mark
+ struct token *expansion, *token, **pptr, *next;
- do {
+ sym->busy++;
+ token = head->next;
+ fprintf(stderr, "expanding symbol '%s'\n", show_token(token));
+
+ expansion = sym->expansion;
+ pptr = &head->next;
+ next = token->next;
+ while (!eof_token(expansion)) {
+ struct token *alloc = __alloc_token(0);
+
+ alloc->type = expansion->type;
+ alloc->stream = token->stream;
+ alloc->pos = token->pos;
+ alloc->newline = 0;
+ alloc->line = token->line;
+ alloc->next = next;
+ alloc->integer = expansion->integer;
+ *pptr = alloc;
+ pptr = &alloc->next;
+ expansion = expansion->next;
+ }
+ sym->busy--;
+}
+
+static int handle_preprocessor_command(struct token *head, struct ident *ident, struct token *left)
+{
+ if (ident->len == 6 && !memcmp(ident->name, "define", 6)) {
+ struct symbol *sym;
+ struct ident *name;
+ if (left->type != TOKEN_IDENT)
+ return 0;
+ name = left->ident;
+ sym = lookup_symbol(name, NS_PREPROCESSOR);
+ if (sym) {
+ warn(left, "preprocessor token redefined");
+ return 1;
+ }
+ sym = alloc_symbol(left, SYM_NONE);
+ bind_symbol(sym, name, NS_PREPROCESSOR);
+ sym->expansion = left->next;
+ return 1;
+ }
+
+ return 0;
+}
+
+static void handle_preprocessor_line(struct token * head, struct token *token)
+{
+ if (!token)
+ return;
+
+ if (token->type == TOKEN_IDENT)
+ if (handle_preprocessor_command(head, token->ident, token->next))
+ return;
+
+ fprintf(stderr, " +++ ");
+ while (!eof_token(token)) {
fprintf(stderr, "%s ", show_token(token));
token = token->next;
- } while (!token->newline && !eof_token(token));
- fprintf(stderr, "\n");
- head->next = token;
- return head;
+ }
+ fprintf(stderr, "+++\n");
+}
+
+static void preprocessor_line(struct token * head)
+{
+ struct token *start = head->next, *next;
+ struct token **tp = &start->next;
+
+ for (;;) {
+ next = *tp;
+ if (next->newline)
+ break;
+ tp = &next->next;
+ }
+ head->next = next;
+ *tp = &eof_token_entry;
+ handle_preprocessor_line(head, start->next);
}
static void do_preprocess(struct token *head)
@@ -34,9 +104,14 @@ static void do_preprocess(struct token *head)
do {
struct token *next = head->next;
if (next->newline && match_op(next, '#')) {
- head = preprocessor_line(head);
+ preprocessor_line(head);
continue;
}
+ if (next->type == TOKEN_IDENT) {
+ struct symbol *sym= lookup_symbol(next->ident, NS_PREPROCESSOR);
+ if (sym)
+ expand(head, sym);
+ }
head = next;
} while (!eof_token(head));
}
diff --git a/symbol.h b/symbol.h
index 96d1daaa..0f9e16f3 100644
--- a/symbol.h
+++ b/symbol.h
@@ -42,14 +42,22 @@ struct symbol {
enum namespace namespace:8;
enum type type:8;
struct token *token; /* Where this symbol was declared */
- struct symbol *next; /* Next symbol at this level */
struct symbol *next_id; /* Next semantic symbol that shares this identifier */
- unsigned long size;
- unsigned long modifiers;
- struct symbol *base_type;
- struct symbol *children;
- struct statement *stmt;
- struct symbol_list *symbol_list;
+ union {
+ struct preprocessor_sym {
+ int busy;
+ struct token *expansion;
+ };
+ struct ctype_symbol {
+ struct symbol *next; /* Next symbol at this level */
+ unsigned long size;
+ unsigned long modifiers;
+ struct symbol *base_type;
+ struct symbol *children;
+ struct statement *stmt;
+ struct symbol_list *symbol_list;
+ };
+ };
};
/* Modifiers */
diff --git a/tokenize.c b/tokenize.c
index 2f7fda6d..a881c088 100644
--- a/tokenize.c
+++ b/tokenize.c
@@ -181,6 +181,7 @@ struct token eof_token_entry;
static void mark_eof(action_t *action)
{
eof_token_entry.next = &eof_token_entry;
+ eof_token_entry.newline = 1;
*action->tokenlist = &eof_token_entry;
action->tokenlist = NULL;
}