[libclang] In ASTUnit::Parse copy the CompilerInvocation object instead of

modifying directly for the preamble.

This avoids an awful, hard to find, bug where "PreprocessorOpts.DisablePCHValidation = true"
would be persistent for subsequent reparses of the translation unit which would result
in defines, present in command-line but not in the PCH, being ignored.

Fixes rdar://9615399.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139512 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Argyrios Kyrtzidis 2011-09-12 18:09:38 +00:00
Родитель 40098e8cd7
Коммит 26d43cd3a0
5 изменённых файлов: 27 добавлений и 17 удалений

Просмотреть файл

@ -879,7 +879,10 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
CICleanup(Clang.get());
Clang->setInvocation(&*Invocation);
llvm::IntrusiveRefCntPtr<CompilerInvocation>
CCInvocation(new CompilerInvocation(*Invocation));
Clang->setInvocation(CCInvocation.getPtr());
OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].second;
// Set up diagnostics, capturing any diagnostics that would
@ -942,13 +945,11 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts();
PreprocessorOpts.DetailedRecordIncludesNestedMacroExpansions
= NestedMacroExpansions;
std::string PriorImplicitPCHInclude;
if (OverrideMainBuffer) {
PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer);
PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();
PreprocessorOpts.PrecompiledPreambleBytes.second
= PreambleEndsAtStartOfLine;
PriorImplicitPCHInclude = PreprocessorOpts.ImplicitPCHInclude;
PreprocessorOpts.ImplicitPCHInclude = PreambleFile;
PreprocessorOpts.DisablePCHValidation = true;
@ -967,9 +968,6 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
// Keep track of the override buffer;
SavedMainFileBuffer = OverrideMainBuffer;
} else {
PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
PreprocessorOpts.PrecompiledPreambleBytes.second = false;
}
llvm::OwningPtr<TopLevelDeclTrackerAction> Act(
@ -1003,21 +1001,11 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
Act->EndSourceFile();
// Remove the overridden buffer we used for the preamble.
if (OverrideMainBuffer) {
PreprocessorOpts.eraseRemappedFile(
PreprocessorOpts.remapped_file_buffer_end() - 1);
PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude;
}
return false;
error:
// Remove the overridden buffer we used for the preamble.
if (OverrideMainBuffer) {
PreprocessorOpts.eraseRemappedFile(
PreprocessorOpts.remapped_file_buffer_end() - 1);
PreprocessorOpts.ImplicitPCHInclude = PriorImplicitPCHInclude;
delete OverrideMainBuffer;
SavedMainFileBuffer = 0;
}

Просмотреть файл

@ -2595,7 +2595,11 @@ ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
// Here comes stuff that we only do once the entire chain is loaded.
// Check the predefines buffers.
if (!DisableValidation && Type != MK_Module && CheckPredefinesBuffers())
if (!DisableValidation && Type != MK_Module && Type != MK_Preamble &&
// FIXME: CheckPredefinesBuffers also sets the SuggestedPredefines;
// if DisableValidation is true, defines that were set on command-line
// but not in the PCH file will not be added to SuggestedPredefines.
CheckPredefinesBuffers())
return IgnorePCH;
// Initialization of keywords and pragmas occurs before the

Просмотреть файл

@ -0,0 +1,9 @@
// RUN: c-index-test -write-pch %t.h.pch %s.h
// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_REMAP_AFTER_TRIAL=1 c-index-test -test-load-source-reparse 3 local \
// RUN: "-remap-file=%s;%s.remap" %s -include %t.h -D CMD_MACRO=1 2>&1 | FileCheck %s
// CHECK-NOT: error:
int foo() {
return x;
}

Просмотреть файл

@ -0,0 +1 @@
extern int x;

Просмотреть файл

@ -0,0 +1,8 @@
#ifndef CMD_MACRO
#error CMD_MACRO undefined
#endif
int foo() {
return x;
}