mirror of https://github.com/rui314/chibicc
Add #line
This commit is contained in:
parent
37998be0c1
commit
c61c0d0025
|
@ -59,6 +59,10 @@ typedef struct {
|
|||
char *name;
|
||||
int file_no;
|
||||
char *contents;
|
||||
|
||||
// For #line directive
|
||||
char *display_name;
|
||||
int line_delta;
|
||||
} File;
|
||||
|
||||
// Token type
|
||||
|
@ -74,7 +78,9 @@ struct Token {
|
|||
char *str; // String literal contents including terminating '\0'
|
||||
|
||||
File *file; // Source location
|
||||
char *filename; // Filename
|
||||
int line_no; // Line number
|
||||
int line_delta; // Line number
|
||||
bool at_bol; // True if this token is at beginning of line
|
||||
bool has_space; // True if this token follows a space character
|
||||
Hideset *hideset; // For macro expansion
|
||||
|
|
33
preprocess.c
33
preprocess.c
|
@ -705,6 +705,24 @@ static Token *include_file(Token *tok, char *path, Token *filename_tok) {
|
|||
return append(tok2, tok);
|
||||
}
|
||||
|
||||
// Read #line arguments
|
||||
static void read_line_marker(Token **rest, Token *tok) {
|
||||
Token *start = tok;
|
||||
tok = preprocess(copy_line(rest, tok));
|
||||
|
||||
if (tok->kind != TK_NUM || tok->ty->kind != TY_INT)
|
||||
error_tok(tok, "invalid line marker");
|
||||
start->file->line_delta = tok->val - start->line_no;
|
||||
|
||||
tok = tok->next;
|
||||
if (tok->kind == TK_EOF)
|
||||
return;
|
||||
|
||||
if (tok->kind != TK_STR)
|
||||
error_tok(tok, "filename expected");
|
||||
start->file->display_name = tok->str;
|
||||
}
|
||||
|
||||
// Visit all tokens in `tok` while evaluating preprocessing
|
||||
// macros and directives.
|
||||
static Token *preprocess2(Token *tok) {
|
||||
|
@ -718,6 +736,8 @@ 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;
|
||||
cur = cur->next = tok;
|
||||
tok = tok->next;
|
||||
continue;
|
||||
|
@ -814,6 +834,11 @@ static Token *preprocess2(Token *tok) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (equal(tok, "line")) {
|
||||
read_line_marker(&tok, tok->next);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (equal(tok, "error"))
|
||||
error_tok(tok, "error");
|
||||
|
||||
|
@ -847,13 +872,14 @@ static Macro *add_builtin(char *name, macro_handler_fn *fn) {
|
|||
static Token *file_macro(Token *tmpl) {
|
||||
while (tmpl->origin)
|
||||
tmpl = tmpl->origin;
|
||||
return new_str_token(tmpl->file->name, tmpl);
|
||||
return new_str_token(tmpl->file->display_name, tmpl);
|
||||
}
|
||||
|
||||
static Token *line_macro(Token *tmpl) {
|
||||
while (tmpl->origin)
|
||||
tmpl = tmpl->origin;
|
||||
return new_num_token(tmpl->line_no, tmpl);
|
||||
int i = tmpl->line_no + tmpl->file->line_delta;
|
||||
return new_num_token(i, tmpl);
|
||||
}
|
||||
|
||||
// __COUNTER__ is expanded to serial values starting from 0.
|
||||
|
@ -1022,5 +1048,8 @@ Token *preprocess(Token *tok) {
|
|||
error_tok(cond_incl->tok, "unterminated conditional directive");
|
||||
convert_pp_tokens(tok);
|
||||
join_adjacent_string_literals(tok);
|
||||
|
||||
for (Token *t = tok; t; t = t->next)
|
||||
t->line_no += t->line_delta;
|
||||
return tok;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
#include "test.h"
|
||||
|
||||
int main() {
|
||||
#line 500 "foo"
|
||||
ASSERT(501, __LINE__);
|
||||
ASSERT(0, strcmp(__FILE__, "foo"));
|
||||
|
||||
#line 800 "bar"
|
||||
ASSERT(801, __LINE__);
|
||||
ASSERT(0, strcmp(__FILE__, "bar"));
|
||||
|
||||
#line 1
|
||||
ASSERT(2, __LINE__);
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
}
|
|
@ -103,6 +103,7 @@ static Token *new_token(TokenKind kind, char *start, char *end) {
|
|||
tok->loc = start;
|
||||
tok->len = end - start;
|
||||
tok->file = current_file;
|
||||
tok->filename = current_file->display_name;
|
||||
tok->at_bol = at_bol;
|
||||
tok->has_space = has_space;
|
||||
|
||||
|
@ -674,6 +675,7 @@ File **get_input_files(void) {
|
|||
File *new_file(char *name, int file_no, char *contents) {
|
||||
File *file = calloc(1, sizeof(File));
|
||||
file->name = name;
|
||||
file->display_name = name;
|
||||
file->file_no = file_no;
|
||||
file->contents = contents;
|
||||
return file;
|
||||
|
|
Loading…
Reference in New Issue