summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-03-07 01:51:17 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-03-07 01:51:17 +0000
commit4a280ff48fd6194d5fe06df21b057d30af93a386 (patch)
tree2a904ffe7ce2cd1dcf1214b18eccd09cbe3ea5ab
parent9b2ab81a0c37d1adbf7924823ac923045a543eed (diff)
downloadbcm5719-llvm-4a280ff48fd6194d5fe06df21b057d30af93a386.tar.gz
bcm5719-llvm-4a280ff48fd6194d5fe06df21b057d30af93a386.zip
[PCH] Mark a PCH file with a flag to indicate if the serialized AST had
compiler errors or not. -Control whether ASTReader should reject such a PCH by a boolean flag at ASTReader's creation time. By default, such a PCH file will be rejected with an error when trying to load it. [libclang] Allow clang_saveTranslationUnit to create a PCH file even if compiler errors occurred. -Have libclang API calls accept a PCH that had compiler errors. The general idea is that we want libclang to stay functional even if a PCH had a compiler error. rdar://10976363. llvm-svn: 152192
-rw-r--r--clang/include/clang/Basic/DiagnosticSerializationKinds.td2
-rw-r--r--clang/include/clang/Frontend/ASTUnit.h6
-rw-r--r--clang/include/clang/Frontend/CompilerInstance.h2
-rw-r--r--clang/include/clang/Frontend/PreprocessorOptions.h4
-rw-r--r--clang/include/clang/Serialization/ASTReader.h10
-rw-r--r--clang/include/clang/Serialization/ASTWriter.h6
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp25
-rw-r--r--clang/lib/Frontend/CompilerInstance.cpp6
-rw-r--r--clang/lib/Frontend/FrontendAction.cpp1
-rw-r--r--clang/lib/Serialization/ASTReader.cpp11
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp9
-rw-r--r--clang/test/Index/pch-with-errors.c28
-rw-r--r--clang/test/Index/werror.c5
-rw-r--r--clang/tools/libclang/CIndex.cpp7
-rw-r--r--clang/tools/libclang/Indexing.cpp1
15 files changed, 97 insertions, 26 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 9a86ebfad86..7f9fe262f7f 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -37,6 +37,8 @@ def warn_pch_version_too_new : Error<
"PCH file uses a newer PCH format that cannot be read">;
def warn_pch_different_branch : Error<
"PCH file built from a different branch (%0) than the compiler (%1)">;
+def err_pch_with_compiler_errors : Error<
+ "PCH file contains compiler errors">;
def warn_cmdline_conflicting_macro_def : Error<
"definition of the macro '%0' conflicts with the definition used to "
"build the precompiled header">;
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h
index 210c7ce23ee..3d0639561a5 100644
--- a/clang/include/clang/Frontend/ASTUnit.h
+++ b/clang/include/clang/Frontend/ASTUnit.h
@@ -642,7 +642,8 @@ public:
bool OnlyLocalDecls = false,
RemappedFile *RemappedFiles = 0,
unsigned NumRemappedFiles = 0,
- bool CaptureDiagnostics = false);
+ bool CaptureDiagnostics = false,
+ bool AllowPCHWithCompilerErrors = false);
private:
/// \brief Helper function for \c LoadFromCompilerInvocation() and
@@ -730,7 +731,8 @@ public:
bool RemappedFilesKeepOriginalName = true,
bool PrecompilePreamble = false,
TranslationUnitKind TUKind = TU_Complete,
- bool CacheCodeCompletionResults = false);
+ bool CacheCodeCompletionResults = false,
+ bool AllowPCHWithCompilerErrors = false);
/// \brief Reparse the source files using the same command-line options that
/// were originally used to produce this translation unit.
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index ff0c30939a4..1bb76952d5a 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -535,6 +535,7 @@ public:
void createPCHExternalASTSource(StringRef Path,
bool DisablePCHValidation,
bool DisableStatCache,
+ bool AllowPCHWithCompilerErrors,
void *DeserializationListener);
/// Create an external AST source to read a PCH file.
@@ -544,6 +545,7 @@ public:
createPCHExternalASTSource(StringRef Path, const std::string &Sysroot,
bool DisablePCHValidation,
bool DisableStatCache,
+ bool AllowPCHWithCompilerErrors,
Preprocessor &PP, ASTContext &Context,
void *DeserializationListener, bool Preamble);
diff --git a/clang/include/clang/Frontend/PreprocessorOptions.h b/clang/include/clang/Frontend/PreprocessorOptions.h
index 4a0de963820..d86a923d430 100644
--- a/clang/include/clang/Frontend/PreprocessorOptions.h
+++ b/clang/include/clang/Frontend/PreprocessorOptions.h
@@ -69,6 +69,9 @@ public:
/// precompiled header or AST file.
bool DisableStatCache;
+ /// \brief When true, a PCH with compiler errors will not be rejected.
+ bool AllowPCHWithCompilerErrors;
+
/// \brief Dump declarations that are deserialized from PCH, for testing.
bool DumpDeserializedPCHDecls;
@@ -165,6 +168,7 @@ public:
PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
DetailedRecordConditionalDirectives(false),
DisablePCHValidation(false), DisableStatCache(false),
+ AllowPCHWithCompilerErrors(false),
DumpDeserializedPCHDecls(false),
PrecompiledPreambleBytes(0, true),
RemappedFilesKeepOriginalName(true),
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index 3ad132c19fe..d0cdbeabbb5 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -579,6 +579,9 @@ private:
/// \brief Whether to disable the use of stat caches in AST files.
bool DisableStatCache;
+ /// \brief Whether to accept an AST file with compiler errors.
+ bool AllowASTWithCompilerErrors;
+
/// \brief The current "generation" of the module file import stack, which
/// indicates how many separate module file load operations have occurred.
unsigned CurrentGeneration;
@@ -875,8 +878,13 @@ public:
/// help when an AST file is being used in cases where the
/// underlying files in the file system may have changed, but
/// parsing should still continue.
+ ///
+ /// \param AllowASTWithCompilerErrors If true, the AST reader will accept an
+ /// AST file the was created out of an AST with compiler errors,
+ /// otherwise it will reject it.
ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "",
- bool DisableValidation = false, bool DisableStatCache = false);
+ bool DisableValidation = false, bool DisableStatCache = false,
+ bool AllowASTWithCompilerErrors = false);
~ASTReader();
diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index 940c86ab333..4c62385cf2c 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -109,6 +109,9 @@ private:
/// serialization, rather than just queueing updates.
bool WritingAST;
+ /// \brief Indicates that the AST contained compiler errors.
+ bool ASTHasCompilerErrors;
+
/// \brief Stores a declaration or a type to be written to the AST file.
class DeclOrType {
public:
@@ -467,7 +470,8 @@ public:
/// are relative to the given system root.
void WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
const std::string &OutputFile,
- Module *WritingModule, StringRef isysroot);
+ Module *WritingModule, StringRef isysroot,
+ bool hasErrors = false);
/// \brief Emit a source location.
void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record);
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index c1678d4ef01..82e33827805 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -652,7 +652,8 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
bool OnlyLocalDecls,
RemappedFile *RemappedFiles,
unsigned NumRemappedFiles,
- bool CaptureDiagnostics) {
+ bool CaptureDiagnostics,
+ bool AllowPCHWithCompilerErrors) {
OwningPtr<ASTUnit> AST(new ASTUnit(true));
// Recover resources if we crash before exiting this method.
@@ -748,7 +749,11 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
/*DelayInitialization=*/true);
ASTContext &Context = *AST->Ctx;
- Reader.reset(new ASTReader(PP, Context));
+ Reader.reset(new ASTReader(PP, Context,
+ /*isysroot=*/"",
+ /*DisableValidation=*/false,
+ /*DisableStatCache=*/false,
+ AllowPCHWithCompilerErrors));
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<ASTReader>
@@ -1862,7 +1867,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
bool RemappedFilesKeepOriginalName,
bool PrecompilePreamble,
TranslationUnitKind TUKind,
- bool CacheCodeCompletionResults) {
+ bool CacheCodeCompletionResults,
+ bool AllowPCHWithCompilerErrors) {
if (!Diags.getPtr()) {
// No diagnostics engine was provided, so create our own diagnostics object
// with the default options.
@@ -1898,8 +1904,9 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, fname);
}
}
- CI->getPreprocessorOpts().RemappedFilesKeepOriginalName =
- RemappedFilesKeepOriginalName;
+ PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
+ PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
+ PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
// Override the resources path.
CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
@@ -2388,9 +2395,6 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,
}
CXSaveError ASTUnit::Save(StringRef File) {
- if (getDiagnostics().hasUnrecoverableErrorOccurred())
- return CXSaveError_TranslationErrors;
-
// Write to a temporary file and later rename it to the actual file, to avoid
// possible race conditions.
SmallString<128> TempPath;
@@ -2420,14 +2424,13 @@ CXSaveError ASTUnit::Save(StringRef File) {
}
bool ASTUnit::serialize(raw_ostream &OS) {
- if (getDiagnostics().hasErrorOccurred())
- return true;
+ bool hasErrors = getDiagnostics().hasErrorOccurred();
SmallString<128> Buffer;
llvm::BitstreamWriter Stream(Buffer);
ASTWriter Writer(Stream);
// FIXME: Handle modules
- Writer.WriteAST(getSema(), 0, std::string(), 0, "");
+ Writer.WriteAST(getSema(), 0, std::string(), 0, "", hasErrors);
// Write the generated bitstream to "Out".
if (!Buffer.empty())
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index c6838be7af0..60273816d91 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -306,12 +306,14 @@ void CompilerInstance::createASTContext() {
void CompilerInstance::createPCHExternalASTSource(StringRef Path,
bool DisablePCHValidation,
bool DisableStatCache,
+ bool AllowPCHWithCompilerErrors,
void *DeserializationListener){
OwningPtr<ExternalASTSource> Source;
bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
DisablePCHValidation,
DisableStatCache,
+ AllowPCHWithCompilerErrors,
getPreprocessor(), getASTContext(),
DeserializationListener,
Preamble));
@@ -324,6 +326,7 @@ CompilerInstance::createPCHExternalASTSource(StringRef Path,
const std::string &Sysroot,
bool DisablePCHValidation,
bool DisableStatCache,
+ bool AllowPCHWithCompilerErrors,
Preprocessor &PP,
ASTContext &Context,
void *DeserializationListener,
@@ -331,7 +334,8 @@ CompilerInstance::createPCHExternalASTSource(StringRef Path,
OwningPtr<ASTReader> Reader;
Reader.reset(new ASTReader(PP, Context,
Sysroot.empty() ? "" : Sysroot.c_str(),
- DisablePCHValidation, DisableStatCache));
+ DisablePCHValidation, DisableStatCache,
+ AllowPCHWithCompilerErrors));
Reader->setDeserializationListener(
static_cast<ASTDeserializationListener *>(DeserializationListener));
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 4bc6dada708..f687ccb22b4 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -268,6 +268,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
CI.getPreprocessorOpts().ImplicitPCHInclude,
CI.getPreprocessorOpts().DisablePCHValidation,
CI.getPreprocessorOpts().DisableStatCache,
+ CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
DeserialListener);
if (!CI.getASTContext().getExternalSource())
goto failure;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 39f24da6d40..5684949e7eb 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -1807,6 +1807,12 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
return IgnorePCH;
}
+ bool hasErrors = Record[5];
+ if (hasErrors && !DisableValidation && !AllowASTWithCompilerErrors) {
+ Diag(diag::err_pch_with_compiler_errors);
+ return IgnorePCH;
+ }
+
RelocatablePCH = Record[4];
if (Listener) {
std::string TargetTriple(BlobStart, BlobLen);
@@ -6282,14 +6288,15 @@ void ASTReader::FinishedDeserializing() {
ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, bool DisableValidation,
- bool DisableStatCache)
+ bool DisableStatCache, bool AllowASTWithCompilerErrors)
: Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
Diags(PP.getDiagnostics()), SemaObj(0), PP(PP), Context(Context),
Consumer(0), ModuleMgr(FileMgr.getFileSystemOptions()),
RelocatablePCH(false), isysroot(isysroot),
DisableValidation(DisableValidation),
- DisableStatCache(DisableStatCache),
+ DisableStatCache(DisableStatCache),
+ AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
CurrentGeneration(0), NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), TotalNumSLocEntries(0),
NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 88c1f70021e..4edfbff2888 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -981,6 +981,7 @@ void ASTWriter::WriteMetadata(ASTContext &Context, StringRef isysroot,
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
+ MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Has errors
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple
unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
@@ -991,6 +992,7 @@ void ASTWriter::WriteMetadata(ASTContext &Context, StringRef isysroot,
Record.push_back(CLANG_VERSION_MAJOR);
Record.push_back(CLANG_VERSION_MINOR);
Record.push_back(!isysroot.empty());
+ Record.push_back(ASTHasCompilerErrors);
const std::string &Triple = Target.getTriple().getTriple();
Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, Triple);
@@ -3115,7 +3117,7 @@ void ASTWriter::SetSelectorOffset(Selector Sel, uint32_t Offset) {
ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
: Stream(Stream), Context(0), PP(0), Chain(0), WritingModule(0),
- WritingAST(false),
+ WritingAST(false), ASTHasCompilerErrors(false),
FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID),
@@ -3144,9 +3146,12 @@ ASTWriter::~ASTWriter() {
void ASTWriter::WriteAST(Sema &SemaRef, MemorizeStatCalls *StatCalls,
const std::string &OutputFile,
- Module *WritingModule, StringRef isysroot) {
+ Module *WritingModule, StringRef isysroot,
+ bool hasErrors) {
WritingAST = true;
+ ASTHasCompilerErrors = hasErrors;
+
// Emit the file header.
Stream.Emit((unsigned)'C', 8);
Stream.Emit((unsigned)'P', 8);
diff --git a/clang/test/Index/pch-with-errors.c b/clang/test/Index/pch-with-errors.c
new file mode 100644
index 00000000000..21cf32a0cbf
--- /dev/null
+++ b/clang/test/Index/pch-with-errors.c
@@ -0,0 +1,28 @@
+
+#ifndef HEADER
+#define HEADER
+
+void erroneous(int);
+void erroneous(float);
+
+#else
+
+void foo(void) {
+ erroneous(0);
+}
+
+#endif
+
+// RUN: c-index-test -write-pch %t.h.pch %s
+// RUN: c-index-test -test-load-source local %s -include %t.h | FileCheck -check-prefix=CHECK-PARSE %s
+// RUN: c-index-test -index-file %s -include %t.h | FileCheck -check-prefix=CHECK-INDEX %s
+
+// CHECK-PARSE: pch-with-errors.c:10:6: FunctionDecl=foo:10:6 (Definition) Extent=[10:1 - 12:2]
+// CHECK-PARSE: pch-with-errors.c:11:3: CallExpr=erroneous:5:6 Extent=[11:3 - 11:15]
+
+// CHECK-INDEX: [indexDeclaration]: kind: function | name: foo
+// CHECK-INDEX: [indexEntityReference]: kind: function | name: erroneous
+
+// RUN: %clang -fsyntax-only %s -include %t.h 2>&1 | FileCheck -check-prefix=PCH-ERR %s
+
+// PCH-ERR: error: PCH file contains compiler errors
diff --git a/clang/test/Index/werror.c b/clang/test/Index/werror.c
index 150095d8599..98b602a170c 100644
--- a/clang/test/Index/werror.c
+++ b/clang/test/Index/werror.c
@@ -7,9 +7,6 @@ void fatal(int);
void fatal(float);
#endif
-// CHECK-FATAL: translation errors
-
// RUN: c-index-test -write-pch %t.pch -Werror %s
-// RUN: not c-index-test -write-pch %t.pch -DFATAL -Werror %s 2>%t.err
-// RUN: FileCheck -check-prefix=CHECK-FATAL %s < %t.err
+// RUN: c-index-test -write-pch %t.pch -DFATAL -Werror %s
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 3b025951884..7e4a1ede74f 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2438,7 +2438,9 @@ CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
CXXIdx->getOnlyLocalDecls(),
- 0, 0, true);
+ 0, 0,
+ /*CaptureDiagnostics=*/true,
+ /*AllowPCHWithCompilerErrors=*/true);
return MakeCXTranslationUnit(TU);
}
@@ -2575,7 +2577,8 @@ static void clang_parseTranslationUnit_Impl(void *UserData) {
/*RemappedFilesKeepOriginalName=*/true,
PrecompilePreamble,
TUKind,
- CacheCodeCompetionResults));
+ CacheCodeCompetionResults,
+ /*AllowPCHWithCompilerErrors=*/true));
if (NumErrors != Diags->getClient()->getNumErrors()) {
// Make sure to check that 'Unit' is non-NULL.
diff --git a/clang/tools/libclang/Indexing.cpp b/clang/tools/libclang/Indexing.cpp
index 1475859e335..aad6e02fe98 100644
--- a/clang/tools/libclang/Indexing.cpp
+++ b/clang/tools/libclang/Indexing.cpp
@@ -369,6 +369,7 @@ static void clang_indexSourceFile_Impl(void *UserData) {
bool CacheCodeCompletionResults = false;
PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
PPOpts.DetailedRecord = false;
+ PPOpts.AllowPCHWithCompilerErrors = true;
if (requestedToGetTU) {
OnlyLocalDecls = CXXIdx->getOnlyLocalDecls();
OpenPOWER on IntegriCloud