1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 3 // This test concerns the identity of dependent types within the 4 // canonical type system, specifically focusing on the difference 5 // between members of the current instantiation and members of an 6 // unknown specialization. This considers C++ [temp.type], which 7 // specifies type equivalence within a template, and C++0x 8 // [temp.dep.type], which defines what it means to be a member of the 9 // current instantiation. 10 11 template<typename T, typename U> 12 struct X0 { 13 typedef T T_type; 14 typedef U U_type; 15 16 void f0(T&); // expected-note{{previous}} 17 void f0(typename X0::U_type&); 18 void f0(typename X0::T_type&); // expected-error{{redecl}} 19 20 void f1(T&); // expected-note{{previous}} 21 void f1(typename X0::U_type&); 22 void f1(typename X0<T, U>::T_type&); // expected-error{{redecl}} 23 24 void f2(T&); // expected-note{{previous}} 25 void f2(typename X0::U_type&); 26 void f2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}} 27 28 void f3(T&); // expected-note{{previous}} 29 void f3(typename X0::U_type&); 30 void f3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}} 31 32 struct X1 { 33 typedef T my_T_type; 34 35 void g0(T&); // expected-note{{previous}} 36 void g0(typename X0::U_type&); 37 void g0(typename X0::T_type&); // expected-error{{redecl}} 38 39 void g1(T&); // expected-note{{previous}} 40 void g1(typename X0::U_type&); 41 void g1(typename X0<T, U>::T_type&); // expected-error{{redecl}} 42 43 void g2(T&); // expected-note{{previous}} 44 void g2(typename X0::U_type&); 45 void g2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}} 46 47 void g3(T&); // expected-note{{previous}} 48 void g3(typename X0::U_type&); 49 void g3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}} 50 51 void g4(T&); // expected-note{{previous}} 52 void g4(typename X0::U_type&); 53 void g4(typename X1::my_T_type&); // expected-error{{redecl}} 54 55 void g5(T&); // expected-note{{previous}} 56 void g5(typename X0::U_type&); 57 void g5(typename X0::X1::my_T_type&); // expected-error{{redecl}} 58 59 void g6(T&); // expected-note{{previous}} 60 void g6(typename X0::U_type&); 61 void g6(typename X0<T, U>::X1::my_T_type&); // expected-error{{redecl}} 62 63 void g7(T&); // expected-note{{previous}} 64 void g7(typename X0::U_type&); 65 void g7(typename ::X0<typename X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}} 66 67 void g8(T&); // expected-note{{previous}} 68 void g8(typename X0<U, T_type>::T_type&); 69 void g8(typename ::X0<typename X0<T_type, U>::X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}} 70 }; 71 }; 72 73 74 template<typename T, typename U> 75 struct X0<T*, U*> { 76 typedef T T_type; 77 typedef U U_type; 78 typedef T* Tptr; 79 typedef U* Uptr; 80 81 void f0(T&); // expected-note{{previous}} 82 void f0(typename X0::U_type&); 83 void f0(typename X0::T_type&); // expected-error{{redecl}} 84 85 void f1(T&); // expected-note{{previous}} 86 void f1(typename X0::U_type&); 87 void f1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}} 88 89 void f2(T&); // expected-note{{previous}} 90 void f2(typename X0::U_type&); 91 void f2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} 92 93 void f3(T&); // expected-note{{previous}} 94 void f3(typename X0::U_type&); 95 void f3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} 96 97 void f4(T&); // expected-note{{previous}} 98 void f4(typename X0::U_type&); 99 void f4(typename ::X0<Tptr, Uptr>::T_type&); // expected-error{{redecl}} 100 101 void f5(X0*); // expected-note{{previous}} 102 void f5(::X0<T, U>*); 103 void f5(::X0<T*, U*>*); // expected-error{{redecl}} 104 105 struct X2 { 106 typedef T my_T_type; 107 108 void g0(T&); // expected-note{{previous}} 109 void g0(typename X0::U_type&); 110 void g0(typename X0::T_type&); // expected-error{{redecl}} 111 112 void g1(T&); // expected-note{{previous}} 113 void g1(typename X0::U_type&); 114 void g1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}} 115 116 void g2(T&); // expected-note{{previous}} 117 void g2(typename X0::U_type&); 118 void g2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} 119 120 void g3(T&); // expected-note{{previous}} 121 void g3(typename X0::U_type&); 122 void g3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} 123 124 void g4(T&); // expected-note{{previous}} 125 void g4(typename X0::U_type&); 126 void g4(typename X2::my_T_type&); // expected-error{{redecl}} 127 128 void g5(T&); // expected-note{{previous}} 129 void g5(typename X0::U_type&); 130 void g5(typename X0::X2::my_T_type&); // expected-error{{redecl}} 131 132 void g6(T&); // expected-note{{previous}} 133 void g6(typename X0::U_type&); 134 void g6(typename X0<T*, U*>::X2::my_T_type&); // expected-error{{redecl}} 135 136 void g7(T&); // expected-note{{previous}} 137 void g7(typename X0::U_type&); 138 void g7(typename ::X0<typename X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}} 139 140 void g8(T&); // expected-note{{previous}} 141 void g8(typename X0<U, T_type>::T_type&); 142 void g8(typename ::X0<typename X0<T_type*, U*>::X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}} 143 }; 144 }; 145 146 template<typename T> 147 struct X1 { 148 static int *a; fX1149 void f(float *b) { 150 X1<T>::a = b; // expected-error{{incompatible}} 151 X1<T*>::a = b; 152 } 153 }; 154 155 namespace ConstantInCurrentInstantiation { 156 template<typename T> 157 struct X { 158 static const int value = 2; 159 static int array[value]; 160 }; 161 162 template<typename T> const int X<T>::value; 163 164 template<typename T> 165 int X<T>::array[X<T>::value] = { 1, 2 }; 166 } 167 168 namespace Expressions { 169 template <bool b> 170 struct Bool { 171 enum anonymous_enum { value = b }; 172 }; 173 struct True : public Bool<true> {}; 174 struct False : public Bool<false> {}; 175 176 template <typename T1, typename T2> 177 struct Is_Same : public False {}; 178 template <typename T> 179 struct Is_Same<T, T> : public True {}; 180 181 template <bool b, typename T = void> 182 struct Enable_If {}; 183 template <typename T> 184 struct Enable_If<true, T> { 185 typedef T type; 186 }; 187 188 template <typename T> 189 class Class { 190 public: 191 template <typename U> 192 typename Enable_If<Is_Same<U, Class>::value, void>::type 193 foo(); 194 }; 195 196 197 template <typename T> 198 template <typename U> 199 typename Enable_If<Is_Same<U, Class<T> >::value, void>::type foo()200 Class<T>::foo() {} 201 } 202 203 namespace PR9255 { 204 template<typename T> 205 class X0 { 206 public: 207 class Inner1; 208 209 class Inner2 { 210 public: f()211 void f() 212 { 213 Inner1::f.g(); 214 } 215 }; 216 }; 217 } 218 219 namespace rdar10194295 { 220 template<typename XT> 221 class X { 222 public: 223 enum Enum { Yes, No }; 224 template<Enum> void foo(); 225 template<Enum> class Inner; 226 }; 227 228 template<typename XT> 229 template<typename X<XT>::Enum> foo()230 void X<XT>::foo() 231 { 232 } 233 234 template<typename XT> 235 template<typename X<XT>::Enum> 236 class X<XT>::Inner { }; 237 } 238 239 namespace RebuildDependentScopeDeclRefExpr { 240 template<int> struct N {}; 241 template<typename T> struct X { 242 static const int thing = 0; 243 N<thing> data(); 244 N<thing> foo(); 245 }; data()246 template<typename T> N<X<T>::thing> X<T>::data() {} 247 // FIXME: We should issue a typo-correction here. foo()248 template<typename T> N<X<T>::think> X<T>::foo() {} // expected-error {{no member named 'think' in 'X<T>'}} 249 } 250