diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-07-31 07:03:56 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-08-15 10:06:21 +0900 |
| commit | 6b1418634534bc3d7f32e63c88a186d030ab31f8 (patch) | |
| tree | 1ab2bed5716c29bb04c12935cfc39b46bd5443fc /preprocess.c | |
| parent | f53b6ff29c79b288792da24feb55b7ed9db2ba40 (diff) | |
| download | ducc-6b1418634534bc3d7f32e63c88a186d030ab31f8.tar.gz ducc-6b1418634534bc3d7f32e63c88a186d030ab31f8.tar.zst ducc-6b1418634534bc3d7f32e63c88a186d030ab31f8.zip | |
feat: expand macro recursively
Diffstat (limited to 'preprocess.c')
| -rw-r--r-- | preprocess.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/preprocess.c b/preprocess.c index 148b89a..b43732b 100644 --- a/preprocess.c +++ b/preprocess.c @@ -692,18 +692,28 @@ PpToken* process_define_directive(Preprocessor* pp, PpToken* tok) { return NULL; } -void expand_macro(Preprocessor* pp, PpToken* tok) { +int expand_macro(Preprocessor* pp, PpToken* tok) { int pp_macro_idx = find_pp_macro(pp, &tok->raw); if (pp_macro_idx == -1) { - return; + return 0; } + int i; + SourceLocation original_loc = tok->loc; PpMacro* pp_macro = pp->pp_macros->data + pp_macro_idx; if (pp_macro->kind == PpMacroKind_func) { // also consume '(' and ')' replace_pp_tokens(pp, tok, tok + 3, pp_macro->n_replacements, pp_macro->replacements); + // Inherit a source location from the original macro token. + for (i = 0; i < pp_macro->n_replacements; ++i) { + tok[i].loc = original_loc; + } } else if (pp_macro->kind == PpMacroKind_obj) { replace_pp_tokens(pp, tok, tok + 1, pp_macro->n_replacements, pp_macro->replacements); + // Inherit a source location from the original macro token. + for (i = 0; i < pp_macro->n_replacements; ++i) { + tok[i].loc = original_loc; + } } else if (pp_macro->kind == PpMacroKind_builtin_file) { PpToken* file_tok = calloc(1, sizeof(PpToken)); file_tok->kind = PpTokenKind_string_literal; @@ -721,6 +731,7 @@ void expand_macro(Preprocessor* pp, PpToken* tok) { } else { unreachable(); } + return 1; } void process_pp_directives(Preprocessor* pp) { @@ -754,7 +765,12 @@ void process_pp_directives(Preprocessor* pp) { } else if (skip_pp_tokens(pp)) { make_token_whitespace(tok); } else if (tok->kind == PpTokenKind_identifier) { - expand_macro(pp, tok); + int expanded = expand_macro(pp, tok); + if (expanded) { + // A macro may expand to another macro. Re-scan the expanded tokens. + // TODO: if the macro is defined recursively, it causes infinite loop. + --tok; + } } ++tok; } |
