diff options
-rw-r--r-- | chibicc.h | 1 | ||||
-rw-r--r-- | codegen.c | 11 | ||||
-rw-r--r-- | main.c | 13 | ||||
-rw-r--r-- | preprocess.c | 11 | ||||
-rw-r--r-- | tests/should_not_build.c | 3 | ||||
-rw-r--r-- | tokenize.c | 4 |
6 files changed, 35 insertions, 8 deletions
@@ -464,6 +464,7 @@ void hashmap_test(void); extern bool opt_fpic; extern bool opt_fcommon; +extern bool opt_line_numbers; extern char *base_file; // @@ -60,6 +60,11 @@ static int count(void) { return i++; } +static void emit_line(struct Token *tok) { + if (opt_line_numbers && tok && tok->line_no && tok->filename) + println("#line %d \"%s\"", tok->line_no, tok->filename); +} + static int RETURN_TMP; void print_label(char *label) { @@ -305,8 +310,7 @@ static void gen_addr(Node *node, int to_tmp) { // Generate code for a given node. static void gen_expr(Node *node, int to_tmp) { - // println(" .loc %d %d", node->tok->file->file_no, node->tok->line_no); - + emit_line(node->tok); switch (node->kind) { case ND_NULL_EXPR: return; @@ -560,6 +564,7 @@ static void gen_expr(Node *node, int to_tmp) { } static void gen_stmt(Node *node) { + emit_line(node->tok); switch (node->kind) { case ND_IF: { int cond = count(), condfalse = count(), c = count(); @@ -838,6 +843,8 @@ static void emit_text(Obj *prog) { if (!fn->is_function || !fn->is_definition) continue; + emit_line(fn->body->tok); + // No code is emitted for "static inline" functions // if no one is referencing them. if (!fn->is_live) @@ -9,6 +9,7 @@ char *base_file; StringArray include_paths; bool opt_fcommon = false; bool opt_fpic; +bool opt_line_numbers; static FILE *open_file(char *path) { if (!path || strcmp(path, "-") == 0) @@ -64,8 +65,14 @@ static void cc1(char *base_file) { } int main(int argc, char **argv) { - assert(argc == 2); - base_file = argv[1]; - cc1(argv[1]); + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "--line-numbers")) { + opt_line_numbers = 1; + } else { + assert(!base_file); + base_file = argv[1]; + } + } + cc1(base_file); return 0; } diff --git a/preprocess.c b/preprocess.c index abc095f..e3a3455 100644 --- a/preprocess.c +++ b/preprocess.c @@ -24,6 +24,10 @@ #include "chibicc.h" +static char *CURR_FILE; +static unsigned long LINE_SUB, + LINE_ADD; + typedef struct MacroParam MacroParam; struct MacroParam { MacroParam *next; @@ -807,6 +811,9 @@ static void read_line_marker(Token **rest, Token *tok) { if (tok->kind != TK_STR) error_tok(tok, "filename expected"); start->file->display_name = tok->str; + CURR_FILE = tok->str; + LINE_SUB = tok->line_no; + LINE_ADD = tok->val; } // Visit all tokens in `tok` while evaluating preprocessing @@ -823,7 +830,9 @@ static Token *preprocess2(Token *tok) { // Pass through if it is not a "#". if (!is_hash(tok)) { tok->line_delta = tok->file->line_delta; - tok->filename = tok->file->display_name; + tok->line_no -= LINE_SUB; + tok->line_no += LINE_ADD; + tok->filename = CURR_FILE ? CURR_FILE : tok->file->display_name; cur = cur->next = tok; tok = tok->next; continue; diff --git a/tests/should_not_build.c b/tests/should_not_build.c new file mode 100644 index 0000000..6a7d2d0 --- /dev/null +++ b/tests/should_not_build.c @@ -0,0 +1,3 @@ +int main() { + return foo(); +} @@ -64,14 +64,14 @@ void error_at(char *loc, char *fmt, ...) { void error_tok(Token *tok, char *fmt, ...) { va_list ap; va_start(ap, fmt); - verror_at(tok->file->name, tok->file->contents, tok->line_no, tok->loc, fmt, ap); + verror_at(tok->filename, tok->file->contents, tok->line_no, tok->loc, fmt, ap); exit(1); } void warn_tok(Token *tok, char *fmt, ...) { va_list ap; va_start(ap, fmt); - verror_at(tok->file->name, tok->file->contents, tok->line_no, tok->loc, fmt, ap); + verror_at(tok->filename, tok->file->contents, tok->line_no, tok->loc, fmt, ap); va_end(ap); } |