Store the full list of pending instantiations in a chained PCH. Previously we attempted to store only new pending instantiations, but our filter was incorrect, dropping implicit instantiations of class template members. It's just not worth coming up with a complex filter that is correct, when the only cost is PCH files that are a few hundred bytes (at most) larger.
llvm-svn: 130098
This commit is contained in:
parent
5519ff9d4e
commit
14afaf0093
|
@ -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<ValueDecl>(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<ValueDecl>(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()) {
|
||||
|
|
|
@ -3039,10 +3039,8 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls,
|
|||
for (std::deque<Sema::PendingImplicitInstantiation>::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!");
|
||||
|
|
|
@ -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 <typename Derived>
|
||||
struct A {
|
||||
Derived* get() { return 0; }
|
||||
};
|
||||
|
||||
struct B : A<B> {
|
||||
};
|
||||
|
||||
#elif !defined(PASS2)
|
||||
#define PASS2
|
||||
|
||||
struct C : B {
|
||||
};
|
||||
|
||||
struct D : C {
|
||||
void run() {
|
||||
(void)get();
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
int main() {
|
||||
D d;
|
||||
d.run();
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue