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