awarzynski updated this revision to Diff 333953.
awarzynski added a comment.

Make sure that `-cpp\-nocpp` controls command line macro definitions too

As @tskeith pointed out, `-cpp\-nocpp` should also affect command line macro
definitions (on top of standard macro predefinitions). With this change, the
file extension becomes significant in all tests that depend on macros. I've
renamed some of them accordingly. Few other tests are updated to
demonstrate that the new flags work as expected.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D99292/new/

https://reviews.llvm.org/D99292

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Flang.cpp
  flang/include/flang/Frontend/CompilerInvocation.h
  flang/include/flang/Frontend/FrontendOptions.h
  flang/include/flang/Frontend/PreprocessorOptions.h
  flang/lib/Frontend/CompilerInstance.cpp
  flang/lib/Frontend/CompilerInvocation.cpp
  flang/lib/Frontend/FrontendAction.cpp
  flang/lib/Frontend/FrontendActions.cpp
  flang/lib/Frontend/FrontendOptions.cpp
  flang/test/Driver/cpp-nocpp-command-line-macro.f90
  flang/test/Driver/cpp-nocpp-predefined-macro.F90
  flang/test/Driver/driver-help-hidden.f90
  flang/test/Driver/driver-help.f90
  flang/test/Driver/input-from-stdin.f90
  flang/test/Driver/macro-def-undef.F90
  flang/test/Driver/macro-def-undef.f90
  flang/test/Driver/macro-multiline.F90
  flang/test/Driver/macro-multiline.f90
  flang/test/Driver/predefined-macros-compiler-version.F90
  flang/test/Driver/predefined-macros-compiler-version.f90

Index: flang/test/Driver/predefined-macros-compiler-version.f90
===================================================================
--- /dev/null
+++ flang/test/Driver/predefined-macros-compiler-version.f90
@@ -1,26 +0,0 @@
-! Check that the driver correctly defines macros with the compiler version
-
-! REQUIRES: new-flang-driver
-
-!--------------------------
-! FLANG DRIVER (flang-new)
-!--------------------------
-! RUN: %flang-new -E %s  2>&1 | FileCheck %s --ignore-case
-
-!-----------------------------------------
-! FRONTEND FLANG DRIVER (flang-new -fc1)
-!-----------------------------------------
-! RUN: %flang-new -fc1 -E %s  2>&1 | FileCheck %s --ignore-case
-
-!-----------------
-! EXPECTED OUTPUT
-!-----------------
-! CHECK: flang = 1
-! CHECK: flang_major = {{[1-9][0-9]*$}}
-! CHECK: flang_minor = {{[0-9]+$}}
-! CHECK: flang_patchlevel = {{[0-9]+$}}
-
-integer, parameter :: flang = __flang__
-integer, parameter :: flang_major = __flang_major__
-integer, parameter :: flang_minor = __flang_minor__
-integer, parameter :: flang_patchlevel = __flang_patchlevel__
Index: flang/test/Driver/macro-multiline.f90
===================================================================
--- /dev/null
+++ flang/test/Driver/macro-multiline.f90
@@ -1,22 +0,0 @@
-! Ensure the end-of-line character and anything that follows after in a macro definition (-D) is ignored.
-
-! REQUIRES: new-flang-driver
-
-!--------------------------
-! FLANG DRIVER (flang-new)
-!--------------------------
-! RUN: printf -- "-DX=A\\\\\nTHIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT\n" | xargs %flang-new -E %s  2>&1 | FileCheck --strict-whitespace --match-full-lines %s
-
-!-----------------------------------------
-! FRONTEND FLANG DRIVER (flang-new -fc1)
-!-----------------------------------------
-! RUN: printf -- "-DX=A\\\\\nTHIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT\n" | xargs %flang-new -fc1 -E %s  2>&1 | FileCheck --strict-whitespace --match-full-lines %s
-
-!-------------------------------
-! EXPECTED OUTPUT FOR MACRO 'X'
-!-------------------------------
-! CHECK:start a end
-! CHECK-NOT:THIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT
-! CHECK-NOT:this_should_not_exist_in_the_output
-
-START X END
\ No newline at end of file
Index: flang/test/Driver/macro-def-undef.F90
===================================================================
--- flang/test/Driver/macro-def-undef.F90
+++ flang/test/Driver/macro-def-undef.F90
@@ -1,20 +1,18 @@
 ! Ensure arguments -D and -U work as expected.
 
-! REQUIRES: new-flang-driver
-
 !--------------------------
 ! FLANG DRIVER (flang-new)
 !--------------------------
-! RUN: %flang-new -E %s  2>&1 | FileCheck %s --check-prefix=UNDEFINED
-! RUN: %flang-new -E -DX=A %s  2>&1 | FileCheck %s --check-prefix=DEFINED
-! RUN: %flang-new -E -DX=A -UX %s  2>&1 | FileCheck %s --check-prefix=UNDEFINED
+! RUN: %flang -E %s  2>&1 | FileCheck %s --check-prefix=UNDEFINED
+! RUN: %flang -E -DX=A %s  2>&1 | FileCheck %s --check-prefix=DEFINED
+! RUN: %flang -E -DX=A -UX %s  2>&1 | FileCheck %s --check-prefix=UNDEFINED
 
 !-----------------------------------------
 ! FRONTEND FLANG DRIVER (flang-new -fc1)
 !-----------------------------------------
-! RUN: %flang-new -fc1 -E %s  2>&1 | FileCheck %s --check-prefix=UNDEFINED
-! RUN: %flang-new -fc1 -E -DX=A %s  2>&1 | FileCheck %s --check-prefix=DEFINED
-! RUN: %flang-new -fc1 -E -DX -UX %s  2>&1 | FileCheck %s --check-prefix=UNDEFINED
+! RUN: %flang_fc1 -E %s  2>&1 | FileCheck %s --check-prefix=UNDEFINED
+! RUN: %flang_fc1 -E -DX=A %s  2>&1 | FileCheck %s --check-prefix=DEFINED
+! RUN: %flang_fc1 -E -DX -UX %s  2>&1 | FileCheck %s --check-prefix=UNDEFINED
 
 !--------------------------------------------
 ! EXPECTED OUTPUT FOR AN UNDEFINED MACRO
@@ -35,4 +33,4 @@
 #else
 program B
 #endif
-end
\ No newline at end of file
+end
Index: flang/test/Driver/input-from-stdin.f90
===================================================================
--- flang/test/Driver/input-from-stdin.f90
+++ flang/test/Driver/input-from-stdin.f90
@@ -6,24 +6,26 @@
 ! FLANG DRIVER (flang)
 !--------------------------
 ! Input type is implicit
-! RUN: cat %s | %flang -E - | FileCheck %s --check-prefix=PP-NOT-DEFINED
-! RUN: cat %s | %flang -DNEW -E - | FileCheck %s --check-prefix=PP-DEFINED
+! RUN: cat %s | %flang -E -cpp - | FileCheck %s --check-prefix=PP-NOT-DEFINED
+! RUN: cat %s | %flang -DNEW -E -cpp - | FileCheck %s --check-prefix=PP-DEFINED
+! RUN: cat %s | %flang -DNEW -E - | FileCheck %s --check-prefix=PP-NOT-DEFINED
+! RUN: cat %s | %flang -DNEW -E -nocpp - | FileCheck %s --check-prefix=PP-NOT-DEFINED
 
 ! Input type is explicit
-! RUN: cat %s | %flang -E -x f95-cpp-input - | FileCheck %s --check-prefix=PP-NOT-DEFINED
-! RUN: cat %s | %flang -DNEW -E -x f95-cpp-input - | FileCheck %s --check-prefix=PP-DEFINED
+! RUN: cat %s | %flang -E -cpp -x f95-cpp-input - | FileCheck %s --check-prefix=PP-NOT-DEFINED
+! RUN: cat %s | %flang -DNEW -E -cpp -x f95-cpp-input - | FileCheck %s --check-prefix=PP-DEFINED
 
 !---------------------------------------
 ! FLANG FRONTEND DRIVER (flang -fc1)
 !---------------------------------------
 ! Test `-E`: for the corresponding frontend actions the driver relies on the prescanner API to handle file I/O
-! RUN: cat %s | %flang -fc1 -E | FileCheck %s --check-prefix=PP-NOT-DEFINED
-! RUN: cat %s | %flang -fc1 -DNEW -E | FileCheck %s --check-prefix=PP-DEFINED
+! RUN: cat %s | %flang -fc1 -E -cpp | FileCheck %s --check-prefix=PP-NOT-DEFINED
+! RUN: cat %s | %flang -fc1 -DNEW -E -cpp | FileCheck %s --check-prefix=PP-DEFINED
 
 ! Test `-test-io`: for the corresponding frontend action (`InputOutputTestAction`) the driver handles the file I/O on its own
 ! the corresponding action (`PrintPreprocessedAction`)
-! RUN: cat %s | %flang -fc1 -test-io | FileCheck %s --check-prefix=IO --match-full-lines
-! RUN: cat %s | %flang -fc1 -DNEW -test-io | FileCheck %s --check-prefix=IO --match-full-lines
+! RUN: cat %s | %flang -fc1 -test-io -cpp | FileCheck %s --check-prefix=IO --match-full-lines
+! RUN: cat %s | %flang -fc1 -DNEW -cpp -test-io | FileCheck %s --check-prefix=IO --match-full-lines
 
 !-------------------------
 ! EXPECTED OUTPUT for `-E`
Index: flang/test/Driver/driver-help.f90
===================================================================
--- flang/test/Driver/driver-help.f90
+++ flang/test/Driver/driver-help.f90
@@ -19,6 +19,7 @@
 ! HELP-EMPTY:
 ! HELP-NEXT:OPTIONS:
 ! HELP-NEXT: -###                   Print (but do not run) the commands to run for this compilation
+! HELP-NEXT: -cpp                   Enable predefined and command line preprocessor macros
 ! HELP-NEXT: -c                     Only run preprocess, compile, and assemble steps
 ! HELP-NEXT: -D <macro>=<value>     Define <macro> to <value> (or 1 if <value> omitted)
 ! HELP-NEXT: -E                     Only run the preprocessor
@@ -46,6 +47,7 @@
 ! HELP-NEXT: -help                  Display available options
 ! HELP-NEXT: -I <dir>               Add directory to the end of the list of include search paths
 ! HELP-NEXT: -module-dir <dir>      Put MODULE files in <dir>
+! HELP-NEXT: -nocpp                 Disable predefined and command line preprocessor macros
 ! HELP-NEXT: -o <file>              Write output to <file>
 ! HELP-NEXT: -pedantic              Warn on language extensions
 ! HELP-NEXT: -std=<value>           Language standard to compile for
@@ -59,6 +61,7 @@
 ! HELP-FC1:USAGE: flang-new
 ! HELP-FC1-EMPTY:
 ! HELP-FC1-NEXT:OPTIONS:
+! HELP-FC1-NEXT: -cpp                   Enable predefined and command line preprocessor macros
 ! HELP-FC1-NEXT: -D <macro>=<value>     Define <macro> to <value> (or 1 if <value> omitted)
 ! HELP-FC1-NEXT: -emit-obj Emit native object files
 ! HELP-FC1-NEXT: -E                     Only run the preprocessor
@@ -97,6 +100,7 @@
 ! HELP-FC1-NEXT: -help                  Display available options
 ! HELP-FC1-NEXT: -I <dir>               Add directory to the end of the list of include search paths
 ! HELP-FC1-NEXT: -module-dir <dir>      Put MODULE files in <dir>
+! HELP-FC1-NEXT: -nocpp                 Disable predefined and command line preprocessor macros
 ! HELP-FC1-NEXT: -o <file>              Write output to <file>
 ! HELP-FC1-NEXT: -pedantic              Warn on language extensions
 ! HELP-FC1-NEXT: -std=<value>           Language standard to compile for
Index: flang/test/Driver/driver-help-hidden.f90
===================================================================
--- flang/test/Driver/driver-help-hidden.f90
+++ flang/test/Driver/driver-help-hidden.f90
@@ -19,6 +19,7 @@
 ! CHECK-EMPTY:
 ! CHECK-NEXT:OPTIONS:
 ! CHECK-NEXT: -###      Print (but do not run) the commands to run for this compilation
+! CHECK-NEXT: -cpp      Enable predefined and command line preprocessor macros
 ! CHECK-NEXT: -c        Only run preprocess, compile, and assemble steps
 ! CHECK-NEXT: -D <macro>=<value>     Define <macro> to <value> (or 1 if <value> omitted)
 ! CHECK-NEXT: -E        Only run the preprocessor
@@ -46,6 +47,7 @@
 ! CHECK-NEXT: -help     Display available options
 ! CHECK-NEXT: -I <dir>               Add directory to the end of the list of include search paths
 ! CHECK-NEXT: -module-dir <dir>      Put MODULE files in <dir>
+! CHECK-NEXT: -nocpp                 Disable predefined and command line preprocessor macros
 ! CHECK-NEXT: -o <file> Write output to <file>
 ! CHECK-NEXT: -pedantic              Warn on language extensions
 ! CHECK-NEXT: -std=<value>           Language standard to compile for
Index: flang/test/Driver/cpp-nocpp-predefined-macro.F90
===================================================================
--- /dev/null
+++ flang/test/Driver/cpp-nocpp-predefined-macro.F90
@@ -0,0 +1,18 @@
+!-----------
+! RUN lines
+!-----------
+! RUN: %flang_fc1 -E %s 2>&1 | FileCheck %s --check-prefix=DEFINED
+! RUN: %flang_fc1 -E -cpp %s 2>&1 | FileCheck %s --check-prefix=DEFINED
+! RUN: %flang_fc1 -E -nocpp %s 2>&1 | FileCheck %s --check-prefix=NOT_DEFINED
+
+!-----------------
+! EXPECTED OUTPUT
+!-----------------
+! DEFINED: flang = 1
+! DEFINED-NEXT: flang_major = {{[1-9][0-9]*$}}
+
+! NOT_DEFINED: flang = __flang__
+! NOT_DEFINED-NEXT: flang_major = __flang_major__
+
+integer, parameter :: flang = __flang__
+integer, parameter :: flang_major = __flang_major__
Index: flang/test/Driver/cpp-nocpp-command-line-macro.f90
===================================================================
--- /dev/null
+++ flang/test/Driver/cpp-nocpp-command-line-macro.f90
@@ -0,0 +1,22 @@
+!-----------
+! RUN lines
+!-----------
+! RUN: %flang_fc1 -E %s 2>&1 | FileCheck %s --check-prefix=UNDEFINED
+! RUN: %flang_fc1 -E -cpp -DX=A %s 2>&1 | FileCheck %s --check-prefix=DEFINED
+! RUN: %flang_fc1 -E -nocpp -DX=A %s 2>&1 | FileCheck %s --check-prefix=UNDEFINED
+
+!-----------------
+! EXPECTED OUTPUT 
+!-----------------
+! UNDEFINED:program b
+! UNDEFINED-NOT:program a
+
+! DEFINED:program a
+! DEFINED-NOT:program b
+
+#ifdef X
+program X
+#else
+program B
+#endif
+end
Index: flang/lib/Frontend/FrontendOptions.cpp
===================================================================
--- flang/lib/Frontend/FrontendOptions.cpp
+++ flang/lib/Frontend/FrontendOptions.cpp
@@ -26,6 +26,12 @@
       suffix == "f08" || suffix == "F08" || suffix == "f18" || suffix == "F18";
 }
 
+bool Fortran::frontend::mustBePreprocessed(llvm::StringRef suffix) {
+  return suffix == "F" || suffix == "FOR" || suffix == "fpp" ||
+      suffix == "FPP" || suffix == "F90" || suffix == "F95" ||
+      suffix == "F03" || suffix == "F08" || suffix == "F18";
+}
+
 // TODO: This is a copy of `asFortran` from f18.cpp and is added here for
 // compatiblity. It doesn't really belong here, but I couldn't find a better
 // place. We should decide whether to add it to the Evaluate or Parse/Unparse
Index: flang/lib/Frontend/FrontendActions.cpp
===================================================================
--- flang/lib/Frontend/FrontendActions.cpp
+++ flang/lib/Frontend/FrontendActions.cpp
@@ -10,6 +10,7 @@
 #include "flang/Common/default-kinds.h"
 #include "flang/Frontend/CompilerInstance.h"
 #include "flang/Frontend/FrontendOptions.h"
+#include "flang/Frontend/PreprocessorOptions.h"
 #include "flang/Lower/PFTBuilder.h"
 #include "flang/Parser/dump-parse-tree.h"
 #include "flang/Parser/parsing.h"
@@ -45,21 +46,9 @@
 
 bool PrescanAction::BeginSourceFileAction(CompilerInstance &c1) {
   CompilerInstance &ci = this->instance();
-
   std::string currentInputPath{GetCurrentFileOrBufferName()};
-
   Fortran::parser::Options parserOptions = ci.invocation().fortranOpts();
 
-  if (ci.invocation().frontendOpts().fortranForm_ == FortranForm::Unknown) {
-    // Switch between fixed and free form format based on the input file
-    // extension.
-    //
-    // Ideally we should have all Fortran options set before entering this
-    // method (i.e. before processing any specific input files). However, we
-    // can't decide between fixed and free form based on the file extension
-    // earlier than this.
-    parserOptions.isFixedForm = currentInput().IsFixedForm();
-  }
 
   // Prescan. In case of failure, report and return.
   ci.parsing().Prescan(currentInputPath, parserOptions);
@@ -78,22 +67,9 @@
 
 bool PrescanAndSemaAction::BeginSourceFileAction(CompilerInstance &c1) {
   CompilerInstance &ci = this->instance();
-
   std::string currentInputPath{GetCurrentFileOrBufferName()};
-
   Fortran::parser::Options parserOptions = ci.invocation().fortranOpts();
 
-  if (ci.invocation().frontendOpts().fortranForm_ == FortranForm::Unknown) {
-    // Switch between fixed and free form format based on the input file
-    // extension.
-    //
-    // Ideally we should have all Fortran options set before entering this
-    // method (i.e. before processing any specific input files). However, we
-    // can't decide between fixed and free form based on the file extension
-    // earlier than this.
-    parserOptions.isFixedForm = currentInput().IsFixedForm();
-  }
-
   // Prescan. In case of failure, report and return.
   ci.parsing().Prescan(currentInputPath, parserOptions);
 
Index: flang/lib/Frontend/FrontendAction.cpp
===================================================================
--- flang/lib/Frontend/FrontendAction.cpp
+++ flang/lib/Frontend/FrontendAction.cpp
@@ -67,6 +67,25 @@
     return false;
   }
 
+  auto &invoc = ci.invocation();
+
+  // Include command-line and predefined preprocessor macros. Use either:
+  //  * `-cpp/-nocpp`, or
+  //  * the file extension (if the user didn't express any preference)
+  // to decide whether to include them or not.
+  if ((invoc.preprocessorOpts().predefs_ == StdMacroPredefs::Include) ||
+      (invoc.preprocessorOpts().predefs_ == StdMacroPredefs::Unknown &&
+          currentInput().MustBePreprocessed())) {
+    invoc.setDefaultPredefinitions();
+    invoc.collectMacroDefinitions();
+  }
+
+  // Decide between fixed and free form (if the user didn't express any
+  // preference, use the file extension to decide)
+  if (invoc.frontendOpts().fortranForm_ == FortranForm::Unknown) {
+    invoc.fortranOpts().isFixedForm = currentInput().IsFixedForm();
+  }
+
   if (!BeginSourceFileAction(ci)) {
     BeginSourceFileCleanUp(*this, ci);
     return false;
Index: flang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- flang/lib/Frontend/CompilerInvocation.cpp
+++ flang/lib/Frontend/CompilerInvocation.cpp
@@ -323,6 +323,14 @@
   for (const auto *currentArg :
       args.filtered(clang::driver::options::OPT_fintrinsic_modules_path))
     opts.searchDirectoriesFromIntrModPath.emplace_back(currentArg->getValue());
+
+  // -cpp/-nocpp
+  if (const auto *currentArg = args.getLastArg(
+          clang::driver::options::OPT_cpp, clang::driver::options::OPT_nocpp))
+    opts.predefs_ =
+        (currentArg->getOption().matches(clang::driver::options::OPT_cpp))
+        ? StdMacroPredefs::Include
+        : StdMacroPredefs::Exclude;
 }
 
 /// Parses all semantic related arguments and populates the variables
@@ -449,13 +457,9 @@
   return success;
 }
 
-/// Collect the macro definitions provided by the given preprocessor
-/// options into the parser options.
-///
-/// \param [in] ppOpts The preprocessor options
-/// \param [out] opts The fortran options
-static void collectMacroDefinitions(
-    const PreprocessorOptions &ppOpts, Fortran::parser::Options &opts) {
+void CompilerInvocation::collectMacroDefinitions() {
+  auto &ppOpts = this->preprocessorOpts();
+
   for (unsigned i = 0, n = ppOpts.macros.size(); i != n; ++i) {
     llvm::StringRef macro = ppOpts.macros[i].first;
     bool isUndef = ppOpts.macros[i].second;
@@ -466,7 +470,7 @@
 
     // For an #undef'd macro, we only care about the name.
     if (isUndef) {
-      opts.predefinitions.emplace_back(
+      parserOpts_.predefinitions.emplace_back(
           macroName.str(), std::optional<std::string>{});
       continue;
     }
@@ -479,7 +483,7 @@
       llvm::StringRef::size_type End = macroBody.find_first_of("\n\r");
       macroBody = macroBody.substr(0, End);
     }
-    opts.predefinitions.emplace_back(
+    parserOpts_.predefinitions.emplace_back(
         macroName, std::optional<std::string>(macroBody.str()));
   }
 }
@@ -535,8 +539,6 @@
   fortranOptions.features = frontendOptions.features_;
   fortranOptions.encoding = frontendOptions.encoding_;
 
-  collectMacroDefinitions(preprocessorOptions, fortranOptions);
-
   // Adding search directories specified by -I
   fortranOptions.searchDirectories.insert(
       fortranOptions.searchDirectories.end(),
Index: flang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- flang/lib/Frontend/CompilerInstance.cpp
+++ flang/lib/Frontend/CompilerInstance.cpp
@@ -142,7 +142,6 @@
 
   // Set some sane defaults for the frontend.
   invoc.SetDefaultFortranOpts();
-  invoc.setDefaultPredefinitions();
   // Update the fortran options based on user-based input.
   invoc.setFortranOpts();
   // Set the encoding to read all input files in based on user input.
Index: flang/include/flang/Frontend/PreprocessorOptions.h
===================================================================
--- flang/include/flang/Frontend/PreprocessorOptions.h
+++ flang/include/flang/Frontend/PreprocessorOptions.h
@@ -19,6 +19,15 @@
 
 namespace Fortran::frontend {
 
+/// Communicates whether to include/exclude standard macro predefinitions
+enum class StdMacroPredefs : uint8_t {
+  /// Use the file extension to decide
+  Unknown,
+
+  Include,
+  Exclude
+};
+
 /// This class is used for passing the various options used
 /// in preprocessor initialization to the parser options.
 class PreprocessorOptions {
@@ -32,6 +41,8 @@
   // Search directories specified by the user with -fintrinsic-modules-path
   std::vector<std::string> searchDirectoriesFromIntrModPath;
 
+  StdMacroPredefs predefs_ = StdMacroPredefs::Unknown;
+
 public:
   PreprocessorOptions() {}
 
Index: flang/include/flang/Frontend/FrontendOptions.h
===================================================================
--- flang/include/flang/Frontend/FrontendOptions.h
+++ flang/include/flang/Frontend/FrontendOptions.h
@@ -79,6 +79,10 @@
 /// \return True if the file extension should be processed as free form
 bool isFreeFormSuffix(llvm::StringRef suffix);
 
+/// \param suffix The file extension
+/// \return True if the file should be preprocessed
+bool mustBePreprocessed(llvm::StringRef suffix);
+
 enum class Language : uint8_t {
   Unknown,
 
@@ -137,6 +141,12 @@
   /// stdin this is never modified.
   bool isFixedForm_ = false;
 
+  /// Must this file be preprocessed? Note that in Flang the preprocessor is
+  /// always run. This flag is used to control whether macro standard
+  /// predefinitions are added or not. In practice, this is sufficient to
+  /// implment gfortran`s logic controlled with `-cpp/-nocpp` flags.
+  unsigned mustBePreprocessed_ : 1;
+
 public:
   FrontendInputFile() = default;
   FrontendInputFile(llvm::StringRef file, InputKind kind)
@@ -147,7 +157,9 @@
     auto pathDotIndex{file.rfind(".")};
     std::string pathSuffix{file.substr(pathDotIndex + 1)};
     isFixedForm_ = isFixedFormSuffix(pathSuffix);
+    mustBePreprocessed_ = mustBePreprocessed(pathSuffix);
   }
+
   FrontendInputFile(const llvm::MemoryBuffer *buffer, InputKind kind)
       : buffer_(buffer), kind_(kind) {}
 
@@ -157,6 +169,7 @@
   bool IsFile() const { return !IsBuffer(); }
   bool IsBuffer() const { return buffer_ != nullptr; }
   bool IsFixedForm() const { return isFixedForm_; }
+  bool MustBePreprocessed() const { return mustBePreprocessed_; }
 
   llvm::StringRef file() const {
     assert(IsFile());
Index: flang/include/flang/Frontend/CompilerInvocation.h
===================================================================
--- flang/include/flang/Frontend/CompilerInvocation.h
+++ flang/include/flang/Frontend/CompilerInvocation.h
@@ -136,12 +136,22 @@
   /// Set the default predefinitions.
   void setDefaultPredefinitions();
 
+  /// Collect the macro definitions provided by the given preprocessor
+  /// options into the parser options.
+  ///
+  /// \param [in] ppOpts The preprocessor options
+  void collectMacroDefinitions();
+
   /// Set the Fortran options to user-specified values.
   /// These values are found in the preprocessor options.
   void setFortranOpts();
 
   /// Set the Semantic Options
   void setSemanticsOpts(Fortran::parser::AllCookedSources &);
+
+  /// Updates this instance based on the extension of the input file (e.g. f90
+  /// s F90)
+  void updateBasedOnExtension(const FrontendInputFile &inputFile);
 };
 
 } // end namespace Fortran::frontend
Index: clang/lib/Driver/ToolChains/Flang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Flang.cpp
+++ clang/lib/Driver/ToolChains/Flang.cpp
@@ -37,7 +37,8 @@
 
 void Flang::AddPreprocessingOptions(const ArgList &Args,
                                     ArgStringList &CmdArgs) const {
-  Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
+  Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I,
+                            options::OPT_cpp, options::OPT_nocpp});
 }
 
 void Flang::AddOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4222,8 +4222,6 @@
 
 // Generic gfortran options.
 def A_DASH : Joined<["-"], "A-">, Group<gfortran_Group>;
-def cpp : Flag<["-"], "cpp">, Group<gfortran_Group>;
-def nocpp : Flag<["-"], "nocpp">, Group<gfortran_Group>;
 def static_libgfortran : Flag<["-"], "static-libgfortran">, Group<gfortran_Group>;
 
 // "f" options with values for gfortran.
@@ -4303,6 +4301,10 @@
 //===----------------------------------------------------------------------===//
 let Flags = [FC1Option, FlangOption, FlangOnlyOption] in {
 
+def cpp : Flag<["-"], "cpp">, Group<f_Group>,
+  HelpText<"Enable predefined and command line preprocessor macros">;
+def nocpp : Flag<["-"], "nocpp">, Group<f_Group>,
+  HelpText<"Disable predefined and command line preprocessor macros">;
 def module_dir : Separate<["-"], "module-dir">, MetaVarName<"<dir>">,
   HelpText<"Put MODULE files in <dir>">,
   DocBrief<[{This option specifies where to put .mod files for compiled modules.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to