arnamoy10 updated this revision to Diff 320617.
arnamoy10 added a comment.

A few more comments addressed and a new test case added for write-module check.


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
@@ -26,6 +26,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
@@ -41,6 +42,7 @@
 ! HELP-FC1-NEXT: -E                     Only run the preprocessor
 ! 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
@@ -26,6 +26,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
@@ -78,8 +78,8 @@
   CompilerInstance &ci = this->instance();
 
   // TODO: These should be specifiable by users. For now just use the defaults.
-  common::LanguageFeatureControl features;
-  Fortran::common::IntrinsicTypeDefaultKinds defaultKinds;
+  // common::LanguageFeatureControl features;
+  // Fortran::common::IntrinsicTypeDefaultKinds defaultKinds;
 
   // Parse. In case of failure, report and return.
   ci.parsing().Parse(llvm::outs());
@@ -100,10 +100,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
@@ -183,6 +183,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) {
+  
+  //for (const auto *currentArg : args.filtered(clang::driver::options::OPT_module_dir))  
+  //	    moduleDir = currentArg->getValue();
+  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) {
@@ -212,6 +231,8 @@
   ParseFrontendArgs(res.frontendOpts(), args, diags);
   // Parse the preprocessor args
   parsePreprocessorArgs(res.preprocessorOpts(), args);
+  // Parse semantic args
+  parseSemaArgs(res.moduleDir(),args, diags);
 
   return success;
 }
@@ -275,6 +296,7 @@
 void CompilerInvocation::setFortranOpts() {
   auto &fortranOptions = fortranOpts();
   const auto &preprocessorOptions = preprocessorOpts();
+  auto &moduleDirJ = moduleDir();
 
   collectMacroDefinitions(preprocessorOptions, fortranOptions);
 
@@ -282,4 +304,16 @@
       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,9 @@
     : 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 +145,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,7 @@
   /// }
   /// @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
@@ -31,7 +31,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);
   ~Flang() override;
Index: clang/lib/Driver/ToolChains/Flang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Flang.cpp
+++ clang/lib/Driver/ToolChains/Flang.cpp
@@ -24,6 +24,11 @@
   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 {
@@ -79,6 +84,9 @@
   if (types::getPreprocessedType(InputType) != types::TY_INVALID)
     AddPreprocessingOptions(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
@@ -944,6 +944,7 @@
 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>">;
@@ -4120,7 +4121,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