diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-05-24 05:44:08 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-05-24 05:44:08 +0000 |
commit | dc9fdaf2171cc480300d5572606a8ede1678d18b (patch) | |
tree | df9549534016f49322087b6780ade57739f298ae /clang/lib | |
parent | aa7906815724171e3f81d71fb9b12fd13b845311 (diff) | |
download | bcm5719-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.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Lex/Lexer.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Lex/PPDirectives.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 5 |
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) { |