================
@@ -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 == ".") {
+ ModulesToLoad.push_back(UmbrellaDir.second);
+ }
+ }
- // Keep track of all of the directories we checked, so we can mark them as
- // having module maps if we eventually do find a module map.
- FixUpDirectories.push_back(*Dir);
- } while (true);
+ // Add umbrella header modules (conservative)
----------------
Bigcheese wrote:
This does not do exactly the same logic for umbrella header attachment as
`ModuleMap::findModuleForHeader` does. One case is that if another header is a
known header due to a direct header decl, it will use that module instead of
the umbrella header. So it's conservative in that it loads it even in cases
where it won't actually be selected. I'll improve this comment to better cover
that.
https://github.com/llvm/llvm-project/pull/181916
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits