diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-02-03 17:16:23 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-02-03 17:16:23 +0000 |
commit | b70126a328f89937f46db42f9e3cba1592887c91 (patch) | |
tree | d3957ff32069747c3538d9b30f6fb1d090b8bfb7 /lib/AST/ASTContext.cpp | |
parent | 23a4ddf7875cff6ee70f6dee0d2a9956ae9b5473 (diff) |
When a pack expansion occurs in the template argument list of an alias
template without a corresponding parameter pack, don't immediately
substitute the alias template. This is under discussion in the C++
committee, and may become ill-formed, but for now we match GCC.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149697 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 3b669320e9..c9af67c8b6 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2450,6 +2450,17 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, Underlying); } +#ifndef NDEBUG +static bool hasAnyPackExpansions(const TemplateArgument *Args, + unsigned NumArgs) { + for (unsigned I = 0; I != NumArgs; ++I) + if (Args[I].isPackExpansion()) + return true; + + return true; +} +#endif + QualType ASTContext::getTemplateSpecializationType(TemplateName Template, const TemplateArgument *Args, @@ -2461,16 +2472,18 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) Template = TemplateName(QTN->getTemplateDecl()); - bool isTypeAlias = + bool IsTypeAlias = Template.getAsTemplateDecl() && isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()); - QualType CanonType; if (!Underlying.isNull()) CanonType = getCanonicalType(Underlying); else { - assert(!isTypeAlias && - "Underlying type for template alias must be computed by caller"); + // We can get here with an alias template when the specialization contains + // a pack expansion that does not match up with a parameter pack. + assert((!IsTypeAlias || hasAnyPackExpansions(Args, NumArgs)) && + "Caller must compute aliased type"); + IsTypeAlias = false; CanonType = getCanonicalTemplateSpecializationType(Template, Args, NumArgs); } @@ -2480,13 +2493,11 @@ ASTContext::getTemplateSpecializationType(TemplateName Template, // we don't unique and don't want to lose. void *Mem = Allocate(sizeof(TemplateSpecializationType) + sizeof(TemplateArgument) * NumArgs + - (isTypeAlias ? sizeof(QualType) : 0), + (IsTypeAlias? sizeof(QualType) : 0), TypeAlignment); TemplateSpecializationType *Spec - = new (Mem) TemplateSpecializationType(Template, - Args, NumArgs, - CanonType, - isTypeAlias ? Underlying : QualType()); + = new (Mem) TemplateSpecializationType(Template, Args, NumArgs, CanonType, + IsTypeAlias ? Underlying : QualType()); Types.push_back(Spec); return QualType(Spec, 0); @@ -2498,9 +2509,6 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template, unsigned NumArgs) const { assert(!Template.getAsDependentTemplateName() && "No dependent template names here!"); - assert((!Template.getAsTemplateDecl() || - !isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())) && - "Underlying type for template alias must be computed by caller"); // Look through qualified template names. if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) |