~sircmpwn/annotatec

d06735fd8763c47c1ede441bf9bddd78779c0cc7 — Drew DeVault 7 months ago 5554c69
Start moving parser state into the graph
5 files changed, 64 insertions(+), 52 deletions(-)

M graph.h
M lang.l
M lang.y
M main.c
M parse.h
M graph.h => graph.h +9 -0
@@ 12,7 12,14 @@ struct symtab_entry {
	struct symbol_definition *symbol;
};

struct typedef_declaration {
	struct typedef_declaration *next;
	char *name;
	int lineno, colno;
};

struct symbol_definition {
	struct symbol_definition *next;
	struct source_file *file;
	char *name;
	int lineno, colno;


@@ 29,8 36,10 @@ struct symbol_reference {
struct source_file {
	struct source_file *next;
	char *path, *blob_sha;
	struct typedef_declaration *typedefs;
	struct symbol_definition *symbols;
	struct symbol_reference *references;
	int nsyms, nrefs;
};

struct project_graph {

M lang.l => lang.l +6 -2
@@ 24,6 24,7 @@ WS  [ \t\v\n\f]
int lineno = 1, colno = 1;
char *filename = "";
const char *original_filename = "";
struct source_file *current_source;

int yyerror(char *s);
static void _lineno(void);


@@ 35,11 36,14 @@ static void multi_comment(void);

void yyrestart(FILE *);

void lexreset(const char *fn, FILE *input) {
struct source_file *lexreset(const char *fn, FILE *input) {
	lineno = 1, colno = 1;
	original_filename = fn;
	filename = strdup(original_filename);
	current_source = calloc(1, sizeof(struct source_file));
	current_source->path = filename;
	yyrestart(input);
	return current_source;
}

%}


@@ 230,7 234,7 @@ static void linemarker(void) {
static int check_type(void) {
	yylval.sval = strdup(yytext);

	struct typedefs *td = parse_state.typedefs;
	struct typedef_declaration *td = current_source->typedefs;
	while (td) {
		if (strcmp(td->name, yytext) == 0) {
			return TYPEDEF_NAME;

M lang.y => lang.y +27 -17
@@ 292,10 292,13 @@ declaration
		if ($1 == CZ_TYPEDEF) {
			struct strloc_list *list = $2, *next;
			while (list) {
				struct typedefs *td = calloc(1, sizeof(struct typedefs));
				struct typedef_declaration *td =
					calloc(1, sizeof(struct typedef_declaration));
				td->name = list->strloc.name;
				td->next = parse_state.typedefs;
				parse_state.typedefs = td;
				td->lineno = lineno;
				td->colno = colno;
				td->next = current_source->typedefs;
				current_source->typedefs = td;
				next = list->next;
				free(list);
				list = next;


@@ 661,24 664,31 @@ external_declaration
function_definition
	: declaration_specifiers declarator declaration_list compound_statement {
		if (!filename || strcmp(filename, original_filename) == 0) {
			struct funcdef *funcdef = calloc(1, sizeof(struct funcdef));
			funcdef->strloc.name = $2.name;
			funcdef->strloc.lineno = $2.lineno;
			funcdef->strloc.colno = $2.colno;
			funcdef->is_static = $1;
			funcdef->next = parse_state.funcdefs;
			parse_state.funcdefs = funcdef;
			/* TODO: Add to symbol_cache for quick lookup */
			struct symbol_definition *symbol =
				calloc(sizeof(struct symbol_definition), 1);
			symbol->file = current_source;
			symbol->name = $2.name;
			symbol->lineno = $2.lineno;
			symbol->colno = $2.colno;
			symbol->is_static = $1 == CZ_STATIC;
			symbol->next = current_source->symbols;
			current_source->symbols = symbol;
			++current_source->nsyms;
		}
	}
	| declaration_specifiers declarator compound_statement {
		if (!filename || strcmp(filename, original_filename) == 0) {
			struct funcdef *funcdef = calloc(1, sizeof(struct funcdef));
			funcdef->strloc.name = $2.name;
			funcdef->strloc.lineno = $2.lineno;
			funcdef->strloc.colno = $2.colno;
			funcdef->is_static = $1;
			funcdef->next = parse_state.funcdefs;
			parse_state.funcdefs = funcdef;
			struct symbol_definition *symbol =
				calloc(sizeof(struct symbol_definition), 1);
			symbol->file = current_source;
			symbol->name = $2.name;
			symbol->lineno = $2.lineno;
			symbol->colno = $2.colno;
			symbol->is_static = $1 == CZ_STATIC;
			symbol->next = current_source->symbols;
			current_source->symbols = symbol;
			++current_source->nsyms;
		}
	}
	;

M main.c => main.c +20 -18
@@ 17,13 17,11 @@ static FILE *invoke_cpp(const char *cppcmd, const char *input) {
}

static void postprocess(struct source_file *file) {
	struct funcdef *def = parse_state.funcdefs;
	while (def) {
		/* TODO: stow away */
		struct funcdef *next = def->next;
		free(def->strloc.name);
		free(def);
		def = next;
	fprintf(stderr, "%3d symbols %3d references\n", file->nsyms, file->nrefs);
	struct symbol_definition *symbol = file->symbols;
	while (symbol) {
		// TODO: Index symbols and adopt orphans
		symbol = symbol->next;
	}

	struct funccall *call = parse_state.funccalls;


@@ 35,13 33,13 @@ static void postprocess(struct source_file *file) {
		call = next;
	}

	struct typedefs *tdefs = parse_state.typedefs;
	while (tdefs) {
		/* TODO: stow away */
		struct typedefs *next = tdefs->next;
		free(tdefs->name);
		free(tdefs);
		tdefs = next;
	struct typedef_declaration *td = file->typedefs;
	while (td) {
		/* Note: we don't track the usage of these, who cares tbh */
		struct typedef_declaration *next = td->next;
		free(td->name);
		free(td);
		td = next;
	}

	memset(&parse_state, 0, sizeof(parse_state));


@@ 69,10 67,12 @@ int main(int argc, char **argv) {
	}

	for (int i = optind; i < argc; ++i) {
		struct source_file *file = calloc(1, sizeof(struct source_file));
		file->path = argv[i];
		FILE *cpp = invoke_cpp(cppcmd, argv[i]);
		lexreset(file->path, cpp);
		const char *path = argv[i];
		// TODO: Put debug prints behind a flag
		fprintf(stderr, "Scanning %d/%-6d %-20s ",
				i - optind + 1, argc - optind, path);
		FILE *cpp = invoke_cpp(cppcmd, path);
		struct source_file *file = lexreset(path, cpp);
		yyparse();
		pclose(cpp);
		postprocess(file);


@@ 80,5 80,7 @@ int main(int argc, char **argv) {
		graph.files = file;
	}

	// TODO: free state

	return 0;
}

M parse.h => parse.h +2 -15
@@ 5,7 5,7 @@
#include "graph.h"

int yyparse(void);
void lexreset(const char *filename, FILE *input);
struct source_file *lexreset(const char *filename, FILE *input);

struct strloc {
	int lineno, colno;


@@ 17,18 17,6 @@ struct strloc_list {
	struct strloc_list *next;
};

struct typedefs {
	char *name;
	struct typedefs *next;
};

/* TODO: replace with symbol_definition */
struct funcdef {
	struct strloc strloc;
	bool is_static;
	struct funcdef *next;
};

/* TODO: replace with symbol_reference */
struct funccall {
	struct strloc strloc;


@@ 36,11 24,10 @@ struct funccall {
};

struct parse_state {
	struct typedefs *typedefs;
	struct funcdef *funcdefs;
	struct funccall *funccalls;
};

extern struct parse_state parse_state;
extern struct source_file *current_source;

#endif