forked from OSchip/llvm-project
Reinstate "Load lazily the template specialization in multi-module setups."
It was reverted in r305460 but the issue appears to only break our self-host libcxx modules bot. Reapplying it will give us a chance to get a reproducer and fix the issue. llvm-svn: 306903
This commit is contained in:
parent
779af828cd
commit
7d26462d70
|
@ -219,6 +219,30 @@ namespace clang {
|
|||
TypedefNameForLinkage(nullptr), HasPendingBody(false),
|
||||
IsDeclMarkedUsed(false) {}
|
||||
|
||||
template <typename T> static
|
||||
void AddLazySpecializations(T *D,
|
||||
SmallVectorImpl<serialization::DeclID>& IDs) {
|
||||
if (IDs.empty())
|
||||
return;
|
||||
|
||||
// FIXME: We should avoid this pattern of getting the ASTContext.
|
||||
ASTContext &C = D->getASTContext();
|
||||
|
||||
auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations;
|
||||
|
||||
if (auto &Old = LazySpecializations) {
|
||||
IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]);
|
||||
std::sort(IDs.begin(), IDs.end());
|
||||
IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end());
|
||||
}
|
||||
|
||||
auto *Result = new (C) serialization::DeclID[1 + IDs.size()];
|
||||
*Result = IDs.size();
|
||||
std::copy(IDs.begin(), IDs.end(), Result + 1);
|
||||
|
||||
LazySpecializations = Result;
|
||||
}
|
||||
|
||||
template <typename DeclT>
|
||||
static Decl *getMostRecentDeclImpl(Redeclarable<DeclT> *D);
|
||||
static Decl *getMostRecentDeclImpl(...);
|
||||
|
@ -247,7 +271,7 @@ namespace clang {
|
|||
void ReadFunctionDefinition(FunctionDecl *FD);
|
||||
void Visit(Decl *D);
|
||||
|
||||
void UpdateDecl(Decl *D);
|
||||
void UpdateDecl(Decl *D, llvm::SmallVectorImpl<serialization::DeclID>&);
|
||||
|
||||
static void setNextObjCCategory(ObjCCategoryDecl *Cat,
|
||||
ObjCCategoryDecl *Next) {
|
||||
|
@ -1971,21 +1995,6 @@ ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
|
|||
return Redecl;
|
||||
}
|
||||
|
||||
static DeclID *newDeclIDList(ASTContext &Context, DeclID *Old,
|
||||
SmallVectorImpl<DeclID> &IDs) {
|
||||
assert(!IDs.empty() && "no IDs to add to list");
|
||||
if (Old) {
|
||||
IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]);
|
||||
std::sort(IDs.begin(), IDs.end());
|
||||
IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end());
|
||||
}
|
||||
|
||||
auto *Result = new (Context) DeclID[1 + IDs.size()];
|
||||
*Result = IDs.size();
|
||||
std::copy(IDs.begin(), IDs.end(), Result + 1);
|
||||
return Result;
|
||||
}
|
||||
|
||||
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
||||
RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
|
||||
|
||||
|
@ -1994,12 +2003,7 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
|
|||
// the specializations.
|
||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||
ReadDeclIDList(SpecIDs);
|
||||
|
||||
if (!SpecIDs.empty()) {
|
||||
auto *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = newDeclIDList(
|
||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
||||
}
|
||||
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
||||
}
|
||||
|
||||
if (D->getTemplatedDecl()->TemplateOrInstantiation) {
|
||||
|
@ -2026,12 +2030,7 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) {
|
|||
// the specializations.
|
||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||
ReadDeclIDList(SpecIDs);
|
||||
|
||||
if (!SpecIDs.empty()) {
|
||||
auto *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = newDeclIDList(
|
||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
||||
}
|
||||
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2137,12 +2136,7 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
|
|||
// This FunctionTemplateDecl owns a CommonPtr; read it.
|
||||
SmallVector<serialization::DeclID, 32> SpecIDs;
|
||||
ReadDeclIDList(SpecIDs);
|
||||
|
||||
if (!SpecIDs.empty()) {
|
||||
auto *CommonPtr = D->getCommonPtr();
|
||||
CommonPtr->LazySpecializations = newDeclIDList(
|
||||
Reader.getContext(), CommonPtr->LazySpecializations, SpecIDs);
|
||||
}
|
||||
ASTDeclReader::AddLazySpecializations(D, SpecIDs);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3688,6 +3682,9 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
|||
Decl *D = Record.D;
|
||||
ProcessingUpdatesRAIIObj ProcessingUpdates(*this);
|
||||
DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
|
||||
|
||||
llvm::SmallVector<serialization::DeclID, 8> PendingLazySpecializationIDs;
|
||||
|
||||
if (UpdI != DeclUpdateOffsets.end()) {
|
||||
auto UpdateOffsets = std::move(UpdI->second);
|
||||
DeclUpdateOffsets.erase(UpdI);
|
||||
|
@ -3712,7 +3709,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
|||
|
||||
ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID,
|
||||
SourceLocation());
|
||||
Reader.UpdateDecl(D);
|
||||
Reader.UpdateDecl(D, PendingLazySpecializationIDs);
|
||||
|
||||
// We might have made this declaration interesting. If so, remember that
|
||||
// we need to hand it off to the consumer.
|
||||
|
@ -3724,6 +3721,17 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Add the lazy specializations to the template.
|
||||
assert((PendingLazySpecializationIDs.empty() || isa<ClassTemplateDecl>(D) ||
|
||||
isa<FunctionTemplateDecl>(D) || isa<VarTemplateDecl>(D)) &&
|
||||
"Must not have pending specializations");
|
||||
if (auto *CTD = dyn_cast<ClassTemplateDecl>(D))
|
||||
ASTDeclReader::AddLazySpecializations(CTD, PendingLazySpecializationIDs);
|
||||
else if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
|
||||
ASTDeclReader::AddLazySpecializations(FTD, PendingLazySpecializationIDs);
|
||||
else if (auto *VTD = dyn_cast<VarTemplateDecl>(D))
|
||||
ASTDeclReader::AddLazySpecializations(VTD, PendingLazySpecializationIDs);
|
||||
PendingLazySpecializationIDs.clear();
|
||||
|
||||
// Load the pending visible updates for this decl context, if it has any.
|
||||
auto I = PendingVisibleUpdates.find(ID);
|
||||
|
@ -3920,7 +3928,8 @@ static void forAllLaterRedecls(DeclT *D, Fn F) {
|
|||
}
|
||||
}
|
||||
|
||||
void ASTDeclReader::UpdateDecl(Decl *D) {
|
||||
void ASTDeclReader::UpdateDecl(Decl *D,
|
||||
llvm::SmallVectorImpl<serialization::DeclID> &PendingLazySpecializationIDs) {
|
||||
while (Record.getIdx() < Record.size()) {
|
||||
switch ((DeclUpdateKind)Record.readInt()) {
|
||||
case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
|
||||
|
@ -3936,8 +3945,8 @@ void ASTDeclReader::UpdateDecl(Decl *D) {
|
|||
}
|
||||
|
||||
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
|
||||
// It will be added to the template's specializations set when loaded.
|
||||
(void)Record.readDecl();
|
||||
// It will be added to the template's lazy specialization set.
|
||||
PendingLazySpecializationIDs.push_back(ReadDeclID());
|
||||
break;
|
||||
|
||||
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
|
||||
|
|
Loading…
Reference in New Issue