summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp139
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;
+}
OpenPOWER on IntegriCloud