================
@@ -1638,33 +1739,72 @@ bool HeaderSearch::hasModuleMap(StringRef FileName,
     auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
     if (!Dir)
       return false;
+    CurDir = *Dir;
+
+    bool IsFramework =
+        llvm::sys::path::extension(Dir->getName()) == ".framework";
 
-    // Try to load the module map file in this directory.
-    switch (parseAndLoadModuleMapFile(
-        *Dir, IsSystem,
-        llvm::sys::path::extension(Dir->getName()) == ".framework")) {
-    case MMR_NewlyProcessed:
-    case MMR_AlreadyProcessed: {
-      // Success. All of the directories we stepped through inherit this module
-      // map file.
-      const ModuleMapDirectoryState &MMDS = DirectoryModuleMap[*Dir];
-      for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
-        DirectoryModuleMap[FixUpDirectories[I]] = MMDS;
+    // Check if it's possible that the module map for this directory can 
resolve
+    // this header.
+    parseModuleMapFile(*Dir, IsSystem, IsFramework);
+    auto DirState = DirectoryModuleMap.find(*Dir);
+    if (DirState == DirectoryModuleMap.end() || 
!DirState->second.ModuleMapFile)
+      continue;
+
+    if (!HSOpts.LazyLoadModMaps)
       return true;
+
+    auto &MMState = DirState->second;
+
+    // Build cache if not already built
+    if (MMState.HeaderToModules.empty() && MMState.UmbrellaDirModules.empty() 
&&
+        MMState.UmbrellaHeaderModules.empty()) {
+      buildHeaderCache(*Dir, MMState);
     }
-    case MMR_NoDirectory:
-    case MMR_InvalidModuleMap:
-      break;
+
+    // Compute relative path from directory to the file. Use DirName (which
+    // we computed via parent_path) rather than Dir->getName() to ensure
+    // consistent path separators.
+    StringRef RelativePath = FileName.substr(DirName.size());
+    // Strip leading separator
+    while (!RelativePath.empty() &&
+           llvm::sys::path::is_separator(RelativePath.front()))
+      RelativePath = RelativePath.substr(1);
+
+    // Check for exact matches in cache
+    llvm::SmallVector<StringRef, 4> ModulesToLoad;
+    auto CachedMods = MMState.HeaderToModules.find(RelativePath);
+    if (CachedMods != MMState.HeaderToModules.end()) {
+      ModulesToLoad.append(CachedMods->second.begin(),
+                           CachedMods->second.end());
     }
 
-    // If we hit the top of our search, we're done.
-    if (*Dir == Root)
-      return false;
+    // Check umbrella directories
+    for (const auto &UmbrellaDir : MMState.UmbrellaDirModules) {
+      if (RelativePath.starts_with(UmbrellaDir.first) ||
+          UmbrellaDir.first == ".") {
----------------
Bigcheese wrote:

We allow:
```
module M {
  umbrella "."
}
```
But in that case `RelativePath` is not `.`.

I can add a test for this case.

https://github.com/llvm/llvm-project/pull/181916
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to