[flang-commits] [clang] [flang] [flang][preprocessor] Don't expand INCLUDE under -E by default (PR #110333)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Fri Sep 27 15:11:33 PDT 2024


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/110333

Fortran INCLUDE lines have (until now) been treated like #include directives.  This isn't how things work with other Fortran compilers when running under the -E option for preprocessing only, so stop doing it by default, and add -fpreprocess-include-lines to turn it back on when desired.

>From 985846bbdeed74a2a22d00fc96e29cfe68e1491f Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Fri, 27 Sep 2024 15:08:08 -0700
Subject: [PATCH] [flang][preprocessor] Don't expand INCLUDE under -E by
 default

Fortran INCLUDE lines have (until now) been treated like #include
directives.  This isn't how things work with other Fortran compilers
when running under the -E option for preprocessing only, so stop
doing it by default, and add -fpreprocess-include-lines to turn it
back on when desired.
---
 clang/include/clang/Driver/Options.td              | 2 ++
 flang/include/flang/Frontend/PreprocessorOptions.h | 3 +++
 flang/include/flang/Parser/parsing.h               | 1 +
 flang/lib/Frontend/CompilerInvocation.cpp          | 6 ++++++
 flang/lib/Frontend/FrontendAction.cpp              | 4 ++++
 flang/lib/Parser/parsing.cpp                       | 2 ++
 flang/lib/Parser/prescan.cpp                       | 3 +++
 flang/lib/Parser/prescan.h                         | 5 +++++
 flang/test/Parser/include.f                        | 2 +-
 9 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 376d7d4290c0bf..388d8cd9d68e5a 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6886,6 +6886,8 @@ def module_suffix : Separate<["-"], "module-suffix">,  Group<f_Group>, MetaVarNa
   HelpText<"Use <suffix> as the suffix for module files (the default value is `.mod`)">;
 def fno_reformat : Flag<["-"], "fno-reformat">, Group<Preprocessor_Group>,
   HelpText<"Dump the cooked character stream in -E mode">;
+def fpreprocess_include_lines : Flag<["-"], "fpreprocess-include-lines">, Group<Preprocessor_Group>,
+  HelpText<"Treat INCLUDE lines like #include directives in -E mode">;
 defm analyzed_objects_for_unparse : OptOutFC1FFlag<"analyzed-objects-for-unparse", "", "Do not use the analyzed objects when unparsing">;
 
 def emit_fir : Flag<["-"], "emit-fir">, Group<Action_Group>,
diff --git a/flang/include/flang/Frontend/PreprocessorOptions.h b/flang/include/flang/Frontend/PreprocessorOptions.h
index 13a91ee9a184f8..2de9dabb1b3722 100644
--- a/flang/include/flang/Frontend/PreprocessorOptions.h
+++ b/flang/include/flang/Frontend/PreprocessorOptions.h
@@ -56,6 +56,9 @@ struct PreprocessorOptions {
   // -fno-reformat: Emit cooked character stream as -E output
   bool noReformat{false};
 
+  // -fpreprocess-include-lines: Treat INCLUDE as #include for -E output
+  bool preprocessIncludeLines{false};
+
   // -dM: Show macro definitions with -dM -E
   bool showMacros{false};
 
diff --git a/flang/include/flang/Parser/parsing.h b/flang/include/flang/Parser/parsing.h
index 4d329c189cb80e..0c774decb16d31 100644
--- a/flang/include/flang/Parser/parsing.h
+++ b/flang/include/flang/Parser/parsing.h
@@ -40,6 +40,7 @@ struct Options {
   bool needProvenanceRangeToCharBlockMappings{false};
   Fortran::parser::Encoding encoding{Fortran::parser::Encoding::UTF_8};
   bool prescanAndReformat{false}; // -E
+  bool expandIncludeLinesInPreprocessedOutput{true};
   bool showColors{false};
 };
 
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 90c327546198b5..f30cda1d051efc 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -819,6 +819,8 @@ static void parsePreprocessorArgs(Fortran::frontend::PreprocessorOptions &opts,
             : PPMacrosFlag::Exclude;
 
   opts.noReformat = args.hasArg(clang::driver::options::OPT_fno_reformat);
+  opts.preprocessIncludeLines =
+      args.hasArg(clang::driver::options::OPT_fpreprocess_include_lines);
   opts.noLineDirectives = args.hasArg(clang::driver::options::OPT_P);
   opts.showMacros = args.hasArg(clang::driver::options::OPT_dM);
 }
@@ -1479,6 +1481,10 @@ void CompilerInvocation::setFortranOpts() {
   }
   fortranOptions.fixedFormColumns = frontendOptions.fixedFormColumns;
 
+  // -E
+  fortranOptions.prescanAndReformat =
+      frontendOptions.programAction == PrintPreprocessedInput;
+
   fortranOptions.features = frontendOptions.features;
   fortranOptions.encoding = frontendOptions.encoding;
 
diff --git a/flang/lib/Frontend/FrontendAction.cpp b/flang/lib/Frontend/FrontendAction.cpp
index 42a614fe46be5b..041182bdf61781 100644
--- a/flang/lib/Frontend/FrontendAction.cpp
+++ b/flang/lib/Frontend/FrontendAction.cpp
@@ -95,6 +95,10 @@ bool FrontendAction::beginSourceFile(CompilerInstance &ci,
         getCurrentInput().getIsCUDAFortran());
   }
 
+  // -fpreprocess-include-lines
+  invoc.getFortranOpts().expandIncludeLinesInPreprocessedOutput =
+      invoc.getPreprocessorOpts().preprocessIncludeLines;
+
   // Decide between fixed and free form (if the user didn't express any
   // preference, use the file extension to decide)
   if (invoc.getFrontendOpts().fortranForm == FortranForm::Unknown) {
diff --git a/flang/lib/Parser/parsing.cpp b/flang/lib/Parser/parsing.cpp
index 37dc113436aa0e..d8448e4c527ac7 100644
--- a/flang/lib/Parser/parsing.cpp
+++ b/flang/lib/Parser/parsing.cpp
@@ -75,6 +75,8 @@ const SourceFile *Parsing::Prescan(const std::string &path, Options options) {
       messages_, *currentCooked_, preprocessor_, options.features};
   prescanner.set_fixedForm(options.isFixedForm)
       .set_fixedFormColumnLimit(options.fixedFormColumns)
+      .set_expandIncludeLines(!options.prescanAndReformat ||
+          options.expandIncludeLinesInPreprocessedOutput)
       .AddCompilerDirectiveSentinel("dir$");
   if (options.features.IsEnabled(LanguageFeature::OpenACC)) {
     prescanner.AddCompilerDirectiveSentinel("$acc");
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index b231c5859cf873..eabfcc244001ad 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -1031,6 +1031,9 @@ const char *Prescanner::IsFreeFormComment(const char *p) const {
 }
 
 std::optional<std::size_t> Prescanner::IsIncludeLine(const char *start) const {
+  if (!expandIncludeLines_) {
+    return std::nullopt;
+  }
   const char *p{SkipWhiteSpace(start)};
   if (*p == '0' && inFixedForm_ && p == start + 5) {
     // Accept "     0INCLUDE" in fixed form.
diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index 9d4f7c0c302a1a..c50bf231e3c705 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -48,6 +48,10 @@ class Prescanner {
   Preprocessor &preprocessor() { return preprocessor_; }
   common::LanguageFeatureControl &features() { return features_; }
 
+  Prescanner &set_expandIncludeLines(bool yes) {
+    expandIncludeLines_ = yes;
+    return *this;
+  }
   Prescanner &set_fixedForm(bool yes) {
     inFixedForm_ = yes;
     return *this;
@@ -209,6 +213,7 @@ class Prescanner {
   Preprocessor &preprocessor_;
   AllSources &allSources_;
   common::LanguageFeatureControl features_;
+  bool expandIncludeLines_{true};
   bool isNestedInIncludeDirective_{false};
   bool backslashFreeFormContinuation_{false};
   bool inFixedForm_{false};
diff --git a/flang/test/Parser/include.f b/flang/test/Parser/include.f
index 8a7fe3a2ecd9d0..6e16afd92ad0ce 100644
--- a/flang/test/Parser/include.f
+++ b/flang/test/Parser/include.f
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -E -I %S/Inputs %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -E -fpreprocess-include-lines -I %S/Inputs %s 2>&1 | FileCheck %s
       include 'include-file'
       include "include-file"
       include 1_'include-file'



More information about the flang-commits mailing list