From 26d43cd3a088d4f1f1645328db3b73afbc7eaa61 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Mon, 12 Sep 2011 18:09:38 +0000 Subject: [PATCH] [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 --- lib/Frontend/ASTUnit.cpp | 20 ++++--------------- lib/Serialization/ASTReader.cpp | 6 +++++- test/Index/preamble-reparse-cmd-define.c | 9 +++++++++ test/Index/preamble-reparse-cmd-define.c.h | 1 + .../Index/preamble-reparse-cmd-define.c.remap | 8 ++++++++ 5 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 test/Index/preamble-reparse-cmd-define.c create mode 100644 test/Index/preamble-reparse-cmd-define.c.h create mode 100644 test/Index/preamble-reparse-cmd-define.c.remap diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index a680d9254b..6f9b437814 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -879,7 +879,10 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { llvm::CrashRecoveryContextCleanupRegistrar CICleanup(Clang.get()); - Clang->setInvocation(&*Invocation); + llvm::IntrusiveRefCntPtr + 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 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; } diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 03efd5bc64..09aee48723 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -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 diff --git a/test/Index/preamble-reparse-cmd-define.c b/test/Index/preamble-reparse-cmd-define.c new file mode 100644 index 0000000000..67ffde1a0c --- /dev/null +++ b/test/Index/preamble-reparse-cmd-define.c @@ -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; +} diff --git a/test/Index/preamble-reparse-cmd-define.c.h b/test/Index/preamble-reparse-cmd-define.c.h new file mode 100644 index 0000000000..2497af651c --- /dev/null +++ b/test/Index/preamble-reparse-cmd-define.c.h @@ -0,0 +1 @@ +extern int x; diff --git a/test/Index/preamble-reparse-cmd-define.c.remap b/test/Index/preamble-reparse-cmd-define.c.remap new file mode 100644 index 0000000000..35c140d082 --- /dev/null +++ b/test/Index/preamble-reparse-cmd-define.c.remap @@ -0,0 +1,8 @@ + +#ifndef CMD_MACRO +#error CMD_MACRO undefined +#endif + +int foo() { + return x; +} -- 2.40.0