summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Sotoudeh <matthew@masot.net>2023-07-30 18:09:52 -0700
committerMatthew Sotoudeh <matthew@masot.net>2023-07-30 18:09:52 -0700
commitf2297c20b69d942fd1e8fdcdd8f4d142c71de662 (patch)
tree5072f8f11eea2d8265e48d6c3bce533e124f016f
parentc84bbdc2a296f4b818fa8ec05a6dbe2dd46fc4f1 (diff)
bad line numbers support
-rw-r--r--chibicc.h1
-rw-r--r--codegen.c11
-rw-r--r--main.c13
-rw-r--r--preprocess.c11
-rw-r--r--tests/should_not_build.c3
-rw-r--r--tokenize.c4
6 files changed, 35 insertions, 8 deletions
diff --git a/chibicc.h b/chibicc.h
index 01f4264..522c214 100644
--- a/chibicc.h
+++ b/chibicc.h
@@ -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;
//
diff --git a/codegen.c b/codegen.c
index 5111c76..7acd2c9 100644
--- a/codegen.c
+++ b/codegen.c
@@ -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)
diff --git a/main.c b/main.c
index db9f31c..36c16e9 100644
--- a/main.c
+++ b/main.c
@@ -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();
+}
diff --git a/tokenize.c b/tokenize.c
index 5c49c02..4cfb1bd 100644
--- a/tokenize.c
+++ b/tokenize.c
@@ -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);
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback