diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -791,6 +791,12 @@ SourceLocation ModuleNameLoc, bool IsInclusionDirective); + // Get the submodule corresponding to the module path. + Module *getSubmoduleCorrespondingToPath( + bool &MapPrivateSubModToTopLevel, Module *Module, SourceLocation ImportLoc, + ModuleIdPath Path, Module::NameVisibilityKind Visibility, + bool IsInclusionDirective); + public: ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1931,65 +1931,12 @@ return M; } -ModuleLoadResult -CompilerInstance::loadModule(SourceLocation ImportLoc, - ModuleIdPath Path, - Module::NameVisibilityKind Visibility, - bool IsInclusionDirective) { - // Determine what file we're searching from. - StringRef ModuleName = Path[0].first->getName(); - SourceLocation ModuleNameLoc = Path[0].second; - - // If we've already handled this import, just return the cached result. - // This one-element cache is important to eliminate redundant diagnostics - // when both the preprocessor and parser see the same import declaration. - if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) { - // Make the named module visible. - if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) - TheASTReader->makeModuleVisible(LastModuleImportResult, Visibility, - ImportLoc); - return LastModuleImportResult; - } - - // If we don't already have information on this module, load the module now. - Module *Module = nullptr; - ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap(); - if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) { - // Use the cached result, which may be nullptr. - Module = *MaybeModule; - } else if (ModuleName == getLangOpts().CurrentModule) { - // This is the module we're building. - Module = PP->getHeaderSearchInfo().lookupModule( - ModuleName, ImportLoc, /*AllowSearch*/ true, - /*AllowExtraModuleMapSearch*/ !IsInclusionDirective); - /// FIXME: perhaps we should (a) look for a module using the module name - // to file map (PrebuiltModuleFiles) and (b) diagnose if still not found? - //if (Module == nullptr) { - // getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) - // << ModuleName; - // DisableGeneratingGlobalModuleIndex = true; - // return ModuleLoadResult(); - //} - MM.cacheModuleLoad(*Path[0].first, Module); - } else { - ModuleLoadResult Result = findOrCompileModuleAndReadAST( - ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective); - if (!Result.isNormal()) - return Result; - if (!Result) - DisableGeneratingGlobalModuleIndex = true; - Module = Result; - MM.cacheModuleLoad(*Path[0].first, Module); - } - - // If we never found the module, fail. Otherwise, verify the module and link - // it up. - if (!Module) - return ModuleLoadResult(); +Module *CompilerInstance::getSubmoduleCorrespondingToPath( + bool &MapPrivateSubModToTopLevel, Module *Module, SourceLocation ImportLoc, + ModuleIdPath Path, Module::NameVisibilityKind Visibility, + bool IsInclusionDirective) { + MapPrivateSubModToTopLevel = false; - // Verify that the rest of the module path actually corresponds to - // a submodule. - bool MapPrivateSubModToTopLevel = false; for (unsigned I = 1, N = Path.size(); I != N; ++I) { StringRef Name = Path[I].first->getName(); clang::Module *Sub = Module->findSubmodule(Name); @@ -2070,6 +2017,70 @@ Module = Sub; } + return Module; +} + +ModuleLoadResult +CompilerInstance::loadModule(SourceLocation ImportLoc, + ModuleIdPath Path, + Module::NameVisibilityKind Visibility, + bool IsInclusionDirective) { + // Determine what file we're searching from. + StringRef ModuleName = Path[0].first->getName(); + SourceLocation ModuleNameLoc = Path[0].second; + + // If we've already handled this import, just return the cached result. + // This one-element cache is important to eliminate redundant diagnostics + // when both the preprocessor and parser see the same import declaration. + if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) { + // Make the named module visible. + if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) + TheASTReader->makeModuleVisible(LastModuleImportResult, Visibility, + ImportLoc); + return LastModuleImportResult; + } + + // If we don't already have information on this module, load the module now. + Module *Module = nullptr; + ModuleMap &MM = getPreprocessor().getHeaderSearchInfo().getModuleMap(); + if (auto MaybeModule = MM.getCachedModuleLoad(*Path[0].first)) { + // Use the cached result, which may be nullptr. + Module = *MaybeModule; + } else if (ModuleName == getLangOpts().CurrentModule) { + // This is the module we're building. + Module = PP->getHeaderSearchInfo().lookupModule( + ModuleName, ImportLoc, /*AllowSearch*/ true, + /*AllowExtraModuleMapSearch*/ !IsInclusionDirective); + /// FIXME: perhaps we should (a) look for a module using the module name + // to file map (PrebuiltModuleFiles) and (b) diagnose if still not found? + //if (Module == nullptr) { + // getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) + // << ModuleName; + // DisableGeneratingGlobalModuleIndex = true; + // return ModuleLoadResult(); + //} + MM.cacheModuleLoad(*Path[0].first, Module); + } else { + ModuleLoadResult Result = findOrCompileModuleAndReadAST( + ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective); + if (!Result.isNormal()) + return Result; + if (!Result) + DisableGeneratingGlobalModuleIndex = true; + Module = Result; + MM.cacheModuleLoad(*Path[0].first, Module); + } + + // If we never found the module, fail. Otherwise, verify the module and link + // it up. + if (!Module) + return ModuleLoadResult(); + + bool MapPrivateSubModToTopLevel = false; + Module = getSubmoduleCorrespondingToPath(MapPrivateSubModToTopLevel, Module, + ImportLoc, Path, Visibility, + IsInclusionDirective); + // Make the named module visible, if it's not already part of the module // we are parsing. if (ModuleName != getLangOpts().CurrentModule) {