aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-03 21:37:45 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-03 21:37:45 +0000
commit7a21fd45d4f04643cbfb5df96a01f84bc6d3dd14 (patch)
treed762ecc339711bceb432d81219247f98284c6e19
parentbacb9493770ff19cfd8f7bc46a075f14b4d08159 (diff)
Properly rebuild pack expansions whose pattern is a non-type template
argument. As part of this, be more careful when determining if there are any parameter packs that cannot be expanded. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122776 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaTemplate.cpp2
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp3
-rw-r--r--lib/Sema/TreeTransform.h13
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp13
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p5.cpp1
5 files changed, 26 insertions, 6 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index c3cfbb8c25..1835899e80 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -3937,7 +3937,7 @@ static bool CheckNonTypeClassTemplatePartialSpecializationArgs(Sema &S,
continue;
}
- // We can have a pack expansion of any of the above.
+ // We can have a pack expansion of any of the bullets below.
if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(ArgExpr))
ArgExpr = Expansion->getPattern();
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index 828d2a3539..a3e308fe11 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -428,7 +428,8 @@ bool Sema::CheckParameterPacksForExpansion(SourceLocation EllipsisLoc,
// If we don't have a template argument at this depth/index, then we
// cannot expand the pack expansion. Make a note of this, but we still
// want to check any parameter packs we *do* have arguments for.
- if (!TemplateArgs.hasTemplateArgument(Depth, Index)) {
+ if (Depth >= TemplateArgs.getNumLevels() ||
+ !TemplateArgs.hasTemplateArgument(Depth, Index)) {
ShouldExpand = false;
continue;
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 9088ae0fef..c38902a3e9 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2102,11 +2102,18 @@ public:
TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
SourceLocation EllipsisLoc) {
switch (Pattern.getArgument().getKind()) {
- case TemplateArgument::Expression:
- // FIXME: We should be able to handle this now!
+ case TemplateArgument::Expression: {
+ ExprResult Result
+ = getSema().ActOnPackExpansion(Pattern.getSourceExpression(),
+ EllipsisLoc);
+ if (Result.isInvalid())
+ return TemplateArgumentLoc();
+
+ return TemplateArgumentLoc(Result.get(), Result.get());
+ }
case TemplateArgument::Template:
- llvm_unreachable("Unsupported pack expansion of expressions/templates");
+ llvm_unreachable("Unsupported pack expansion of templates");
case TemplateArgument::Null:
case TemplateArgument::Integral:
diff --git a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
new file mode 100644
index 0000000000..649c9b8ef2
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T, T ...Values> struct value_tuple {};
+
+template<typename T>
+struct X0 {
+ template<T ...Values>
+ void f(value_tuple<T, Values...> * = 0);
+};
+
+void test_X0() {
+ X0<int>().f<1, 2, 3, 4, 5>();
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
index d52d9c52a4..729a6a0bb2 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -212,7 +212,6 @@ struct TestUnexpandedDecls : T{
// FIXME: Test for unexpanded parameter packs in each of the statements.
// Test unexpanded parameter packs in partial specializations.
-
template<typename ...Types>
struct TestUnexpandedDecls<int, Types>; // expected-error{{partial specialization contains unexpanded parameter pack 'Types'}}