summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaTemplate/alias-templates.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-10-19 22:18:42 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-10-19 22:18:42 +0000
commitc5452ed941909c04dcae6466677b4dffcf88e09e (patch)
treeedd836cac8a816816126e530a33602ecf45cd0a6 /clang/test/SemaTemplate/alias-templates.cpp
parent01d6b963d2903977fea1950cf6b083d44be0745a (diff)
downloadbcm5719-llvm-c5452ed941909c04dcae6466677b4dffcf88e09e.tar.gz
bcm5719-llvm-c5452ed941909c04dcae6466677b4dffcf88e09e.zip
Add optimization to sizeof...(X) handling: if none of parameter pack X's
corresponding arguments are unexpanded pack expansions, we can compute the result without substituting them. This significantly improves the memory usage and performance of make_integer_sequence implementations that do this kind of thing: using result = integer_sequence<T, Ns ..., sizeof...(Ns) + Ns ...>; ... but note that such an implementation will still perform O(sizeof...(Ns)^2) work while building the second pack expansion (we just have a somewhat lower constant now). In principle we could get this down to linear time by caching whether the number of expansions of a pack is constant, or checking whether we're within an alias template before scanning the pack for pack expansions (since that's the only case in which we do substitutions within a dependent context at the moment), but this patch doesn't attempt that. llvm-svn: 284653
Diffstat (limited to 'clang/test/SemaTemplate/alias-templates.cpp')
-rw-r--r--clang/test/SemaTemplate/alias-templates.cpp17
1 files changed, 17 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp
index b7078353ff1..bcdc84e19f7 100644
--- a/clang/test/SemaTemplate/alias-templates.cpp
+++ b/clang/test/SemaTemplate/alias-templates.cpp
@@ -220,6 +220,23 @@ namespace PR14858 {
template<typename ...T, typename ...U> void h(X<T...> &) {}
template<typename ...T, typename ...U> void h(X<U...> &) {} // ok, different
+
+ template<typename ...T> void i(auto (T ...t) -> int(&)[sizeof...(t)]);
+ auto mk_arr(int, int) -> int(&)[2];
+ void test_i() { i<int, int>(mk_arr); }
+
+#if 0 // FIXME: This causes clang to assert.
+ template<typename ...T> using Z = auto (T ...p) -> int (&)[sizeof...(p)];
+ template<typename ...T, typename ...U> void j(Z<T..., U...> &) {}
+ void test_j() { j<int, int>(mk_arr); }
+#endif
+
+ template<typename ...T> struct Q {
+ template<typename ...U> using V = int[sizeof...(U)];
+ template<typename ...U> void f(V<typename U::type..., typename T::type...> *);
+ };
+ struct B { typedef int type; };
+ void test_q(int (&a)[5]) { Q<B, B, B>().f<B, B>(&a); }
}
namespace redecl {
OpenPOWER on IntegriCloud