aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/DeclTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/DeclTemplate.cpp')
-rw-r--r--clang/lib/AST/DeclTemplate.cpp80
1 files changed, 44 insertions, 36 deletions
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index e5fba1b..c0be986 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -1653,57 +1653,65 @@ void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS,
getValue().printPretty(OS, Policy, getType(), &getASTContext());
}
-TemplateParameterList *clang::getReplacedTemplateParameterList(const Decl *D) {
+std::tuple<NamedDecl *, TemplateArgument>
+clang::getReplacedTemplateParameter(Decl *D, unsigned Index) {
switch (D->getKind()) {
- case Decl::Kind::CXXRecord:
- return cast<CXXRecordDecl>(D)
- ->getDescribedTemplate()
- ->getTemplateParameters();
+ case Decl::Kind::BuiltinTemplate:
case Decl::Kind::ClassTemplate:
- return cast<ClassTemplateDecl>(D)->getTemplateParameters();
+ case Decl::Kind::Concept:
+ case Decl::Kind::FunctionTemplate:
+ case Decl::Kind::TemplateTemplateParm:
+ case Decl::Kind::TypeAliasTemplate:
+ case Decl::Kind::VarTemplate:
+ return {cast<TemplateDecl>(D)->getTemplateParameters()->getParam(Index),
+ {}};
case Decl::Kind::ClassTemplateSpecialization: {
const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D);
auto P = CTSD->getSpecializedTemplateOrPartial();
+ TemplateParameterList *TPL;
if (const auto *CTPSD =
dyn_cast<ClassTemplatePartialSpecializationDecl *>(P))
- return CTPSD->getTemplateParameters();
- return cast<ClassTemplateDecl *>(P)->getTemplateParameters();
+ TPL = CTPSD->getTemplateParameters();
+ else
+ TPL = cast<ClassTemplateDecl *>(P)->getTemplateParameters();
+ return {TPL->getParam(Index), CTSD->getTemplateArgs()[Index]};
+ }
+ case Decl::Kind::VarTemplateSpecialization: {
+ const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
+ auto P = VTSD->getSpecializedTemplateOrPartial();
+ TemplateParameterList *TPL;
+ if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P))
+ TPL = VTPSD->getTemplateParameters();
+ else
+ TPL = cast<VarTemplateDecl *>(P)->getTemplateParameters();
+ return {TPL->getParam(Index), VTSD->getTemplateArgs()[Index]};
}
case Decl::Kind::ClassTemplatePartialSpecialization:
- return cast<ClassTemplatePartialSpecializationDecl>(D)
- ->getTemplateParameters();
- case Decl::Kind::TypeAliasTemplate:
- return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters();
- case Decl::Kind::BuiltinTemplate:
- return cast<BuiltinTemplateDecl>(D)->getTemplateParameters();
+ return {cast<ClassTemplatePartialSpecializationDecl>(D)
+ ->getTemplateParameters()
+ ->getParam(Index),
+ {}};
+ case Decl::Kind::VarTemplatePartialSpecialization:
+ return {cast<VarTemplatePartialSpecializationDecl>(D)
+ ->getTemplateParameters()
+ ->getParam(Index),
+ {}};
+ // This is used as the AssociatedDecl for placeholder type deduction.
+ case Decl::TemplateTypeParm:
+ return {cast<NamedDecl>(D), {}};
+ // FIXME: Always use the template decl as the AssociatedDecl.
+ case Decl::Kind::CXXRecord:
+ return getReplacedTemplateParameter(
+ cast<CXXRecordDecl>(D)->getDescribedClassTemplate(), Index);
case Decl::Kind::CXXDeductionGuide:
case Decl::Kind::CXXConversion:
case Decl::Kind::CXXConstructor:
case Decl::Kind::CXXDestructor:
case Decl::Kind::CXXMethod:
case Decl::Kind::Function:
- return cast<FunctionDecl>(D)
- ->getTemplateSpecializationInfo()
- ->getTemplate()
- ->getTemplateParameters();
- case Decl::Kind::FunctionTemplate:
- return cast<FunctionTemplateDecl>(D)->getTemplateParameters();
- case Decl::Kind::VarTemplate:
- return cast<VarTemplateDecl>(D)->getTemplateParameters();
- case Decl::Kind::VarTemplateSpecialization: {
- const auto *VTSD = cast<VarTemplateSpecializationDecl>(D);
- auto P = VTSD->getSpecializedTemplateOrPartial();
- if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P))
- return VTPSD->getTemplateParameters();
- return cast<VarTemplateDecl *>(P)->getTemplateParameters();
- }
- case Decl::Kind::VarTemplatePartialSpecialization:
- return cast<VarTemplatePartialSpecializationDecl>(D)
- ->getTemplateParameters();
- case Decl::Kind::TemplateTemplateParm:
- return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters();
- case Decl::Kind::Concept:
- return cast<ConceptDecl>(D)->getTemplateParameters();
+ return getReplacedTemplateParameter(
+ cast<FunctionDecl>(D)->getTemplateSpecializationInfo()->getTemplate(),
+ Index);
default:
llvm_unreachable("Unhandled templated declaration kind");
}