diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 3525c7020782..addd73ba3566 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4118,22 +4118,22 @@ void ASTReader::InitializeSema(Sema &S) { SemaObj->ReferencedSelectors.insert(std::make_pair(Sel, SelLoc)); } } - - // If there were any pending implicit instantiations, deserialize them - // and add them to Sema's queue of such instantiations. - assert(F->PendingInstantiations.size() % 2 == 0 && - "Expected pairs of entries"); - for (unsigned Idx = 0, N = F->PendingInstantiations.size(); Idx < N;) { - ValueDecl *D=cast(GetDecl(F->PendingInstantiations[Idx++])); - SourceLocation Loc = ReadSourceLocation(*F, F->PendingInstantiations,Idx); - SemaObj->PendingInstantiations.push_back(std::make_pair(D, Loc)); - } } - // The two special data sets below always come from the most recent PCH, + // The special data sets below always come from the most recent PCH, // which is at the front of the chain. PerFileData &F = *Chain.front(); + // If there were any pending implicit instantiations, deserialize them + // and add them to Sema's queue of such instantiations. + assert(F.PendingInstantiations.size() % 2 == 0 && + "Expected pairs of entries"); + for (unsigned Idx = 0, N = F.PendingInstantiations.size(); Idx < N;) { + ValueDecl *D=cast(GetDecl(F.PendingInstantiations[Idx++])); + SourceLocation Loc = ReadSourceLocation(F, F.PendingInstantiations,Idx); + SemaObj->PendingInstantiations.push_back(std::make_pair(D, Loc)); + } + // If there were any weak undeclared identifiers, deserialize them and add to // Sema's list of weak undeclared identifiers. if (!WeakUndeclaredIdentifiers.empty()) { diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 7196a7271831..fb193651b876 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3039,10 +3039,8 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, for (std::deque::iterator I = SemaRef.PendingInstantiations.begin(), N = SemaRef.PendingInstantiations.end(); I != N; ++I) { - if (I->first->getPCHLevel() == 0) { - AddDeclRef(I->first, PendingInstantiations); - AddSourceLocation(I->second, PendingInstantiations); - } + AddDeclRef(I->first, PendingInstantiations); + AddSourceLocation(I->second, PendingInstantiations); } assert(SemaRef.PendingLocalImplicitInstantiations.empty() && "There are local ones at end of translation unit!"); diff --git a/clang/test/PCH/chain-pending-instantiations.cpp b/clang/test/PCH/chain-pending-instantiations.cpp new file mode 100644 index 000000000000..e49abcda4484 --- /dev/null +++ b/clang/test/PCH/chain-pending-instantiations.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -chain-include %s -chain-include %s | FileCheck %s +// CHECK: define linkonce_odr %{{[^ ]+}} @_ZN1AI1BE3getEv +#if !defined(PASS1) +#define PASS1 + +template +struct A { + Derived* get() { return 0; } +}; + +struct B : A { +}; + +#elif !defined(PASS2) +#define PASS2 + +struct C : B { +}; + +struct D : C { + void run() { + (void)get(); + } +}; + +#else + +int main() { + D d; + d.run(); +} + +#endif