This revision was automatically updated to reflect the committed changes.
Closed by commit rG985a42fdf8ae: [flang][driver] Add support for 
`-J/-module-dir` (authored by arnamoy10, committed by awarzynski).

Changed prior to commit:
  https://reviews.llvm.org/D95448?vs=320617&id=321448#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95448

Files:
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Flang.cpp
  clang/lib/Driver/ToolChains/Flang.h
  flang/include/flang/Frontend/CompilerInstance.h
  flang/include/flang/Frontend/CompilerInvocation.h
  flang/lib/Frontend/CompilerInstance.cpp
  flang/lib/Frontend/CompilerInvocation.cpp
  flang/lib/Frontend/FrontendActions.cpp
  flang/test/Flang-Driver/driver-help-hidden.f90
  flang/test/Flang-Driver/driver-help.f90
  flang/test/Flang-Driver/include-module.f90
  flang/test/Flang-Driver/write-module.f90

Index: flang/test/Flang-Driver/write-module.f90
===================================================================
--- /dev/null
+++ flang/test/Flang-Driver/write-module.f90
@@ -0,0 +1,10 @@
+! RUN: mkdir -p %t/dir-f18 && %f18 -fparse-only -I tools/flang/include/flang -module %t/dir-f18 %s  2>&1
+! RUN: ls %t/dir-f18/testmodule.mod && not ls %t/testmodule.mod
+
+! RUN: mkdir -p %t/dir-flang-new && %flang-new -fsyntax-only -module-dir %t/dir-flang-new %s  2>&1
+! RUN: ls %t/dir-flang-new/testmodule.mod && not ls %t/testmodule.mod
+
+module testmodule
+  type::t2
+  end type
+end
Index: flang/test/Flang-Driver/include-module.f90
===================================================================
--- flang/test/Flang-Driver/include-module.f90
+++ flang/test/Flang-Driver/include-module.f90
@@ -7,12 +7,26 @@
 !--------------------------
 ! RUN: not %flang-new -fsyntax-only -I %S/Inputs -I %S/Inputs/module-dir %s  2>&1 | FileCheck %s --check-prefix=INCLUDED
 ! RUN: not %flang-new -fsyntax-only -I %S/Inputs %s  2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE
+! RUN: not %flang-new -fsyntax-only -I %S/Inputs -J %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED
+! RUN: not %flang-new -fsyntax-only -J %S/Inputs %s  2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE
+! RUN: not %flang-new -fsyntax-only -I %S/Inputs -module-dir %S/Inputs/module-dir %s  2>&1 | FileCheck %s --check-prefix=INCLUDED
+! RUN: not %flang-new -fsyntax-only -module-dir %S/Inputs %s  2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE
+! RUN: not %flang-new -fsyntax-only -J %S/Inputs/module-dir -J %S/Inputs/ %s  2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE
+! RUN: not %flang-new -fsyntax-only -J %S/Inputs/module-dir -module-dir %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE
+! RUN: not %flang-new -fsyntax-only -module-dir %S/Inputs/module-dir -J%S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE
 
 !-----------------------------------------
 ! FRONTEND FLANG DRIVER (flang-new -fc1)
 !-----------------------------------------
 ! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs -I %S/Inputs/module-dir %s  2>&1 | FileCheck %s --check-prefix=INCLUDED
 ! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs %s  2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE
+! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs -J %S/Inputs/module-dir %s 2>&1 | FileCheck %s --check-prefix=INCLUDED
+! RUN: not %flang-new -fc1 -fsyntax-only -J %S/Inputs %s  2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE
+! RUN: not %flang-new -fc1 -fsyntax-only -I %S/Inputs -module-dir %S/Inputs/module-dir %s  2>&1 | FileCheck %s --check-prefix=INCLUDED
+! RUN: not %flang-new -fc1 -fsyntax-only -module-dir %S/Inputs %s  2>&1 | FileCheck %s --check-prefix=SINGLEINCLUDE
+! RUN: not %flang-new -fc1 -fsyntax-only -J %S/Inputs/module-dir -J %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE
+! RUN: not %flang-new -fc1 -fsyntax-only -J %S/Inputs/module-dir -module-dir %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE
+! RUN: not %flang-new -fc1 -fsyntax-only -module-dir %S/Inputs/module-dir -J%S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=DOUBLEINCLUDE
 
 !-----------------------------------------
 ! EXPECTED OUTPUT FOR MISSING MODULE FILE
@@ -22,6 +36,11 @@
 ! SINGLEINCLUDE-NOT:error: Derived type 't1' not found
 ! SINGLEINCLUDE:error: Derived type 't2' not found
 
+!-----------------------------------------
+! EXPECTED OUTPUT FOR MISSING MODULE FILE
+!-----------------------------------------
+! DOUBLEINCLUDE:error: Only one '-module-dir/-J' option allowed
+
 !---------------------------------------
 ! EXPECTED OUTPUT FOR ALL MODULES FOUND
 !---------------------------------------
Index: flang/test/Flang-Driver/driver-help.f90
===================================================================
--- flang/test/Flang-Driver/driver-help.f90
+++ flang/test/Flang-Driver/driver-help.f90
@@ -30,6 +30,7 @@
 ! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics
 ! 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: -o <file>              Write output to <file>
 ! HELP-NEXT: -U <macro>             Undefine macro <macro>
 ! HELP-NEXT: --version              Print version information
@@ -49,6 +50,7 @@
 ! HELP-FC1-NEXT: -ffree-form            Process source files in free form
 ! 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: -o <file>              Write output to <file>
 ! HELP-FC1-NEXT: -U <macro>             Undefine macro <macro>
 ! HELP-FC1-NEXT: --version              Print version information
Index: flang/test/Flang-Driver/driver-help-hidden.f90
===================================================================
--- flang/test/Flang-Driver/driver-help-hidden.f90
+++ flang/test/Flang-Driver/driver-help-hidden.f90
@@ -30,6 +30,7 @@
 ! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics
 ! 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: -o <file> Write output to <file>
 ! CHECK-NEXT: -test-io  Run the InputOuputTest action. Use for development and testing only.
 ! CHECK-NEXT: -U <macro>             Undefine macro <macro>
Index: flang/lib/Frontend/FrontendActions.cpp
===================================================================
--- flang/lib/Frontend/FrontendActions.cpp
+++ flang/lib/Frontend/FrontendActions.cpp
@@ -109,10 +109,6 @@
 void ParseSyntaxOnlyAction::ExecuteAction() {
   CompilerInstance &ci = this->instance();
 
-  // TODO: These should be specifiable by users. For now just use the defaults.
-  common::LanguageFeatureControl features;
-  Fortran::common::IntrinsicTypeDefaultKinds defaultKinds;
-
   // Parse. In case of failure, report and return.
   ci.parsing().Parse(llvm::outs());
 
@@ -132,10 +128,8 @@
   auto &parseTree{*ci.parsing().parseTree()};
 
   // Prepare semantics
-  Fortran::semantics::SemanticsContext semanticsContext{
-      defaultKinds, features, ci.allCookedSources()};
   Fortran::semantics::Semantics semantics{
-      semanticsContext, parseTree, ci.parsing().cooked().AsCharBlock()};
+      ci.semanticsContext(), parseTree, ci.parsing().cooked().AsCharBlock()};
 
   // Run semantic checks
   semantics.Perform();
Index: flang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- flang/lib/Frontend/CompilerInvocation.cpp
+++ flang/lib/Frontend/CompilerInvocation.cpp
@@ -221,6 +221,25 @@
     opts.searchDirectoriesFromDashI.emplace_back(currentArg->getValue());
 }
 
+/// Parses all semantic related arguments and populates the variables
+/// options accordingly.
+static void parseSemaArgs(std::string &moduleDir, llvm::opt::ArgList &args,
+    clang::DiagnosticsEngine &diags) {
+
+  auto moduleDirList =
+      args.getAllArgValues(clang::driver::options::OPT_module_dir);
+  // User can only specify -J/-module-dir once
+  // https://gcc.gnu.org/onlinedocs/gfortran/Directory-Options.html
+  if (moduleDirList.size() > 1) {
+    const unsigned diagID =
+        diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
+            "Only one '-module-dir/-J' option allowed");
+    diags.Report(diagID);
+  }
+  if (moduleDirList.size() == 1)
+    moduleDir = moduleDirList[0];
+}
+
 bool CompilerInvocation::CreateFromArgs(CompilerInvocation &res,
     llvm::ArrayRef<const char *> commandLineArgs,
     clang::DiagnosticsEngine &diags) {
@@ -250,6 +269,8 @@
   ParseFrontendArgs(res.frontendOpts(), args, diags);
   // Parse the preprocessor args
   parsePreprocessorArgs(res.preprocessorOpts(), args);
+  // Parse semantic args
+  parseSemaArgs(res.moduleDir(), args, diags);
 
   return success;
 }
@@ -314,6 +335,7 @@
   auto &fortranOptions = fortranOpts();
   const auto &frontendOptions = frontendOpts();
   const auto &preprocessorOptions = preprocessorOpts();
+  auto &moduleDirJ = moduleDir();
 
   if (frontendOptions.fortranForm_ != FortranForm::Unknown) {
     fortranOptions.isFixedForm =
@@ -327,4 +349,18 @@
       fortranOptions.searchDirectories.end(),
       preprocessorOptions.searchDirectoriesFromDashI.begin(),
       preprocessorOptions.searchDirectoriesFromDashI.end());
+
+  // Add the directory supplied through -J/-module-dir to the list of search
+  // directories
+  if (moduleDirJ.compare(".") != 0)
+    fortranOptions.searchDirectories.emplace_back(moduleDirJ);
+}
+
+void CompilerInvocation::setSemanticsOpts(
+    Fortran::semantics::SemanticsContext &semaCtxt) {
+  auto &fortranOptions = fortranOpts();
+  auto &moduleDirJ = moduleDir();
+  semaCtxt.set_moduleDirectory(moduleDirJ)
+      .set_searchDirectories(fortranOptions.searchDirectories);
+  return;
 }
Index: flang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- flang/lib/Frontend/CompilerInstance.cpp
+++ flang/lib/Frontend/CompilerInstance.cpp
@@ -24,8 +24,10 @@
     : invocation_(new CompilerInvocation()),
       allSources_(new Fortran::parser::AllSources()),
       allCookedSources_(new Fortran::parser::AllCookedSources(*allSources_)),
-      parsing_(new Fortran::parser::Parsing(*allCookedSources_)) {
-
+      parsing_(new Fortran::parser::Parsing(*allCookedSources_)),
+      semanticsContext_(new Fortran::semantics::SemanticsContext(
+          *(new Fortran::common::IntrinsicTypeDefaultKinds()),
+          *(new common::LanguageFeatureControl()), *allCookedSources_)) {
   // TODO: This is a good default during development, but ultimately we should
   // give the user the opportunity to specify this.
   allSources_->set_encoding(Fortran::parser::Encoding::UTF_8);
@@ -144,6 +146,8 @@
   invoc.SetDefaultFortranOpts();
   // Update the fortran options based on user-based input.
   invoc.setFortranOpts();
+  // Set semantic options
+  invoc.setSemanticsOpts(this->semanticsContext());
 
   // Run the frontend action `act` for every input file.
   for (const FrontendInputFile &fif : frontendOpts().inputs_) {
Index: flang/include/flang/Frontend/CompilerInvocation.h
===================================================================
--- flang/include/flang/Frontend/CompilerInvocation.h
+++ flang/include/flang/Frontend/CompilerInvocation.h
@@ -11,6 +11,7 @@
 #include "flang/Frontend/FrontendOptions.h"
 #include "flang/Frontend/PreprocessorOptions.h"
 #include "flang/Parser/parsing.h"
+#include "flang/Semantics/semantics.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "llvm/Option/ArgList.h"
@@ -60,6 +61,11 @@
   // of options.
   Fortran::parser::Options parserOpts_;
 
+  /// Semantic options
+  // TODO: Merge with or translate to frontendOpts_. We shouldn't need two sets
+  // of options.
+  std::string moduleDir_ = ".";
+
 public:
   CompilerInvocation() = default;
 
@@ -69,6 +75,9 @@
   Fortran::parser::Options &fortranOpts() { return parserOpts_; }
   const Fortran::parser::Options &fortranOpts() const { return parserOpts_; }
 
+  std::string &moduleDir() { return moduleDir_; }
+  const std::string &moduleDir() const { return moduleDir_; }
+
   /// Create a compiler invocation from a list of input options.
   /// \returns true on success.
   /// \returns false if an error was encountered while parsing the arguments
@@ -87,6 +96,9 @@
   /// 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::semantics::SemanticsContext &);
 };
 
 } // end namespace Fortran::frontend
Index: flang/include/flang/Frontend/CompilerInstance.h
===================================================================
--- flang/include/flang/Frontend/CompilerInstance.h
+++ flang/include/flang/Frontend/CompilerInstance.h
@@ -30,6 +30,8 @@
 
   std::shared_ptr<Fortran::parser::Parsing> parsing_;
 
+  std::unique_ptr<Fortran::semantics::SemanticsContext> semanticsContext_;
+
   /// The stream for diagnostics from Semantics
   llvm::raw_ostream *semaOutputStream_ = &llvm::errs();
 
@@ -100,6 +102,9 @@
   /// }
   /// @name Semantic analysis
   /// {
+  Fortran::semantics::SemanticsContext &semanticsContext() const {
+    return *semanticsContext_;
+  }
 
   /// Replace the current stream for verbose output.
   void set_semaOutputStream(llvm::raw_ostream &Value);
Index: clang/lib/Driver/ToolChains/Flang.h
===================================================================
--- clang/lib/Driver/ToolChains/Flang.h
+++ clang/lib/Driver/ToolChains/Flang.h
@@ -39,6 +39,13 @@
   /// \param [out] CmdArgs The list of output command arguments
   void AddPreprocessingOptions(const llvm::opt::ArgList &Args,
                                llvm::opt::ArgStringList &CmdArgs) const;
+  /// Extract other compilation options from the driver arguments and add them
+  /// to the command arguments.
+  ///
+  /// \param [in] Args The list of input driver arguments
+  /// \param [out] CmdArgs The list of output command arguments
+  void AddOtherOptions(const llvm::opt::ArgList &Args,
+                       llvm::opt::ArgStringList &CmdArgs) const;
 
 public:
   Flang(const ToolChain &TC);
Index: clang/lib/Driver/ToolChains/Flang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Flang.cpp
+++ clang/lib/Driver/ToolChains/Flang.cpp
@@ -30,6 +30,10 @@
   Args.AddAllArgs(CmdArgs, {options::OPT_D, options::OPT_U, options::OPT_I});
 }
 
+void Flang::AddOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
+  Args.AddAllArgs(CmdArgs, options::OPT_module_dir);
+}
+
 void Flang::ConstructJob(Compilation &C, const JobAction &JA,
                          const InputInfo &Output, const InputInfoList &Inputs,
                          const ArgList &Args, const char *LinkingOutput) const {
@@ -87,6 +91,9 @@
 
   AddFortranDialectOptions(Args, CmdArgs);
 
+  // Add other compile options
+  AddOtherOptions(Args, CmdArgs);
+
   if (Output.isFilename()) {
     CmdArgs.push_back("-o");
     CmdArgs.push_back(Output.getFilename());
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -949,6 +949,11 @@
 def module_dependency_dir : Separate<["-"], "module-dependency-dir">,
   Flags<[CC1Option]>, HelpText<"Directory to dump module dependencies to">,
   MarshallingInfoString<DependencyOutputOpts<"ModuleDependencyOutputDir">>;
+def module_dir : Separate<["-"], "module-dir">, Flags<[FlangOption,FC1Option]>, MetaVarName<"<dir>">,
+  HelpText<"Put MODULE files in <dir>">,
+  DocBrief<[{This option specifies where to put .mod files for compiled modules.
+It is also added to the list of directories to be searched by an USE statement.
+The default is the current directory.}]>;
 def dsym_dir : JoinedOrSeparate<["-"], "dsym-dir">,
   Flags<[NoXarchOption, RenderAsInput]>,
   HelpText<"Directory to output dSYM's (if any) to">, MetaVarName<"<dir>">;
@@ -4121,7 +4126,7 @@
 
 // Generic gfortran options.
 def A_DASH : Joined<["-"], "A-">, Group<gfortran_Group>;
-def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined]>, Group<gfortran_Group>;
+def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined,FlangOption,FC1Option]>, Group<gfortran_Group>, Alias<module_dir>;
 def cpp : Flag<["-"], "cpp">, Group<gfortran_Group>;
 def nocpp : Flag<["-"], "nocpp">, Group<gfortran_Group>;
 def static_libgfortran : Flag<["-"], "static-libgfortran">, Group<gfortran_Group>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to