mirror of
https://github.com/rui314/chibicc
synced 2024-11-22 06:11:18 +03:00
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 has_space; // True if this token follows a space character
|
||||
Hideset *hideset; // For macro expansion
|
||||
Token *origin; // If this is expanded from a macro, the original token
|
||||
};
|
||||
|
||||
void error(char *fmt, ...);
|
||||
|
35
preprocess.c
35
preprocess.c
@ -37,6 +37,8 @@ struct MacroArg {
|
||||
Token *tok;
|
||||
};
|
||||
|
||||
typedef Token *macro_handler_fn(Token *);
|
||||
|
||||
typedef struct Macro Macro;
|
||||
struct Macro {
|
||||
Macro *next;
|
||||
@ -45,6 +47,7 @@ struct Macro {
|
||||
MacroParam *params;
|
||||
Token *body;
|
||||
bool deleted;
|
||||
macro_handler_fn *handler;
|
||||
};
|
||||
|
||||
// `#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)
|
||||
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
|
||||
if (m->is_objlike) {
|
||||
Hideset *hs = hideset_union(tok->hideset, new_hideset(m->name));
|
||||
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)->at_bol = tok->at_bol;
|
||||
(*rest)->has_space = tok->has_space;
|
||||
@ -590,6 +602,8 @@ static bool expand_macro(Token **rest, Token *tok) {
|
||||
|
||||
Token *body = subst(m->body, args);
|
||||
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)->at_bol = macro_token->at_bol;
|
||||
(*rest)->has_space = macro_token->has_space;
|
||||
@ -788,6 +802,24 @@ static void define_macro(char *name, char *buf) {
|
||||
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) {
|
||||
// Define predefined macros
|
||||
define_macro("_LP64", "1");
|
||||
@ -831,6 +863,9 @@ static void init_macros(void) {
|
||||
define_macro("__x86_64__", "1");
|
||||
define_macro("linux", "1");
|
||||
define_macro("unix", "1");
|
||||
|
||||
add_builtin("__FILE__", file_macro);
|
||||
add_builtin("__LINE__", line_macro);
|
||||
}
|
||||
|
||||
// Entry point function of the preprocessor.
|
||||
|
@ -1,3 +1,6 @@
|
||||
#include "include2.h"
|
||||
|
||||
char *include1_filename = __FILE__;
|
||||
int include1_line = __LINE__;
|
||||
|
||||
int include1 = 5;
|
||||
|
11
test/macro.c
11
test/macro.c
@ -1,6 +1,11 @@
|
||||
#include "test.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(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");
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user