forked from OSchip/llvm-project
[modules] Reconstruct template default argument inheritance on reload rather
than wasting storage and triggering eager deserializations by serializing it. llvm-svn: 239454
This commit is contained in:
parent
4881e8b239
commit
8346e52f89
|
@ -2034,11 +2034,6 @@ void ASTDeclReader::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
|
|||
D->setDeclaredWithTypename(Record[Idx++]);
|
||||
|
||||
if (Record[Idx++])
|
||||
// FIXME: Rebuild inherited default argument chain when linking together
|
||||
// the redecl chain.
|
||||
D->setInheritedDefaultArgument(
|
||||
Reader.getContext(), ReadDeclAs<TemplateTypeParmDecl>(Record, Idx));
|
||||
else
|
||||
D->setDefaultArgument(GetTypeSourceInfo(Record, Idx));
|
||||
}
|
||||
|
||||
|
@ -2057,12 +2052,6 @@ void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
|
|||
// Rest of NonTypeTemplateParmDecl.
|
||||
D->ParameterPack = Record[Idx++];
|
||||
if (Record[Idx++])
|
||||
// FIXME: Rebuild inherited default argument chain when linking together
|
||||
// the redecl chain.
|
||||
D->setInheritedDefaultArgument(
|
||||
Reader.getContext(),
|
||||
ReadDeclAs<NonTypeTemplateParmDecl>(Record, Idx));
|
||||
else
|
||||
D->setDefaultArgument(Reader.ReadExpr(F));
|
||||
}
|
||||
}
|
||||
|
@ -2081,12 +2070,6 @@ void ASTDeclReader::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
|
|||
// Rest of TemplateTemplateParmDecl.
|
||||
D->ParameterPack = Record[Idx++];
|
||||
if (Record[Idx++])
|
||||
// FIXME: Rebuild inherited default argument chain when linking together
|
||||
// the redecl chain.
|
||||
D->setInheritedDefaultArgument(
|
||||
Reader.getContext(),
|
||||
ReadDeclAs<TemplateTemplateParmDecl>(Record, Idx));
|
||||
else
|
||||
D->setDefaultArgument(Reader.getContext(),
|
||||
Reader.ReadTemplateArgumentLoc(F, Record, Idx));
|
||||
}
|
||||
|
@ -2917,6 +2900,44 @@ void ASTDeclReader::attachPreviousDeclImpl(ASTReader &Reader, ...) {
|
|||
llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");
|
||||
}
|
||||
|
||||
/// Inherit the default template argument from \p From to \p To. Returns
|
||||
/// \c false if there is no default template for \p From.
|
||||
template <typename ParmDecl>
|
||||
static bool inheritDefaultTemplateArgument(ASTContext &Context, ParmDecl *From,
|
||||
Decl *ToD) {
|
||||
auto *To = cast<ParmDecl>(ToD);
|
||||
if (!From->hasDefaultArgument())
|
||||
return false;
|
||||
if (!To->hasDefaultArgument())
|
||||
To->setInheritedDefaultArgument(Context, From);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void inheritDefaultTemplateArguments(ASTContext &Context,
|
||||
TemplateDecl *From,
|
||||
TemplateDecl *To) {
|
||||
auto *FromTP = From->getTemplateParameters();
|
||||
auto *ToTP = To->getTemplateParameters();
|
||||
assert(FromTP->size() == ToTP->size() && "merged mismatched templates?");
|
||||
|
||||
for (unsigned I = 0, N = FromTP->size(); I != N; ++I) {
|
||||
NamedDecl *FromParam = FromTP->getParam(N - I - 1);
|
||||
NamedDecl *ToParam = ToTP->getParam(N - I - 1);
|
||||
|
||||
if (auto *FTTP = dyn_cast<TemplateTypeParmDecl>(FromParam)) {
|
||||
if (inheritDefaultTemplateArgument(Context, FTTP, ToParam))
|
||||
break;
|
||||
} else if (auto *FNTTP = dyn_cast<NonTypeTemplateParmDecl>(FromParam)) {
|
||||
if (inheritDefaultTemplateArgument(Context, FNTTP, ToParam))
|
||||
break;
|
||||
} else {
|
||||
if (inheritDefaultTemplateArgument(
|
||||
Context, cast<TemplateTemplateParmDecl>(FromParam), ToParam))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
|
||||
Decl *Previous, Decl *Canon) {
|
||||
assert(D && Previous);
|
||||
|
@ -2943,6 +2964,12 @@ void ASTDeclReader::attachPreviousDecl(ASTReader &Reader, Decl *D,
|
|||
// be too.
|
||||
if (Previous->Used)
|
||||
D->Used = true;
|
||||
|
||||
// If the declaration declares a template, it may inherit default arguments
|
||||
// from the previous declaration.
|
||||
if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
|
||||
inheritDefaultTemplateArguments(Reader.getContext(),
|
||||
cast<TemplateDecl>(Previous), TD);
|
||||
}
|
||||
|
||||
template<typename DeclT>
|
||||
|
|
|
@ -1380,10 +1380,11 @@ void ASTDeclWriter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
|
|||
VisitTypeDecl(D);
|
||||
|
||||
Record.push_back(D->wasDeclaredWithTypename());
|
||||
Record.push_back(D->defaultArgumentWasInherited());
|
||||
if (D->defaultArgumentWasInherited())
|
||||
Writer.AddDeclRef(D->getDefaultArgStorage().getInheritedFrom(), Record);
|
||||
else
|
||||
|
||||
bool OwnsDefaultArg = D->hasDefaultArgument() &&
|
||||
!D->defaultArgumentWasInherited();
|
||||
Record.push_back(OwnsDefaultArg);
|
||||
if (OwnsDefaultArg)
|
||||
Writer.AddTypeSourceInfo(D->getDefaultArgumentInfo(), Record);
|
||||
|
||||
Code = serialization::DECL_TEMPLATE_TYPE_PARM;
|
||||
|
@ -1411,10 +1412,10 @@ void ASTDeclWriter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
|
|||
} else {
|
||||
// Rest of NonTypeTemplateParmDecl.
|
||||
Record.push_back(D->isParameterPack());
|
||||
Record.push_back(D->defaultArgumentWasInherited());
|
||||
if (D->defaultArgumentWasInherited())
|
||||
Writer.AddDeclRef(D->getDefaultArgStorage().getInheritedFrom(), Record);
|
||||
else
|
||||
bool OwnsDefaultArg = D->hasDefaultArgument() &&
|
||||
!D->defaultArgumentWasInherited();
|
||||
Record.push_back(OwnsDefaultArg);
|
||||
if (OwnsDefaultArg)
|
||||
Writer.AddStmt(D->getDefaultArgument());
|
||||
Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
|
||||
}
|
||||
|
@ -1441,10 +1442,10 @@ void ASTDeclWriter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
|
|||
} else {
|
||||
// Rest of TemplateTemplateParmDecl.
|
||||
Record.push_back(D->isParameterPack());
|
||||
Record.push_back(D->defaultArgumentWasInherited());
|
||||
if (D->defaultArgumentWasInherited())
|
||||
Writer.AddDeclRef(D->getDefaultArgStorage().getInheritedFrom(), Record);
|
||||
else
|
||||
bool OwnsDefaultArg = D->hasDefaultArgument() &&
|
||||
!D->defaultArgumentWasInherited();
|
||||
Record.push_back(OwnsDefaultArg);
|
||||
if (OwnsDefaultArg)
|
||||
Writer.AddTemplateArgumentLoc(D->getDefaultArgument(), Record);
|
||||
Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue