250 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C++
		
	
	
	
// 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>'}}
 | 
						|
}
 |