// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s template struct A { typedef S B; template using C = typename T::B; template struct D { template using E = typename A::template C>; template using F = A>; template using G = C>; G g; }; typedef decltype(D().g) H; D h; template using I = A; template using J = typename A::template C>; }; A a; A::D b; template T make(); namespace X { template struct traits { typedef T thing; typedef decltype(val(make())) inner_ptr; template using rebind_thing = typename thing::template rebind; template using rebind = traits>; inner_ptr &&alloc(); void free(inner_ptr&&); }; template struct ptr_traits { typedef T *type; }; template using ptr = typename ptr_traits::type; template struct thing { typedef T inner; typedef ptr inner_ptr; typedef traits> traits_type; template using rebind = thing; thing(traits_type &traits) : traits(traits), val(traits.alloc()) {} ~thing() { traits.free(static_cast(val)); } traits_type &traits; inner_ptr val; friend inner_ptr val(const thing &t) { return t.val; } }; template<> struct ptr_traits { typedef bool &type; }; template<> bool &traits>::alloc() { static bool b; return b; } template<> void traits>::free(bool&) {} } typedef X::traits> itt; itt::thing::traits_type itr; itt::thing ith(itr); itt::rebind btr; itt::rebind_thing btt(btr); namespace PR11848 { template using U = int; template void f1(U i, U ...is) { // expected-note 2{{couldn't infer template argument 'T'}} return i + f1(is...); } // FIXME: This note is technically correct, but could be better. We // should really say that we couldn't infer template argument 'Ts'. template void f2(U ...is) { } // expected-note {{requires 0 arguments, but 1 was provided}} template struct type_tuple {}; template void f3(type_tuple, U ...is) {} // expected-note {{requires 4 arguments, but 3 were provided}} void g() { f1(U()); // expected-error {{no match}} f1(1, 2, 3, 4, 5); // expected-error {{no match}} f2(); // ok f2(1); // expected-error {{no match}} f3(type_tuple<>()); f3(type_tuple(), 1, 2); // expected-error {{no match}} f3(type_tuple(), 1, 2, 3); } template struct S { S(U...ts); }; template struct Hidden1 { template Hidden1(typename T::template U ...ts); }; template struct Hidden2 { Hidden2(typename T::template U ...ts); }; struct Hide { template using U = int; }; Hidden1 h1; Hidden2 h2(1, 2); } namespace Core22036 { struct X {}; void h(...); template using Y = X; template struct S { // An expression can contain an unexpanded pack without being type or // value dependent. This is true even if the expression's type is a pack // expansion type. void f1(Y a) { h(g(a)); } // expected-error {{undeclared identifier 'g'}} void f2(Y...as) { h(g(as)...); } // expected-error {{undeclared identifier 'g'}} void f3(Y...as) { g(as...); } // ok void f4(Ts ...ts) { h(g(sizeof(ts))...); } // expected-error {{undeclared identifier 'g'}} // FIXME: We can reject this, since it has no valid instantiations because // 'g' never has any associated namespaces. void f5(Ts ...ts) { g(sizeof(ts)...); } // ok }; } namespace PR13243 { template struct X {}; template struct C {}; template using Ci = C; template void f(X, Ci) {} template void f(X, C<0>); } namespace PR13136 { template struct NumberTuple { }; template using MyNumberTuple = NumberTuple; template void foo(U&&, MyNumberTuple); template void bar(U&&, NumberTuple); int main() { foo(1, NumberTuple()); bar(1, NumberTuple()); return 0; } } namespace PR16646 { namespace test1 { template struct DefaultValue { const T value=0;}; template struct tuple {}; template using Zero = tuple ...>; template void f(const Zero &t); void f() { f(Zero()); } } namespace test2 { template struct X {}; template class temp> struct DefaultValue { const temp<0> value; }; template struct tuple {}; template class... Args> using Zero = tuple ...>; template class... Args> void f(const Zero &t); void f() { f(Zero()); } } } namespace PR16904 { template struct base { template struct derived; }; // FIXME: The diagnostics here are terrible. template using derived = base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}} template using derived2 = ::PR16904::base::template derived; // expected-error {{expected a type}} expected-error {{expected ';'}} } namespace PR14858 { template using X = int[sizeof...(T)]; template struct Y { using Z = X; }; using A = Y::Z; using A = int[4]; // FIXME: These should be treated as being redeclarations. template void f(X &) {} template void f(int(&)[sizeof...(T)]) {} template void g(X &) {} template void g(int(&)[sizeof...(T)]) {} // ok, different template void h(X &) {} template void h(X &) {} // ok, different template void i(auto (T ...t) -> int(&)[sizeof...(t)]); auto mk_arr(int, int) -> int(&)[2]; void test_i() { i(mk_arr); } #if 0 // FIXME: This causes clang to assert. template using Z = auto (T ...p) -> int (&)[sizeof...(p)]; template void j(Z &) {} void test_j() { j(mk_arr); } #endif template struct Q { template using V = int[sizeof...(U)]; template void f(V *); }; struct B { typedef int type; }; void test_q(int (&a)[5]) { Q().f(&a); } } namespace redecl { template using A = int; template using A = int; A<> a; // ok } namespace PR31514 { template using EnableTupleSize = T; template struct tuple_size { static const int value = 0; }; template struct tuple_size::value)>> {}; template struct tuple_size::value)>> {}; tuple_size t; } namespace an_alias_template_is_not_a_class_template { template using Foo = int; // expected-note 2{{here}} Foo x; // expected-error {{use of alias template 'Foo' requires template arguments}} Foo<> y; // expected-error {{too few template arguments for alias template 'Foo'}} template class Bar> void f() { // expected-note 2{{here}} Bar x; // expected-error {{use of template template parameter 'Bar' requires template arguments}} Bar<> y; // expected-error {{too few template arguments for template template parameter 'Bar'}} } }