diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-14 02:55:32 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-14 02:55:32 +0000 |
commit | c3069d618f4661d923cb1b5c4525b082fce73b04 (patch) | |
tree | dc913bb334487a5751df1fb526a232634d7406c4 /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 4e26caa0365347eb63d483df29cdf86ca084510c (diff) |
Start implementing support for substitution into pack expansions that
involve template parameter packs at multiple template levels that
occur within the signatures members of class templates (and partial
specializations thereof). This is a work-in-progress that is deficient
in several ways, notably:
- It only works for template type parameter packs, but we need to
also support non-type template parameter packs and template template
parameter packs.
- It doesn't keep track of the lengths of the substituted argument
packs in the expansion, so it can't properly diagnose length
mismatches.
However, this is a concrete step in the right direction.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123425 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 5f181fb5e1..629dc58958 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -712,6 +712,12 @@ namespace { QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL); + /// \brief Transforms an already-substituted template type parameter pack + /// into either itself (if we aren't substituting into its pack expansion) + /// or the appropriate substituted argument. + QualType TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB, + SubstTemplateTypeParmPackTypeLoc TL); + ExprResult TransformCallExpr(CallExpr *CE) { getSema().CallsUndergoingInstantiation.push_back(CE); ExprResult Result = @@ -1024,10 +1030,15 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB, "Missing argument pack"); if (getSema().ArgumentPackSubstitutionIndex == -1) { - // FIXME: Variadic templates fun case. - getSema().Diag(TL.getSourceRange().getBegin(), - diag::err_pack_expansion_mismatch_unsupported); - return QualType(); + // We have the template argument pack, but we're not expanding the + // enclosing pack expansion yet. Just save the template argument + // pack for later substitution. + QualType Result + = getSema().Context.getSubstTemplateTypeParmPackType(T, Arg); + SubstTemplateTypeParmPackTypeLoc NewTL + = TLB.push<SubstTemplateTypeParmPackTypeLoc>(Result); + NewTL.setNameLoc(TL.getNameLoc()); + return Result; } assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size()); @@ -1063,6 +1074,32 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB, return Result; } +QualType +TemplateInstantiator::TransformSubstTemplateTypeParmPackType( + TypeLocBuilder &TLB, + SubstTemplateTypeParmPackTypeLoc TL) { + if (getSema().ArgumentPackSubstitutionIndex == -1) { + // We aren't expanding the parameter pack, so just return ourselves. + SubstTemplateTypeParmPackTypeLoc NewTL + = TLB.push<SubstTemplateTypeParmPackTypeLoc>(TL.getType()); + NewTL.setNameLoc(TL.getNameLoc()); + return TL.getType(); + } + + const TemplateArgument &ArgPack = TL.getTypePtr()->getArgumentPack(); + unsigned Index = (unsigned)getSema().ArgumentPackSubstitutionIndex; + assert(Index < ArgPack.pack_size() && "Substitution index out-of-range"); + + QualType Result = ArgPack.pack_begin()[Index].getAsType(); + Result = getSema().Context.getSubstTemplateTypeParmType( + TL.getTypePtr()->getReplacedParameter(), + Result); + SubstTemplateTypeParmTypeLoc NewTL + = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); + NewTL.setNameLoc(TL.getNameLoc()); + return Result; +} + /// \brief Perform substitution on the type T with a given set of template /// arguments. /// |