[flang-commits] [flang] 6086007 - [flang][preprocessor] Replace macros in some #include directives (#80039)
via flang-commits
flang-commits at lists.llvm.org
Wed Jan 31 11:50:55 PST 2024
Author: Peter Klausler
Date: 2024-01-31T11:50:51-08:00
New Revision: 60860079ec9416a263d1078e0e29cf393a89737a
URL: https://github.com/llvm/llvm-project/commit/60860079ec9416a263d1078e0e29cf393a89737a
DIFF: https://github.com/llvm/llvm-project/commit/60860079ec9416a263d1078e0e29cf393a89737a.diff
LOG: [flang][preprocessor] Replace macros in some #include directives (#80039)
Ensure that #include FOO undergoes macro replacement. But, as is the
case with C/C++, continue to not perform macro replacement in a #include
directive with <angled brackets>.
Added:
flang/test/Preprocessing/macro-in-include.F90
Modified:
flang/lib/Parser/preprocessor.cpp
flang/test/Driver/prescanner-diag.f90
flang/test/Preprocessing/include-comment.F90
Removed:
################################################################################
diff --git a/flang/lib/Parser/preprocessor.cpp b/flang/lib/Parser/preprocessor.cpp
index 8c993e7ced0e8..10661dda32bc3 100644
--- a/flang/lib/Parser/preprocessor.cpp
+++ b/flang/lib/Parser/preprocessor.cpp
@@ -642,27 +642,33 @@ void Preprocessor::Directive(const TokenSequence &dir, Prescanner &prescanner) {
"#include: missing name of file to include"_err_en_US);
return;
}
- std::string include;
std::optional<std::string> prependPath;
- if (dir.TokenAt(j).ToString() == "<") { // #include <foo>
- std::size_t k{j + 1};
- if (k >= tokens) {
- prescanner.Say(dir.GetIntervalProvenanceRange(j, tokens - j),
+ TokenSequence path{dir, j, tokens - j};
+ std::string include{path.TokenAt(0).ToString()};
+ if (include != "<" && include.substr(0, 1) != "\"" &&
+ include.substr(0, 1) != "'") {
+ path = ReplaceMacros(path, prescanner);
+ include = path.empty() ? ""s : path.TokenAt(0).ToString();
+ }
+ auto pathTokens{path.SizeInTokens()};
+ std::size_t k{0};
+ if (include == "<") { // #include <foo>
+ k = 1;
+ if (k >= pathTokens) {
+ prescanner.Say(dir.GetIntervalProvenanceRange(j, pathTokens),
"#include: file name missing"_err_en_US);
return;
}
- while (k < tokens && dir.TokenAt(k) != ">") {
+ while (k < pathTokens && path.TokenAt(k) != ">") {
++k;
}
- if (k >= tokens) {
+ if (k >= pathTokens) {
prescanner.Say(dir.GetIntervalProvenanceRange(j, tokens - j),
"#include: expected '>' at end of included file"_port_en_US);
}
- TokenSequence braced{dir, j + 1, k - j - 1};
+ TokenSequence braced{path, 1, k - 1};
include = braced.ToString();
- j = k;
- } else if (((include = dir.TokenAt(j).ToString()).substr(0, 1) == "\"" ||
- include.substr(0, 1) == "'") &&
+ } else if ((include.substr(0, 1) == "\"" || include.substr(0, 1) == "'") &&
include.substr(include.size() - 1, 1) == include.substr(0, 1)) {
// #include "foo" and #include 'foo'
include = include.substr(1, include.size() - 2);
@@ -673,16 +679,17 @@ void Preprocessor::Directive(const TokenSequence &dir, Prescanner &prescanner) {
}
} else {
prescanner.Say(dir.GetTokenProvenanceRange(j < tokens ? j : tokens - 1),
- "#include: expected name of file to include"_err_en_US);
+ "#include %s: expected name of file to include"_err_en_US,
+ path.ToString());
return;
}
if (include.empty()) {
prescanner.Say(dir.GetTokenProvenanceRange(dirOffset),
- "#include: empty include file name"_err_en_US);
+ "#include %s: empty include file name"_err_en_US, path.ToString());
return;
}
- j = dir.SkipBlanks(j + 1);
- if (j < tokens && dir.TokenAt(j).ToString() != "!") {
+ k = path.SkipBlanks(k + 1);
+ if (k < pathTokens && path.TokenAt(k).ToString() != "!") {
prescanner.Say(dir.GetIntervalProvenanceRange(j, tokens - j),
"#include: extra stuff ignored after file name"_port_en_US);
}
@@ -691,8 +698,8 @@ void Preprocessor::Directive(const TokenSequence &dir, Prescanner &prescanner) {
const SourceFile *included{
allSources_.Open(include, error, std::move(prependPath))};
if (!included) {
- prescanner.Say(dir.GetTokenProvenanceRange(dirOffset),
- "#include: %s"_err_en_US, error.str());
+ prescanner.Say(dir.GetTokenProvenanceRange(j), "#include: %s"_err_en_US,
+ error.str());
} else if (included->bytes() > 0) {
ProvenanceRange fileRange{
allSources_.AddIncludedFile(*included, dir.GetProvenanceRange())};
diff --git a/flang/test/Driver/prescanner-diag.f90 b/flang/test/Driver/prescanner-diag.f90
index e133628f71d77..7c2f8d4d7ef4f 100644
--- a/flang/test/Driver/prescanner-diag.f90
+++ b/flang/test/Driver/prescanner-diag.f90
@@ -12,8 +12,8 @@
! RUN: %flang -fsyntax-only -I %S/Inputs/ %s 2>&1 | FileCheck %s
! RUN: %flang_fc1 -fsyntax-only -I %S/Inputs/ %s 2>&1 | FileCheck %s
-! CHECK: prescanner-diag.f90:[[#@LINE+3]]:20: portability: #include: extra stuff ignored after file name
-! CHECK: prescanner-diag.f90:[[#@LINE+3]]:20: portability: #include: extra stuff ignored after file name
+! CHECK: prescanner-diag.f90:[[#@LINE+3]]:10: portability: #include: extra stuff ignored after file name
+! CHECK: prescanner-diag.f90:[[#@LINE+3]]:10: portability: #include: extra stuff ignored after file name
#include <empty.h> comment
#include "empty.h" comment
diff --git a/flang/test/Preprocessing/include-comment.F90 b/flang/test/Preprocessing/include-comment.F90
index 5997a52292a5f..c55d07ec66d30 100644
--- a/flang/test/Preprocessing/include-comment.F90
+++ b/flang/test/Preprocessing/include-comment.F90
@@ -5,7 +5,7 @@
#include <empty.h> /* comment */
! CHECK-NOT: :7:
#include <empty.h> !comment
-! CHECK: :9:20: portability: #include: extra stuff ignored after file name
+! CHECK: :9:10: portability: #include: extra stuff ignored after file name
#include <empty.h> comment
! CHECK-NOT: :11:
#include "empty.h" ! comment
@@ -13,6 +13,6 @@
#include "empty.h" /* comment */
! CHECK-NOT: :15:
#include "empty.h" !comment
-! CHECK: :17:20: portability: #include: extra stuff ignored after file name
+! CHECK: :17:10: portability: #include: extra stuff ignored after file name
#include "empty.h" comment
end
diff --git a/flang/test/Preprocessing/macro-in-include.F90 b/flang/test/Preprocessing/macro-in-include.F90
new file mode 100644
index 0000000000000..047398859d651
--- /dev/null
+++ b/flang/test/Preprocessing/macro-in-include.F90
@@ -0,0 +1,20 @@
+! RUN: %flang -I%S '-DFILE="defines.F90"' -DFOO=1 -DBAR=2 -E %s 2>&1 | FileCheck %s
+#include FILE
+! CHECK: integer :: a = 1
+! CHECK: integer :: b = 2
+#define SAME(x) x
+#undef FOO
+#undef BAR
+#define FOO 3
+#define BAR 4
+#include SAME(FILE)
+! CHECK: integer :: a = 3
+! CHECK: integer :: b = 4
+#define TOSTR(x) #x
+#undef FOO
+#undef BAR
+#define FOO 5
+#define BAR 6
+#include TOSTR(defines.F90)
+! CHECK: integer :: a = 5
+! CHECK: integer :: b = 6
More information about the flang-commits
mailing list