summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-11-29 23:55:25 +0000
committerDouglas Gregor <dgregor@apple.com>2012-11-29 23:55:25 +0000
commit7a626570ef4f457caab1302f238955aa1a2c7989 (patch)
tree6c393a27c8319fd95dca2f69ccfe166d2f0e28c9 /clang/lib/Frontend/CompilerInstance.cpp
parent136d6746c58fe3ab431e2279289646769918a48f (diff)
downloadbcm5719-llvm-7a626570ef4f457caab1302f238955aa1a2c7989.tar.gz
bcm5719-llvm-7a626570ef4f457caab1302f238955aa1a2c7989.zip
Keep track of modules that have failed to build. If we encounter an
import of that module elsewhere, don't try to build the module again: it won't work, and the experience is quite dreadful. We track this information somewhat globally, shared among all of the related CompilerInvocations used to build modules on-the-fly, so that a particular Clang instance will only try to build a given module once. Fixes <rdar://problem/12552849>. llvm-svn: 168961
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp73
1 files changed, 55 insertions, 18 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index b01a3f6e1a7..f87a6354205 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -801,6 +801,15 @@ static void compileModule(CompilerInstance &ImportingInstance,
// can detect cycles in the module graph.
PPOpts.ModuleBuildPath.push_back(Module->getTopLevelModuleName());
+ // Make sure that the failed-module structure has been allocated in
+ // the importing instance, and propagate the pointer to the newly-created
+ // instance.
+ PreprocessorOptions &ImportingPPOpts
+ = ImportingInstance.getInvocation().getPreprocessorOpts();
+ if (!ImportingPPOpts.FailedModules)
+ ImportingPPOpts.FailedModules = new PreprocessorOptions::FailedModulesSet;
+ PPOpts.FailedModules = ImportingPPOpts.FailedModules;
+
// If there is a module map file, build the module using the module map.
// Set up the inputs/outputs so that we build the module from its umbrella
// header.
@@ -872,10 +881,11 @@ static void compileModule(CompilerInstance &ImportingInstance,
llvm::sys::Path(TempModuleMapFileName).eraseFromDisk();
}
-Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
- ModuleIdPath Path,
- Module::NameVisibilityKind Visibility,
- bool IsInclusionDirective) {
+ModuleLoadResult
+CompilerInstance::loadModule(SourceLocation ImportLoc,
+ ModuleIdPath Path,
+ Module::NameVisibilityKind Visibility,
+ bool IsInclusionDirective) {
// 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.
@@ -910,14 +920,14 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module);
else
ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName);
-
+
if (ModuleFileName.empty()) {
getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
<< ModuleName
<< SourceRange(ImportLoc, ModuleNameLoc);
LastModuleImportLoc = ImportLoc;
- LastModuleImportResult = 0;
- return 0;
+ LastModuleImportResult = ModuleLoadResult();
+ return LastModuleImportResult;
}
const FileEntry *ModuleFile
@@ -943,7 +953,18 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
getDiagnostics().Report(ModuleNameLoc, diag::err_module_cycle)
<< ModuleName << CyclePath;
- return 0;
+ 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);
+
+ return ModuleLoadResult();
}
getDiagnostics().Report(ModuleNameLoc, diag::warn_module_build)
@@ -951,6 +972,9 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
BuildingModule = true;
compileModule(*this, Module, ModuleFileName);
ModuleFile = FileMgr->getFile(ModuleFileName);
+
+ if (!ModuleFile)
+ getPreprocessorOpts().FailedModules->addFailed(ModuleName);
}
if (!ModuleFile) {
@@ -959,7 +983,7 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
: diag::err_module_not_found)
<< ModuleName
<< SourceRange(ImportLoc, ModuleNameLoc);
- return 0;
+ return ModuleLoadResult();
}
// If we don't already have an ASTReader, create one now.
@@ -1004,6 +1028,18 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
getFileManager().invalidateCache(ModuleFile);
bool Existed;
llvm::sys::fs::remove(ModuleFileName, Existed);
+
+ // 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);
+
+ return ModuleLoadResult();
+ }
+
compileModule(*this, Module, ModuleFileName);
// Try loading the module again.
@@ -1012,8 +1048,9 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
ModuleManager->ReadAST(ModuleFileName,
serialization::MK_Module, ImportLoc,
ASTReader::ARR_None) != ASTReader::Success) {
+ getPreprocessorOpts().FailedModules->addFailed(ModuleName);
KnownModules[Path[0].first] = 0;
- return 0;
+ return ModuleLoadResult();
}
// Okay, we've rebuilt and now loaded the module.
@@ -1026,12 +1063,12 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
// FIXME: The ASTReader will already have complained, but can we showhorn
// that diagnostic information into a more useful form?
KnownModules[Path[0].first] = 0;
- return 0;
+ return ModuleLoadResult();
case ASTReader::Failure:
// Already complained, but note now that we failed.
KnownModules[Path[0].first] = 0;
- return 0;
+ return ModuleLoadResult();
}
if (!Module) {
@@ -1050,7 +1087,7 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
// If we never found the module, fail.
if (!Module)
- return 0;
+ return ModuleLoadResult();
// Verify that the rest of the module path actually corresponds to
// a submodule.
@@ -1120,7 +1157,7 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
<< Module->getFullModuleName()
<< SourceRange(Path.front().second, Path.back().second);
- return 0;
+ return ModuleLoadResult(0, true);
}
// Check whether this module is available.
@@ -1131,8 +1168,8 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
<< Feature
<< SourceRange(Path.front().second, Path.back().second);
LastModuleImportLoc = ImportLoc;
- LastModuleImportResult = 0;
- return 0;
+ LastModuleImportResult = ModuleLoadResult();
+ return ModuleLoadResult();
}
ModuleManager->makeModuleVisible(Module, Visibility);
@@ -1151,6 +1188,6 @@ Module *CompilerInstance::loadModule(SourceLocation ImportLoc,
}
LastModuleImportLoc = ImportLoc;
- LastModuleImportResult = Module;
- return Module;
+ LastModuleImportResult = ModuleLoadResult(Module, false);
+ return LastModuleImportResult;
}
OpenPOWER on IntegriCloud