[flang-commits] [flang] dcbfabb - [flang] Be more persistent in search for non-intrinsic module file

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Aug 18 15:10:23 PDT 2022


Author: Peter Klausler
Date: 2022-08-18T15:05:05-07:00
New Revision: dcbfabbeb5e3c185734a88ca49a07a6d5354a248

URL: https://github.com/llvm/llvm-project/commit/dcbfabbeb5e3c185734a88ca49a07a6d5354a248
DIFF: https://github.com/llvm/llvm-project/commit/dcbfabbeb5e3c185734a88ca49a07a6d5354a248.diff

LOG: [flang] Be more persistent in search for non-intrinsic module file

When a particular module name has been brought into a compilation
as an intrinsic module via USE,INTRINSIC, perhaps indirectly via
an enclosing USE statement, f18 will resolve later USE statements
to it unless they are USE,NON_INTRINSIC.  This is not entirely
correct -- a bare USE statement for a module name that happens to
match that of an intrinsic module should still search the search
paths for a non-intrinsic module file of the same name.

Differential Revision: https://reviews.llvm.org/D132163

Added: 
    

Modified: 
    flang/lib/Semantics/mod-file.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/mod-file.cpp b/flang/lib/Semantics/mod-file.cpp
index 0be0e961f349..504ec4e78cb5 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -928,49 +928,64 @@ Scope *ModFileReader::Read(const SourceName &name,
       return scope;
     }
     ancestorName = ancestor->GetName().value().ToString();
-  } else {
-    if (!isIntrinsic.value_or(false)) {
-      auto it{context_.globalScope().find(name)};
-      if (it != context_.globalScope().end()) {
-        Scope *scope{it->second->scope()};
-        if (scope->kind() == Scope::Kind::Module) {
-          return scope;
-        } else {
-          notAModule = scope->symbol();
-          // USE, NON_INTRINSIC global name isn't a module?
-          fatalError = isIntrinsic.has_value();
-        }
-      }
-    }
-    if (isIntrinsic.value_or(true)) {
-      auto it{context_.intrinsicModulesScope().find(name)};
-      if (it != context_.intrinsicModulesScope().end()) {
-        return it->second->scope();
+  }
+  if (!isIntrinsic.value_or(false) && !ancestor) {
+    // Already present in the symbol table as a usable non-intrinsic module?
+    auto it{context_.globalScope().find(name)};
+    if (it != context_.globalScope().end()) {
+      Scope *scope{it->second->scope()};
+      if (scope->kind() == Scope::Kind::Module) {
+        return scope;
+      } else {
+        notAModule = scope->symbol();
+        // USE, NON_INTRINSIC global name isn't a module?
+        fatalError = isIntrinsic.has_value();
       }
     }
   }
+  auto path{ModFileName(name, ancestorName, context_.moduleFileSuffix())};
   parser::Parsing parsing{context_.allCookedSources()};
   parser::Options options;
   options.isModuleFile = true;
   options.features.Enable(common::LanguageFeature::BackslashEscapes);
   options.features.Enable(common::LanguageFeature::OpenMP);
   if (!isIntrinsic.value_or(false) && !notAModule) {
-    // Scan non-intrinsic module directories
+    // The search for this module file will scan non-intrinsic module
+    // directories.  If a directory is in both the intrinsic and non-intrinsic
+    // directory lists, the intrinsic module directory takes precedence.
     options.searchDirectories = context_.searchDirectories();
-    // If a directory is in both lists, the intrinsic module directory
-    // takes precedence.
     for (const auto &dir : context_.intrinsicModuleDirectories()) {
       std::remove(options.searchDirectories.begin(),
           options.searchDirectories.end(), dir);
     }
     options.searchDirectories.insert(options.searchDirectories.begin(), "."s);
   }
+  bool foundNonIntrinsicModuleFile{false};
+  if (!isIntrinsic) {
+    std::list<std::string> searchDirs;
+    for (const auto &d : options.searchDirectories) {
+      searchDirs.push_back(d);
+    }
+    foundNonIntrinsicModuleFile =
+        parser::LocateSourceFile(path, searchDirs).has_value();
+  }
+  if (isIntrinsic.value_or(!foundNonIntrinsicModuleFile)) {
+    // Explicitly intrinsic, or not specified and not found in the search
+    // path; see whether it's already in the symbol table as an intrinsic
+    // module.
+    auto it{context_.intrinsicModulesScope().find(name)};
+    if (it != context_.intrinsicModulesScope().end()) {
+      return it->second->scope();
+    }
+  }
+  // We don't have this module in the symbol table yet.
+  // Find its module file and parse it.  Define or extend the search
+  // path with intrinsic module directories, if appropriate.
   if (isIntrinsic.value_or(true)) {
     for (const auto &dir : context_.intrinsicModuleDirectories()) {
       options.searchDirectories.push_back(dir);
     }
   }
-  auto path{ModFileName(name, ancestorName, context_.moduleFileSuffix())};
   const auto *sourceFile{fatalError ? nullptr : parsing.Prescan(path, options)};
   if (fatalError || parsing.messages().AnyFatalError()) {
     if (!silent) {


        


More information about the flang-commits mailing list