summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/CompilerInstance.cpp
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-06-17 22:35:27 +0000
committerBen Langmuir <blangmuir@apple.com>2014-06-17 22:35:27 +0000
commitdbdc036858b04a888cd855e270187bdd03c31353 (patch)
treee0f0a9242a7436ec5a88ddf07952c746411b3875 /clang/lib/Frontend/CompilerInstance.cpp
parent518867327f60cefc028681b175696f14dafde850 (diff)
downloadbcm5719-llvm-dbdc036858b04a888cd855e270187bdd03c31353.tar.gz
bcm5719-llvm-dbdc036858b04a888cd855e270187bdd03c31353.zip
Retry building modules that were compiled by other instances and are out-of-date
When another clang instance builds a module, it may still be considered "out of date" for the current instance in a couple of cases*. This patch prevents us from giving spurious errors when compilers race to build a module by allowing the module load to fail when the pcm was built by a different compiler instance. * Cases where a module can be out of date despite just having been built: 1) There are different -I paths between invocations that result in finding a different module map file for some dependent module. This is not an error, and should never be diagnosed. <rdar://problem/16843887> 2) There are file system races where the headers making up a module are touched or moved. Although this can sometimes mean trouble, diagnosing it only during a build-race is worse than useless and we cannot detect this in general. It is more robust to just rebuild. This was causing spurious issues in some setups where only the modtime of headers was bumped during a build. <rdar://problem/16157638> llvm-svn: 211129
Diffstat (limited to 'clang/lib/Frontend/CompilerInstance.cpp')
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp60
1 files changed, 34 insertions, 26 deletions
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index bca4a59d7cc..e8ca0804090 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -896,23 +896,28 @@ static void compileModuleImpl(CompilerInstance &ImportingInstance,
}
}
-static void compileModule(CompilerInstance &ImportingInstance,
- SourceLocation ImportLoc,
- Module *Module,
- StringRef ModuleFileName) {
+static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
+ SourceLocation ImportLoc,
+ SourceLocation ModuleNameLoc,
+ Module *Module,
+ StringRef ModuleFileName) {
// FIXME: have LockFileManager return an error_code so that we can
// avoid the mkdir when the directory already exists.
StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
llvm::sys::fs::create_directories(Dir);
while (1) {
+ unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing;
llvm::LockFileManager Locked(ModuleFileName);
switch (Locked) {
case llvm::LockFileManager::LFS_Error:
- return;
+ return false;
case llvm::LockFileManager::LFS_Owned:
- // We're responsible for building the module ourselves. Do so below.
+ // We're responsible for building the module ourselves.
+ // FIXME: if there are errors, don't attempt to load the module.
+ compileModuleImpl(ImportingInstance, ModuleNameLoc, Module,
+ ModuleFileName);
break;
case llvm::LockFileManager::LFS_Shared:
@@ -920,11 +925,28 @@ static void compileModule(CompilerInstance &ImportingInstance,
// finish.
if (Locked.waitForUnlock() == llvm::LockFileManager::Res_OwnerDied)
continue; // try again to get the lock.
- return;
+ ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate;
+ break;
}
- return compileModuleImpl(ImportingInstance, ImportLoc, Module,
- ModuleFileName);
+ // Try to read the module file, now that we've compiled it.
+ ASTReader::ASTReadResult ReadResult =
+ ImportingInstance.getModuleManager()->ReadAST(
+ ModuleFileName, serialization::MK_Module, ImportLoc,
+ ModuleLoadCapabilities);
+
+ if (ReadResult == ASTReader::OutOfDate &&
+ Locked == llvm::LockFileManager::LFS_Shared) {
+ // The module may be out of date in the presence of file system races,
+ // or if one of its imports depends on header search paths that are not
+ // consistent with this ImportingInstance. Try again...
+ continue;
+ } else if (ReadResult == ASTReader::Missing) {
+ ImportingInstance.getDiagnostics().Report(ModuleNameLoc,
+ diag::err_module_not_built)
+ << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
+ }
+ return ReadResult == ASTReader::Success;
}
}
@@ -1235,23 +1257,9 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
return ModuleLoadResult();
}
- // Try to compile the module.
- compileModule(*this, ModuleNameLoc, Module, ModuleFileName);
-
- // Try to read the module file, now that we've compiled it.
- ASTReader::ASTReadResult ReadResult
- = ModuleManager->ReadAST(ModuleFileName,
- serialization::MK_Module, ImportLoc,
- ASTReader::ARR_Missing);
- if (ReadResult != ASTReader::Success) {
- if (ReadResult == ASTReader::Missing) {
- getDiagnostics().Report(ModuleNameLoc,
- Module? diag::err_module_not_built
- : diag::err_module_not_found)
- << ModuleName
- << SourceRange(ImportLoc, ModuleNameLoc);
- }
-
+ // Try to compile and then load the module.
+ if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module,
+ ModuleFileName)) {
if (getPreprocessorOpts().FailedModules)
getPreprocessorOpts().FailedModules->addFailed(ModuleName);
KnownModules[Path[0].first] = nullptr;
OpenPOWER on IntegriCloud