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