1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 template<typename T, typename U> 3 struct is_same { 4 static const bool value = false; 5 }; 6 7 template<typename T> 8 struct is_same<T, T> { 9 static const bool value = true; 10 }; 11 12 template<typename MetaFun, typename T1, typename T2> 13 struct metafun_apply2 { 14 typedef typename MetaFun::template apply<T1, T2> inner; 15 typedef typename inner::type type; 16 }; 17 18 template<typename T, typename U> struct pair; 19 20 struct make_pair { 21 template<typename T1, typename T2> 22 struct apply { 23 typedef pair<T1, T2> type; 24 }; 25 }; 26 27 int a0[is_same<metafun_apply2<make_pair, int, float>::type, 28 pair<int, float> >::value? 1 : -1]; 29 int a1[is_same< 30 typename make_pair::template apply<int, float>, // expected-warning{{'template' keyword outside of a template}} \ 31 // expected-warning{{'typename' occurs outside of a template}} 32 make_pair::apply<int, float> 33 >::value? 1 : -1]; 34 35 template<typename MetaFun> 36 struct swap_and_apply2 { 37 template<typename T1, typename T2> 38 struct apply { 39 typedef typename MetaFun::template apply<T2, T1> new_metafun; 40 typedef typename new_metafun::type type; 41 }; 42 }; 43 44 int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type, 45 pair<float, int> >::value? 1 : -1]; 46 47 template<typename MetaFun> 48 struct swap_and_apply2b { 49 template<typename T1, typename T2> 50 struct apply { 51 typedef typename MetaFun::template apply<T2, T1>::type type; 52 }; 53 }; 54 55 int a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type, 56 pair<float, int> >::value? 1 : -1]; 57 58 template<typename T> 59 struct X0 { 60 template<typename U, typename V> 61 struct Inner; 62 63 void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}} 64 void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}} 65 66 void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}} 67 void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}} 68 69 void f2(typename X0<T>::Inner<T*, T&>::type); // expected-note{{here}} 70 void f2(typename X0<T>::template Inner<T*, T&>::type); // expected-error{{redecl}} 71 }; 72 73 namespace PR6236 { 74 template<typename T, typename U> struct S { }; 75 76 template<typename T> struct S<T, T> { 77 template<typename U> struct K { }; 78 79 void f() { 80 typedef typename S<T, T>::template K<T> Foo; 81 } 82 }; 83 } 84 85 namespace PR6268 { 86 template <typename T> 87 struct Outer { 88 template <typename U> 89 struct Inner {}; 90 91 template <typename U> 92 typename Outer<T>::template Inner<U> 93 foo(typename Outer<T>::template Inner<U>); 94 }; 95 96 template <typename T> 97 template <typename U> 98 typename Outer<T>::template Inner<U> 99 Outer<T>::foo(typename Outer<T>::template Inner<U>) { 100 return Inner<U>(); 101 } 102 } 103 104 namespace PR6463 { 105 struct B { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}} 106 struct C { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}} 107 108 template<typename T> 109 struct A : B, C { 110 type& a(); // expected-error{{found in multiple base classes}} 111 int x; 112 }; 113 114 // FIXME: Improve source location info here. 115 template<typename T> 116 typename A<T>::type& A<T>::a() { // expected-error{{found in multiple base classes}} 117 return x; 118 } 119 } 120 121 namespace PR7419 { 122 template <typename T> struct S { 123 typedef typename T::Y T2; 124 typedef typename T2::Z T3; 125 typedef typename T3::W T4; 126 T4 *f(); 127 128 typedef typename T::template Y<int> TT2; 129 typedef typename TT2::template Z<float> TT3; 130 typedef typename TT3::template W<double> TT4; 131 TT4 g(); 132 }; 133 134 template <typename T> typename T::Y::Z::W *S<T>::f() { } 135 template <typename T> typename T::template Y<int>::template Z<float>::template W<double> S<T>::g() { } 136 } 137 138 namespace rdar8740998 { 139 template<typename T> 140 struct X : public T { 141 using T::iterator; // expected-note{{add 'typename' to treat this using declaration as a type}} \ 142 // expected-error{{dependent using declaration resolved to type without 'typename'}} 143 144 void f() { 145 typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}} 146 } 147 }; 148 149 struct HasIterator { 150 typedef int *iterator; // expected-note{{target of using declaration}} 151 }; 152 153 void test_X(X<HasIterator> xi) { // expected-note{{in instantiation of template class}} 154 xi.f(); 155 } 156 } 157 158 namespace rdar9068589 { 159 // From GCC PR c++/13950 160 template <class T> struct Base {}; 161 template <class T> struct Derived: public Base<T> { 162 typename Derived::template Base<double>* p1; 163 }; 164 } 165