mirror of https://github.com/rui314/chibicc
Add __FILE__ and __LINE__
This commit is contained in:
parent
5f5a8507ff
commit
6f17071885
|
@ -75,6 +75,7 @@ struct Token {
|
||||||
bool at_bol; // True if this token is at beginning of line
|
bool at_bol; // True if this token is at beginning of line
|
||||||
bool has_space; // True if this token follows a space character
|
bool has_space; // True if this token follows a space character
|
||||||
Hideset *hideset; // For macro expansion
|
Hideset *hideset; // For macro expansion
|
||||||
|
Token *origin; // If this is expanded from a macro, the original token
|
||||||
};
|
};
|
||||||
|
|
||||||
void error(char *fmt, ...);
|
void error(char *fmt, ...);
|
||||||
|
|
35
preprocess.c
35
preprocess.c
|
@ -37,6 +37,8 @@ struct MacroArg {
|
||||||
Token *tok;
|
Token *tok;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef Token *macro_handler_fn(Token *);
|
||||||
|
|
||||||
typedef struct Macro Macro;
|
typedef struct Macro Macro;
|
||||||
struct Macro {
|
struct Macro {
|
||||||
Macro *next;
|
Macro *next;
|
||||||
|
@ -45,6 +47,7 @@ struct Macro {
|
||||||
MacroParam *params;
|
MacroParam *params;
|
||||||
Token *body;
|
Token *body;
|
||||||
bool deleted;
|
bool deleted;
|
||||||
|
macro_handler_fn *handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
// `#if` can be nested, so we use a stack to manage nested `#if`s.
|
// `#if` can be nested, so we use a stack to manage nested `#if`s.
|
||||||
|
@ -560,10 +563,19 @@ static bool expand_macro(Token **rest, Token *tok) {
|
||||||
if (!m)
|
if (!m)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Built-in dynamic macro application such as __LINE__
|
||||||
|
if (m->handler) {
|
||||||
|
*rest = m->handler(tok);
|
||||||
|
(*rest)->next = tok->next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Object-like macro application
|
// Object-like macro application
|
||||||
if (m->is_objlike) {
|
if (m->is_objlike) {
|
||||||
Hideset *hs = hideset_union(tok->hideset, new_hideset(m->name));
|
Hideset *hs = hideset_union(tok->hideset, new_hideset(m->name));
|
||||||
Token *body = add_hideset(m->body, hs);
|
Token *body = add_hideset(m->body, hs);
|
||||||
|
for (Token *t = body; t->kind != TK_EOF; t = t->next)
|
||||||
|
t->origin = tok;
|
||||||
*rest = append(body, tok->next);
|
*rest = append(body, tok->next);
|
||||||
(*rest)->at_bol = tok->at_bol;
|
(*rest)->at_bol = tok->at_bol;
|
||||||
(*rest)->has_space = tok->has_space;
|
(*rest)->has_space = tok->has_space;
|
||||||
|
@ -590,6 +602,8 @@ static bool expand_macro(Token **rest, Token *tok) {
|
||||||
|
|
||||||
Token *body = subst(m->body, args);
|
Token *body = subst(m->body, args);
|
||||||
body = add_hideset(body, hs);
|
body = add_hideset(body, hs);
|
||||||
|
for (Token *t = body; t->kind != TK_EOF; t = t->next)
|
||||||
|
t->origin = macro_token;
|
||||||
*rest = append(body, tok->next);
|
*rest = append(body, tok->next);
|
||||||
(*rest)->at_bol = macro_token->at_bol;
|
(*rest)->at_bol = macro_token->at_bol;
|
||||||
(*rest)->has_space = macro_token->has_space;
|
(*rest)->has_space = macro_token->has_space;
|
||||||
|
@ -788,6 +802,24 @@ static void define_macro(char *name, char *buf) {
|
||||||
add_macro(name, true, tok);
|
add_macro(name, true, tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Macro *add_builtin(char *name, macro_handler_fn *fn) {
|
||||||
|
Macro *m = add_macro(name, true, NULL);
|
||||||
|
m->handler = fn;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Token *file_macro(Token *tmpl) {
|
||||||
|
while (tmpl->origin)
|
||||||
|
tmpl = tmpl->origin;
|
||||||
|
return new_str_token(tmpl->file->name, tmpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Token *line_macro(Token *tmpl) {
|
||||||
|
while (tmpl->origin)
|
||||||
|
tmpl = tmpl->origin;
|
||||||
|
return new_num_token(tmpl->line_no, tmpl);
|
||||||
|
}
|
||||||
|
|
||||||
static void init_macros(void) {
|
static void init_macros(void) {
|
||||||
// Define predefined macros
|
// Define predefined macros
|
||||||
define_macro("_LP64", "1");
|
define_macro("_LP64", "1");
|
||||||
|
@ -831,6 +863,9 @@ static void init_macros(void) {
|
||||||
define_macro("__x86_64__", "1");
|
define_macro("__x86_64__", "1");
|
||||||
define_macro("linux", "1");
|
define_macro("linux", "1");
|
||||||
define_macro("unix", "1");
|
define_macro("unix", "1");
|
||||||
|
|
||||||
|
add_builtin("__FILE__", file_macro);
|
||||||
|
add_builtin("__LINE__", line_macro);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry point function of the preprocessor.
|
// Entry point function of the preprocessor.
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
#include "include2.h"
|
#include "include2.h"
|
||||||
|
|
||||||
|
char *include1_filename = __FILE__;
|
||||||
|
int include1_line = __LINE__;
|
||||||
|
|
||||||
int include1 = 5;
|
int include1 = 5;
|
||||||
|
|
11
test/macro.c
11
test/macro.c
|
@ -1,6 +1,11 @@
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "include1.h"
|
#include "include1.h"
|
||||||
|
|
||||||
|
char *main_filename1 = __FILE__;
|
||||||
|
int main_line1 = __LINE__;
|
||||||
|
#define LINE() __LINE__
|
||||||
|
int main_line2 = LINE();
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
||||||
/* */ #
|
/* */ #
|
||||||
|
@ -324,6 +329,12 @@ int main() {
|
||||||
|
|
||||||
ASSERT(1, __STDC__);
|
ASSERT(1, __STDC__);
|
||||||
|
|
||||||
|
ASSERT(0, strcmp(main_filename1, "test/macro.c"));
|
||||||
|
ASSERT(5, main_line1);
|
||||||
|
ASSERT(7, main_line2);
|
||||||
|
ASSERT(0, strcmp(include1_filename, "test/include1.h"));
|
||||||
|
ASSERT(4, include1_line);
|
||||||
|
|
||||||
printf("OK\n");
|
printf("OK\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue