// RUN: %clang_cc1 -fsyntax-only -verify %s // This test concerns the identity of dependent types within the // canonical type system, specifically focusing on the difference // between members of the current instantiation and members of an // unknown specialization. This considers C++ [temp.type], which // specifies type equivalence within a template, and C++0x // [temp.dep.type], which defines what it means to be a member of the // current instantiation. template<typename T, typename U> struct X0 { typedef T T_type; typedef U U_type; void f0(T&); // expected-note{{previous}} void f0(typename X0::U_type&); void f0(typename X0::T_type&); // expected-error{{redecl}} void f1(T&); // expected-note{{previous}} void f1(typename X0::U_type&); void f1(typename X0<T, U>::T_type&); // expected-error{{redecl}} void f2(T&); // expected-note{{previous}} void f2(typename X0::U_type&); void f2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}} void f3(T&); // expected-note{{previous}} void f3(typename X0::U_type&); void f3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}} struct X1 { typedef T my_T_type; void g0(T&); // expected-note{{previous}} void g0(typename X0::U_type&); void g0(typename X0::T_type&); // expected-error{{redecl}} void g1(T&); // expected-note{{previous}} void g1(typename X0::U_type&); void g1(typename X0<T, U>::T_type&); // expected-error{{redecl}} void g2(T&); // expected-note{{previous}} void g2(typename X0::U_type&); void g2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}} void g3(T&); // expected-note{{previous}} void g3(typename X0::U_type&); void g3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}} void g4(T&); // expected-note{{previous}} void g4(typename X0::U_type&); void g4(typename X1::my_T_type&); // expected-error{{redecl}} void g5(T&); // expected-note{{previous}} void g5(typename X0::U_type&); void g5(typename X0::X1::my_T_type&); // expected-error{{redecl}} void g6(T&); // expected-note{{previous}} void g6(typename X0::U_type&); void g6(typename X0<T, U>::X1::my_T_type&); // expected-error{{redecl}} void g7(T&); // expected-note{{previous}} void g7(typename X0::U_type&); void g7(typename ::X0<typename X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}} void g8(T&); // expected-note{{previous}} void g8(typename X0<U, T_type>::T_type&); void g8(typename ::X0<typename X0<T_type, U>::X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}} }; }; template<typename T, typename U> struct X0<T*, U*> { typedef T T_type; typedef U U_type; typedef T* Tptr; typedef U* Uptr; void f0(T&); // expected-note{{previous}} void f0(typename X0::U_type&); void f0(typename X0::T_type&); // expected-error{{redecl}} void f1(T&); // expected-note{{previous}} void f1(typename X0::U_type&); void f1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}} void f2(T&); // expected-note{{previous}} void f2(typename X0::U_type&); void f2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} void f3(T&); // expected-note{{previous}} void f3(typename X0::U_type&); void f3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} void f4(T&); // expected-note{{previous}} void f4(typename X0::U_type&); void f4(typename ::X0<Tptr, Uptr>::T_type&); // expected-error{{redecl}} void f5(X0*); // expected-note{{previous}} void f5(::X0<T, U>*); void f5(::X0<T*, U*>*); // expected-error{{redecl}} struct X2 { typedef T my_T_type; void g0(T&); // expected-note{{previous}} void g0(typename X0::U_type&); void g0(typename X0::T_type&); // expected-error{{redecl}} void g1(T&); // expected-note{{previous}} void g1(typename X0::U_type&); void g1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}} void g2(T&); // expected-note{{previous}} void g2(typename X0::U_type&); void g2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} void g3(T&); // expected-note{{previous}} void g3(typename X0::U_type&); void g3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}} void g4(T&); // expected-note{{previous}} void g4(typename X0::U_type&); void g4(typename X2::my_T_type&); // expected-error{{redecl}} void g5(T&); // expected-note{{previous}} void g5(typename X0::U_type&); void g5(typename X0::X2::my_T_type&); // expected-error{{redecl}} void g6(T&); // expected-note{{previous}} void g6(typename X0::U_type&); void g6(typename X0<T*, U*>::X2::my_T_type&); // expected-error{{redecl}} void g7(T&); // expected-note{{previous}} void g7(typename X0::U_type&); void g7(typename ::X0<typename X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}} void g8(T&); // expected-note{{previous}} void g8(typename X0<U, T_type>::T_type&); void g8(typename ::X0<typename X0<T_type*, U*>::X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}} }; }; template<typename T> struct X1 { static int *a; void f(float *b) { X1<T>::a = b; // expected-error{{incompatible}} X1<T*>::a = b; } }; namespace ConstantInCurrentInstantiation { template<typename T> struct X { static const int value = 2; static int array[value]; }; template<typename T> const int X<T>::value; template<typename T> int X<T>::array[X<T>::value] = { 1, 2 }; } namespace Expressions { template <bool b> struct Bool { enum anonymous_enum { value = b }; }; struct True : public Bool<true> {}; struct False : public Bool<false> {}; template <typename T1, typename T2> struct Is_Same : public False {}; template <typename T> struct Is_Same<T, T> : public True {}; template <bool b, typename T = void> struct Enable_If {}; template <typename T> struct Enable_If<true, T> { typedef T type; }; template <typename T> class Class { public: template <typename U> typename Enable_If<Is_Same<U, Class>::value, void>::type foo(); }; template <typename T> template <typename U> typename Enable_If<Is_Same<U, Class<T> >::value, void>::type Class<T>::foo() {} } namespace PR9255 { template<typename T> class X0 { public: class Inner1; class Inner2 { public: void f() { Inner1::f.g(); } }; }; } namespace rdar10194295 { template<typename XT> class X { public: enum Enum { Yes, No }; template<Enum> void foo(); template<Enum> class Inner; }; template<typename XT> template<typename X<XT>::Enum> void X<XT>::foo() { } template<typename XT> template<typename X<XT>::Enum> class X<XT>::Inner { }; } namespace RebuildDependentScopeDeclRefExpr { template<int> struct N {}; template<typename T> struct X { static const int thing = 0; N<thing> data(); N<thing> foo(); }; template<typename T> N<X<T>::thing> X<T>::data() {} // FIXME: We should issue a typo-correction here. template<typename T> N<X<T>::think> X<T>::foo() {} // expected-error {{no member named 'think' in 'X<T>'}} }