1// RUN: %clang_cc1 -fsyntax-only -verify %s 2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s 3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 4template<typename T, int N = 2> struct X; // expected-note{{template is declared here}} 5 6X<int, 1> *x1; 7X<int> *x2; 8 9X<> *x3; // expected-error{{too few template arguments for class template 'X'}} 10 11template<typename U = float, int M> struct X; 12 13X<> *x4; 14 15template<typename T = int> struct Z { }; 16template struct Z<>; 17 18// PR4362 19template<class T> struct a { }; 20template<> struct a<int> { static const bool v = true; }; 21 22template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}} 23 24template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}} 25template struct p<int>; 26 27// PR5187 28template<typename T, typename U> 29struct A; 30 31template<typename T, typename U = T> 32struct A; 33 34template<typename T, typename U> 35struct A { 36 void f(A<T>); 37}; 38 39template<typename T> 40struct B { }; 41 42template<> 43struct B<void> { 44 typedef B<void*> type; 45}; 46 47// Nested default arguments for template parameters. 48template<typename T> struct X1 { }; 49 50template<typename T> 51struct X2 { 52 template<typename U = typename X1<T>::type> // expected-error{{no type named 'type' in 'X1<int>'}} \ 53 // expected-error{{no type named 'type' in 'X1<char>'}} 54 struct Inner1 { }; // expected-note{{template is declared here}} 55 56 template<T Value = X1<T>::value> // expected-error{{no member named 'value' in 'X1<int>'}} \ 57 // expected-error{{no member named 'value' in 'X1<char>'}} 58 struct NonType1 { }; // expected-note{{template is declared here}} 59 60 template<T Value> 61 struct Inner2 { }; 62 63 template<typename U> 64 struct Inner3 { 65 template<typename X = T, typename V = U> 66 struct VeryInner { }; 67 68 template<T Value1 = sizeof(T), T Value2 = sizeof(U), 69 T Value3 = Value1 + Value2> 70 struct NonType2 { }; 71 }; 72}; 73 74X2<int> x2i; // expected-note{{in instantiation of template class 'X2<int>' requested here}} 75X2<int>::Inner1<float> x2iif; 76 77X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}} 78 79X2<int>::NonType1<'a'> x2_nontype1; 80X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}} 81 82// Check multi-level substitution into template type arguments 83X2<int>::Inner3<float>::VeryInner<> vi; 84X2<char>::Inner3<int>::NonType2<> x2_deep_nontype; // expected-note{{in instantiation of template class 'X2<char>' requested here}} 85 86template<typename T, typename U> 87struct is_same { static const bool value = false; }; 88 89template<typename T> 90struct is_same<T, T> { static const bool value = true; }; 91 92int array1[is_same<__typeof__(vi), 93 X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1]; 94 95int array2[is_same<__typeof(x2_deep_nontype), 96 X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int), 97 sizeof(char)+sizeof(int)> >::value? 1 : -1]; 98 99// Template template parameter defaults 100template<template<typename T> class X = X2> struct X3 { }; 101int array3[is_same<X3<>, X3<X2> >::value? 1 : -1]; 102 103struct add_pointer { 104 template<typename T> 105 struct apply { 106 typedef T* type; 107 }; 108}; 109 110template<typename T, template<typename> class X = T::template apply> 111 struct X4; 112int array4[is_same<X4<add_pointer>, 113 X4<add_pointer, add_pointer::apply> >::value? 1 : -1]; 114 115template<int> struct X5 {}; // expected-note{{has a different type 'int'}} 116template<long> struct X5b {}; 117template<typename T, 118 template<T> class B = X5> // expected-error{{template template argument has different}} \ 119 // expected-note{{previous non-type template parameter}} 120 struct X6 {}; 121 122X6<int> x6a; 123X6<long> x6b; // expected-note{{while checking a default template argument}} 124X6<long, X5b> x6c; 125 126 127template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}} 128 129namespace PR9643 { 130 template<typename T> class allocator {}; 131 template<typename T, typename U = allocator<T> > class vector {}; 132 133 template<template<typename U, typename = allocator<U> > class container, 134 typename DT> 135 container<DT> initializer(const DT& d) { 136 return container<DT>(); 137 } 138 139 void f() { 140 vector<int, allocator<int> > v = initializer<vector>(5); 141 } 142} 143 144namespace PR16288 { 145 template<typename X> 146 struct S { 147 template<typename T = int, typename U> 148#if __cplusplus <= 199711L // C++03 or earlier modes 149 // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}} 150#endif 151 void f(); 152 }; 153 template<typename X> 154 template<typename T, typename U> 155 void S<X>::f() {} 156} 157 158namespace DR1635 { 159 template <class T> struct X { 160 template <class U = typename T::type> static void f(int) {} // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} 161#if __cplusplus <= 199711L // C++03 or earlier modes 162 // expected-warning@-2 {{default template arguments for a function template are a C++11 extension}} 163#endif 164 static void f(...) {} 165 }; 166 167 int g() { X<int>::f(0); } // expected-note {{in instantiation of template class 'DR1635::X<int>' requested here}} 168} 169 170namespace NondefDecls { 171 template<typename T> void f1() { 172 int g1(int defarg = T::error); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} 173 } 174 template void f1<int>(); // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}} 175} 176 177template <typename T> 178struct C { 179 C(T t = ); // expected-error {{expected expression}} 180}; 181C<int> obj; 182 183namespace PR26134 { 184// Make sure when substituting default template arguments we do it in the current context. 185template<class T, bool Val = T::value> 186struct X {}; 187 188template<bool B> struct Y { 189 void f() { X<Y> xy; } 190 static const bool value = B; 191}; 192 193namespace ns1 { 194template<class T0> 195struct X { 196 template<bool B = T0::value> struct XInner { static const bool value = B; }; 197}; 198template<bool B> struct S { static const bool value = B; }; 199#if __cplusplus > 199711L 200template<bool B> struct Y { 201 static constexpr bool f() { return typename X<S<B>>::template XInner<>{}.value; } 202 static_assert(f() == B, ""); 203}; 204Y<true> y; 205Y<false> y2; 206#endif 207 208} // end ns1 209} // end ns PR26134 210