[flang-commits] [flang] 9efe158 - [flang][preprocessing] Allow keyword macro to rename a function-like macro
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon May 22 14:43:54 PDT 2023
Author: Peter Klausler
Date: 2023-05-22T14:43:45-07:00
New Revision: 9efe1581502f1433811ea479345f84ca5008c754
URL: https://github.com/llvm/llvm-project/commit/9efe1581502f1433811ea479345f84ca5008c754
DIFF: https://github.com/llvm/llvm-project/commit/9efe1581502f1433811ea479345f84ca5008c754.diff
LOG: [flang][preprocessing] Allow keyword macro to rename a function-like macro
#define FOO(x) ((x)+1)
#define BAR FOO
print *, BAR(1)
should work as one would expect.
Fixes https://github.com/llvm/llvm-project/issues/47162.
Differential Revision: https://reviews.llvm.org/D151154
Added:
flang/test/Preprocessing/renaming.F
Modified:
flang/lib/Parser/preprocessor.cpp
Removed:
################################################################################
diff --git a/flang/lib/Parser/preprocessor.cpp b/flang/lib/Parser/preprocessor.cpp
index 58b54f4f1a8c9..6dea1298e77c6 100644
--- a/flang/lib/Parser/preprocessor.cpp
+++ b/flang/lib/Parser/preprocessor.cpp
@@ -273,7 +273,7 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
}
TokenSequence result{input, 0, j};
for (; j < tokens; ++j) {
- const CharBlock &token{input.TokenAt(j)};
+ CharBlock token{input.TokenAt(j)};
if (token.IsBlank() || !IsLegalIdentifierStart(token[0])) {
result.Put(input, j);
continue;
@@ -283,14 +283,15 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
result.Put(input, j);
continue;
}
- Definition &def{it->second};
- if (def.isDisabled()) {
+ Definition *def{&it->second};
+ if (def->isDisabled()) {
result.Put(input, j);
continue;
}
- if (!def.isFunctionLike()) {
- if (def.isPredefined()) {
- std::string name{def.replacement().TokenAt(0).ToString()};
+ if (!def->isFunctionLike()) {
+ bool isRenaming{false};
+ if (def->isPredefined()) {
+ std::string name{def->replacement().TokenAt(0).ToString()};
std::string repl;
if (name == "__FILE__") {
repl = "\""s +
@@ -309,18 +310,38 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
continue;
}
}
- def.set_isDisabled(true);
+ def->set_isDisabled(true);
TokenSequence replaced{
- TokenPasting(ReplaceMacros(def.replacement(), prescanner))};
- def.set_isDisabled(false);
- if (!replaced.empty()) {
- ProvenanceRange from{def.replacement().GetProvenanceRange()};
- ProvenanceRange use{input.GetTokenProvenanceRange(j)};
- ProvenanceRange newRange{
- allSources_.AddMacroCall(from, use, replaced.ToString())};
- result.Put(replaced, newRange);
+ TokenPasting(ReplaceMacros(def->replacement(), prescanner))};
+ def->set_isDisabled(false);
+ // Allow a keyword-like macro replacement to be the name of
+ // a function-like macro, possibly surrounded by blanks.
+ std::size_t k{0}, repTokens{replaced.SizeInTokens()};
+ for (; k < repTokens && replaced.TokenAt(k).IsBlank(); ++k) {
+ }
+ if (k < repTokens) {
+ token = replaced.TokenAt(k);
+ for (++k; k < repTokens && replaced.TokenAt(k).IsBlank(); ++k) {
+ }
+ if (k == repTokens && IsLegalIdentifierStart(token[0])) {
+ auto it{definitions_.find(token)};
+ if (it != definitions_.end() && !it->second.isDisabled() &&
+ it->second.isFunctionLike()) {
+ def = &it->second;
+ isRenaming = true;
+ }
+ }
+ }
+ if (!isRenaming) {
+ if (!replaced.empty()) {
+ ProvenanceRange from{def->replacement().GetProvenanceRange()};
+ ProvenanceRange use{input.GetTokenProvenanceRange(j)};
+ ProvenanceRange newRange{
+ allSources_.AddMacroCall(from, use, replaced.ToString())};
+ result.Put(replaced, newRange);
+ }
+ continue;
}
- continue;
}
// Possible function-like macro call. Skip spaces and newlines to see
// whether '(' is next.
@@ -354,13 +375,13 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
}
}
}
- if (argStart.size() == 1 && k == argStart[0] && def.argumentCount() == 0) {
+ if (argStart.size() == 1 && k == argStart[0] && def->argumentCount() == 0) {
// Subtle: () is zero arguments, not one empty argument,
// unless one argument was expected.
argStart.clear();
}
- if (k >= tokens || argStart.size() < def.argumentCount() ||
- (argStart.size() > def.argumentCount() && !def.isVariadic())) {
+ if (k >= tokens || argStart.size() < def->argumentCount() ||
+ (argStart.size() > def->argumentCount() && !def->isVariadic())) {
result.Put(input, j);
continue;
}
@@ -371,12 +392,12 @@ std::optional<TokenSequence> Preprocessor::MacroReplacement(
(n + 1 == argStart.size() ? k : argStart[n + 1] - 1) - at};
args.emplace_back(TokenSequence(input, at, count));
}
- def.set_isDisabled(true);
+ def->set_isDisabled(true);
TokenSequence replaced{
- ReplaceMacros(def.Apply(args, prescanner), prescanner)};
- def.set_isDisabled(false);
+ ReplaceMacros(def->Apply(args, prescanner), prescanner)};
+ def->set_isDisabled(false);
if (!replaced.empty()) {
- ProvenanceRange from{def.replacement().GetProvenanceRange()};
+ ProvenanceRange from{def->replacement().GetProvenanceRange()};
ProvenanceRange use{input.GetIntervalProvenanceRange(j, k - j)};
ProvenanceRange newRange{
allSources_.AddMacroCall(from, use, replaced.ToString())};
diff --git a/flang/test/Preprocessing/renaming.F b/flang/test/Preprocessing/renaming.F
new file mode 100644
index 0000000000000..1bef18116901e
--- /dev/null
+++ b/flang/test/Preprocessing/renaming.F
@@ -0,0 +1,8 @@
+! RUN: %flang -E %s | FileCheck %s
+! CHECK: ((1)*10000+(11)*100)
+! Ensure that a keyword-like macro can be used to rename a
+! function-like macro.
+#define TO_VERSION2(MAJOR, MINOR) ((MAJOR) * 10000 + (MINOR) * 100)
+#define TO_VERSION TO_VERSION2
+ print *, TO_VERSION(1,11)
+ end
More information about the flang-commits
mailing list