summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-05-24 05:44:08 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-05-24 05:44:08 +0000
commitdc9fdaf2171cc480300d5572606a8ede1678d18b (patch)
treedf9549534016f49322087b6780ade57739f298ae /clang/lib
parentaa7906815724171e3f81d71fb9b12fd13b845311 (diff)
downloadbcm5719-llvm-dc9fdaf2171cc480300d5572606a8ede1678d18b.tar.gz
bcm5719-llvm-dc9fdaf2171cc480300d5572606a8ede1678d18b.zip
[modules] If we hit a failure while loading a PCH/module, abort parsing instead of trying to continue in an invalid state.
Also don't let libclang create a PCH with such an error. Fixes rdar://13953768 llvm-svn: 182629
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp7
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp2
-rw-r--r--clang/lib/Lex/Lexer.cpp6
-rw-r--r--clang/lib/Lex/PPDirectives.cpp14
-rw-r--r--clang/lib/Parse/Parser.cpp8
-rw-r--r--clang/lib/Serialization/ASTReader.cpp5
6 files changed, 39 insertions, 3 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 7850dc697be..2d916536d3d 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -216,7 +216,8 @@ const unsigned DefaultPreambleRebuildInterval = 5;
static llvm::sys::cas_flag ActiveASTUnitObjects;
ASTUnit::ASTUnit(bool _MainFileIsAST)
- : Reader(0), OnlyLocalDecls(false), CaptureDiagnostics(false),
+ : Reader(0), HadModuleLoaderFatalFailure(false),
+ OnlyLocalDecls(false), CaptureDiagnostics(false),
MainFileIsAST(_MainFileIsAST),
TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")),
OwnsRemappedFileBuffers(true),
@@ -1705,6 +1706,7 @@ void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
CI.setFileManager(0);
Target = &CI.getTarget();
Reader = CI.getModuleManager();
+ HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
}
StringRef ASTUnit::getMainFileName() const {
@@ -2504,6 +2506,9 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,
}
bool ASTUnit::Save(StringRef File) {
+ if (HadModuleLoaderFatalFailure)
+ return true;
+
// Write to a temporary file and later rename it to the actual file, to avoid
// possible race conditions.
SmallString<128> TempPath;
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index cf856fc2ab6..b4bb6f32517 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -1247,12 +1247,14 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
case ASTReader::VersionMismatch:
case ASTReader::ConfigurationMismatch:
case ASTReader::HadErrors:
+ ModuleLoader::HadFatalFailure = true;
// 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 ModuleLoadResult();
case ASTReader::Failure:
+ ModuleLoader::HadFatalFailure = true;
// Already complained, but note now that we failed.
KnownModules[Path[0].first] = 0;
ModuleBuildFailed = true;
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index e58581ee06b..e3daf346926 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3426,6 +3426,12 @@ HandleDirective:
FormTokenWithChars(Result, CurPtr, tok::hash);
PP->HandleDirective(Result);
+ if (PP->hadModuleLoaderFatalFailure()) {
+ // With a fatal failure in the module loader, we abort parsing.
+ assert(Result.is(tok::eof) && "Preprocessor did not set tok:eof");
+ return;
+ }
+
// As an optimization, if the preprocessor didn't switch lexers, tail
// recurse.
if (PP->isCurrentLexer(this)) {
diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index ba3291aa398..947011d7075 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -1512,6 +1512,20 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
/*IsIncludeDirective=*/true);
assert((Imported == 0 || Imported == SuggestedModule) &&
"the imported module is different than the suggested one");
+
+ if (!Imported && hadModuleLoaderFatalFailure()) {
+ // With a fatal failure in the module loader, we abort parsing.
+ Token &Result = IncludeTok;
+ if (CurLexer) {
+ Result.startToken();
+ CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);
+ CurLexer->cutOffLexing();
+ } else {
+ assert(CurPTHLexer && "#include but no current lexer set!");
+ CurPTHLexer->getEOF(Result);
+ }
+ return;
+ }
// If this header isn't part of the module we're building, we're done.
if (!BuildingImportedModule && Imported) {
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index a5371f9e612..3124b96455e 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1884,7 +1884,13 @@ Parser::DeclGroupPtrTy Parser::ParseModuleImport(SourceLocation AtLoc) {
break;
} while (true);
-
+
+ if (PP.hadModuleLoaderFatalFailure()) {
+ // With a fatal failure in the module loader, we abort parsing.
+ cutOffParsing();
+ return DeclGroupPtrTy();
+ }
+
DeclResult Import = Actions.ActOnModuleImport(AtLoc, ImportLoc, Path);
ExpectAndConsumeSemi(diag::err_module_expected_semi);
if (Import.isInvalid())
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 17f01380ed0..a4c8c353077 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2900,6 +2900,9 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
ModuleKind Type,
SourceLocation ImportLoc,
unsigned ClientLoadCapabilities) {
+ llvm::SaveAndRestore<SourceLocation>
+ SetCurImportLocRAII(CurrentImportLoc, ImportLoc);
+
// Bump the generation number.
unsigned PreviousGeneration = CurrentGeneration++;
@@ -7167,7 +7170,7 @@ CXXTemporary *ASTReader::ReadCXXTemporary(ModuleFile &F,
}
DiagnosticBuilder ASTReader::Diag(unsigned DiagID) {
- return Diag(SourceLocation(), DiagID);
+ return Diag(CurrentImportLoc, DiagID);
}
DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) {
OpenPOWER on IntegriCloud