diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-12-23 16:00:30 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-12-23 16:00:30 +0000 |
commit | b7d09d627c8576b9bc85f44f05befdd44fedc7ed (patch) | |
tree | b720ca0a657956f83cd6e5d9a8a368b33d9ce72d /lib/AST/DeclTemplate.cpp | |
parent | 3e310d33e4b3b2094df11b25eabde2caab610a94 (diff) |
When forming the injected-class-name of a variadic template, the
template argument corresponding to a template parameter pack is an
argument pack of a pack expansion of that template parameter
pack. Implements C++0x [temp.dep.type]p2 (at least, as much of it as
we can).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122498 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclTemplate.cpp')
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index f21c9a3af3..422e5e30f8 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -300,10 +300,13 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() { if (!CommonPtr->InjectedClassNameType.isNull()) return CommonPtr->InjectedClassNameType; - // FIXME: n2800 14.6.1p1 should say how the template arguments - // corresponding to template parameter packs should be pack - // expansions. We already say that in 14.6.2.1p2, so it would be - // better to fix that redundancy. + // C++0x [temp.dep.type]p2: + // The template argument list of a primary template is a template argument + // list in which the nth template argument has the value of the nth template + // parameter of the class template. If the nth template parameter is a + // template parameter pack (14.5.3), the nth template argument is a pack + // expansion (14.5.3) whose pattern is the name of the template parameter + // pack. ASTContext &Context = getASTContext(); TemplateParameterList *Params = getTemplateParameters(); llvm::SmallVector<TemplateArgument, 16> TemplateArgs; @@ -311,20 +314,34 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() { for (TemplateParameterList::iterator Param = Params->begin(), ParamEnd = Params->end(); Param != ParamEnd; ++Param) { - if (isa<TemplateTypeParmDecl>(*Param)) { - QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param)); - TemplateArgs.push_back(TemplateArgument(ParamType)); + TemplateArgument Arg; + if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { + QualType ArgType = Context.getTypeDeclType(TTP); + if (TTP->isParameterPack()) + ArgType = Context.getPackExpansionType(ArgType); + + Arg = TemplateArgument(ArgType); } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*Param)) { Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType().getNonLValueExprType(Context), Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation()); - TemplateArgs.push_back(TemplateArgument(E)); + // FIXME: Variadic templates. + Arg = TemplateArgument(E); } else { TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); - TemplateArgs.push_back(TemplateArgument(TemplateName(TTP))); + // FIXME: Variadic templates. + Arg = TemplateArgument(TemplateName(TTP)); } + + if ((*Param)->isTemplateParameterPack()) { + TemplateArgument *Pack = new (Context) TemplateArgument [1]; + *Pack = Arg; + Arg = TemplateArgument(Pack, 1); + } + + TemplateArgs.push_back(Arg); } CommonPtr->InjectedClassNameType |