diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-14 17:04:44 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-14 17:04:44 +0000 |
commit | cded4f649cd4b7ba7d461c25c6482ef52b8d3a2a (patch) | |
tree | 886197b026701bb900caeca77c4135297c4b276a /lib/Sema/SemaTemplateVariadic.cpp | |
parent | 5576d9b0a389f6f1f89bdcd37194f4e992b1fbcb (diff) |
Keep track of the number of expansions to be produced from a type pack
expansion, when it is known due to the substitution of an out
parameter pack. This allows us to properly handle substitution into
pack expansions that involve multiple parameter packs at different
template parameter levels, even when this substitution happens one
level at a time (as with partial specializations of member class
templates and the signatures of member function templates).
Note that the diagnostic we provide when there is an arity mismatch
between an outer parameter pack and an inner parameter pack in this
case isn't as clear as the normal diagnostic for an arity
mismatch. However, this doesn't matter because these cases are very,
very rare and (even then) only typically occur in a SFINAE context.
The other kinds of pack expansions (expression, template, etc.) still
need to support optional tracking of the number of expansions, and we
need the moral equivalent of SubstTemplateTypeParmPackType for
substituted argument packs of template template and non-type template
parameters.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123448 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateVariadic.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index dc5013c25d..899b58e558 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -368,7 +368,8 @@ TypeResult Sema::ActOnPackExpansion(ParsedType Type, if (!TSInfo) return true; - TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc); + TypeSourceInfo *TSResult = CheckPackExpansion(TSInfo, EllipsisLoc, + llvm::Optional<unsigned>()); if (!TSResult) return true; @@ -376,11 +377,12 @@ TypeResult Sema::ActOnPackExpansion(ParsedType Type, } TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, - SourceLocation EllipsisLoc) { + SourceLocation EllipsisLoc, + llvm::Optional<unsigned> NumExpansions) { // Create the pack expansion type and source-location information. QualType Result = CheckPackExpansion(Pattern->getType(), Pattern->getTypeLoc().getSourceRange(), - EllipsisLoc); + EllipsisLoc, NumExpansions); if (Result.isNull()) return 0; @@ -397,7 +399,8 @@ TypeSourceInfo *Sema::CheckPackExpansion(TypeSourceInfo *Pattern, QualType Sema::CheckPackExpansion(QualType Pattern, SourceRange PatternRange, - SourceLocation EllipsisLoc) { + SourceLocation EllipsisLoc, + llvm::Optional<unsigned> NumExpansions) { // C++0x [temp.variadic]p5: // The pattern of a pack expansion shall name one or more // parameter packs that are not expanded by a nested pack @@ -408,7 +411,7 @@ QualType Sema::CheckPackExpansion(QualType Pattern, return QualType(); } - return Context.getPackExpansionType(Pattern); + return Context.getPackExpansionType(Pattern, NumExpansions); } ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc) { @@ -450,7 +453,7 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, const MultiLevelTemplateArgumentList &TemplateArgs, bool &ShouldExpand, bool &RetainExpansion, - unsigned &NumExpansions) { + llvm::Optional<unsigned> &NumExpansions) { ShouldExpand = true; RetainExpansion = false; std::pair<IdentifierInfo *, SourceLocation> FirstPack; @@ -527,7 +530,7 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, RetainExpansion = true; } - if (!HaveFirstPack) { + if (!NumExpansions) { // The is the first pack we've seen for which we have an argument. // Record it. NumExpansions = NewPackSize; @@ -537,13 +540,18 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc, continue; } - if (NewPackSize != NumExpansions) { + if (NewPackSize != *NumExpansions) { // C++0x [temp.variadic]p5: // All of the parameter packs expanded by a pack expansion shall have // the same number of arguments specified. - Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) - << FirstPack.first << Name << NumExpansions << NewPackSize - << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second); + if (HaveFirstPack) + Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict) + << FirstPack.first << Name << *NumExpansions << NewPackSize + << SourceRange(FirstPack.second) << SourceRange(Unexpanded[I].second); + else + Diag(EllipsisLoc, diag::err_pack_expansion_length_conflict_multilevel) + << Name << *NumExpansions << NewPackSize + << SourceRange(Unexpanded[I].second); return true; } } |