diff options
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 625 |
1 files changed, 333 insertions, 292 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index c409c07ff133a..688f21dd0908b 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -75,7 +75,7 @@ void CompilerInstance::setInvocation( bool CompilerInstance::shouldBuildGlobalModuleIndex() const { return (BuildGlobalModuleIndex || - (ModuleManager && ModuleManager->isGlobalIndexUnavailable() && + (TheASTReader && TheASTReader->isGlobalIndexUnavailable() && getFrontendOpts().GenerateGlobalModuleIndex)) && !ModuleBuildFailed; } @@ -135,13 +135,13 @@ std::unique_ptr<Sema> CompilerInstance::takeSema() { return std::move(TheSema); } -IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { - return ModuleManager; +IntrusiveRefCntPtr<ASTReader> CompilerInstance::getASTReader() const { + return TheASTReader; } void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { assert(ModuleCache.get() == &Reader->getModuleManager().getModuleCache() && "Expected ASTReader to use the same PCM cache"); - ModuleManager = std::move(Reader); + TheASTReader = std::move(Reader); } std::shared_ptr<ModuleDependencyCollector> @@ -380,7 +380,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { const PreprocessorOptions &PPOpts = getPreprocessorOpts(); // The module manager holds a reference to the old preprocessor (if any). - ModuleManager.reset(); + TheASTReader.reset(); // Create the Preprocessor. HeaderSearch *HeaderInfo = @@ -494,7 +494,7 @@ void CompilerInstance::createPCHExternalASTSource( StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, void *DeserializationListener, bool OwnDeserializationListener) { bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; - ModuleManager = createPCHExternalASTSource( + TheASTReader = createPCHExternalASTSource( Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, AllowPCHWithCompilerErrors, getPreprocessor(), getModuleCache(), getASTContext(), getPCHContainerReader(), @@ -672,7 +672,7 @@ CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile, StringRef Extension) { return createOutputFile(getFrontendOpts().OutputFile, Binary, /*RemoveFileOnSignal=*/true, InFile, Extension, - /*UseTemporary=*/true); + getFrontendOpts().UseTemporary); } std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() { @@ -917,8 +917,9 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) { if (!hasTarget()) return false; - // Create TargetInfo for the other side of CUDA and OpenMP compilation. - if ((getLangOpts().CUDA || getLangOpts().OpenMPIsDevice) && + // Create TargetInfo for the other side of CUDA/OpenMP/SYCL compilation. + if ((getLangOpts().CUDA || getLangOpts().OpenMPIsDevice || + getLangOpts().SYCLIsDevice) && !getFrontendOpts().AuxTriple.empty()) { auto TO = std::make_shared<TargetOptions>(); TO->Triple = llvm::Triple::normalize(getFrontendOpts().AuxTriple); @@ -1179,13 +1180,12 @@ static const FileEntry *getPublicModuleMap(const FileEntry *File, return nullptr; } -/// Compile a module file for the given module, using the options -/// provided by the importing compiler instance. Returns true if the module -/// was built without errors. -static bool compileModuleImpl(CompilerInstance &ImportingInstance, - SourceLocation ImportLoc, - Module *Module, - StringRef ModuleFileName) { +/// Compile a module file for the given module in a separate compiler instance, +/// using the options provided by the importing compiler instance. Returns true +/// if the module was built without errors. +static bool compileModule(CompilerInstance &ImportingInstance, + SourceLocation ImportLoc, Module *Module, + StringRef ModuleFileName) { InputKind IK(getLanguageFromOptions(ImportingInstance.getLangOpts()), InputKind::ModuleMap); @@ -1245,10 +1245,17 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance, return Result; } -static bool compileAndLoadModule(CompilerInstance &ImportingInstance, - SourceLocation ImportLoc, - SourceLocation ModuleNameLoc, Module *Module, - StringRef ModuleFileName) { +/// Compile a module in a separate compiler instance and read the AST, +/// returning true if the module compiles without errors. +/// +/// Uses a lock file manager and exponential backoff to reduce the chances that +/// multiple instances will compete to create the same module. On timeout, +/// deletes the lock file in order to avoid deadlock from crashing processes or +/// bugs in the lock file manager. +static bool compileModuleAndReadAST(CompilerInstance &ImportingInstance, + SourceLocation ImportLoc, + SourceLocation ModuleNameLoc, + Module *Module, StringRef ModuleFileName) { DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics(); auto diagnoseBuildFailure = [&] { @@ -1276,8 +1283,8 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance, LLVM_FALLTHROUGH; case llvm::LockFileManager::LFS_Owned: // We're responsible for building the module ourselves. - if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module, - ModuleFileName)) { + if (!compileModule(ImportingInstance, ModuleNameLoc, Module, + ModuleFileName)) { diagnoseBuildFailure(); return false; } @@ -1307,7 +1314,7 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance, // Try to read the module file, now that we've compiled it. ASTReader::ASTReadResult ReadResult = - ImportingInstance.getModuleManager()->ReadAST( + ImportingInstance.getASTReader()->ReadAST( ModuleFileName, serialization::MK_ImplicitModule, ImportLoc, ModuleLoadCapabilities); @@ -1471,52 +1478,52 @@ static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { } } -void CompilerInstance::createModuleManager() { - if (!ModuleManager) { - if (!hasASTContext()) - createASTContext(); +void CompilerInstance::createASTReader() { + if (TheASTReader) + return; - // If we're implicitly building modules but not currently recursively - // building a module, check whether we need to prune the module cache. - if (getSourceManager().getModuleBuildStack().empty() && - !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() && - getHeaderSearchOpts().ModuleCachePruneInterval > 0 && - getHeaderSearchOpts().ModuleCachePruneAfter > 0) { - pruneModuleCache(getHeaderSearchOpts()); - } + if (!hasASTContext()) + createASTContext(); + + // If we're implicitly building modules but not currently recursively + // building a module, check whether we need to prune the module cache. + if (getSourceManager().getModuleBuildStack().empty() && + !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() && + getHeaderSearchOpts().ModuleCachePruneInterval > 0 && + getHeaderSearchOpts().ModuleCachePruneAfter > 0) { + pruneModuleCache(getHeaderSearchOpts()); + } - HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); - std::string Sysroot = HSOpts.Sysroot; - const PreprocessorOptions &PPOpts = getPreprocessorOpts(); - std::unique_ptr<llvm::Timer> ReadTimer; - if (FrontendTimerGroup) - ReadTimer = std::make_unique<llvm::Timer>("reading_modules", - "Reading modules", - *FrontendTimerGroup); - ModuleManager = new ASTReader( - getPreprocessor(), getModuleCache(), &getASTContext(), - getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions, - Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, - /*AllowASTWithCompilerErrors=*/false, - /*AllowConfigurationMismatch=*/false, - HSOpts.ModulesValidateSystemHeaders, - HSOpts.ValidateASTInputFilesContent, - getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer)); - if (hasASTConsumer()) { - ModuleManager->setDeserializationListener( + HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); + std::string Sysroot = HSOpts.Sysroot; + const PreprocessorOptions &PPOpts = getPreprocessorOpts(); + std::unique_ptr<llvm::Timer> ReadTimer; + if (FrontendTimerGroup) + ReadTimer = std::make_unique<llvm::Timer>("reading_modules", + "Reading modules", + *FrontendTimerGroup); + TheASTReader = new ASTReader( + getPreprocessor(), getModuleCache(), &getASTContext(), + getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions, + Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation, + /*AllowASTWithCompilerErrors=*/false, + /*AllowConfigurationMismatch=*/false, HSOpts.ModulesValidateSystemHeaders, + HSOpts.ValidateASTInputFilesContent, + getFrontendOpts().UseGlobalModuleIndex, std::move(ReadTimer)); + if (hasASTConsumer()) { + TheASTReader->setDeserializationListener( getASTConsumer().GetASTDeserializationListener()); - getASTContext().setASTMutationListener( - getASTConsumer().GetASTMutationListener()); - } - getASTContext().setExternalSource(ModuleManager); - if (hasSema()) - ModuleManager->InitializeSema(getSema()); - if (hasASTConsumer()) - ModuleManager->StartTranslationUnit(&getASTConsumer()); - - for (auto &Listener : DependencyCollectors) - Listener->attachToASTReader(*ModuleManager); + getASTContext().setASTMutationListener( + getASTConsumer().GetASTMutationListener()); } + getASTContext().setExternalSource(TheASTReader); + if (hasSema()) + TheASTReader->InitializeSema(getSema()); + if (hasASTConsumer()) + TheASTReader->StartTranslationUnit(&getASTConsumer()); + + for (auto &Listener : DependencyCollectors) + Listener->attachToASTReader(*TheASTReader); } bool CompilerInstance::loadModuleFile(StringRef FileName) { @@ -1541,12 +1548,9 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { } void registerAll() { - for (auto *II : LoadedModules) { - CI.KnownModules[II] = CI.getPreprocessor() - .getHeaderSearchInfo() - .getModuleMap() - .findModule(II->getName()); - } + ModuleMap &MM = CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(); + for (auto *II : LoadedModules) + MM.cacheModuleLoad(*II, MM.findModule(II->getName())); LoadedModules.clear(); } @@ -1576,8 +1580,8 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { }; // If we don't already have an ASTReader, create one now. - if (!ModuleManager) - createModuleManager(); + if (!TheASTReader) + createASTReader(); // If -Wmodule-file-config-mismatch is mapped as an error or worse, allow the // ASTReader to diagnose it, since it can produce better errors that we can. @@ -1588,11 +1592,11 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { auto Listener = std::make_unique<ReadModuleNames>(*this); auto &ListenerRef = *Listener; - ASTReader::ListenerScope ReadModuleNamesListener(*ModuleManager, + ASTReader::ListenerScope ReadModuleNamesListener(*TheASTReader, std::move(Listener)); // Try to load the module file. - switch (ModuleManager->ReadAST( + switch (TheASTReader->ReadAST( FileName, serialization::MK_ExplicitModule, SourceLocation(), ConfigMismatchIsRecoverable ? ASTReader::ARR_ConfigurationMismatch : 0)) { case ASTReader::Success: @@ -1615,6 +1619,220 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { } } +namespace { +enum ModuleSource { + MS_ModuleNotFound, + MS_ModuleCache, + MS_PrebuiltModulePath, + MS_ModuleBuildPragma +}; +} // end namespace + +/// Select a source for loading the named module and compute the filename to +/// load it from. +static ModuleSource +selectModuleSource(Module *M, StringRef ModuleName, std::string &ModuleFilename, + const std::map<std::string, std::string> &BuiltModules, + HeaderSearch &HS) { + assert(ModuleFilename.empty() && "Already has a module source?"); + + // Check to see if the module has been built as part of this compilation + // via a module build pragma. + auto BuiltModuleIt = BuiltModules.find(ModuleName); + if (BuiltModuleIt != BuiltModules.end()) { + ModuleFilename = BuiltModuleIt->second; + return MS_ModuleBuildPragma; + } + + // Try to load the module from the prebuilt module path. + const HeaderSearchOptions &HSOpts = HS.getHeaderSearchOpts(); + if (!HSOpts.PrebuiltModuleFiles.empty() || + !HSOpts.PrebuiltModulePaths.empty()) { + ModuleFilename = HS.getPrebuiltModuleFileName(ModuleName); + if (!ModuleFilename.empty()) + return MS_PrebuiltModulePath; + } + + // Try to load the module from the module cache. + if (M) { + ModuleFilename = HS.getCachedModuleFileName(M); + return MS_ModuleCache; + } + + return MS_ModuleNotFound; +} + +ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST( + StringRef ModuleName, SourceLocation ImportLoc, + SourceLocation ModuleNameLoc, bool IsInclusionDirective) { + // Search for a module with the given name. + HeaderSearch &HS = PP->getHeaderSearchInfo(); + Module *M = HS.lookupModule(ModuleName, true, !IsInclusionDirective); + + // Select the source and filename for loading the named module. + std::string ModuleFilename; + ModuleSource Source = + selectModuleSource(M, ModuleName, ModuleFilename, BuiltModules, HS); + if (Source == MS_ModuleNotFound) { + // We can't find a module, error out here. + getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) + << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); + ModuleBuildFailed = true; + // FIXME: Why is this not cached? + return ModuleLoadResult::OtherUncachedFailure; + } + if (ModuleFilename.empty()) { + if (M && M->HasIncompatibleModuleFile) { + // We tried and failed to load a module file for this module. Fall + // back to textual inclusion for its headers. + return ModuleLoadResult::ConfigMismatch; + } + + getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled) + << ModuleName; + ModuleBuildFailed = true; + // FIXME: Why is this not cached? + return ModuleLoadResult::OtherUncachedFailure; + } + + // Create an ASTReader on demand. + if (!getASTReader()) + createASTReader(); + + // Time how long it takes to load the module. + llvm::Timer Timer; + if (FrontendTimerGroup) + Timer.init("loading." + ModuleFilename, "Loading " + ModuleFilename, + *FrontendTimerGroup); + llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); + llvm::TimeTraceScope TimeScope("Module Load", ModuleName); + + // Try to load the module file. If we are not trying to load from the + // module cache, we don't know how to rebuild modules. + unsigned ARRFlags = Source == MS_ModuleCache + ? ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing + : Source == MS_PrebuiltModulePath + ? 0 + : ASTReader::ARR_ConfigurationMismatch; + switch (getASTReader()->ReadAST(ModuleFilename, + Source == MS_PrebuiltModulePath + ? serialization::MK_PrebuiltModule + : Source == MS_ModuleBuildPragma + ? serialization::MK_ExplicitModule + : serialization::MK_ImplicitModule, + ImportLoc, ARRFlags)) { + case ASTReader::Success: { + if (M) + return M; + assert(Source != MS_ModuleCache && + "missing module, but file loaded from cache"); + + // A prebuilt module is indexed as a ModuleFile; the Module does not exist + // until the first call to ReadAST. Look it up now. + M = HS.lookupModule(ModuleName, true, !IsInclusionDirective); + + // Check whether M refers to the file in the prebuilt module path. + if (M && M->getASTFile()) + if (auto ModuleFile = FileMgr->getFile(ModuleFilename)) + if (*ModuleFile == M->getASTFile()) + return M; + + ModuleBuildFailed = true; + getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt) + << ModuleName; + return ModuleLoadResult(); + } + + case ASTReader::OutOfDate: + case ASTReader::Missing: + // The most interesting case. + break; + + case ASTReader::ConfigurationMismatch: + if (Source == MS_PrebuiltModulePath) + // FIXME: We shouldn't be setting HadFatalFailure below if we only + // produce a warning here! + getDiagnostics().Report(SourceLocation(), + diag::warn_module_config_mismatch) + << ModuleFilename; + // Fall through to error out. + LLVM_FALLTHROUGH; + case ASTReader::VersionMismatch: + case ASTReader::HadErrors: + // FIXME: Should this set ModuleBuildFailed = true? + ModuleLoader::HadFatalFailure = true; + // FIXME: The ASTReader will already have complained, but can we shoehorn + // that diagnostic information into a more useful form? + return ModuleLoadResult(); + + case ASTReader::Failure: + // FIXME: Should this set ModuleBuildFailed = true? + ModuleLoader::HadFatalFailure = true; + return ModuleLoadResult(); + } + + // ReadAST returned Missing or OutOfDate. + if (Source != MS_ModuleCache) { + // We don't know the desired configuration for this module and don't + // necessarily even have a module map. Since ReadAST already produces + // diagnostics for these two cases, we simply error out here. + ModuleBuildFailed = true; + return ModuleLoadResult(); + } + + // The module file is missing or out-of-date. Build it. + assert(M && "missing module, but trying to compile for cache"); + + // Check whether there is a cycle in the module graph. + ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); + ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); + for (; Pos != PosEnd; ++Pos) { + if (Pos->first == ModuleName) + break; + } + + if (Pos != PosEnd) { + SmallString<256> CyclePath; + for (; Pos != PosEnd; ++Pos) { + CyclePath += Pos->first; + CyclePath += " -> "; + } + CyclePath += ModuleName; + + getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) + << ModuleName << CyclePath; + // FIXME: Should this set ModuleBuildFailed = true? + // FIXME: Why is this not cached? + return ModuleLoadResult::OtherUncachedFailure; + } + + // Check whether we have already attempted to build this module (but + // failed). + if (getPreprocessorOpts().FailedModules && + getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { + getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) + << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); + ModuleBuildFailed = true; + // FIXME: Why is this not cached? + return ModuleLoadResult::OtherUncachedFailure; + } + + // Try to compile and then read the AST. + if (!compileModuleAndReadAST(*this, ImportLoc, ModuleNameLoc, M, + ModuleFilename)) { + assert(getDiagnostics().hasErrorOccurred() && + "undiagnosed error in compileModuleAndReadAST"); + if (getPreprocessorOpts().FailedModules) + getPreprocessorOpts().FailedModules->addFailed(ModuleName); + ModuleBuildFailed = true; + // FIXME: Why is this not cached? + return ModuleLoadResult::OtherUncachedFailure; + } + + // Okay, we've rebuilt and now loaded the module. + return M; +} + ModuleLoadResult CompilerInstance::loadModule(SourceLocation ImportLoc, ModuleIdPath Path, @@ -1630,19 +1848,17 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) { // Make the named module visible. if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule) - ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility, - ImportLoc); + TheASTReader->makeModuleVisible(LastModuleImportResult, Visibility, + ImportLoc); return LastModuleImportResult; } - clang::Module *Module = nullptr; - // If we don't already have information on this module, load the module now. - llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known - = KnownModules.find(Path[0].first); - if (Known != KnownModules.end()) { - // Retrieve the cached top-level module. - Module = Known->second; + 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( @@ -1656,198 +1872,23 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, // ModuleBuildFailed = true; // return ModuleLoadResult(); //} - Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; + MM.cacheModuleLoad(*Path[0].first, Module); } else { - // Search for a module with the given name. - Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true, - !IsInclusionDirective); - HeaderSearchOptions &HSOpts = - PP->getHeaderSearchInfo().getHeaderSearchOpts(); - - std::string ModuleFileName; - enum ModuleSource { - ModuleNotFound, ModuleCache, PrebuiltModulePath, ModuleBuildPragma - } Source = ModuleNotFound; - - // Check to see if the module has been built as part of this compilation - // via a module build pragma. - auto BuiltModuleIt = BuiltModules.find(ModuleName); - if (BuiltModuleIt != BuiltModules.end()) { - ModuleFileName = BuiltModuleIt->second; - Source = ModuleBuildPragma; - } - - // Try to load the module from the prebuilt module path. - if (Source == ModuleNotFound && (!HSOpts.PrebuiltModuleFiles.empty() || - !HSOpts.PrebuiltModulePaths.empty())) { - ModuleFileName = - PP->getHeaderSearchInfo().getPrebuiltModuleFileName(ModuleName); - if (!ModuleFileName.empty()) - Source = PrebuiltModulePath; - } - - // Try to load the module from the module cache. - if (Source == ModuleNotFound && Module) { - ModuleFileName = PP->getHeaderSearchInfo().getCachedModuleFileName(Module); - Source = ModuleCache; - } - - if (Source == ModuleNotFound) { - // We can't find a module, error out here. - getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found) - << ModuleName << SourceRange(ImportLoc, ModuleNameLoc); - ModuleBuildFailed = true; - return ModuleLoadResult(); - } - - if (ModuleFileName.empty()) { - if (Module && Module->HasIncompatibleModuleFile) { - // We tried and failed to load a module file for this module. Fall - // back to textual inclusion for its headers. - return ModuleLoadResult::ConfigMismatch; - } - - getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled) - << ModuleName; - ModuleBuildFailed = true; - return ModuleLoadResult(); - } - - // If we don't already have an ASTReader, create one now. - if (!ModuleManager) - createModuleManager(); - - llvm::Timer Timer; - if (FrontendTimerGroup) - Timer.init("loading." + ModuleFileName, "Loading " + ModuleFileName, - *FrontendTimerGroup); - llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr); - llvm::TimeTraceScope TimeScope("Module Load", ModuleName); - - // Try to load the module file. If we are not trying to load from the - // module cache, we don't know how to rebuild modules. - unsigned ARRFlags = Source == ModuleCache ? - ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing : - Source == PrebuiltModulePath ? - 0 : - ASTReader::ARR_ConfigurationMismatch; - switch (ModuleManager->ReadAST(ModuleFileName, - Source == PrebuiltModulePath - ? serialization::MK_PrebuiltModule - : Source == ModuleBuildPragma - ? serialization::MK_ExplicitModule - : serialization::MK_ImplicitModule, - ImportLoc, ARRFlags)) { - case ASTReader::Success: { - if (Source != ModuleCache && !Module) { - Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true, - !IsInclusionDirective); - auto ModuleFile = FileMgr->getFile(ModuleFileName); - if (!Module || !Module->getASTFile() || - !ModuleFile || (*ModuleFile != Module->getASTFile())) { - // Error out if Module does not refer to the file in the prebuilt - // module path. - getDiagnostics().Report(ModuleNameLoc, diag::err_module_prebuilt) - << ModuleName; - ModuleBuildFailed = true; - KnownModules[Path[0].first] = nullptr; - return ModuleLoadResult(); - } - } - break; - } - - case ASTReader::OutOfDate: - case ASTReader::Missing: { - if (Source != ModuleCache) { - // We don't know the desired configuration for this module and don't - // necessarily even have a module map. Since ReadAST already produces - // diagnostics for these two cases, we simply error out here. - ModuleBuildFailed = true; - KnownModules[Path[0].first] = nullptr; - return ModuleLoadResult(); - } - - // The module file is missing or out-of-date. Build it. - assert(Module && "missing module file"); - // Check whether there is a cycle in the module graph. - ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack(); - ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end(); - for (; Pos != PosEnd; ++Pos) { - if (Pos->first == ModuleName) - break; - } - - if (Pos != PosEnd) { - SmallString<256> CyclePath; - for (; Pos != PosEnd; ++Pos) { - CyclePath += Pos->first; - CyclePath += " -> "; - } - CyclePath += ModuleName; - - getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle) - << ModuleName << CyclePath; - return ModuleLoadResult(); - } - - // Check whether we have already attempted to build this module (but - // failed). - if (getPreprocessorOpts().FailedModules && - getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) { - getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built) - << ModuleName - << SourceRange(ImportLoc, ModuleNameLoc); - ModuleBuildFailed = true; - return ModuleLoadResult(); - } - - // Try to compile and then load the module. - if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module, - ModuleFileName)) { - assert(getDiagnostics().hasErrorOccurred() && - "undiagnosed error in compileAndLoadModule"); - if (getPreprocessorOpts().FailedModules) - getPreprocessorOpts().FailedModules->addFailed(ModuleName); - KnownModules[Path[0].first] = nullptr; - ModuleBuildFailed = true; - return ModuleLoadResult(); - } - - // Okay, we've rebuilt and now loaded the module. - break; - } - - case ASTReader::ConfigurationMismatch: - if (Source == PrebuiltModulePath) - // FIXME: We shouldn't be setting HadFatalFailure below if we only - // produce a warning here! - getDiagnostics().Report(SourceLocation(), - diag::warn_module_config_mismatch) - << ModuleFileName; - // Fall through to error out. - LLVM_FALLTHROUGH; - case ASTReader::VersionMismatch: - case ASTReader::HadErrors: - ModuleLoader::HadFatalFailure = true; - // FIXME: The ASTReader will already have complained, but can we shoehorn - // that diagnostic information into a more useful form? - KnownModules[Path[0].first] = nullptr; - return ModuleLoadResult(); - - case ASTReader::Failure: - ModuleLoader::HadFatalFailure = true; - // Already complained, but note now that we failed. - KnownModules[Path[0].first] = nullptr; - ModuleBuildFailed = true; - return ModuleLoadResult(); - } - - // Cache the result of this top-level module lookup for later. - Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first; + ModuleLoadResult Result = findOrCompileModuleAndReadAST( + ModuleName, ImportLoc, ModuleNameLoc, IsInclusionDirective); + // FIXME: Can we pull 'ModuleBuildFailed = true' out of the return + // sequences for findOrCompileModuleAndReadAST and do it here (as long as + // the result is not a config mismatch)? See FIXMEs there. + if (!Result.isNormal()) + return Result; + Module = Result; + MM.cacheModuleLoad(*Path[0].first, Module); + if (!Module) + return Module; } - // If we never found the module, fail. + // If we never found the module, fail. Otherwise, verify the module and link + // it up. if (!Module) return ModuleLoadResult(); @@ -1967,7 +2008,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, return ModuleLoadResult(); } - ModuleManager->makeModuleVisible(Module, Visibility, ImportLoc); + TheASTReader->makeModuleVisible(Module, Visibility, ImportLoc); } // Check for any configuration macros that have changed. @@ -1988,9 +2029,9 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, return LastModuleImportResult; } -void CompilerInstance::loadModuleFromSource(SourceLocation ImportLoc, - StringRef ModuleName, - StringRef Source) { +void CompilerInstance::createModuleFromSource(SourceLocation ImportLoc, + StringRef ModuleName, + StringRef Source) { // Avoid creating filenames with special characters. SmallString<128> CleanModuleName(ModuleName); for (auto &C : CleanModuleName) @@ -2044,27 +2085,27 @@ void CompilerInstance::loadModuleFromSource(SourceLocation ImportLoc, void CompilerInstance::makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, SourceLocation ImportLoc) { - if (!ModuleManager) - createModuleManager(); - if (!ModuleManager) + if (!TheASTReader) + createASTReader(); + if (!TheASTReader) return; - ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc); + TheASTReader->makeModuleVisible(Mod, Visibility, ImportLoc); } GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( SourceLocation TriggerLoc) { if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty()) return nullptr; - if (!ModuleManager) - createModuleManager(); + if (!TheASTReader) + createASTReader(); // Can't do anything if we don't have the module manager. - if (!ModuleManager) + if (!TheASTReader) return nullptr; // Get an existing global index. This loads it if not already // loaded. - ModuleManager->loadGlobalIndex(); - GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex(); + TheASTReader->loadGlobalIndex(); + GlobalModuleIndex *GlobalIndex = TheASTReader->getGlobalIndex(); // If the global index doesn't exist, create it. if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && hasPreprocessor()) { @@ -2080,9 +2121,9 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( consumeError(std::move(Err)); return nullptr; } - ModuleManager->resetForReload(); - ModuleManager->loadGlobalIndex(); - GlobalIndex = ModuleManager->getGlobalIndex(); + TheASTReader->resetForReload(); + TheASTReader->loadGlobalIndex(); + GlobalIndex = TheASTReader->getGlobalIndex(); } // For finding modules needing to be imported for fixit messages, // we need to make the global index cover all modules, so we do that here. @@ -2111,9 +2152,9 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( consumeError(std::move(Err)); return nullptr; } - ModuleManager->resetForReload(); - ModuleManager->loadGlobalIndex(); - GlobalIndex = ModuleManager->getGlobalIndex(); + TheASTReader->resetForReload(); + TheASTReader->loadGlobalIndex(); + GlobalIndex = TheASTReader->getGlobalIndex(); } HaveFullGlobalModuleIndex = true; } |