From 29600298319923c55bea91d70f52957c5617bc82 Mon Sep 17 00:00:00 2001 From: Michael Spencer Date: Wed, 8 Oct 2025 16:11:38 -0700 Subject: [PATCH] Revert "[clang][modules] Lazily load by name lookups in module maps (#132853)" This is causing a slowdown in SourceKit completion requests. The slowdown is caused by the call to `SourceManager::translateFile` that was added to avoid allocating separate source location space for each module map in each `CompilerInstance`. rdar://162196108 This reverts commit 32fb8c5f5fdeb20de28846e2fe9e2c7525f62086. --- .../modularize/ModularizeUtilities.cpp | 2 +- clang/include/clang/Basic/DiagnosticGroups.td | 1 - .../include/clang/Basic/DiagnosticLexKinds.td | 6 - clang/include/clang/Lex/HeaderSearch.h | 70 ++---- clang/include/clang/Lex/ModuleMap.h | 29 +-- clang/include/clang/Lex/ModuleMapFile.h | 9 - clang/lib/Frontend/CompilerInstance.cpp | 4 +- clang/lib/Frontend/FrontendAction.cpp | 8 +- clang/lib/Lex/HeaderSearch.cpp | 234 ++++++------------ clang/lib/Lex/ModuleMap.cpp | 162 ++---------- clang/lib/Lex/ModuleMapFile.cpp | 3 - clang/lib/Sema/SemaModule.cpp | 2 +- .../modules-canononical-module-map-case.c | 11 - clang/test/Modules/Inputs/shadow/A1/A1.h | 0 .../Modules/Inputs/shadow/A1/module.modulemap | 4 +- clang/test/Modules/Inputs/shadow/A2/A2.h | 0 .../Modules/Inputs/shadow/A2/module.modulemap | 4 +- clang/test/Modules/lazy-by-name-lookup.c | 31 --- clang/test/Modules/shadow.m | 11 +- .../Clang/ClangModulesDeclVendor.cpp | 2 +- 20 files changed, 136 insertions(+), 457 deletions(-) delete mode 100644 clang/test/Modules/Inputs/shadow/A1/A1.h delete mode 100644 clang/test/Modules/Inputs/shadow/A2/A2.h delete mode 100644 clang/test/Modules/lazy-by-name-lookup.c diff --git a/clang-tools-extra/modularize/ModularizeUtilities.cpp b/clang-tools-extra/modularize/ModularizeUtilities.cpp index 8a24f21d658df..e66f2058e6617 100644 --- a/clang-tools-extra/modularize/ModularizeUtilities.cpp +++ b/clang-tools-extra/modularize/ModularizeUtilities.cpp @@ -287,7 +287,7 @@ std::error_code ModularizeUtilities::loadModuleMap( Target.get(), *HeaderInfo)); // Parse module.modulemap file into module map. - if (ModMap->parseAndLoadModuleMapFile(ModuleMapEntry, false, Dir)) { + if (ModMap->loadModuleMapFile(ModuleMapEntry, false, Dir)) { return std::error_code(1, std::generic_category()); } diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index be8f08f8bb82f..519673e47e5ad 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -627,7 +627,6 @@ def ModuleImport : DiagGroup<"module-import">; def ModuleConflict : DiagGroup<"module-conflict">; def ModuleFileExtension : DiagGroup<"module-file-extension">; def ModuleIncludeDirectiveTranslation : DiagGroup<"module-include-translation">; -def ModuleMap : DiagGroup<"module-map">; def IndexStore : DiagGroup<"index-store">; def RoundTripCC1Args : DiagGroup<"round-trip-cc1-args">; def NewlineEOF : DiagGroup<"newline-eof">; diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 137e7cc3bd76f..dc0554ecfd186 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -848,12 +848,6 @@ def err_pp_encounter_nonreproducible: Error< "encountered non-reproducible token, caching failed">; // Module map parsing -def remark_mmap_parse : Remark< - "parsing modulemap '%0'">, ShowInSystemHeader, InGroup; -def remark_mmap_load : Remark< - "loading modulemap '%0'">, ShowInSystemHeader, InGroup; -def remark_mmap_load_module : Remark< - "loading parsed module '%0'">, ShowInSystemHeader, InGroup; def err_mmap_unknown_token : Error<"skipping stray token">; def err_mmap_expected_module : Error<"expected module declaration">; def err_mmap_expected_module_name : Error<"expected module name">; diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index 2e0c8bec8bd8c..bccec4dd951d6 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -332,27 +332,13 @@ class HeaderSearch { /// The mapping between modules and headers. mutable ModuleMap ModMap; - struct ModuleMapDirectoryState { - OptionalFileEntryRef ModuleMapFile; - enum { - Parsed, - Loaded, - Invalid, - } Status; - }; - /// Describes whether a given directory has a module map in it. - llvm::DenseMap - DirectoryModuleMap; + llvm::DenseMap DirectoryHasModuleMap; /// Set of module map files we've already loaded, and a flag indicating /// whether they were valid or not. llvm::DenseMap LoadedModuleMaps; - /// Set of module map files we've already parsed, and a flag indicating - /// whether they were valid or not. - llvm::DenseMap ParsedModuleMaps; - // A map of discovered headers with their associated include file name. llvm::DenseMap> IncludeNames; @@ -447,6 +433,11 @@ class HeaderSearch { /// Retrieve the path to the module cache. StringRef getModuleCachePath() const { return ModuleCachePath; } + /// Consider modules when including files from this directory. + void setDirectoryHasModuleMap(const DirectoryEntry* Dir) { + DirectoryHasModuleMap[Dir] = true; + } + /// Forget everything we know about headers so far. void ClearFileInfo() { FileInfo.clear(); @@ -722,10 +713,9 @@ class HeaderSearch { /// used to resolve paths within the module (this is required when /// building the module from preprocessed source). /// \returns true if an error occurred, false otherwise. - bool parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, - FileID ID = FileID(), - unsigned *Offset = nullptr, - StringRef OriginalModuleMapFile = StringRef()); + bool loadModuleMapFile(FileEntryRef File, bool IsSystem, FileID ID = FileID(), + unsigned *Offset = nullptr, + StringRef OriginalModuleMapFile = StringRef()); /// Collect the set of all known, top-level modules. /// @@ -925,31 +915,26 @@ class HeaderSearch { size_t getTotalMemory() const; private: - /// Describes what happened when we tried to load or parse a module map file. - enum ModuleMapResult { - /// The module map file had already been processed. - MMR_AlreadyProcessed, + /// Describes what happened when we tried to load a module map file. + enum LoadModuleMapResult { + /// The module map file had already been loaded. + LMM_AlreadyLoaded, - /// The module map file was processed by this invocation. - MMR_NewlyProcessed, + /// The module map file was loaded by this invocation. + LMM_NewlyLoaded, /// There is was directory with the given name. - MMR_NoDirectory, + LMM_NoDirectory, /// There was either no module map file or the module map file was /// invalid. - MMR_InvalidModuleMap + LMM_InvalidModuleMap }; - ModuleMapResult parseAndLoadModuleMapFileImpl(FileEntryRef File, - bool IsSystem, - DirectoryEntryRef Dir, - FileID ID = FileID(), - unsigned *Offset = nullptr); - - ModuleMapResult parseModuleMapFileImpl(FileEntryRef File, bool IsSystem, - DirectoryEntryRef Dir, - FileID ID = FileID()); + LoadModuleMapResult loadModuleMapFileImpl(FileEntryRef File, bool IsSystem, + DirectoryEntryRef Dir, + FileID ID = FileID(), + unsigned *Offset = nullptr); /// Try to load the module map file in the given directory. /// @@ -960,8 +945,8 @@ class HeaderSearch { /// /// \returns The result of attempting to load the module map file from the /// named directory. - ModuleMapResult parseAndLoadModuleMapFile(StringRef DirName, bool IsSystem, - bool IsFramework); + LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem, + bool IsFramework); /// Try to load the module map file in the given directory. /// @@ -971,13 +956,8 @@ class HeaderSearch { /// /// \returns The result of attempting to load the module map file from the /// named directory. - ModuleMapResult parseAndLoadModuleMapFile(DirectoryEntryRef Dir, - bool IsSystem, bool IsFramework); - - ModuleMapResult parseModuleMapFile(StringRef DirName, bool IsSystem, - bool IsFramework); - ModuleMapResult parseModuleMapFile(DirectoryEntryRef Dir, bool IsSystem, - bool IsFramework); + LoadModuleMapResult loadModuleMapFile(DirectoryEntryRef Dir, bool IsSystem, + bool IsFramework); }; /// Apply the header search options to get given HeaderSearch object. diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h index e3e479ce10766..9b3be5dc6d86e 100644 --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -18,7 +18,6 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Lex/ModuleMapFile.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -271,18 +270,6 @@ class ModuleMap { /// Describes whether we haved loaded a particular file as a module /// map. llvm::DenseMap LoadedModuleMap; - llvm::DenseMap - ParsedModuleMap; - - std::vector> ParsedModuleMaps; - - /// Map from top level module name to a list of ModuleDecls in the order they - /// were discovered. This allows handling shadowing correctly and diagnosing - /// redefinitions. - llvm::StringMap, - 1>> - ParsedModules; /// Resolve the given export declaration into an actual export /// declaration. @@ -499,8 +486,6 @@ class ModuleMap { /// \returns The named module, if known; otherwise, returns null. Module *findModule(StringRef Name) const; - Module *findOrLoadModule(StringRef Name); - Module *findOrInferSubmodule(Module *Parent, StringRef Name); /// Retrieve a module with the given name using lexical name lookup, @@ -716,11 +701,6 @@ class ModuleMap { void addHeader(Module *Mod, Module::Header Header, ModuleHeaderRole Role, bool Imported = false); - /// Parse a module map without creating `clang::Module` instances. - bool parseModuleMapFile(FileEntryRef File, bool IsSystem, - DirectoryEntryRef Dir, FileID ID = FileID(), - SourceLocation ExternModuleLoc = SourceLocation()); - /// Load the given module map file, and record any modules we /// encounter. /// @@ -741,11 +721,10 @@ class ModuleMap { /// that caused us to load this module map file, if any. /// /// \returns true if an error occurred, false otherwise. - bool - parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, - DirectoryEntryRef HomeDir, FileID ID = FileID(), - unsigned *Offset = nullptr, - SourceLocation ExternModuleLoc = SourceLocation()); + bool loadModuleMapFile(FileEntryRef File, bool IsSystem, + DirectoryEntryRef HomeDir, FileID ID = FileID(), + unsigned *Offset = nullptr, + SourceLocation ExternModuleLoc = SourceLocation()); /// Dump the contents of the module map, for debugging purposes. void dump(); diff --git a/clang/include/clang/Lex/ModuleMapFile.h b/clang/include/clang/Lex/ModuleMapFile.h index 7d0e36e9ab86c..1219cc2b50753 100644 --- a/clang/include/clang/Lex/ModuleMapFile.h +++ b/clang/include/clang/Lex/ModuleMapFile.h @@ -133,17 +133,8 @@ using TopLevelDecl = std::variant; /// This holds many reference types (StringRef, SourceLocation, etc.) whose /// lifetimes are bound by the SourceManager and FileManager used. struct ModuleMapFile { - /// The FileID used to parse this module map. This is always a local ID. - FileID ID; - - /// The directory in which the module map was discovered. Declarations in - /// the module map are relative to this directory. - OptionalDirectoryEntryRef Dir; - /// Beginning of the file, used for moduleMapFileRead callback. SourceLocation Start; - - bool IsSystem; std::vector Decls; void dump(llvm::raw_ostream &out) const; diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index b9016b4a0fd6a..2f25e3f9e8643 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -599,13 +599,13 @@ struct ReadModuleNames : ASTReaderListener { ModuleMap &MM = PP.getHeaderSearchInfo().getModuleMap(); for (const std::string &LoadedModule : LoadedModules) MM.cacheModuleLoad(*PP.getIdentifierInfo(LoadedModule), - MM.findOrLoadModule(LoadedModule)); + MM.findModule(LoadedModule)); LoadedModules.clear(); } void markAllUnavailable() { for (const std::string &LoadedModule : LoadedModules) { - if (Module *M = PP.getHeaderSearchInfo().getModuleMap().findOrLoadModule( + if (Module *M = PP.getHeaderSearchInfo().getModuleMap().findModule( LoadedModule)) { M->HasIncompatibleModuleFile = true; diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 2a8d00c31ec41..269dba1745d73 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -627,8 +627,8 @@ static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem, } // Load the module map file. - if (HS.parseAndLoadModuleMapFile(*ModuleMap, IsSystem, ModuleMapID, &Offset, - PresumedModuleMapFile)) + if (HS.loadModuleMapFile(*ModuleMap, IsSystem, ModuleMapID, &Offset, + PresumedModuleMapFile)) return true; if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset) @@ -1248,8 +1248,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // If we were asked to load any module map files, do so now. for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) { if (auto File = CI.getFileManager().getOptionalFileRef(Filename)) - CI.getPreprocessor().getHeaderSearchInfo().parseAndLoadModuleMapFile( - *File, /*IsSystem*/ false); + CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile( + *File, /*IsSystem*/false); else CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename; } diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index ea2391f6812cf..2665580e5afce 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -299,7 +299,7 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, SourceLocation ImportLoc, bool AllowSearch, bool AllowExtraModuleMapSearch) { // Look in the module map to determine if there is a module by this name. - Module *Module = ModMap.findOrLoadModule(ModuleName); + Module *Module = ModMap.findModule(ModuleName); if (Module || !AllowSearch || !HSOpts.ImplicitModuleMaps) return Module; @@ -359,11 +359,11 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName, // checked DirectoryEntryRef NormalDir = *Dir.getDirRef(); // Search for a module map file in this directory. - if (parseModuleMapFile(NormalDir, IsSystem, - /*IsFramework*/ false) == MMR_NewlyProcessed) { - // We just parsed a module map file; check whether the module can be - // loaded now. - Module = ModMap.findOrLoadModule(ModuleName); + if (loadModuleMapFile(NormalDir, IsSystem, + /*IsFramework*/false) == LMM_NewlyLoaded) { + // We just loaded a module map file; check whether the module is + // available now. + Module = ModMap.findModule(ModuleName); if (Module) break; } @@ -373,10 +373,10 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName, SmallString<128> NestedModuleMapDirName; NestedModuleMapDirName = Dir.getDirRef()->getName(); llvm::sys::path::append(NestedModuleMapDirName, ModuleName); - if (parseModuleMapFile(NestedModuleMapDirName, IsSystem, - /*IsFramework*/ false) == MMR_NewlyProcessed) { - // If we just parsed a module map file, look for the module again. - Module = ModMap.findOrLoadModule(ModuleName); + if (loadModuleMapFile(NestedModuleMapDirName, IsSystem, + /*IsFramework*/false) == LMM_NewlyLoaded){ + // If we just loaded a module map file, look for the module again. + Module = ModMap.findModule(ModuleName); if (Module) break; } @@ -393,7 +393,7 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName, loadSubdirectoryModuleMaps(Dir); // Look again for the module. - Module = ModMap.findOrLoadModule(ModuleName); + Module = ModMap.findModule(ModuleName); if (Module) break; } @@ -1559,7 +1559,7 @@ bool HeaderSearch::hasModuleMap(StringRef FileName, if (!HSOpts.ImplicitModuleMaps) return false; - SmallVector FixUpDirectories; + SmallVector FixUpDirectories; StringRef DirName = FileName; do { @@ -1574,20 +1574,19 @@ bool HeaderSearch::hasModuleMap(StringRef FileName, return false; // 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: { + switch (loadModuleMapFile(*Dir, IsSystem, + llvm::sys::path::extension(Dir->getName()) == + ".framework")) { + case LMM_NewlyLoaded: + case LMM_AlreadyLoaded: // 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; + DirectoryHasModuleMap[FixUpDirectories[I]] = true; return true; - } - case MMR_NoDirectory: - case MMR_InvalidModuleMap: + + case LMM_NoDirectory: + case LMM_InvalidModuleMap: break; } @@ -1707,8 +1706,7 @@ bool HeaderSearch::findUsableModuleForFrameworkHeader( static OptionalFileEntryRef getPrivateModuleMap(FileEntryRef File, FileManager &FileMgr, - DiagnosticsEngine &Diags, - bool Diagnose = true) { + DiagnosticsEngine &Diags) { StringRef Filename = llvm::sys::path::filename(File.getName()); SmallString<128> PrivateFilename(File.getDir().getName()); if (Filename == "module.map") @@ -1719,7 +1717,7 @@ static OptionalFileEntryRef getPrivateModuleMap(FileEntryRef File, return std::nullopt; auto PMMFile = FileMgr.getOptionalFileRef(PrivateFilename); if (PMMFile) { - if (Diagnose && Filename == "module.map") + if (Filename == "module.map") Diags.Report(diag::warn_deprecated_module_dot_map) << PrivateFilename << 1 << File.getDir().getName().ends_with(".framework"); @@ -1727,9 +1725,9 @@ static OptionalFileEntryRef getPrivateModuleMap(FileEntryRef File, return PMMFile; } -bool HeaderSearch::parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, - FileID ID, unsigned *Offset, - StringRef OriginalModuleMapFile) { +bool HeaderSearch::loadModuleMapFile(FileEntryRef File, bool IsSystem, + FileID ID, unsigned *Offset, + StringRef OriginalModuleMapFile) { // Find the directory for the module. For frameworks, that may require going // up from the 'Modules' directory. OptionalDirectoryEntryRef Dir; @@ -1763,72 +1761,43 @@ bool HeaderSearch::parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, } assert(Dir && "module map home directory must exist"); - switch (parseAndLoadModuleMapFileImpl(File, IsSystem, *Dir, ID, Offset)) { - case MMR_AlreadyProcessed: - case MMR_NewlyProcessed: + switch (loadModuleMapFileImpl(File, IsSystem, *Dir, ID, Offset)) { + case LMM_AlreadyLoaded: + case LMM_NewlyLoaded: return false; - case MMR_NoDirectory: - case MMR_InvalidModuleMap: + case LMM_NoDirectory: + case LMM_InvalidModuleMap: return true; } llvm_unreachable("Unknown load module map result"); } -HeaderSearch::ModuleMapResult -HeaderSearch::parseAndLoadModuleMapFileImpl(FileEntryRef File, bool IsSystem, - DirectoryEntryRef Dir, FileID ID, - unsigned *Offset) { +HeaderSearch::LoadModuleMapResult +HeaderSearch::loadModuleMapFileImpl(FileEntryRef File, bool IsSystem, + DirectoryEntryRef Dir, FileID ID, + unsigned *Offset) { // Check whether we've already loaded this module map, and mark it as being // loaded in case we recursively try to load it from itself. auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true)); if (!AddResult.second) - return AddResult.first->second ? MMR_AlreadyProcessed - : MMR_InvalidModuleMap; + return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; - if (ModMap.parseAndLoadModuleMapFile(File, IsSystem, Dir, ID, Offset)) { + if (ModMap.loadModuleMapFile(File, IsSystem, Dir, ID, Offset)) { LoadedModuleMaps[File] = false; - return MMR_InvalidModuleMap; + return LMM_InvalidModuleMap; } // Try to load a corresponding private module map. - if (OptionalFileEntryRef PMMFile = - getPrivateModuleMap(File, FileMgr, Diags, !ParsedModuleMaps[File])) { - if (ModMap.parseAndLoadModuleMapFile(*PMMFile, IsSystem, Dir)) { - LoadedModuleMaps[File] = false; - return MMR_InvalidModuleMap; - } - } - - // This directory has a module map. - return MMR_NewlyProcessed; -} - -HeaderSearch::ModuleMapResult -HeaderSearch::parseModuleMapFileImpl(FileEntryRef File, bool IsSystem, - DirectoryEntryRef Dir, FileID ID) { - // Check whether we've already parsed this module map, and mark it as being - // parsed in case we recursively try to parse it from itself. - auto AddResult = ParsedModuleMaps.insert(std::make_pair(File, true)); - if (!AddResult.second) - return AddResult.first->second ? MMR_AlreadyProcessed - : MMR_InvalidModuleMap; - - if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID)) { - ParsedModuleMaps[File] = false; - return MMR_InvalidModuleMap; - } - - // Try to parse a corresponding private module map. if (OptionalFileEntryRef PMMFile = getPrivateModuleMap(File, FileMgr, Diags)) { - if (ModMap.parseModuleMapFile(*PMMFile, IsSystem, Dir)) { - ParsedModuleMaps[File] = false; - return MMR_InvalidModuleMap; + if (ModMap.loadModuleMapFile(*PMMFile, IsSystem, Dir)) { + LoadedModuleMaps[File] = false; + return LMM_InvalidModuleMap; } } // This directory has a module map. - return MMR_NewlyProcessed; + return LMM_NewlyLoaded; } OptionalFileEntryRef @@ -1868,109 +1837,54 @@ HeaderSearch::lookupModuleMapFile(DirectoryEntryRef Dir, bool IsFramework) { Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir, bool IsSystem) { // Try to load a module map file. - switch (parseAndLoadModuleMapFile(Dir, IsSystem, /*IsFramework*/ true)) { - case MMR_InvalidModuleMap: + switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) { + case LMM_InvalidModuleMap: // Try to infer a module map from the framework directory. if (HSOpts.ImplicitModuleMaps) ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr); break; - case MMR_NoDirectory: + case LMM_NoDirectory: return nullptr; - case MMR_AlreadyProcessed: - case MMR_NewlyProcessed: + case LMM_AlreadyLoaded: + case LMM_NewlyLoaded: break; } - return ModMap.findOrLoadModule(Name); + return ModMap.findModule(Name); } -HeaderSearch::ModuleMapResult -HeaderSearch::parseAndLoadModuleMapFile(StringRef DirName, bool IsSystem, - bool IsFramework) { +HeaderSearch::LoadModuleMapResult +HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem, + bool IsFramework) { if (auto Dir = FileMgr.getOptionalDirectoryRef(DirName)) - return parseAndLoadModuleMapFile(*Dir, IsSystem, IsFramework); + return loadModuleMapFile(*Dir, IsSystem, IsFramework); - return MMR_NoDirectory; + return LMM_NoDirectory; } -HeaderSearch::ModuleMapResult -HeaderSearch::parseAndLoadModuleMapFile(DirectoryEntryRef Dir, bool IsSystem, - bool IsFramework) { - auto InsertRes = DirectoryModuleMap.insert(std::pair{ - Dir, ModuleMapDirectoryState{{}, ModuleMapDirectoryState::Invalid}}); - ModuleMapDirectoryState &MMState = InsertRes.first->second; - if (!InsertRes.second) { - switch (MMState.Status) { - case ModuleMapDirectoryState::Parsed: - break; - case ModuleMapDirectoryState::Loaded: - return MMR_AlreadyProcessed; - case ModuleMapDirectoryState::Invalid: - return MMR_InvalidModuleMap; - }; - } - - if (!MMState.ModuleMapFile) - MMState.ModuleMapFile = lookupModuleMapFile(Dir, IsFramework); - - if (MMState.ModuleMapFile) { - ModuleMapResult Result = - parseAndLoadModuleMapFileImpl(*MMState.ModuleMapFile, IsSystem, Dir); - // Add Dir explicitly in case ModuleMapFile is in a subdirectory. - // E.g. Foo.framework/Modules/module.modulemap - // ^Dir ^ModuleMapFile - if (Result == MMR_NewlyProcessed) - MMState.Status = ModuleMapDirectoryState::Loaded; - else if (Result == MMR_InvalidModuleMap) - MMState.Status = ModuleMapDirectoryState::Invalid; - return Result; - } - return MMR_InvalidModuleMap; -} - -HeaderSearch::ModuleMapResult -HeaderSearch::parseModuleMapFile(StringRef DirName, bool IsSystem, - bool IsFramework) { - if (auto Dir = FileMgr.getOptionalDirectoryRef(DirName)) - return parseModuleMapFile(*Dir, IsSystem, IsFramework); - - return MMR_NoDirectory; -} - -HeaderSearch::ModuleMapResult -HeaderSearch::parseModuleMapFile(DirectoryEntryRef Dir, bool IsSystem, - bool IsFramework) { - auto InsertRes = DirectoryModuleMap.insert(std::pair{ - Dir, ModuleMapDirectoryState{{}, ModuleMapDirectoryState::Invalid}}); - ModuleMapDirectoryState &MMState = InsertRes.first->second; - if (!InsertRes.second) { - switch (MMState.Status) { - case ModuleMapDirectoryState::Parsed: - case ModuleMapDirectoryState::Loaded: - return MMR_AlreadyProcessed; - case ModuleMapDirectoryState::Invalid: - return MMR_InvalidModuleMap; - }; - } - - if (!MMState.ModuleMapFile) - MMState.ModuleMapFile = lookupModuleMapFile(Dir, IsFramework); +HeaderSearch::LoadModuleMapResult +HeaderSearch::loadModuleMapFile(DirectoryEntryRef Dir, bool IsSystem, + bool IsFramework) { + auto KnownDir = DirectoryHasModuleMap.find(Dir); + if (KnownDir != DirectoryHasModuleMap.end()) + return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; - if (MMState.ModuleMapFile) { - ModuleMapResult Result = - parseModuleMapFileImpl(*MMState.ModuleMapFile, IsSystem, Dir); + if (OptionalFileEntryRef ModuleMapFile = + lookupModuleMapFile(Dir, IsFramework)) { + LoadModuleMapResult Result = + loadModuleMapFileImpl(*ModuleMapFile, IsSystem, Dir); // Add Dir explicitly in case ModuleMapFile is in a subdirectory. // E.g. Foo.framework/Modules/module.modulemap // ^Dir ^ModuleMapFile - if (Result == MMR_NewlyProcessed) - MMState.Status = ModuleMapDirectoryState::Parsed; - else if (Result == MMR_InvalidModuleMap) - MMState.Status = ModuleMapDirectoryState::Invalid; + if (Result == LMM_NewlyLoaded) + DirectoryHasModuleMap[Dir] = true; + else if (Result == LMM_InvalidModuleMap) + DirectoryHasModuleMap[Dir] = false; return Result; } - return MMR_InvalidModuleMap; + return LMM_InvalidModuleMap; } void HeaderSearch::collectAllModules(SmallVectorImpl &Modules) { @@ -2009,8 +1923,7 @@ void HeaderSearch::collectAllModules(SmallVectorImpl &Modules) { continue; // Try to load a module map file for the search directory. - parseAndLoadModuleMapFile(*DL.getDirRef(), IsSystem, - /*IsFramework*/ false); + loadModuleMapFile(*DL.getDirRef(), IsSystem, /*IsFramework*/ false); // Try to load module map files for immediate subdirectories of this // search directory. @@ -2033,8 +1946,8 @@ void HeaderSearch::loadTopLevelSystemModules() { continue; // Try to load a module map file for the search directory. - parseAndLoadModuleMapFile(*DL.getDirRef(), DL.isSystemHeaderDirectory(), - DL.isFramework()); + loadModuleMapFile(*DL.getDirRef(), DL.isSystemHeaderDirectory(), + DL.isFramework()); } } @@ -2057,9 +1970,8 @@ void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { continue; bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework"; if (IsFramework == SearchDir.isFramework()) - parseAndLoadModuleMapFile(Dir->path(), - SearchDir.isSystemHeaderDirectory(), - SearchDir.isFramework()); + loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(), + SearchDir.isFramework()); } SearchDir.setSearchedAllModuleMaps(true); diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 678c122e32f34..4dfb38ceaf8bb 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -1059,9 +1059,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir, bool IsFrameworkDir = Parent.ends_with(".framework"); if (OptionalFileEntryRef ModMapFile = HeaderInfo.lookupModuleMapFile(*ParentDir, IsFrameworkDir)) { - // TODO: Parsing a module map should populate `InferredDirectories` - // so we don't need to do a full load here. - parseAndLoadModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir); + loadModuleMapFile(*ModMapFile, Attrs.IsSystem, *ParentDir); inferred = InferredDirectories.find(*ParentDir); } @@ -1330,83 +1328,6 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header, Cb->moduleMapAddHeader(HeaderEntry.getName()); } -bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem, - DirectoryEntryRef Dir, FileID ID, - SourceLocation ExternModuleLoc) { - llvm::DenseMap::iterator - Known = ParsedModuleMap.find(File); - if (Known != ParsedModuleMap.end()) - return Known->second == nullptr; - - // If the module map file wasn't already entered, do so now. - if (ID.isInvalid()) { - ID = SourceMgr.translateFile(File); - if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) { - auto FileCharacter = - IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; - ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); - } - } - - std::optional Buffer = SourceMgr.getBufferOrNone(ID); - if (!Buffer) { - ParsedModuleMap[File] = nullptr; - return true; - } - - Diags.Report(diag::remark_mmap_parse) << File.getName(); - std::optional MaybeMMF = - modulemap::parseModuleMap(ID, Dir, SourceMgr, Diags, IsSystem, nullptr); - - if (!MaybeMMF) { - ParsedModuleMap[File] = nullptr; - return true; - } - - ParsedModuleMaps.push_back( - std::make_unique(std::move(*MaybeMMF))); - const modulemap::ModuleMapFile &MMF = *ParsedModuleMaps.back(); - std::vector PendingExternalModuleMaps; - for (const auto &Decl : MMF.Decls) { - std::visit(llvm::makeVisitor( - [&](const modulemap::ModuleDecl &MD) { - // Only use the first part of the name even for submodules. - // This will correctly load the submodule declarations when - // the module is loaded. - auto &ModuleDecls = - ParsedModules[StringRef(MD.Id.front().first)]; - ModuleDecls.push_back(std::pair(&MMF, &MD)); - }, - [&](const modulemap::ExternModuleDecl &EMD) { - PendingExternalModuleMaps.push_back(&EMD); - }), - Decl); - } - - for (const modulemap::ExternModuleDecl *EMD : PendingExternalModuleMaps) { - StringRef FileNameRef = EMD->Path; - SmallString<128> ModuleMapFileName; - if (llvm::sys::path::is_relative(FileNameRef)) { - ModuleMapFileName += Dir.getName(); - llvm::sys::path::append(ModuleMapFileName, EMD->Path); - FileNameRef = ModuleMapFileName; - } - - if (auto EFile = - SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) { - parseModuleMapFile(*EFile, IsSystem, EFile->getDir(), FileID(), - ExternModuleLoc); - } - } - - ParsedModuleMap[File] = &MMF; - - for (const auto &Cb : Callbacks) - Cb->moduleMapFileRead(SourceLocation(), File, IsSystem); - - return false; -} - FileID ModuleMap::getContainingModuleMapFileID(const Module *Module) const { if (Module->DefinitionLoc.isInvalid()) return {}; @@ -1545,6 +1466,7 @@ bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) { namespace clang { class ModuleMapLoader { + modulemap::ModuleMapFile &MMF; SourceManager &SourceMgr; DiagnosticsEngine &Diags; @@ -1601,15 +1523,13 @@ class ModuleMapLoader { using Attributes = ModuleMap::Attributes; public: - ModuleMapLoader(SourceManager &SourceMgr, DiagnosticsEngine &Diags, - ModuleMap &Map, FileID ModuleMapFID, + ModuleMapLoader(modulemap::ModuleMapFile &MMF, SourceManager &SourceMgr, + DiagnosticsEngine &Diags, ModuleMap &Map, FileID ModuleMapFID, DirectoryEntryRef Directory, bool IsSystem) - : SourceMgr(SourceMgr), Diags(Diags), Map(Map), + : MMF(MMF), SourceMgr(SourceMgr), Diags(Diags), Map(Map), ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {} - bool loadModuleDecl(const modulemap::ModuleDecl &MD); - bool loadExternModuleDecl(const modulemap::ExternModuleDecl &EMD); - bool parseAndLoadModuleMapFile(const modulemap::ModuleMapFile &MMF); + bool loadModuleMapFile(); }; } // namespace clang @@ -1748,11 +1668,7 @@ void ModuleMapLoader::handleModuleDecl(const modulemap::ModuleDecl &MD) { Map.LangOpts.CurrentModule == ModuleName && SourceMgr.getDecomposedLoc(ModuleNameLoc).first != SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first; - // TODO: Remove this check when we can avoid loading module maps multiple - // times. - bool SameModuleDecl = ModuleNameLoc == Existing->DefinitionLoc; - if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput || - SameModuleDecl) { + if (LoadedFromASTFile || Inferred || PartOfFramework || ParsedAsMainInput) { ActiveModule = PreviousActiveModule; // Skip the module definition. return; @@ -1865,7 +1781,7 @@ void ModuleMapLoader::handleExternModuleDecl( FileNameRef = ModuleMapFileName; } if (auto File = SourceMgr.getFileManager().getOptionalFileRef(FileNameRef)) - Map.parseAndLoadModuleMapFile( + Map.loadModuleMapFile( *File, IsSystem, Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd ? Directory @@ -2196,19 +2112,7 @@ void ModuleMapLoader::handleInferredModuleDecl( } } -bool ModuleMapLoader::loadModuleDecl(const modulemap::ModuleDecl &MD) { - handleModuleDecl(MD); - return HadError; -} - -bool ModuleMapLoader::loadExternModuleDecl( - const modulemap::ExternModuleDecl &EMD) { - handleExternModuleDecl(EMD); - return HadError; -} - -bool ModuleMapLoader::parseAndLoadModuleMapFile( - const modulemap::ModuleMapFile &MMF) { +bool ModuleMapLoader::loadModuleMapFile() { for (const auto &Decl : MMF.Decls) { std::visit( llvm::makeVisitor( @@ -2221,32 +2125,10 @@ bool ModuleMapLoader::parseAndLoadModuleMapFile( return HadError; } -Module *ModuleMap::findOrLoadModule(StringRef Name) { - llvm::StringMap::const_iterator Known = Modules.find(Name); - if (Known != Modules.end()) - return Known->getValue(); - - auto ParsedMod = ParsedModules.find(Name); - if (ParsedMod == ParsedModules.end()) - return nullptr; - - Diags.Report(diag::remark_mmap_load_module) << Name; - - for (const auto &ModuleDecl : ParsedMod->second) { - const modulemap::ModuleMapFile &MMF = *ModuleDecl.first; - ModuleMapLoader Loader(SourceMgr, Diags, const_cast(*this), - MMF.ID, *MMF.Dir, MMF.IsSystem); - if (Loader.loadModuleDecl(*ModuleDecl.second)) - return nullptr; - } - - return findModule(Name); -} - -bool ModuleMap::parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, - DirectoryEntryRef Dir, FileID ID, - unsigned *Offset, - SourceLocation ExternModuleLoc) { +bool ModuleMap::loadModuleMapFile(FileEntryRef File, bool IsSystem, + DirectoryEntryRef Dir, FileID ID, + unsigned *Offset, + SourceLocation ExternModuleLoc) { assert(Target && "Missing target information"); llvm::DenseMap::iterator Known = LoadedModuleMap.find(File); @@ -2255,16 +2137,9 @@ bool ModuleMap::parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, // If the module map file wasn't already entered, do so now. if (ID.isInvalid()) { - ID = SourceMgr.translateFile(File); - // TODO: The way we compute affecting module maps requires this to be a - // local FileID. This should be changed to reuse loaded FileIDs when - // available, and change the way that affecting module maps are - // computed to not require this. - if (ID.isInvalid() || SourceMgr.isLoadedFileID(ID)) { - auto FileCharacter = - IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; - ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); - } + auto FileCharacter = + IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap; + ID = SourceMgr.createFileID(File, ExternModuleLoc, FileCharacter); } assert(Target && "Missing target information"); @@ -2278,9 +2153,8 @@ bool ModuleMap::parseAndLoadModuleMapFile(FileEntryRef File, bool IsSystem, modulemap::parseModuleMap(ID, Dir, SourceMgr, Diags, IsSystem, Offset); bool Result = false; if (MMF) { - Diags.Report(diag::remark_mmap_load) << File.getName(); - ModuleMapLoader Loader(SourceMgr, Diags, *this, ID, Dir, IsSystem); - Result = Loader.parseAndLoadModuleMapFile(*MMF); + ModuleMapLoader Loader(*MMF, SourceMgr, Diags, *this, ID, Dir, IsSystem); + Result = Loader.loadModuleMapFile(); } LoadedModuleMap[File] = Result; diff --git a/clang/lib/Lex/ModuleMapFile.cpp b/clang/lib/Lex/ModuleMapFile.cpp index 00337b830ad4c..d59f37a3345bd 100644 --- a/clang/lib/Lex/ModuleMapFile.cpp +++ b/clang/lib/Lex/ModuleMapFile.cpp @@ -167,10 +167,7 @@ modulemap::parseModuleMap(FileID ID, clang::DirectoryEntryRef Dir, if (Failed) return std::nullopt; - Parser.MMF.ID = ID; - Parser.MMF.Dir = Dir; Parser.MMF.Start = Start; - Parser.MMF.IsSystem = IsSystem; return std::move(Parser.MMF); } diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index c26aa3308aca3..86b6dcbbf6167 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -397,7 +397,7 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, case ModuleDeclKind::PartitionInterface: { // We can't have parsed or imported a definition of this module or parsed a // module map defining it already. - if (auto *M = Map.findOrLoadModule(ModuleName)) { + if (auto *M = Map.findModule(ModuleName)) { Diag(Path[0].getLoc(), diag::err_module_redefinition) << ModuleName; if (M->DefinitionLoc.isValid()) Diag(M->DefinitionLoc, diag::note_prev_module_definition); diff --git a/clang/test/ClangScanDeps/modules-canononical-module-map-case.c b/clang/test/ClangScanDeps/modules-canononical-module-map-case.c index 34d5949c6bac2..ccb0653dfc5ec 100644 --- a/clang/test/ClangScanDeps/modules-canononical-module-map-case.c +++ b/clang/test/ClangScanDeps/modules-canononical-module-map-case.c @@ -36,17 +36,6 @@ framework module FW { ], "name": "DIR/frameworks/FW.framework/Headers", "type": "directory" - }, - { - "contents": [ - { - "external-contents": "DIR/frameworks/FW.framework/Modules/module.modulemap", - "name": "module.modulemap", - "type": "file" - } - ], - "name": "DIR/frameworks/FW.framework/Modules", - "type": "directory" } ] } diff --git a/clang/test/Modules/Inputs/shadow/A1/A1.h b/clang/test/Modules/Inputs/shadow/A1/A1.h deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/clang/test/Modules/Inputs/shadow/A1/module.modulemap b/clang/test/Modules/Inputs/shadow/A1/module.modulemap index 3a47280776ae2..9439a431b1dbe 100644 --- a/clang/test/Modules/Inputs/shadow/A1/module.modulemap +++ b/clang/test/Modules/Inputs/shadow/A1/module.modulemap @@ -2,6 +2,4 @@ module A { header "A.h" } -module A1 { - header "A1.h" -} +module A1 {} diff --git a/clang/test/Modules/Inputs/shadow/A2/A2.h b/clang/test/Modules/Inputs/shadow/A2/A2.h deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/clang/test/Modules/Inputs/shadow/A2/module.modulemap b/clang/test/Modules/Inputs/shadow/A2/module.modulemap index 9e6fe6448ead8..935d89bb425e0 100644 --- a/clang/test/Modules/Inputs/shadow/A2/module.modulemap +++ b/clang/test/Modules/Inputs/shadow/A2/module.modulemap @@ -2,6 +2,4 @@ module A { header "A.h" } -module A2 { - header "A2.h" -} +module A2 {} diff --git a/clang/test/Modules/lazy-by-name-lookup.c b/clang/test/Modules/lazy-by-name-lookup.c deleted file mode 100644 index 11a3a5cda709d..0000000000000 --- a/clang/test/Modules/lazy-by-name-lookup.c +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: rm -rf %t -// RUN: split-file %s %t -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -I%t \ -// RUN: -fmodules-cache-path=%t/cache %t/tu.c -fsyntax-only -Rmodule-map \ -// RUN: -verify - -//--- module.modulemap - -module A { - header "A.h" -} - -module B { - header "B.h" -} - -//--- A.h - -//--- B.h - -//--- tu.c - -#pragma clang __debug module_lookup A // does module map search for A -#pragma clang __debug module_map A // A is now in the ModuleMap, -#pragma clang __debug module_map B // expected-warning{{unknown module 'B'}} - // but B isn't. -#include // Now load B via header search - -// expected-remark@*{{parsing modulemap}} -// expected-remark@*{{loading parsed module 'A'}} -// expected-remark@*{{loading modulemap}} \ No newline at end of file diff --git a/clang/test/Modules/shadow.m b/clang/test/Modules/shadow.m index c45d0185d4d80..44320af2b0c66 100644 --- a/clang/test/Modules/shadow.m +++ b/clang/test/Modules/shadow.m @@ -1,14 +1,13 @@ // RUN: rm -rf %t -// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/shadow/A1 -I %S/Inputs/shadow/A2 -I %S/Inputs/shadow %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION -// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -fmodule-map-file=%S/Inputs/shadow/A2/module.modulemap %S/Inputs/shadow %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION +// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/shadow/A1 -I %S/Inputs/shadow/A2 %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION +// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -fmodule-map-file=%S/Inputs/shadow/A2/module.modulemap %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION // REDEFINITION: error: redefinition of module 'A' // REDEFINITION: note: previously defined -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c-header %S/Inputs/shadow/A1/module.modulemap -emit-module -o %t/A.pcm -fmodule-name=A -// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -fmodule-file=A=%t/A.pcm -I %S/Inputs/shadow %s -verify +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -I %S/Inputs/shadow %s -verify -#import "A1/A1.h" -#import "A2/A2.h" +@import A1; +@import A2; @import A; #import "A2/A.h" // expected-note {{implicitly imported}} diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp index cfd1e8efabf08..e314ffb1260dd 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -330,7 +330,7 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module, auto file = HS.lookupModuleMapFile(*dir, is_framework); if (!file) return error(); - if (HS.parseAndLoadModuleMapFile(*file, is_system)) + if (HS.loadModuleMapFile(*file, is_system)) return error(); } }