aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--preprocess.c22
-rw-r--r--tests/073.sh6
-rw-r--r--tests/074.sh6
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