diff options
| -rw-r--r-- | preprocess.c | 22 | ||||
| -rw-r--r-- | tests/073.sh | 6 | ||||
| -rw-r--r-- | tests/074.sh | 6 |
3 files changed, 27 insertions, 7 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; } diff --git a/tests/073.sh b/tests/073.sh index 8dc165e..3bc42af 100644 --- a/tests/073.sh +++ b/tests/073.sh @@ -2,6 +2,8 @@ set -e cat <<'EOF' > expected main.c +main.c +main.c EOF cat <<'EOF' > header.h @@ -14,7 +16,7 @@ bash ../../test_diff.sh <<'EOF' int printf(); int main() { printf("%s\n", __FILE__); - // printf("%s\n", B); - // printf("%s\n", A); + printf("%s\n", B); + printf("%s\n", A); } EOF diff --git a/tests/074.sh b/tests/074.sh index 90b86c6..a4d42ea 100644 --- a/tests/074.sh +++ b/tests/074.sh @@ -2,6 +2,8 @@ set -e cat <<'EOF' > expected 5 +6 6 +7 7 EOF cat <<'EOF' > header.h @@ -14,7 +16,7 @@ bash ../../test_diff.sh <<'EOF' int printf(); int main() { printf("%d\n", __LINE__); - // printf("%d\n", B); - // printf("%d\n", A); + printf("%d %d\n", B, B); + printf("%d %d\n", A, A); } EOF |
