[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