aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-15 06:45:20 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-15 06:45:20 +0000
commit1aee05d08b2184acadeb36de300e216390780d6c (patch)
treea995851490cb0ea0b3e3c15fa55cf50606c68500 /lib/AST/ASTContext.cpp
parent610068c8cd2321f90e147b12cf794e1f840b6405 (diff)
Introduce a new kind of TemplateName that captures a substituted
template template parameter pack that cannot be fully expanded because its enclosing pack expansion could not be expanded. This form of TemplateName plays the same role as SubstTemplateTypeParmPackType and SubstNonTypeTemplateParmPackExpr do for template type parameter packs and non-type template parameter packs, respectively. We should now handle these multi-level pack expansion substitutions anywhere. The largest remaining gap in our variadic-templates support is that we cannot cope with non-type template parameter packs whose type is a pack expansion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123521 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r--lib/AST/ASTContext.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e1e6fd08aa..a18247d7ce 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2737,6 +2737,15 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const {
return TemplateName(cast<TemplateDecl>(Template->getCanonicalDecl()));
}
+ if (SubstTemplateTemplateParmPackStorage *SubstPack
+ = Name.getAsSubstTemplateTemplateParmPack()) {
+ TemplateTemplateParmDecl *CanonParam
+ = getCanonicalTemplateTemplateParmDecl(SubstPack->getParameterPack());
+ TemplateArgument CanonArgPack
+ = getCanonicalTemplateArgument(SubstPack->getArgumentPack());
+ return getSubstTemplateTemplateParmPack(CanonParam, CanonArgPack);
+ }
+
assert(!Name.getAsOverloadedTemplate());
DependentTemplateName *DTN = Name.getAsDependentTemplateName();
@@ -4344,6 +4353,27 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
return TemplateName(QTN);
}
+TemplateName
+ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
+ const TemplateArgument &ArgPack) const {
+ ASTContext &Self = const_cast<ASTContext &>(*this);
+ llvm::FoldingSetNodeID ID;
+ SubstTemplateTemplateParmPackStorage::Profile(ID, Self, Param, ArgPack);
+
+ void *InsertPos = 0;
+ SubstTemplateTemplateParmPackStorage *Subst
+ = SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos);
+
+ if (!Subst) {
+ Subst = new (*this) SubstTemplateTemplateParmPackStorage(Self, Param,
+ ArgPack.pack_size(),
+ ArgPack.pack_begin());
+ SubstTemplateTemplateParmPacks.InsertNode(Subst, InsertPos);
+ }
+
+ return TemplateName(Subst);
+}
+
/// getFromTargetType - Given one of the integer types provided by
/// TargetInfo, produce the corresponding type. The unsigned @p Type
/// is actually a value of type @c TargetInfo::IntType.