[PATCH] depend.c: build up a dependency tree from c entities downto tokens: entries in the tree are: macro-depend: tree of #if nesting macro-expansions: possible macro expansion source of a token tok->macro-expansions->macro tok->macro-depend->macro c entities are linked in via [stmt|expr|sym]->start-end-token

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: KE <eiselekd@xxxxxx>

---
 Makefile      |    6 +-
 allocate.c    |    8 ++-
 allocate.h    |   10 ++-
 attr.c        |   67 ++++++++++++
 attr.h        |   18 +++
 depend.c      |  329 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 depend.h      |   91 ++++++++++++++++
 expand.c      |    1 +
 expression.c  |   60 +++++-----
 expression.h  |    8 ++
 inline.c      |   10 ++
 lib.c         |    8 ++
 parse.c       |   73 +++++++++----
 parse.h       |    1 +
 pre-process.c |  104 ++++++++++++------
 shrink.c      |  102 ++++++++++++++++++
 sparse.c      |    3 +
 symbol.h      |    9 ++
 token.h       |   10 ++
 19 files changed, 826 insertions(+), 92 deletions(-)
 create mode 100644 attr.c
 create mode 100644 attr.h
 create mode 100644 depend.c
 create mode 100644 depend.h
 create mode 100644 shrink.c

diff --git a/Makefile b/Makefile
index 79cadb0..833ec70 100644
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,8 @@ INCLUDEDIR=$(PREFIX)/include
 PKGCONFIGDIR=$(LIBDIR)/pkgconfig
 
 PROGRAMS=test-lexing test-parsing obfuscate compile graph sparse \
-	 test-linearize example test-unssa test-dissect ctags
+	 test-linearize example test-unssa test-dissect ctags \
+	 shrink
 INST_PROGRAMS=sparse cgcc
 INST_MAN1=sparse.1 cgcc.1
 
@@ -70,7 +71,8 @@ LIB_H=    token.h parse.h lib.h symbol.h scope.h expression.h target.h \
 LIB_OBJS= target.o parse.o tokenize.o pre-process.o symbol.o lib.o scope.o \
 	  expression.o show-parse.o evaluate.o expand.o inline.o linearize.o \
 	  sort.o allocate.o compat-$(OS).o ptrlist.o \
-	  flow.o cse.o simplify.o memops.o liveness.o storage.o unssa.o dissect.o
+	  flow.o cse.o simplify.o memops.o liveness.o storage.o unssa.o dissect.o \
+	  depend.o attr.o
 
 LIB_FILE= libsparse.a
 SLIB_FILE= libsparse.so
diff --git a/allocate.c b/allocate.c
index 5cc52a9..30378d3 100644
--- a/allocate.c
+++ b/allocate.c
@@ -26,6 +26,7 @@
 #include "scope.h"
 #include "expression.h"
 #include "linearize.h"
+#include "depend.h"
 
 void protect_allocations(struct allocator_struct *desc)
 {
@@ -125,5 +126,10 @@ ALLOCATOR(entrypoint, "entrypoint");
 ALLOCATOR(instruction, "instruction");
 ALLOCATOR(multijmp, "multijmp");
 ALLOCATOR(pseudo, "pseudo");
+ALLOCATOR(macro_dep, "macro dependency");
+ALLOCATOR(macro_expansion, "macro expansion");
 
-
+void token_allocator_nofree(void) 
+{
+	token_allocator.nofree = 1;
+}
diff --git a/allocate.h b/allocate.h
index 9f1dc8c..de85320 100644
--- a/allocate.h
+++ b/allocate.h
@@ -12,6 +12,7 @@ struct allocator_struct {
 	struct allocation_blob *blobs;
 	unsigned int alignment;
 	unsigned int chunking;
+	unsigned int nofree;
 	void *freelist;
 	/* statistics */
 	unsigned int allocations, total_bytes, useful_bytes;
@@ -22,6 +23,7 @@ extern void drop_all_allocations(struct allocator_struct *desc);
 extern void *allocate(struct allocator_struct *desc, unsigned int size);
 extern void free_one_entry(struct allocator_struct *desc, void *entry);
 extern void show_allocations(struct allocator_struct *);
+extern void token_allocator_nofree(void);
 
 #define __DECLARE_ALLOCATOR(type, x)		\
 	extern type *__alloc_##x(int);		\
@@ -42,7 +44,8 @@ extern void show_allocations(struct allocator_struct *);
 	}							\
 	void __free_##x(type *entry)				\
 	{							\
-		free_one_entry(&x##_allocator, entry);		\
+		if (!x##_allocator.nofree)			\
+			free_one_entry(&x##_allocator, entry);	\
 	}							\
 	void show_##x##_alloc(void)				\
 	{							\
@@ -50,7 +53,8 @@ extern void show_allocations(struct allocator_struct *);
 	}							\
 	void clear_##x##_alloc(void)				\
 	{							\
-		drop_all_allocations(&x##_allocator);		\
+		if (!x##_allocator.nofree)			\
+			drop_all_allocations(&x##_allocator);	\
 	}							\
 	void protect_##x##_alloc(void)				\
 	{							\
@@ -77,5 +81,7 @@ DECLARE_ALLOCATOR(instruction);
 DECLARE_ALLOCATOR(multijmp);
 DECLARE_ALLOCATOR(phi);
 DECLARE_ALLOCATOR(pseudo);
+DECLARE_ALLOCATOR(macro_dep);
+DECLARE_ALLOCATOR(macro_expansion);
 
 #endif
diff --git a/attr.c b/attr.c
new file mode 100644
index 0000000..54c4c21
--- /dev/null
+++ b/attr.c
@@ -0,0 +1,67 @@
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "allocate.h"
+#include "compat.h"
+#include "attr.h"
+
+struct hash_v {
+	struct hash_v *n;
+	void *key;
+	enum attr_tags tag;
+	void *v;
+};
+
+__DECLARE_ALLOCATOR(struct hash_v, hash_v);
+__ALLOCATOR(struct hash_v, "hash value", hash_v);
+
+#define HASH_LEN (1024*4)
+struct hash {
+	struct hash_v *f;
+} h[HASH_LEN];
+
+void init_attr(void) {
+	memset(h, 0, sizeof(h));
+}
+
+static int hash_func(void *key, enum attr_tags tag) {
+	unsigned int k = ((unsigned int)key) >> 4;
+	return ((k) ^ (k >> 16) ^ (k >> 24) ^ tag) & (HASH_LEN-1);
+}
+
+void **lookup_attr(void *key, enum attr_tags tag, int create) {
+	int i = hash_func(key, tag);
+	struct hash *hp = &h[i];
+	struct hash_v *p;
+	struct hash_v **c = &hp->f;
+	while((p = *c)) {
+		if ((p ->tag == tag)
+		    && (p ->key == key)) {
+			return &p->v;
+		}
+		c = &p->n;
+	}
+	if (create) {
+		p = __alloc_hash_v(0);
+		p->key = key;
+		p->tag = tag;
+		p->v = 0;
+		*c = p;
+		return &p->v;
+	}
+	return 0;
+}
+
+void *set_attr(void *key, enum attr_tags tag, void *data) {
+	void **p = lookup_attr(key, tag, 1);
+	assert(p);
+	*p = data;
+	return data;
+}
+
+void *get_attr(void *key, enum attr_tags tag) {
+	void **p = lookup_attr(key, tag, 0);
+	if (!p)
+		return 0;
+	return *p;
+}
diff --git a/attr.h b/attr.h
new file mode 100644
index 0000000..aa5750c
--- /dev/null
+++ b/attr.h
@@ -0,0 +1,18 @@
+#ifndef _SPARSE_ATTR_H
+#define _SPARSE_ATTR_H
+
+enum attr_tags {
+	ATTR_TAG_MACRO_DEP = 1,
+	ATTR_TAG_FLAGS = 2,
+	ATTR_TAG_MACRO_EXP = 3
+};
+
+#define SET_MACRO_DEP(a,v) set_attr(a, ATTR_TAG_MACRO_DEP, v)
+#define GET_MACRO_DEP(a) ((struct macro_dep *)get_attr(a, ATTR_TAG_MACRO_DEP))
+#define NEW_MACRO_DEP() ((struct macro_dep *)attr_data(ATTR_TAG_MACRO_DEP))
+
+extern void *set_attr(void *key, enum attr_tags tag, void *data);
+extern void *get_attr(void *key, enum attr_tags tag);
+extern void *attr_data(enum attr_tags tag);
+
+#endif
diff --git a/depend.c b/depend.c
new file mode 100644
index 0000000..f36134a
--- /dev/null
+++ b/depend.c
@@ -0,0 +1,329 @@
+/*
+ * Build macros dependency tree 
+ * Copyright (C) 2012 Konrad Eisele <konrad@xxxxxxxxxxx,eiselekd@xxxxxxxxx>
+ * BSD-License
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the <organization>.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "token.h"
+#include "allocate.h"
+#include "compat.h"
+#include "depend.h"
+#include "attr.h"
+#include "parse.h"
+#include "symbol.h"
+#include "expression.h"
+
+__DECLARE_ALLOCATOR(struct dep_flags, dep_flags);
+__ALLOCATOR(struct dep_flags, "dependency flags", dep_flags);
+__DECLARE_ALLOCATOR(struct tok_macro_dep, tok_macro_dep);
+__ALLOCATOR(struct tok_macro_dep, "token macro expansion relation", tok_macro_dep);
+__DECLARE_ALLOCATOR(struct macro_dep_el, macro_dep_el);
+__ALLOCATOR(struct macro_dep_el, "macro dependency element", macro_dep_el);
+
+static void * push_dep(struct depend_if *dif, struct token *tok);
+static void * else_dep(struct depend_if *dif, struct token *tok);
+static void * pop_dep(struct depend_if *dif, struct token *tok);
+static void * push_sym(struct depend_if *dif, struct symbol *sym);
+static void * on_dep(struct depend_if *dif, void *p);
+static void * off_dep(struct depend_if *dif, void *p);
+static void * tag_dep(struct depend_if *dif,struct token *tok);
+static void * set_tok(struct depend_if *dif,void *p, struct token *tok);
+static void * end_tok(struct depend_if *dif,void *p, struct token *tok);
+static void * inherit_tok(struct depend_if *dif,void *a, void *b);
+static void * set_symlist(struct depend_if *dif,void *a, struct symbol_list * l);
+static void * macro_exp(struct depend_if *dif,struct token *tok, struct tok_macro_dep *m);
+
+static void depend_symbol_list(struct symbol_list *ptrlist);
+static void depend_expression(struct expression *expr);
+static void depend_statement(struct statement *stmt);
+
+struct depend_if d = {
+	.push_dep = push_dep,
+	.else_dep = else_dep,
+	.pop_dep = pop_dep,
+	.push_sym = push_sym,
+	.on = on_dep,
+	.off = off_dep,
+	.tag_dep = tag_dep,
+	.set_tok = set_tok,
+	.end_tok = end_tok,
+	.inherit_tok = inherit_tok,
+	.set_symlist = set_symlist,
+	.macro_exp = macro_exp,
+	.dep = &d.root_dep,
+};
+
+struct macro_dep *alloc_macro_dep(struct token *tok) {
+	struct macro_dep *e;
+	e = __alloc_macro_dep(0);
+	e->ppline = tok;
+	return e;
+}
+
+static int is_root(struct depend_if *dif) {
+	return dif->dep == &dif->root_dep ? 1 : 0;
+}
+
+static void *on_dep(struct depend_if *dif, void *p) {
+	dif->dep_use = dif->dep;
+	return 0;
+}
+
+static void *off_dep(struct depend_if *dif, void *p) {
+	dif->dep_use = 0;
+	return 0;
+}
+
+static void *push_dep(struct depend_if *dif, struct token *tok) {
+	struct macro_dep *e = alloc_macro_dep(tok);
+	e->up = dif->dep;
+	dif->dep = e;
+	on_dep(dif, 0);
+	return e;
+}
+
+/* push a macro_dep not on top of stack but one below, to reference <tok> */
+static void *else_dep(struct depend_if *dif, struct token *tok) {
+	struct macro_dep *e;
+	e = alloc_macro_dep(tok);
+	e->up = dif->dep->up;
+	dif->dep->up = e;
+	return e;
+}
+
+static void *pop_dep(struct depend_if *dif, struct token *tok) {
+	struct macro_dep *r = 0;
+	if (!is_root(dif)) {
+		dif->dep = dif->dep->up;
+	}
+	return r;
+}
+
+static void *push_sym(struct depend_if *dif, struct symbol *sym) {
+	
+	struct macro_dep_el *e = 0;
+	if (dif->dep_use) {
+		e = __alloc_macro_dep_el(0);
+		e->sym = sym;
+		e->n = dif->dep_use->f;
+		dif->dep_use->f = e;
+	}
+	return e;
+}
+
+static void * tag_dep(struct depend_if *dif,struct token *tok)
+{
+	struct macro_dep *a = 0, *c, *d = GET_MACRO_DEP(tok);
+	if (!eof_token(tok) && (a = dif->dep) && !is_root(dif)) {
+		if (d) {
+			c = alloc_macro_dep(0);
+			c->up = a;
+			c->same = d;
+			a = c;
+		}
+		SET_MACRO_DEP(tok, a);
+	}
+	return a;
+}
+
+void init_dep(void) {
+	dif = &d;
+	token_allocator_nofree();
+}
+
+struct dep_flags *depend_flags(void *p, int create) {
+	struct dep_flags *f;
+	if (!(f = (struct dep_flags *)get_attr(p, ATTR_TAG_FLAGS))) {
+		if (create) {
+			f = __alloc_dep_flags(0);
+			memset(f, 0, sizeof(struct dep_flags));
+			set_attr(p, ATTR_TAG_FLAGS, f);
+		}
+	}
+	return f;
+}
+
+struct dep_flags *depend_visited(void *p) {
+	struct dep_flags *f = 0; int r = 1;
+	if (p) {
+		f = depend_flags(p,1);
+		r = f->visited;
+		f->visited = 1;
+	}
+	return r ? 0 : f;
+}
+
+static void * set_tok(struct depend_if *dif,void *p, struct token *tok)
+{
+	struct dep_flags *f = depend_flags(p,1);
+	f->tok = tok;
+	return f;
+}
+
+static void * end_tok(struct depend_if *dif,void *p, struct token *tok)
+{
+	struct dep_flags *f = depend_flags(p,1);
+	f->end = tok;
+	return f;
+}
+
+static void * inherit_tok(struct depend_if *dif,void *a, void *b)
+{
+	struct dep_flags *af = depend_flags(a,1);
+	struct dep_flags *bf = depend_flags(b,1);
+	af->tok = bf->tok;
+	af->end = bf->end;
+	return af;
+}
+
+static void * set_symlist(struct depend_if *dif,void *a, struct symbol_list * l)
+{
+	struct dep_flags *f = depend_flags(a,1);
+	f->symlist = l;
+	return f;
+}
+
+static void * macro_exp(struct depend_if *dif, struct token *tok, struct tok_macro_dep *m) {
+	struct tok_macro_dep *p = 0;
+	if (tok && m) {
+		p  = __alloc_tok_macro_dep(0);
+		*p = *m;
+		set_attr(tok, ATTR_TAG_MACRO_EXP, p);
+		return p;
+	}
+	return p;
+}
+
+void depend_statement_list(struct ptr_list *ptrlist)
+{
+	void *ptr;
+	if (!ptrlist)
+		return;
+	FOR_EACH_PTR(ptrlist, ptr) {
+		depend_statement(ptr);
+	} END_FOR_EACH_PTR(ptr);
+}
+
+void depend_symbol_list(struct symbol_list *ptrlist)
+{
+	void *ptr;
+	if (!ptrlist) 
+		return;
+	FOR_EACH_PTR(((struct ptr_list *)ptrlist), ptr) {
+		depend_symbol(ptr);
+	} END_FOR_EACH_PTR(ptr);
+}
+
+void depend_statement(struct statement *stmt)
+{
+	struct dep_flags *f;
+	if (!(f = depend_visited(stmt)))
+		return;
+	
+	switch (stmt->type) {
+	case STMT_COMPOUND:
+		depend_statement_list((struct ptr_list *)stmt->stmts);
+		break;
+	case STMT_EXPRESSION:
+		depend_expression(stmt->expression);
+		break;
+	case STMT_IF:
+		depend_expression(stmt->if_conditional);
+		depend_statement(stmt->if_true);
+		depend_statement(stmt->if_false);
+		break;
+	case STMT_ITERATOR:
+		depend_symbol(stmt->iterator_break);
+		depend_symbol(stmt->iterator_continue);
+		depend_statement(stmt->iterator_pre_statement);
+		depend_statement(stmt->iterator_statement);
+		depend_statement(stmt->iterator_post_statement);
+		break;
+	case STMT_SWITCH:
+		depend_expression(stmt->switch_expression);
+		depend_statement(stmt->switch_statement);
+		depend_symbol(stmt->switch_break);
+		depend_symbol(stmt->switch_case);
+		break;
+	case STMT_CASE:
+		depend_expression(stmt->case_expression);
+		depend_expression(stmt->case_to);
+		depend_statement(stmt->case_statement);
+		depend_symbol(stmt->case_label);
+		break;
+	case STMT_RETURN:
+		depend_expression(stmt->ret_value);
+		depend_symbol(stmt->ret_target);
+		break;
+	default:
+		break;
+	}
+}
+
+void depend_expression(struct expression *expr)
+{
+	struct dep_flags *f;
+	if (!(f = depend_visited(expr)))
+		return;
+	switch (expr->type) {
+	case EXPR_STATEMENT:
+		depend_statement(expr->statement);
+		break;
+	case EXPR_BINOP:
+	case EXPR_COMMA:
+	case EXPR_COMPARE:
+	case EXPR_LOGICAL:
+	case EXPR_ASSIGNMENT:
+		depend_expression(expr->left);
+		depend_expression(expr->right);
+		break;
+	case EXPR_CAST:
+	case EXPR_FORCE_CAST:
+	case EXPR_IMPLIED_CAST:
+		depend_symbol(expr->cast_type);
+		depend_expression(expr->cast_expression);
+		break;
+	case EXPR_PREOP:
+		depend_expression(expr->unop);
+		break;
+	default:
+		break;
+	}
+}
+
+void depend_symbol(struct symbol *sym)
+{
+	struct dep_flags *f;
+	if (!(f = depend_visited(sym)))
+		return;
+	
+	depend_symbol(sym->ctype.base_type);
+	depend_symbol_list(f->symlist);
+
+	switch (sym->namespace) {
+	case NS_PREPROCESSOR:
+		break;
+	case NS_MACRO:
+		/*depend_macro_dep(sym->dep);*/
+	default:
+		/*use_line_fromto(sym->token, sym->endtoken);*/
+		depend_symbol_list(sym->arguments);
+		depend_symbol_list(sym->symbol_list);
+		depend_statement(sym->stmt);
+		break;
+	}
+}
diff --git a/depend.h b/depend.h
new file mode 100644
index 0000000..34a2159
--- /dev/null
+++ b/depend.h
@@ -0,0 +1,91 @@
+/*
+ * Build macros dependency tree 
+ * Copyright (C) 2012 Konrad Eisele <konrad@xxxxxxxxxxx>
+ * BSD-License
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the <organization>.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ */
+
+#ifndef _SPARSE_DEPEND_H
+#define _SPARSE_DEPEND_H
+
+#include "attr.h"
+#include "token.h"
+
+struct macro_dep_el {
+	struct macro_dep_el *n;
+	struct symbol *sym;
+};
+
+struct macro_dep {
+	struct macro_dep *up, *same;
+	struct token *ppline;
+	struct macro_dep_el *f;
+	int visited : 1;
+};
+
+struct dep_flags {
+	struct token *tok;
+	struct token *end;
+	struct symbol_list *symlist;
+	unsigned int visited : 1;
+};
+
+struct macro_expansion {
+	int nargs;
+	struct symbol *sym;
+	struct token *m;
+	struct arg args[0];
+};
+
+struct tok_macro_dep {
+	struct macro_expansion *m;
+	unsigned int argi;
+	unsigned int isbody : 1;
+	unsigned int visited : 1;
+};
+
+struct depend_if {
+	/* ATTR_TAG_MACRO_DEP tagging */
+	void * (*push_dep)(struct depend_if *dif, struct token *tok);
+	void * (*else_dep)(struct depend_if *dif, struct token *tok);
+	void * (*pop_dep)(struct depend_if *dif, struct token *tok);
+	void * (*push_sym)(struct depend_if *dif, struct symbol *sym);
+	void * (*on)(struct depend_if *dif, void *p);
+	void * (*off)(struct depend_if *dif, void *p);
+	/* ATTR_TAG_FLAGS tagging */
+	void * (*tag_dep)(struct depend_if *dif,struct token *tok);
+	void * (*set_tok)(struct depend_if *dif,void *p, struct token *tok);
+	void * (*end_tok)(struct depend_if *dif,void *p, struct token *tok);
+	void * (*inherit_tok)(struct depend_if *dif,void *a, void *b);
+	void * (*set_symlist)(struct depend_if *dif,void *a, struct symbol_list * l);
+	/* ATTR_TAG_MACRO_EXP tagging */
+	void * (*macro_exp)(struct depend_if *dif, struct token *tok, struct tok_macro_dep *m);
+	
+	struct macro_dep *dep, *dep_use;
+	struct macro_dep root_dep;
+};
+
+#define DEPEN() (dif != 0)
+#define DEPCALL(f,v) if (DEPEN()) dif->f(dif,v)
+#define DEP_TOK(p,tok) if (DEPEN()) dif->set_tok(dif,p,tok)
+#define DEP_INHERIT(a,b) if (DEPEN()) dif->inherit_tok(dif,a,b)
+#define DEP_END(p,tok) if (DEPEN()) dif->end_tok(dif,p,tok)
+#define DEP_SYMLIST(p,l) if (DEPEN()) dif->set_symlist(dif,p,l)
+#define DEP_MACRO_EXP(p,m,i,b) if (DEPEN()) {		\
+		struct tok_macro_dep n = { m, i, b };	\
+		dif->macro_exp(dif,p,&n);		\
+	}
+
+extern void init_dep(void);
+extern void depend_symbol(struct symbol *sym);
+#endif
diff --git a/expand.c b/expand.c
index 63a9075..cf292e1 100644
--- a/expand.c
+++ b/expand.c
@@ -859,6 +859,7 @@ static int expand_pos_expression(struct expression *expr)
 						 * zero..
 						 */
 						reuse = alloc_expression(entry->pos, EXPR_POS);
+						DEP_INHERIT (reuse, entry);
 					}
 					reuse->type = EXPR_POS;
 					reuse->ctype = entry->ctype;
diff --git a/expression.c b/expression.c
index 0ae3a60..9ae8148 100644
--- a/expression.c
+++ b/expression.c
@@ -47,7 +47,7 @@ struct token *parens_expression(struct token *token, struct expression **expr, c
 {
 	token = expect(token, '(', where);
 	if (match_op(token, '{')) {
-		struct expression *e = alloc_expression(token->pos, EXPR_STATEMENT);
+		struct expression *e = alloc_expression_tok(token, EXPR_STATEMENT);
 		struct statement *stmt = alloc_statement(token->pos, STMT_COMPOUND);
 		*expr = e;
 		e->statement = stmt;
@@ -116,7 +116,7 @@ static int convert_function(struct token *next)
 static struct token *parse_type(struct token *token, struct expression **tree)
 {
 	struct symbol *sym;
-	*tree = alloc_expression(token->pos, EXPR_TYPE);
+	*tree = alloc_expression_tok(token, EXPR_TYPE);
 	(*tree)->flags = Int_const_expr; /* sic */
 	token = typename(token, &sym, NULL);
 	if (sym->ident)
@@ -130,8 +130,8 @@ static struct token *parse_type(struct token *token, struct expression **tree)
 static struct token *builtin_types_compatible_p_expr(struct token *token,
 						     struct expression **tree)
 {
-	struct expression *expr = alloc_expression(
-		token->pos, EXPR_COMPARE);
+	struct expression *expr = alloc_expression_tok(
+		token, EXPR_COMPARE);
 	expr->flags = Int_const_expr;
 	expr->op = SPECIAL_EQUAL;
 	token = token->next;
@@ -185,7 +185,7 @@ static struct token *builtin_offsetof_expr(struct token *token,
 		default:
 			return expect(token, ')', "at end of __builtin_offset");
 		case SPECIAL_DEREFERENCE:
-			e = alloc_expression(token->pos, EXPR_OFFSETOF);
+			e = alloc_expression_tok(token, EXPR_OFFSETOF);
 			e->flags = Int_const_expr;
 			e->op = '[';
 			*p = e;
@@ -193,7 +193,7 @@ static struct token *builtin_offsetof_expr(struct token *token,
 			/* fall through */
 		case '.':
 			token = token->next;
-			e = alloc_expression(token->pos, EXPR_OFFSETOF);
+			e = alloc_expression_tok(token, EXPR_OFFSETOF);
 			e->flags = Int_const_expr;
 			e->op = '.';
 			if (token_type(token) != TOKEN_IDENT) {
@@ -205,7 +205,7 @@ static struct token *builtin_offsetof_expr(struct token *token,
 			break;
 		case '[':
 			token = token->next;
-			e = alloc_expression(token->pos, EXPR_OFFSETOF);
+			e = alloc_expression_tok(token, EXPR_OFFSETOF);
 			e->flags = Int_const_expr;
 			e->op = '[';
 			token = parse_expression(token, &e->index);
@@ -406,7 +406,7 @@ struct token *primary_expression(struct token *token, struct expression **tree)
 	switch (token_type(token)) {
 	case TOKEN_CHAR:
 	case TOKEN_WIDE_CHAR:
-		expr = alloc_expression(token->pos, EXPR_VALUE);   
+		expr = alloc_expression_tok(token, EXPR_VALUE);   
 		expr->flags = Int_const_expr;
 		expr->ctype = token_type(token) == TOKEN_CHAR ? &int_ctype : &long_ctype;
 		expr->value = (unsigned char) token->character;
@@ -414,13 +414,13 @@ struct token *primary_expression(struct token *token, struct expression **tree)
 		break;
 
 	case TOKEN_NUMBER:
-		expr = alloc_expression(token->pos, EXPR_VALUE);
+		expr = alloc_expression_tok(token, EXPR_VALUE);
 		get_number_value(expr, token); /* will see if it's an integer */
 		token = token->next;
 		break;
 
 	case TOKEN_ZERO_IDENT: {
-		expr = alloc_expression(token->pos, EXPR_SYMBOL);
+		expr = alloc_expression_tok(token, EXPR_SYMBOL);
 		expr->flags = Int_const_expr;
 		expr->ctype = &int_ctype;
 		expr->symbol = &zero_int;
@@ -445,7 +445,7 @@ struct token *primary_expression(struct token *token, struct expression **tree)
 				break;
 			}
 		} else if (sym->enum_member) {
-			expr = alloc_expression(token->pos, EXPR_VALUE);
+			expr = alloc_expression_tok(token, EXPR_VALUE);
 			*expr = *sym->initializer;
 			/* we want the right position reported, thus the copy */
 			expr->pos = token->pos;
@@ -454,7 +454,7 @@ struct token *primary_expression(struct token *token, struct expression **tree)
 			break;
 		}
 
-		expr = alloc_expression(token->pos, EXPR_SYMBOL);
+		expr = alloc_expression_tok(token, EXPR_SYMBOL);
 
 		/*
 		 * We support types as real first-class citizens, with type
@@ -475,7 +475,7 @@ struct token *primary_expression(struct token *token, struct expression **tree)
 	case TOKEN_STRING:
 	case TOKEN_WIDE_STRING: {
 	handle_string:
-		expr = alloc_expression(token->pos, EXPR_STRING);
+		expr = alloc_expression_tok(token, EXPR_STRING);
 		expr->wide = token_type(token) == TOKEN_WIDE_STRING;
 		token = string_expression(token, expr);
 		break;
@@ -483,7 +483,7 @@ struct token *primary_expression(struct token *token, struct expression **tree)
 
 	case TOKEN_SPECIAL:
 		if (token->special == '(') {
-			expr = alloc_expression(token->pos, EXPR_PREOP);
+			expr = alloc_expression_tok(token, EXPR_PREOP);
 			expr->op = '(';
 			token = parens_expression(token, &expr->unop, "in expression");
 			if (expr->unop)
@@ -491,7 +491,7 @@ struct token *primary_expression(struct token *token, struct expression **tree)
 			break;
 		}
 		if (token->special == '[' && lookup_type(token->next)) {
-			expr = alloc_expression(token->pos, EXPR_TYPE);
+			expr = alloc_expression_tok(token, EXPR_TYPE);
 			expr->flags = Int_const_expr; /* sic */
 			token = typename(token->next, &expr->symbol, NULL);
 			token = expect(token, ']', "in type expression");
@@ -534,8 +534,8 @@ static struct token *postfix_expression(struct token *token, struct expression *
 	while (expr && token_type(token) == TOKEN_SPECIAL) {
 		switch (token->special) {
 		case '[': {			/* Array dereference */
-			struct expression *deref = alloc_expression(token->pos, EXPR_PREOP);
-			struct expression *add = alloc_expression(token->pos, EXPR_BINOP);
+			struct expression *deref = alloc_expression_tok(token, EXPR_PREOP);
+			struct expression *add = alloc_expression_tok(token, EXPR_BINOP);
 
 			deref->op = '*';
 			deref->unop = add;
@@ -549,7 +549,7 @@ static struct token *postfix_expression(struct token *token, struct expression *
 		}
 		case SPECIAL_INCREMENT:		/* Post-increment */
 		case SPECIAL_DECREMENT:	{	/* Post-decrement */
-			struct expression *post = alloc_expression(token->pos, EXPR_POSTOP);
+			struct expression *post = alloc_expression_tok(token, EXPR_POSTOP);
 			post->op = token->special;
 			post->unop = expr;
 			expr = post;
@@ -558,14 +558,14 @@ static struct token *postfix_expression(struct token *token, struct expression *
 		}
 		case SPECIAL_DEREFERENCE: {	/* Structure pointer member dereference */
 			/* "x->y" is just shorthand for "(*x).y" */
-			struct expression *inner = alloc_expression(token->pos, EXPR_PREOP);
+			struct expression *inner = alloc_expression_tok(token, EXPR_PREOP);
 			inner->op = '*';
 			inner->unop = expr;
 			expr = inner;
 		}
 		/* Fall through!! */
 		case '.': {			/* Structure member dereference */
-			struct expression *deref = alloc_expression(token->pos, EXPR_DEREF);
+			struct expression *deref = alloc_expression_tok(token, EXPR_DEREF);
 			deref->op = '.';
 			deref->deref = expr;
 			token = token->next;
@@ -580,7 +580,7 @@ static struct token *postfix_expression(struct token *token, struct expression *
 		}
 
 		case '(': {			/* Function call */
-			struct expression *call = alloc_expression(token->pos, EXPR_CALL);
+			struct expression *call = alloc_expression_tok(token, EXPR_CALL);
 			call->op = '(';
 			call->fn = expr;
 			token = expression_list(token->next, &call->args);
@@ -604,7 +604,7 @@ static struct token *unary_expression(struct token *token, struct expression **t
 static struct token *type_info_expression(struct token *token,
 	struct expression **tree, int type)
 {
-	struct expression *expr = alloc_expression(token->pos, type);
+	struct expression *expr = alloc_expression_tok(token, type);
 	struct token *p;
 
 	*tree = expr;
@@ -630,7 +630,7 @@ static struct token *type_info_expression(struct token *token,
 	 * of a typed initializer expression..
 	 */
 	if (match_op(token, '{')) {
-		struct expression *cast = alloc_expression(p->pos, EXPR_CAST);
+		struct expression *cast = alloc_expression_tok(p, EXPR_CAST);
 		cast->cast_type = expr->cast_type;
 		expr->cast_type = NULL;
 		expr->cast_expression = cast;
@@ -676,7 +676,7 @@ static struct token *unary_expression(struct token *token, struct expression **t
 				*tree = NULL;
 				return next;
 			}
-			unary = alloc_expression(token->pos, EXPR_PREOP);
+			unary = alloc_expression_tok(token, EXPR_PREOP);
 			unary->op = token->special;
 			unary->unop = unop;
 			*tree = unary;
@@ -694,7 +694,7 @@ static struct token *unary_expression(struct token *token, struct expression **t
 				*tree = NULL;
 				return next;
 			}
-			unary = alloc_expression(token->pos, EXPR_PREOP);
+			unary = alloc_expression_tok(token, EXPR_PREOP);
 			unary->op = token->special;
 			unary->unop = unop;
 			unary->flags = unop->flags & Int_const_expr;
@@ -704,7 +704,7 @@ static struct token *unary_expression(struct token *token, struct expression **t
 		/* Gcc extension: &&label gives the address of a label */
 		if (match_op(token, SPECIAL_LOGICAL_AND) &&
 		    token_type(token->next) == TOKEN_IDENT) {
-			struct expression *label = alloc_expression(token->pos, EXPR_LABEL);
+			struct expression *label = alloc_expression_tok(token, EXPR_LABEL);
 			struct symbol *sym = label_symbol(token->next);
 			if (!(sym->ctype.modifiers & MOD_ADDRESSABLE)) {
 				sym->ctype.modifiers |= MOD_ADDRESSABLE;
@@ -733,7 +733,7 @@ static struct token *cast_expression(struct token *token, struct expression **tr
 	if (match_op(token, '(')) {
 		struct token *next = token->next;
 		if (lookup_type(next)) {
-			struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
+			struct expression *cast = alloc_expression_tok(next, EXPR_CAST);
 			struct expression *v;
 			struct symbol *sym;
 			int is_force;
@@ -789,7 +789,7 @@ static struct token *cast_expression(struct token *token, struct expression **tr
 									\
 			if (!(compare))					\
 				goto out;				\
-			top = alloc_expression(next->pos, type);	\
+			top = alloc_expression_tok(next, type);	\
 			next = inner(next->next, &right);		\
 			if (!right) {					\
 				sparse_error(next->pos, "No right hand side of '%s'-expression", show_special(op));	\
@@ -892,7 +892,7 @@ struct token *conditional_expression(struct token *token, struct expression **tr
 {
 	token = logical_or_expression(token, tree);
 	if (*tree && match_op(token, '?')) {
-		struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL);
+		struct expression *expr = alloc_expression_tok(token, EXPR_CONDITIONAL);
 		expr->op = token->special;
 		expr->left = *tree;
 		*tree = expr;
@@ -925,7 +925,7 @@ struct token *assignment_expression(struct token *token, struct expression **tre
 		int i, op = token->special;
 		for (i = 0; i < ARRAY_SIZE(assignments); i++)
 			if (assignments[i] == op) {
-				struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT);
+				struct expression * expr = alloc_expression_tok(token, EXPR_ASSIGNMENT);
 				expr->left = *tree;
 				expr->op = op;
 				*tree = expr;
diff --git a/expression.h b/expression.h
index 9778de8..95edf0f 100644
--- a/expression.h
+++ b/expression.h
@@ -14,6 +14,7 @@
 #include "allocate.h"
 #include "lib.h"
 #include "symbol.h"
+#include "depend.h"
 
 struct expression_list;
 
@@ -185,6 +186,13 @@ static inline struct expression *alloc_expression(struct position pos, int type)
 	return expr;
 }
 
+static inline struct expression *alloc_expression_tok(struct token *tok, int type)
+{
+	struct expression *e = alloc_expression(tok->pos, type);
+	DEP_TOK(e, tok);
+	return e;
+}
+
 static inline struct expression *alloc_const_expression(struct position pos, int value)
 {
 	struct expression *expr = __alloc_expression(0);
diff --git a/inline.c b/inline.c
index 9ed4570..5ba1747 100644
--- a/inline.c
+++ b/inline.c
@@ -20,6 +20,7 @@
 static struct expression * dup_expression(struct expression *expr)
 {
 	struct expression *dup = alloc_expression(expr->pos, expr->type);
+	DEP_INHERIT (dup, expr);
 	*dup = *expr;
 	return dup;
 }
@@ -27,6 +28,7 @@ static struct expression * dup_expression(struct expression *expr)
 static struct statement * dup_statement(struct statement *stmt)
 {
 	struct statement *dup = alloc_statement(stmt->pos, stmt->type);
+	DEP_INHERIT (dup, stmt);
 	*dup = *stmt;
 	return dup;
 }
@@ -142,6 +144,7 @@ static struct expression * copy_expression(struct expression *expr)
 			expr = dup_expression(expr);
 			expr->cast_expression = copy_expression(cast);
 			expr->cast_type = alloc_symbol(sym->pos, sym->type);
+			DEP_INHERIT (expr->cast_type, sym);
 			*expr->cast_type = *sym;
 			break;
 		}
@@ -176,6 +179,7 @@ static struct expression * copy_expression(struct expression *expr)
 	/* Statement expression */
 	case EXPR_STATEMENT: {
 		struct statement *stmt = alloc_statement(expr->pos, STMT_COMPOUND);
+		DEP_INHERIT (stmt, expr);
 		copy_statement(expr->statement, stmt);
 		expr = dup_expression(expr);
 		expr->statement = stmt;
@@ -347,6 +351,7 @@ static struct statement *copy_one_statement(struct statement *stmt)
 	}
 	case STMT_COMPOUND: {
 		struct statement *new = alloc_statement(stmt->pos, STMT_COMPOUND);
+		DEP_INHERIT (new, stmt);
 		copy_statement(stmt, new);
 		stmt = new;
 		break;
@@ -469,6 +474,7 @@ static struct symbol *create_copy_symbol(struct symbol *orig)
 	struct symbol *sym = orig;
 	if (orig) {
 		sym = alloc_symbol(orig->pos, orig->type);
+		DEP_INHERIT (sym, orig);
 		*sym = *orig;
 		sym->bb_target = NULL;
 		sym->pseudo = NULL;
@@ -499,6 +505,7 @@ int inline_function(struct expression *expr, struct symbol *sym)
 	struct symbol_list *name_list, *arg_decl;
 	struct symbol *name;
 	struct expression *arg;
+	DEP_INHERIT (stmt, expr);
 
 	if (!fn->inline_stmt) {
 		sparse_error(fn->pos, "marked inline, but without a definition");
@@ -521,6 +528,7 @@ int inline_function(struct expression *expr, struct symbol *sym)
 	PREPARE_PTR_LIST(name_list, name);
 	FOR_EACH_PTR(arg_list, arg) {
 		struct symbol *a = alloc_symbol(arg->pos, SYM_NODE);
+		DEP_INHERIT (a, arg);
 
 		a->ctype.base_type = arg->ctype;
 		if (name) {
@@ -539,6 +547,7 @@ int inline_function(struct expression *expr, struct symbol *sym)
 
 	if (arg_decl) {
 		struct statement *decl = alloc_statement(expr->pos, STMT_DECLARATION);
+		DEP_INHERIT (decl, expr);
 		decl->declaration = arg_decl;
 		stmt->args = decl;
 	}
@@ -563,6 +572,7 @@ void uninline(struct symbol *sym)
 		p->replace = p;
 	} END_FOR_EACH_PTR(p);
 	fn->stmt = alloc_statement(fn->pos, STMT_COMPOUND);
+	DEP_INHERIT (fn->stmt, fn);
 	copy_statement(fn->inline_stmt, fn->stmt);
 	unset_replace_list(sym->symbol_list);
 	unset_replace_list(arg_list);
diff --git a/lib.c b/lib.c
index 396e9f1..d835870 100644
--- a/lib.c
+++ b/lib.c
@@ -213,6 +213,8 @@ int Wundef = 0;
 int Wuninitialized = 1;
 int Wdeclarationafterstatement = -1;
 
+int fnobuiltin = 0;
+
 int dbg_entry = 0;
 int dbg_dead = 0;
 
@@ -553,6 +555,9 @@ static char **handle_switch_f(char *arg, char **next)
 		arg += 3;
 	}
 	/* handle switch here.. */
+	if (!strncmp(arg, "builtin", 7)) {
+		fnobuiltin = 1;
+	}
 	return next;
 }
 
@@ -668,6 +673,9 @@ static char **handle_switch(char *arg, char **next)
 
 void declare_builtin_functions(void)
 {
+	if (fnobuiltin)
+		return;
+	
 	/* Gaah. gcc knows tons of builtin <string.h> functions */
 	add_pre_buffer("extern void *__builtin_memcpy(void *, const void *, __SIZE_TYPE__);\n");
 	add_pre_buffer("extern void *__builtin_mempcpy(void *, const void *, __SIZE_TYPE__);\n");
diff --git a/parse.c b/parse.c
index bd42180..f7bfc1c 100644
--- a/parse.c
+++ b/parse.c
@@ -652,9 +652,9 @@ static void apply_modifiers(struct position pos, struct decl_state *ctx)
 	
 }
 
-static struct symbol * alloc_indirect_symbol(struct position pos, struct ctype *ctype, int type)
+static struct symbol * alloc_indirect_symbol(struct token *tok, struct ctype *ctype, int type)
 {
-	struct symbol *sym = alloc_symbol(pos, type);
+	struct symbol *sym = alloc_symbol_tok(tok, type);
 
 	sym->ctype.base_type = ctype->base_type;
 	sym->ctype.modifiers = ctype->modifiers;
@@ -673,7 +673,7 @@ struct symbol *label_symbol(struct token *token)
 {
 	struct symbol *sym = lookup_symbol(token->ident, NS_LABEL);
 	if (!sym) {
-		sym = alloc_symbol(token->pos, SYM_LABEL);
+		sym = alloc_symbol_tok(token, SYM_LABEL);
 		bind_symbol(sym, token->ident, NS_LABEL);
 		fn_local_symbol(sym);
 	}
@@ -695,7 +695,7 @@ static struct token *struct_union_enum_specifier(enum type type,
 		     (match_op(token->next,';') || match_op(token->next,'{')))) {
 			// Either a new symbol, or else an out-of-scope
 			// symbol being redefined.
-			sym = alloc_symbol(token->pos, type);
+			sym = alloc_symbol_tok(token, type);
 			bind_symbol(sym, token->ident, NS_STRUCT);
 		}
 		if (sym->type != type)
@@ -716,6 +716,7 @@ static struct token *struct_union_enum_specifier(enum type type,
 			// Mark the structure as needing re-examination
 			sym->examined = 0;
 			sym->endpos = token->pos;
+			DEP_END (sym, token);
 		}
 		return token;
 	}
@@ -727,11 +728,12 @@ static struct token *struct_union_enum_specifier(enum type type,
 		return token;
 	}
 
-	sym = alloc_symbol(token->pos, type);
+	sym = alloc_symbol_tok(token, type);
 	token = parse(token->next, sym);
 	ctx->ctype.base_type = sym;
 	token =  expect(token, '}', "at end of specifier");
 	sym->endpos = token->pos;
+	DEP_END (sym, token);
 
 	return token;
 }
@@ -875,7 +877,7 @@ static struct token *parse_enum_declaration(struct token *token, struct symbol *
 			expr->ctype = ctype;
 		}
 
-		sym = alloc_symbol(token->pos, SYM_NODE);
+		sym = alloc_symbol_tok(token, SYM_NODE);
 		bind_symbol(sym, token->ident, NS_SYMBOL);
 		sym->ctype.modifiers &= ~MOD_ADDRESSABLE;
 		sym->initializer = expr;
@@ -926,6 +928,7 @@ static struct token *parse_enum_declaration(struct token *token, struct symbol *
 		token = next;
 
 		sym->endpos = token->pos;
+		DEP_END (sym, token);
 
 		if (!match_op(token, ','))
 			break;
@@ -988,10 +991,11 @@ static struct token *typeof_specifier(struct token *token, struct decl_state *ct
 		ctx->ctype.base_type = sym->ctype.base_type;
 		apply_ctype(token->pos, &sym->ctype, &ctx->ctype);
 	} else {
-		struct symbol *typeof_sym = alloc_symbol(token->pos, SYM_TYPEOF);
+		struct symbol *typeof_sym = alloc_symbol_tok(token, SYM_TYPEOF);
 		token = parse_expression(token->next, &typeof_sym->initializer);
 
 		typeof_sym->endpos = token->pos;
+		DEP_END (typeof_sym, token);
 		if (!typeof_sym->initializer) {
 			sparse_error(token->pos, "expected expression after the '(' token");
 			typeof_sym = &bad_ctype;
@@ -1440,6 +1444,8 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta
 						 NS_TYPEDEF | NS_SYMBOL);
 		if (!s || !(s->namespace & NS_TYPEDEF))
 			break;
+		if (DEPEN())
+			add_symbol (&ctx->dep, s);
 		if (s->type != SYM_KEYWORD) {
 			if (seen & Set_Any)
 				break;
@@ -1493,7 +1499,7 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta
 			sparse_error(token->pos, "invalid modifier");
 			return token;
 		}
-		type = alloc_symbol(token->pos, SYM_BASETYPE);
+		type = alloc_symbol_tok(token, SYM_BASETYPE);
 		*type = *ctx->ctype.base_type;
 		type->ctype.modifiers &= ~MOD_SPECIFIER;
 		type->ctype.base_type = ctx->ctype.base_type;
@@ -1679,7 +1685,7 @@ static struct token *direct_declarator(struct token *token, struct decl_state *c
 	if (match_op(token, '(')) {
 		enum kind kind = which_func(token, p, ctx->prefer_abstract);
 		struct symbol *fn;
-		fn = alloc_indirect_symbol(token->pos, ctype, SYM_FN);
+		fn = alloc_indirect_symbol(token, ctype, SYM_FN);
 		token = token->next;
 		if (kind == K_R)
 			token = identifier_list(token, fn);
@@ -1687,15 +1693,17 @@ static struct token *direct_declarator(struct token *token, struct decl_state *c
 			token = parameter_type_list(token, fn);
 		token = expect(token, ')', "in function declarator");
 		fn->endpos = token->pos;
+		DEP_END (fn, token);
 		return token;
 	}
 
 	while (match_op(token, '[')) {
 		struct symbol *array;
-		array = alloc_indirect_symbol(token->pos, ctype, SYM_ARRAY);
+		array = alloc_indirect_symbol(token, ctype, SYM_ARRAY);
 		token = abstract_array_declarator(token->next, array);
 		token = expect(token, ']', "in abstract_array_declarator");
 		array->endpos = token->pos;
+		DEP_END (array, token);
 		ctype = &array->ctype;
 	}
 	return token;
@@ -1704,7 +1712,7 @@ static struct token *direct_declarator(struct token *token, struct decl_state *c
 static struct token *pointer(struct token *token, struct decl_state *ctx)
 {
 	while (match_op(token,'*')) {
-		struct symbol *ptr = alloc_symbol(token->pos, SYM_PTR);
+		struct symbol *ptr = alloc_symbol_tok(token, SYM_PTR);
 		ptr->ctype.modifiers = ctx->ctype.modifiers;
 		ptr->ctype.base_type = ctx->ctype.base_type;
 		ptr->ctype.as = ctx->ctype.as;
@@ -1717,6 +1725,8 @@ static struct token *pointer(struct token *token, struct decl_state *ctx)
 
 		token = handle_qualifiers(token->next, ctx);
 		ctx->ctype.base_type->endpos = token->pos;
+		DEP_END (ctx->ctype.base_type, token);
+
 	}
 	return token;
 }
@@ -1741,7 +1751,7 @@ static struct token *handle_bitfield(struct token *token, struct decl_state *ctx
 		return conditional_expression(token->next, &expr);
 	}
 
-	bitfield = alloc_indirect_symbol(token->pos, ctype, SYM_BITFIELD);
+	bitfield = alloc_indirect_symbol(token, ctype, SYM_BITFIELD);
 	token = conditional_expression(token->next, &expr);
 	width = const_expression_value(expr);
 	bitfield->bit_size = width;
@@ -1772,6 +1782,7 @@ static struct token *handle_bitfield(struct token *token, struct decl_state *ctx
 	}
 	bitfield->bit_size = width;
 	bitfield->endpos = token->pos;
+	DEP_END (bitfield, token);
 	return token;
 }
 
@@ -1785,7 +1796,7 @@ static struct token *declaration_list(struct token *token, struct symbol_list **
 	mod = storage_modifiers(&ctx);
 	saved = ctx.ctype;
 	for (;;) {
-		struct symbol *decl = alloc_symbol(token->pos, SYM_NODE);
+		struct symbol *decl = alloc_symbol_tok(token, SYM_NODE);
 		ctx.ident = &decl->ident;
 
 		token = declarator(token, &ctx);
@@ -1798,6 +1809,7 @@ static struct token *declaration_list(struct token *token, struct symbol_list **
 		decl->ctype = ctx.ctype;
 		decl->ctype.modifiers |= mod;
 		decl->endpos = token->pos;
+		DEP_END (decl, token);
 		add_symbol(list, decl);
 		if (!match_op(token, ','))
 			break;
@@ -1833,6 +1845,7 @@ static struct token *parameter_declaration(struct token *token, struct symbol *s
 	sym->ctype = ctx.ctype;
 	sym->ctype.modifiers |= storage_modifiers(&ctx);
 	sym->endpos = token->pos;
+	DEP_END (sym, token);
 	return token;
 }
 
@@ -1840,13 +1853,14 @@ struct token *typename(struct token *token, struct symbol **p, int *forced)
 {
 	struct decl_state ctx = {.prefer_abstract = 1};
 	int class;
-	struct symbol *sym = alloc_symbol(token->pos, SYM_NODE);
+	struct symbol *sym = alloc_symbol_tok(token, SYM_NODE);
 	*p = sym;
 	token = declaration_specifiers(token, &ctx);
 	token = declarator(token, &ctx);
 	apply_modifiers(token->pos, &ctx);
 	sym->ctype = ctx.ctype;
 	sym->endpos = token->pos;
+	DEP_END (sym, token);
 	class = ctx.storage_class;
 	if (forced) {
 		*forced = 0;
@@ -1965,6 +1979,7 @@ static struct statement *make_statement(struct expression *expr)
 	if (!expr)
 		return NULL;
 	stmt = alloc_statement(expr->pos, STMT_EXPRESSION);
+	DEP_INHERIT (stmt, expr);
 	stmt->expression = expr;
 	return stmt;
 }
@@ -1984,8 +1999,10 @@ static void start_iterator(struct statement *stmt)
 
 	start_symbol_scope();
 	cont = alloc_symbol(stmt->pos, SYM_NODE);
+	DEP_INHERIT (cont, stmt);
 	bind_symbol(cont, &continue_ident, NS_ITERATOR);
 	brk = alloc_symbol(stmt->pos, SYM_NODE);
+	DEP_INHERIT (brk, stmt);
 	bind_symbol(brk, &break_ident, NS_ITERATOR);
 
 	stmt->type = STMT_ITERATOR;
@@ -2004,9 +2021,11 @@ static struct statement *start_function(struct symbol *sym)
 {
 	struct symbol *ret;
 	struct statement *stmt = alloc_statement(sym->pos, STMT_COMPOUND);
+	DEP_INHERIT (stmt, sym);
 
 	start_function_scope();
 	ret = alloc_symbol(sym->pos, SYM_NODE);
+	DEP_INHERIT (ret, sym);
 	ret->ctype = sym->ctype.base_type->ctype;
 	ret->ctype.modifiers &= ~(MOD_STORAGE | MOD_CONST | MOD_VOLATILE | MOD_TLS | MOD_INLINE | MOD_ADDRESSABLE | MOD_NOCAST | MOD_NODEREF | MOD_ACCESSED | MOD_TOPLEVEL);
 	ret->ctype.modifiers |= (MOD_AUTO | MOD_REGISTER);
@@ -2044,9 +2063,11 @@ static void start_switch(struct statement *stmt)
 
 	start_symbol_scope();
 	brk = alloc_symbol(stmt->pos, SYM_NODE);
+	DEP_INHERIT (brk, stmt);
 	bind_symbol(brk, &break_ident, NS_ITERATOR);
 
 	switch_case = alloc_symbol(stmt->pos, SYM_NODE);
+	DEP_INHERIT (switch_case, stmt);
 	bind_symbol(switch_case, &case_ident, NS_ITERATOR);
 	switch_case->stmt = stmt;
 
@@ -2076,6 +2097,7 @@ static void add_case_statement(struct statement *stmt)
 		return;
 	}
 	sym = alloc_symbol(stmt->pos, SYM_NODE);
+	DEP_INHERIT (sym, stmt);
 	add_symbol(&target->symbol_list, sym);
 	sym->stmt = stmt;
 	stmt->case_label = sym;
@@ -2266,6 +2288,7 @@ static struct token *parse_range_statement(struct token *token, struct statement
 static struct token *statement(struct token *token, struct statement **tree)
 {
 	struct statement *stmt = alloc_statement(token->pos, STMT_NONE);
+	DEP_TOK (stmt, token);
 
 	*tree = stmt;
 	if (token_type(token) == TOKEN_IDENT) {
@@ -2298,7 +2321,7 @@ static struct token *statement(struct token *token, struct statement **tree)
 static struct token *label_statement(struct token *token)
 {
 	while (token_type(token) == TOKEN_IDENT) {
-		struct symbol *sym = alloc_symbol(token->pos, SYM_LABEL);
+		struct symbol *sym = alloc_symbol_tok(token, SYM_LABEL);
 		/* it's block-scope, but we want label namespace */
 		bind_symbol(sym, token->ident, NS_SYMBOL);
 		sym->namespace = NS_LABEL;
@@ -2329,6 +2352,7 @@ static struct token * statement_list(struct token *token, struct statement_list
 				seen_statement = 0;
 			}
 			stmt = alloc_statement(token->pos, STMT_DECLARATION);
+			DEP_TOK (stmt, token);
 			token = external_declaration(token, &stmt->declaration);
 		} else {
 			seen_statement = Wdeclarationafterstatement;
@@ -2343,10 +2367,11 @@ static struct token *identifier_list(struct token *token, struct symbol *fn)
 {
 	struct symbol_list **list = &fn->arguments;
 	for (;;) {
-		struct symbol *sym = alloc_symbol(token->pos, SYM_NODE);
+		struct symbol *sym = alloc_symbol_tok(token, SYM_NODE);
 		sym->ident = token->ident;
 		token = token->next;
 		sym->endpos = token->pos;
+		DEP_END (sym, token);
 		sym->ctype.base_type = &incomplete_ctype;
 		add_symbol(list, sym);
 		if (!match_op(token, ',') ||
@@ -2371,7 +2396,7 @@ static struct token *parameter_type_list(struct token *token, struct symbol *fn)
 			break;
 		}
 
-		sym = alloc_symbol(token->pos, SYM_NODE);
+		sym = alloc_symbol_tok(token, SYM_NODE);
 		token = parameter_declaration(token, sym);
 		if (sym->ctype.base_type == &void_ctype) {
 			/* Special case: (void) */
@@ -2642,12 +2667,13 @@ static struct token *parse_k_r_arguments(struct token *token, struct symbol *dec
 
 static struct token *toplevel_asm_declaration(struct token *token, struct symbol_list **list)
 {
-	struct symbol *anon = alloc_symbol(token->pos, SYM_NODE);
-	struct symbol *fn = alloc_symbol(token->pos, SYM_FN);
+	struct symbol *anon = alloc_symbol_tok(token, SYM_NODE);
+	struct symbol *fn = alloc_symbol_tok(token, SYM_FN);
 	struct statement *stmt;
 
 	anon->ctype.base_type = fn;
 	stmt = alloc_statement(token->pos, STMT_NONE);
+	DEP_TOK (stmt, token);
 	fn->stmt = stmt;
 
 	token = parse_asm_statement(token, stmt);
@@ -2660,7 +2686,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 {
 	struct ident *ident = NULL;
 	struct symbol *decl;
-	struct decl_state ctx = { .ident = &ident };
+	struct decl_state ctx = { .ident = &ident, .dep = 0 };
 	struct ctype saved;
 	struct symbol *base_type;
 	unsigned long mod;
@@ -2676,7 +2702,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 	/* Parse declaration-specifiers, if any */
 	token = declaration_specifiers(token, &ctx);
 	mod = storage_modifiers(&ctx);
-	decl = alloc_symbol(token->pos, SYM_NODE);
+	decl = alloc_symbol_tok(token, SYM_NODE);
 	/* Just a type declaration? */
 	if (match_op(token, ';')) {
 		apply_modifiers(token->pos, &ctx);
@@ -2691,6 +2717,8 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 	decl->ctype = ctx.ctype;
 	decl->ctype.modifiers |= mod;
 	decl->endpos = token->pos;
+	DEP_END (decl, token);
+	DEP_SYMLIST (decl, ctx.dep);
 
 	/* Just a type declaration? */
 	if (!ident) {
@@ -2755,7 +2783,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 
 		token = token->next;
 		ident = NULL;
-		decl = alloc_symbol(token->pos, SYM_NODE);
+		decl = alloc_symbol_tok(token, SYM_NODE);
 		ctx.ctype = saved;
 		token = handle_attributes(token, &ctx, KW_ATTRIBUTE);
 		token = declarator(token, &ctx);
@@ -2764,6 +2792,7 @@ struct token *external_declaration(struct token *token, struct symbol_list **lis
 		decl->ctype = ctx.ctype;
 		decl->ctype.modifiers |= mod;
 		decl->endpos = token->pos;
+		DEP_END (decl, token);
 		if (!ident) {
 			sparse_error(token->pos, "expected identifier name in type definition");
 			return token;
diff --git a/parse.h b/parse.h
index b26bd03..9ff6639 100644
--- a/parse.h
+++ b/parse.h
@@ -10,6 +10,7 @@
  */
 
 #include "symbol.h"
+#include "depend.h"
 
 enum statement_type {
 	STMT_NONE,
diff --git a/pre-process.c b/pre-process.c
index 8a16f8b..3dbbb11 100644
--- a/pre-process.c
+++ b/pre-process.c
@@ -27,7 +27,10 @@
 #include "symbol.h"
 #include "expression.h"
 #include "scope.h"
+#include "depend.h"
 
+/* interface to depend.c, if set */
+struct depend_if *dif; 
 static int false_nesting = 0;
 
 #define INCLUDEPATHS 300
@@ -111,6 +114,7 @@ static struct symbol *lookup_macro(struct ident *ident)
 	struct symbol *sym = lookup_symbol(ident, NS_MACRO | NS_UNDEF);
 	if (sym && sym->namespace != NS_MACRO)
 		sym = NULL;
+	DEPCALL(push_sym, sym);
 	return sym;
 }
 
@@ -244,15 +248,6 @@ static struct token *collect_arg(struct token *prev, int vararg, struct position
  * We store arglist as <counter> [arg1] <number of uses for arg1> ... eof
  */
 
-struct arg {
-	struct token *arg;
-	struct token *expanded;
-	struct token *str;
-	int n_normal;
-	int n_quoted;
-	int n_str;
-};
-
 static int collect_arguments(struct token *start, struct token *arglist, struct arg *args, struct token *what)
 {
 	int wanted = arglist->count.normal;
@@ -325,15 +320,22 @@ out:
 	return 0;
 }
 
-static struct token *dup_list(struct token *list)
+static struct token *dup_one(struct token *list)
+{
+	struct token *newtok = __alloc_token(0);
+	*newtok = *list;
+	return newtok;
+}
+
+static struct token *dup_list(struct token *list, struct macro_expansion *me, int argi)
 {
 	struct token *res = NULL;
 	struct token **p = &res;
 
 	while (!eof_token(list)) {
-		struct token *newtok = __alloc_token(0);
-		*newtok = *list;
+		struct token *newtok = dup_one(list);
 		*p = newtok;
+		DEP_MACRO_EXP(newtok, me, argi, 0);
 		p = &newtok->next;
 		list = list->next;
 	}
@@ -356,7 +358,7 @@ static struct token *stringify(struct token *arg)
 	return token;
 }
 
-static void expand_arguments(int count, struct arg *args)
+static void expand_arguments(int count, struct arg *args, struct macro_expansion *me)
 {
 	int i;
 	for (i = 0; i < count; i++) {
@@ -372,7 +374,7 @@ static void expand_arguments(int count, struct arg *args)
 			} else if (eof_token(arg)) {
 				args[i].expanded = arg;
 			} else {
-				args[i].expanded = dup_list(arg);
+				args[i].expanded = dup_list(arg,me,i);
 			}
 			expand_list(&args[i].expanded);
 		}
@@ -472,7 +474,7 @@ static int merge(struct token *left, struct token *right)
 	return 0;
 }
 
-static struct token *dup_token(struct token *token, struct position *streampos, struct position *pos)
+static struct token *dup_token(struct token *token, struct position *streampos, struct position *pos, struct macro_expansion *me)
 {
 	struct token *alloc = alloc_token(streampos);
 	token_type(alloc) = token_type(token);
@@ -480,16 +482,17 @@ static struct token *dup_token(struct token *token, struct position *streampos,
 	alloc->pos.whitespace = pos->whitespace;
 	alloc->number = token->number;
 	alloc->pos.noexpand = token->pos.noexpand;
-	return alloc;	
+	DEP_MACRO_EXP(token, me, 0, 1);
+	return alloc;
 }
 
-static struct token **copy(struct token **where, struct token *list, int *count)
+static struct token **copy(struct token **where, struct token *list, int *count, struct macro_expansion *me)
 {
 	int need_copy = --*count;
 	while (!eof_token(list)) {
 		struct token *token;
 		if (need_copy)
-			token = dup_token(list, &list->pos, &list->pos);
+			token = dup_token(list, &list->pos, &list->pos, me);
 		else
 			token = list;
 		if (token_type(token) == TOKEN_IDENT && token->ident->tainted)
@@ -502,7 +505,7 @@ static struct token **copy(struct token **where, struct token *list, int *count)
 	return where;
 }
 
-static struct token **substitute(struct token **list, struct token *body, struct arg *args)
+static struct token **substitute(struct token **list, struct token *body, struct arg *args, struct macro_expansion *me)
 {
 	struct token *token = *list;
 	struct position *base_pos = &token->pos;
@@ -526,7 +529,7 @@ static struct token **substitute(struct token **list, struct token *body, struct
 			 */
 			if (!args[body->next->argnum].arg)
 				continue;
-			added = dup_token(body, base_pos, pos);
+			added = dup_token(body, base_pos, pos, me);
 			token_type(added) = TOKEN_SPECIAL;
 			tail = &added->next;
 			break;
@@ -556,7 +559,7 @@ static struct token **substitute(struct token **list, struct token *body, struct
 				continue;
 			}
 		copy_arg:
-			tail = copy(&added, arg, count);
+			tail = copy(&added, arg, count, me);
 			added->pos.newline = pos->newline;
 			added->pos.whitespace = pos->whitespace;
 			break;
@@ -569,14 +572,14 @@ static struct token **substitute(struct token **list, struct token *body, struct
 			continue;
 
 		case TOKEN_IDENT:
-			added = dup_token(body, base_pos, pos);
+			added = dup_token(body, base_pos, pos, me);
 			if (added->ident->tainted)
 				added->pos.noexpand = 1;
 			tail = &added->next;
 			break;
 
 		default:
-			added = dup_token(body, base_pos, pos);
+			added = dup_token(body, base_pos, pos, me);
 			tail = &added->next;
 			break;
 		}
@@ -606,7 +609,16 @@ static int expand(struct token **list, struct symbol *sym)
 	struct ident *expanding = token->ident;
 	struct token **tail;
 	int nargs = sym->arglist ? sym->arglist->count.normal : 0;
-	struct arg args[nargs];
+	struct arg _args[nargs];
+	struct arg *args = _args;
+	struct macro_expansion *me = 0;
+
+	if (DEPEN()) {
+		me = __alloc_macro_expansion(sizeof(struct arg) * nargs);
+		me->m = token;
+		me->sym = sym;
+		args = me->args;
+	}
 
 	if (expanding->tainted) {
 		token->pos.noexpand = 1;
@@ -618,13 +630,13 @@ static int expand(struct token **list, struct symbol *sym)
 			return 1;
 		if (!collect_arguments(token->next, sym->arglist, args, token))
 			return 1;
-		expand_arguments(nargs, args);
+		expand_arguments(nargs, args, me);
 	}
 
 	expanding->tainted = 1;
 
 	last = token->next;
-	tail = substitute(list, sym->expansion, args);
+	tail = substitute(list, sym->expansion, args, me);
 	*tail = last;
 
 	return 0;
@@ -907,11 +919,18 @@ static inline void set_arg_count(struct token *token)
 	token->count.str = token->count.vararg = 0;
 }
 
-static struct token *parse_arguments(struct token *list)
+#define DUP(l) (DEPEN() ? dup_one(l) : (l))
+#define DUP_NEXT(l) (DEPEN() ? (l)->next = dup_one((l)->next) : (l)->next)
+
+static struct token *parse_arguments(struct token **arglist)
 {
-	struct token *arg = list->next, *next = list;
+	struct token *list = DUP(*arglist);
+	struct token *arg = DUP_NEXT(list), *next = list;
 	struct argcount *count = &list->count;
 
+	if (DEPEN())
+		*arglist = list;
+	
 	set_arg_count(list);
 
 	if (match_op(arg, ')')) {
@@ -925,11 +944,11 @@ static struct token *parse_arguments(struct token *list)
 			goto Eva_args;
 		if (!++count->normal)
 			goto Eargs;
-		next = arg->next;
+		next = DUP_NEXT(arg);
 
 		if (match_op(next, ',')) {
 			set_arg_count(next);
-			arg = next->next;
+			arg = DUP_NEXT(next);
 			continue;
 		}
 
@@ -964,7 +983,7 @@ static struct token *parse_arguments(struct token *list)
 	}
 
 	if (match_op(arg, SPECIAL_ELLIPSIS)) {
-		next = arg->next;
+		next = DUP_NEXT(arg);
 		token_type(arg) = TOKEN_IDENT;
 		arg->ident = &__VA_ARGS___ident;
 		if (!match_op(next, ')'))
@@ -1125,7 +1144,7 @@ static int do_handle_define(struct stream *stream, struct token **line, struct t
 	if (!expansion->pos.whitespace) {
 		if (match_op(expansion, '(')) {
 			arglist = expansion;
-			expansion = parse_arguments(expansion);
+			expansion = parse_arguments(&arglist);
 			if (!expansion)
 				return 1;
 		} else if (!eof_token(expansion)) {
@@ -1299,6 +1318,8 @@ static int expression_value(struct token **where)
 	long long value;
 	int state = 0;
 
+	DEPCALL(on, *list);
+	
 	while (!eof_token(p = scan_next(list))) {
 		switch (state) {
 		case 0:
@@ -1352,8 +1373,10 @@ static int expression_value(struct token **where)
 static int handle_if(struct stream *stream, struct token **line, struct token *token)
 {
 	int value = 0;
-	if (!false_nesting)
+	if (!false_nesting) {
+		DEPCALL(push_dep,token);
 		value = expression_value(&token->next);
+	}
 
 	dirty_stream(stream);
 	return preprocessor_if(stream, token, value);
@@ -1378,6 +1401,8 @@ static int handle_elif(struct stream * stream, struct token **line, struct token
 		return 1;
 	}
 
+	DEPCALL(else_dep,token);
+	
 	dirty_stream(stream);
 	if (token_type(top_if) != TOKEN_IF)
 		return 1;
@@ -1407,6 +1432,9 @@ static int handle_else(struct stream *stream, struct token **line, struct token
 		nesting_error(stream);
 		sparse_error(token->pos, "#else after #else");
 	}
+
+	DEPCALL(else_dep,token);
+	
 	if (false_nesting) {
 		if (token_type(top_if) == TOKEN_IF)
 			false_nesting = 0;
@@ -1428,6 +1456,9 @@ static int handle_endif(struct stream *stream, struct token **line, struct token
 	}
 	if (false_nesting)
 		false_nesting--;
+
+	DEPCALL(pop_dep,token);
+	
 	stream->top_if = top_if->next;
 	__free_token(top_if);
 	return 1;
@@ -1740,7 +1771,7 @@ static void handle_preprocessor_line(struct stream *stream, struct token **line,
 	int is_normal = 1;
 
 	if (eof_token(token))
-		return;
+		goto ret;
 
 	if (token_type(token) == TOKEN_IDENT) {
 		struct symbol *sym = lookup_symbol(token->ident, NS_PREPROCESSOR);
@@ -1762,10 +1793,12 @@ static void handle_preprocessor_line(struct stream *stream, struct token **line,
 			goto out;
 	}
 	if (!handler(stream, line, token))	/* all set */
-		return;
+		goto ret;
 
 out:
 	free_preprocessor_line(token);
+ret:
+	DEPCALL(off, token);
 }
 
 static void preprocessor_line(struct stream *stream, struct token **line)
@@ -1817,6 +1850,7 @@ static void do_preprocess(struct token **list)
 
 		default:
 			dirty_stream(stream);
+			DEPCALL(tag_dep, next);
 			if (false_nesting) {
 				*list = next->next;
 				__free_token(next);
diff --git a/shrink.c b/shrink.c
new file mode 100644
index 0000000..b7a4404
--- /dev/null
+++ b/shrink.c
@@ -0,0 +1,102 @@
+/*
+ * Build macros dependency tree 
+ * Copyright (C) 2012 Konrad Eisele <konrad@xxxxxxxxxxx,eiselekd@xxxxxxxxx>
+ * BSD-License
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the <organization>.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "lib.h"
+#include "allocate.h"
+#include "token.h"
+#include "parse.h"
+#include "symbol.h"
+#include "expression.h"
+#include "depend.h"
+
+void  stream_print_line(FILE *io, struct stream *stream, int j);
+
+static void 
+expand_symbols(struct symbol_list *list)
+{
+	struct symbol *sym;
+	FOR_EACH_PTR(list, sym) {
+		expand_symbol(sym);
+		depend_symbol(sym);
+	} END_FOR_EACH_PTR(sym);
+}
+
+int 
+main(int argc, char **argv)
+{
+	struct string_list *filelist = NULL; int i;
+	char *file; struct symbol_list *all_syms = 0;
+	
+	init_dep();
+	
+	expand_symbols(sparse_initialize(argc, argv, &filelist));
+	FOR_EACH_PTR_NOTAG(filelist, file) {
+		struct symbol_list *syms = sparse(file);
+		expand_symbols(syms);
+		concat_symbol_list(syms, &all_syms);
+	} END_FOR_EACH_PTR_NOTAG(file);
+	
+	for (i = 0; i < input_stream_nr; i++) {
+		/* struct stream *c; int j; */
+		/* c = input_streams + i; */
+		/* if (c->n && c->b) { */
+		/* 	for (j =  0; j < c->linenr; j++) { */
+		/* 		struct stream_line *l = c->n[j]; */
+		/* 		if (l->used) { */
+		/* 			stream_print_line(stdout, c, j); */
+		/* 		} */
+		/* 	} */
+		/* } */
+
+	}
+
+	return 0;
+}
+
+/* void  */
+/* stream_print_line(FILE *io, struct stream *stream, int j) */
+/* { */
+/* 	int k; */
+/* 	if (stream->b && j < stream->linenr) { */
+/* 		struct stream_line *l = stream->n[j]; */
+/* 		int f, t, len; */
+/* 		f = t = l->off; */
+/* 		if (j+1 < stream->linenr &&  */
+/* 		    stream->n[j+1] && */
+/* 		    stream->n[j+1]->off > t) { */
+/* 			t = stream->n[j+1]->off; */
+/* 		} */
+/* 		if (f > stream->bz) */
+/* 			f = stream->bz; */
+/* 		if (t > stream->bz) */
+/* 			t = stream->bz; */
+/* 		len = t - f; */
+/* 		/\*fprintf(io, "%s:%04d:",stream->name,j);*\/ */
+/* 		for (k = 0; k < len; k++) { */
+/* 			fprintf(io, "%c", stream->b[f + k]); */
+/* 		} */
+/* 		/\*fprintf(io, "\n");*\/ */
+/* 	} */
+/* } */
diff --git a/sparse.c b/sparse.c
index 67b7d9e..ffdd8d4 100644
--- a/sparse.c
+++ b/sparse.c
@@ -23,6 +23,7 @@
 #include "symbol.h"
 #include "expression.h"
 #include "linearize.h"
+#include "depend.h"
 
 static int context_increase(struct basic_block *bb, int entry)
 {
@@ -278,6 +279,8 @@ int main(int argc, char **argv)
 	struct string_list *filelist = NULL;
 	char *file;
 
+	init_dep();
+	
 	// Expand, linearize and show it.
 	check_symbols(sparse_initialize(argc, argv, &filelist));
 	FOR_EACH_PTR_NOTAG(filelist, file) {
diff --git a/symbol.h b/symbol.h
index 1e74579..e7dcb82 100644
--- a/symbol.h
+++ b/symbol.h
@@ -11,6 +11,7 @@
 
 #include "token.h"
 #include "target.h"
+#include "depend.h"
 
 /*
  * An identifier with semantic meaning is a "symbol".
@@ -94,6 +95,7 @@ struct decl_state {
 	struct ident **ident;
 	struct symbol_op *mode;
 	unsigned char prefer_abstract, is_inline, storage_class, is_tls;
+	struct symbol_list *dep;
 };
 
 struct symbol_op {
@@ -294,6 +296,13 @@ extern void debug_symbol(struct symbol *);
 extern void merge_type(struct symbol *sym, struct symbol *base_type);
 extern void check_declaration(struct symbol *sym);
 
+static inline struct symbol *alloc_symbol_tok(struct token *tok, int type)
+{
+	struct symbol *e = alloc_symbol (tok->pos, type);
+	DEP_TOK(e, tok);
+	return e;
+}
+
 static inline struct symbol *get_base_type(const struct symbol *sym)
 {
 	return examine_symbol_type(sym->ctype.base_type);
diff --git a/token.h b/token.h
index cd29233..00518e5 100644
--- a/token.h
+++ b/token.h
@@ -152,6 +152,15 @@ struct argcount {
 	unsigned vararg:1;
 };
 
+struct arg {
+	struct token *arg;
+	struct token *expanded;
+	struct token *str;
+	int n_normal;
+	int n_quoted;
+	int n_str;
+};
+
 /*
  * This is a very common data structure, it should be kept
  * as small as humanly possible. Big (rare) types go as
@@ -203,6 +212,7 @@ extern struct token * tokenize_buffer(void *, unsigned long, struct token **);
 
 extern void show_identifier_stats(void);
 extern struct token *preprocess(struct token *);
+extern struct depend_if *dif;
 
 static inline int match_op(struct token *token, int op)
 {
-- 
1.7.4.4

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux