diff options
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 139 |
1 files changed, 101 insertions, 38 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 267d318fa98..f06633ca511 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -31,6 +31,7 @@ #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Sema/Sema.h" #include "clang/Serialization/ASTReader.h" +#include "clang/Serialization/GlobalModuleIndex.h" #include "llvm/ADT/Statistic.h" #include "llvm/Config/config.h" #include "llvm/Support/CrashRecoveryContext.h" @@ -49,9 +50,11 @@ using namespace clang; -CompilerInstance::CompilerInstance() - : Invocation(new CompilerInvocation()), ModuleManager(0), - BuildGlobalModuleIndex(false), ModuleBuildFailed(false) { +CompilerInstance::CompilerInstance(bool BuildingModule) + : ModuleLoader(BuildingModule), + Invocation(new CompilerInvocation()), ModuleManager(0), + BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false), + ModuleBuildFailed(false) { } CompilerInstance::~CompilerInstance() { @@ -830,7 +833,7 @@ static void compileModuleImpl(CompilerInstance &ImportingInstance, // Construct a compiler instance that will be used to actually create the // module. - CompilerInstance Instance; + CompilerInstance Instance(/*BuildingModule=*/true); Instance.setInvocation(&*Invocation); Instance.createDiagnostics(new ForwardingDiagnosticConsumer( @@ -1097,6 +1100,43 @@ static void pruneModuleCache(const HeaderSearchOptions &HSOpts) { } } +void CompilerInstance::createModuleManager() { + if (!ModuleManager) { + if (!hasASTContext()) + createASTContext(); + + // If we're not recursively building a module, check whether we + // need to prune the module cache. + if (getSourceManager().getModuleBuildStack().empty() && + getHeaderSearchOpts().ModuleCachePruneInterval > 0 && + getHeaderSearchOpts().ModuleCachePruneAfter > 0) { + pruneModuleCache(getHeaderSearchOpts()); + } + + HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); + std::string Sysroot = HSOpts.Sysroot; + const PreprocessorOptions &PPOpts = getPreprocessorOpts(); + ModuleManager = new ASTReader(getPreprocessor(), *Context, + Sysroot.empty() ? "" : Sysroot.c_str(), + PPOpts.DisablePCHValidation, + /*AllowASTWithCompilerErrors=*/false, + /*AllowConfigurationMismatch=*/false, + HSOpts.ModulesValidateSystemHeaders, + getFrontendOpts().UseGlobalModuleIndex); + if (hasASTConsumer()) { + ModuleManager->setDeserializationListener( + getASTConsumer().GetASTDeserializationListener()); + getASTContext().setASTMutationListener( + getASTConsumer().GetASTMutationListener()); + } + getASTContext().setExternalSource(ModuleManager); + if (hasSema()) + ModuleManager->InitializeSema(getSema()); + if (hasASTConsumer()) + ModuleManager->StartTranslationUnit(&getASTConsumer()); + } +} + ModuleLoadResult CompilerInstance::loadModule(SourceLocation ImportLoc, ModuleIdPath Path, @@ -1143,40 +1183,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, std::string ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module); // If we don't already have an ASTReader, create one now. - if (!ModuleManager) { - if (!hasASTContext()) - createASTContext(); - - // If we're not recursively building a module, check whether we - // need to prune the module cache. - if (getSourceManager().getModuleBuildStack().empty() && - getHeaderSearchOpts().ModuleCachePruneInterval > 0 && - getHeaderSearchOpts().ModuleCachePruneAfter > 0) { - pruneModuleCache(getHeaderSearchOpts()); - } - - HeaderSearchOptions &HSOpts = getHeaderSearchOpts(); - std::string Sysroot = HSOpts.Sysroot; - const PreprocessorOptions &PPOpts = getPreprocessorOpts(); - ModuleManager = new ASTReader(getPreprocessor(), *Context, - Sysroot.empty() ? "" : Sysroot.c_str(), - PPOpts.DisablePCHValidation, - /*AllowASTWithCompilerErrors=*/false, - /*AllowConfigurationMismatch=*/false, - HSOpts.ModulesValidateSystemHeaders, - getFrontendOpts().UseGlobalModuleIndex); - if (hasASTConsumer()) { - ModuleManager->setDeserializationListener( - getASTConsumer().GetASTDeserializationListener()); - getASTContext().setASTMutationListener( - getASTConsumer().GetASTMutationListener()); - } - getASTContext().setExternalSource(ModuleManager); - if (hasSema()) - ModuleManager->InitializeSema(getSema()); - if (hasASTConsumer()) - ModuleManager->StartTranslationUnit(&getASTConsumer()); - } + if (!ModuleManager) + createModuleManager(); if (TheDependencyFileGenerator) TheDependencyFileGenerator->AttachToASTReader(*ModuleManager); @@ -1403,3 +1411,58 @@ void CompilerInstance::makeModuleVisible(Module *Mod, ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain); } +GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex( + SourceLocation TriggerLoc) { + if (!ModuleManager) + createModuleManager(); + // Can't do anything if we don't have the module manager. + if (!ModuleManager) + return 0; + // Get an existing global index. This loads it if not already + // loaded. + ModuleManager->loadGlobalIndex(); + GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex(); + // If the global index doesn't exist, create it. + if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() && + hasPreprocessor()) { + llvm::sys::fs::create_directories( + getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); + GlobalModuleIndex::writeIndex( + getFileManager(), + getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); + ModuleManager->resetForReload(); + ModuleManager->loadGlobalIndex(); + GlobalIndex = ModuleManager->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. + if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) { + ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap(); + bool RecreateIndex = false; + for (ModuleMap::module_iterator I = MMap.module_begin(), + E = MMap.module_end(); I != E; ++I) { + Module *TheModule = I->second; + const FileEntry *Entry = TheModule->getASTFile(); + if (!Entry) { + SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path; + Path.push_back(std::make_pair( + getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc)); + std::reverse(Path.begin(), Path.end()); + // Load a module as hidden. This also adds it to the global index. + ModuleLoadResult Result = loadModule(TheModule->DefinitionLoc, Path, + Module::Hidden, false); + RecreateIndex = true; + } + } + if (RecreateIndex) { + GlobalModuleIndex::writeIndex( + getFileManager(), + getPreprocessor().getHeaderSearchInfo().getModuleCachePath()); + ModuleManager->resetForReload(); + ModuleManager->loadGlobalIndex(); + GlobalIndex = ModuleManager->getGlobalIndex(); + } + HaveFullGlobalModuleIndex = true; + } + return GlobalIndex; +} |