aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateVariadic.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-14 17:04:44 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-14 17:04:44 +0000
commitcded4f649cd4b7ba7d461c25c6482ef52b8d3a2a (patch)
tree886197b026701bb900caeca77c4135297c4b276a /lib/Sema/SemaTemplateVariadic.cpp
parent5576d9b0a389f6f1f89bdcd37194f4e992b1fbcb (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.cpp30
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;
}
}