diff options
author | Saar Raz <saar@raz.email> | 2019-12-18 20:59:01 +0200 |
---|---|---|
committer | Saar Raz <saar@raz.email> | 2019-12-18 21:01:31 +0200 |
commit | fc0731b98a67c793862288f8ae334322666214dc (patch) | |
tree | 6b40608a727d7ddd36cf7afa6ac657f56804a2b1 /clang/lib/AST/DeclTemplate.cpp | |
parent | 406b6019cd2bd50924be11c634b058c01053fbd3 (diff) | |
download | bcm5719-llvm-fc0731b98a67c793862288f8ae334322666214dc.tar.gz bcm5719-llvm-fc0731b98a67c793862288f8ae334322666214dc.zip |
[Concepts] Constrained partial specializations and function overloads.
Added support for constraint satisfaction checking and partial ordering of constraints in constrained partial specialization and function template overloads.
Phabricator: D41910
Diffstat (limited to 'clang/lib/AST/DeclTemplate.cpp')
-rwxr-xr-x[-rw-r--r--] | clang/lib/AST/DeclTemplate.cpp | 79 |
1 files changed, 65 insertions, 14 deletions
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 7e013c6c54d..23734396b76 100644..100755 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -231,15 +231,16 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { } } -template<class EntryType> +template<class EntryType, typename... ProfileArguments> typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType * RedeclarableTemplateDecl::findSpecializationImpl( - llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args, - void *&InsertPos) { + llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos, + ProfileArguments&&... ProfileArgs) { using SETraits = SpecEntryTraits<EntryType>; llvm::FoldingSetNodeID ID; - EntryType::Profile(ID, Args, getASTContext()); + EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)..., + getASTContext()); EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr; } @@ -254,8 +255,8 @@ void RedeclarableTemplateDecl::addSpecializationImpl( #ifndef NDEBUG void *CorrectInsertPos; assert(!findSpecializationImpl(Specializations, - SETraits::getTemplateArgs(Entry), - CorrectInsertPos) && + CorrectInsertPos, + SETraits::getTemplateArgs(Entry)) && InsertPos == CorrectInsertPos && "given incorrect InsertPos for specialization"); #endif @@ -312,7 +313,7 @@ FunctionTemplateDecl::getSpecializations() const { FunctionDecl * FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos) { - return findSpecializationImpl(getSpecializations(), Args, InsertPos); + return findSpecializationImpl(getSpecializations(), InsertPos, Args); } void FunctionTemplateDecl::addSpecialization( @@ -418,7 +419,7 @@ ClassTemplateDecl::newCommon(ASTContext &C) const { ClassTemplateSpecializationDecl * ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos) { - return findSpecializationImpl(getSpecializations(), Args, InsertPos); + return findSpecializationImpl(getSpecializations(), InsertPos, Args); } void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, @@ -427,9 +428,48 @@ void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, } ClassTemplatePartialSpecializationDecl * -ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, - void *&InsertPos) { - return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); +ClassTemplateDecl::findPartialSpecialization( + ArrayRef<TemplateArgument> Args, + TemplateParameterList *TPL, void *&InsertPos) { + return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args, + TPL); +} + +static void ProfileTemplateParameterList(ASTContext &C, + llvm::FoldingSetNodeID &ID, const TemplateParameterList *TPL) { + const Expr *RC = TPL->getRequiresClause(); + ID.AddBoolean(RC != nullptr); + if (RC) + RC->Profile(ID, C, /*Canonical=*/true); + ID.AddInteger(TPL->size()); + for (NamedDecl *D : *TPL) { + if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) { + ID.AddInteger(0); + ID.AddBoolean(NTTP->isParameterPack()); + NTTP->getType().getCanonicalType().Profile(ID); + continue; + } + if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) { + ID.AddInteger(1); + ID.AddBoolean(TTP->isParameterPack()); + // TODO: Concepts: profile type-constraints. + continue; + } + const auto *TTP = cast<TemplateTemplateParmDecl>(D); + ID.AddInteger(2); + ID.AddBoolean(TTP->isParameterPack()); + ProfileTemplateParameterList(C, ID, TTP->getTemplateParameters()); + } +} + +void +ClassTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID, + ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL, + ASTContext &Context) { + ID.AddInteger(TemplateArgs.size()); + for (const TemplateArgument &TemplateArg : TemplateArgs) + TemplateArg.Profile(ID, Context); + ProfileTemplateParameterList(Context, ID, TPL); } void ClassTemplateDecl::AddPartialSpecialization( @@ -1035,7 +1075,7 @@ VarTemplateDecl::newCommon(ASTContext &C) const { VarTemplateSpecializationDecl * VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos) { - return findSpecializationImpl(getSpecializations(), Args, InsertPos); + return findSpecializationImpl(getSpecializations(), InsertPos, Args); } void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, @@ -1045,8 +1085,19 @@ void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, VarTemplatePartialSpecializationDecl * VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, - void *&InsertPos) { - return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); + TemplateParameterList *TPL, void *&InsertPos) { + return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args, + TPL); +} + +void +VarTemplatePartialSpecializationDecl::Profile(llvm::FoldingSetNodeID &ID, + ArrayRef<TemplateArgument> TemplateArgs, TemplateParameterList *TPL, + ASTContext &Context) { + ID.AddInteger(TemplateArgs.size()); + for (const TemplateArgument &TemplateArg : TemplateArgs) + TemplateArg.Profile(ID, Context); + ProfileTemplateParameterList(Context, ID, TPL); } void VarTemplateDecl::AddPartialSpecialization( |