250 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2 3// This test concerns the identity of dependent types within the4// canonical type system, specifically focusing on the difference5// between members of the current instantiation and members of an6// unknown specialization. This considers C++ [temp.type], which7// specifies type equivalence within a template, and C++0x8// [temp.dep.type], which defines what it means to be a member of the9// current instantiation.10 11template<typename T, typename U>12struct 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 74template<typename T, typename U>75struct 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 146template<typename T>147struct X1 {148 static int *a;149 void f(float *b) {150 X1<T>::a = b; // expected-error{{incompatible}}151 X1<T*>::a = b;152 }153};154 155namespace 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 168namespace 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>::type193 foo();194 };195 196 197 template <typename T>198 template <typename U>199 typename Enable_If<Is_Same<U, Class<T> >::value, void>::type200 Class<T>::foo() {}201}202 203namespace PR9255 {204 template<typename T>205 class X0 {206 public:207 class Inner1;208 209 class Inner2 {210 public:211 void f()212 {213 Inner1::f.g();214 }215 };216 };217}218 219namespace 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>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 239namespace 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 };246 template<typename T> N<X<T>::thing> X<T>::data() {}247 // FIXME: We should issue a typo-correction here.248 template<typename T> N<X<T>::think> X<T>::foo() {} // expected-error {{no member named 'think' in 'RebuildDependentScopeDeclRefExpr::X<T>'}}249}250