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