Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
      2 
      3 // This test concerns the identity of dependent types within the
      4 // canonical type system. This corresponds to C++ [temp.type], which
      5 // specifies type equivalence within a template.
      6 //
      7 // FIXME: template template parameters
      8 
      9 namespace N {
     10   template<typename T>
     11   struct X2 {
     12     template<typename U>
     13     struct apply {
     14       typedef U* type;
     15     };
     16   };
     17 }
     18 
     19 namespace Nalias = N;
     20 
     21 template<typename T>
     22 struct X0 { };
     23 
     24 using namespace N;
     25 
     26 template<typename T, typename U>
     27 struct X1 {
     28   typedef T type;
     29   typedef U U_type;
     30 
     31   void f0(T); // expected-note{{previous}}
     32   void f0(U);
     33   void f0(type); // expected-error{{redeclar}}
     34 
     35   void f1(T*); // expected-note{{previous}}
     36   void f1(U*);
     37   void f1(type*); // expected-error{{redeclar}}
     38 
     39   void f2(X0<T>*); // expected-note{{previous}}
     40   void f2(X0<U>*);
     41   void f2(X0<type>*); // expected-error{{redeclar}}
     42 
     43   void f3(X0<T>*); // expected-note{{previous}}
     44   void f3(X0<U>*);
     45   void f3(::X0<type>*); // expected-error{{redeclar}}
     46 
     47   void f4(typename T::template apply<U>*); // expected-note{{previous}}
     48   void f4(typename U::template apply<U>*);
     49   void f4(typename type::template apply<T>*);
     50   void f4(typename type::template apply<U_type>*); // expected-error{{redeclar}}
     51 
     52   void f5(typename T::template apply<U>::type*); // expected-note{{previous}}
     53   void f5(typename U::template apply<U>::type*);
     54   void f5(typename U::template apply<T>::type*);
     55   void f5(typename type::template apply<T>::type*);
     56   void f5(typename type::template apply<U_type>::type*); // expected-error{{redeclar}}
     57 
     58   void f6(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
     59   void f6(typename N::X2<U>::template apply<U> *);
     60   void f6(typename N::X2<U>::template apply<T> *);
     61   void f6(typename ::N::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
     62 
     63   void f7(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
     64   void f7(typename N::X2<U>::template apply<U> *);
     65   void f7(typename N::X2<U>::template apply<T> *);
     66   void f7(typename X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
     67 
     68   void f8(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
     69   void f8(typename N::X2<U>::template apply<U> *);
     70   void f8(typename N::X2<U>::template apply<T> *);
     71   void f8(typename ::Nalias::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
     72 };
     73 
     74 namespace PR6851 {
     75   template <bool v>
     76   struct S;
     77 
     78   struct N {
     79     template <bool w>
     80     S< S<w>::cond && 1 > foo();
     81   };
     82 
     83   struct Alien;
     84   bool operator&&(const Alien&, const Alien&);
     85 
     86   template <bool w>
     87   S< S<w>::cond && 1 > N::foo() { }
     88 }
     89 
     90 namespace PR7460 {
     91   template <typename T>
     92   struct TemplateClass2
     93   {
     94     enum { SIZE = 100 };
     95     static T member[SIZE];
     96   };
     97 
     98   template <typename T>
     99   T TemplateClass2<T>::member[TemplateClass2<T>::SIZE];
    100 }
    101 
    102 namespace PR18275 {
    103   template<typename T> struct A {
    104     void f(const int);
    105     void g(int);
    106     void h(const T);
    107     void i(T);
    108   };
    109 
    110   template<typename T>
    111   void A<T>::f(int x) { x = 0; }
    112 
    113   template<typename T>
    114   void A<T>::g(const int x) {  // expected-note {{declared const here}}
    115     x = 0; // expected-error {{cannot assign to variable 'x'}}
    116   }
    117 
    118   template<typename T>
    119   void A<T>::h(T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type.
    120 
    121   template<typename T>
    122   void A<T>::i(const T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type.
    123 
    124   template struct A<int>;
    125   template struct A<int[1]>;
    126 }
    127 
    128 namespace PR21289 {
    129   template<typename T> using X = int;
    130   template<typename T, decltype(sizeof(0))> using Y = int;
    131   template<typename ...Ts> struct S {};
    132   template<typename ...Ts> void f() {
    133     // This is a dependent type. It is *not* S<int>, even though it canonically
    134     // contains no template parameters.
    135     using Type = S<X<Ts>...>;
    136     Type s;
    137     using Type = S<int, int, int>;
    138   }
    139   void g() { f<void, void, void>(); }
    140 
    141   template<typename ...Ts> void h(S<int>) {}
    142   // Pending a core issue, it's not clear if these are redeclarations, but they
    143   // are probably intended to be... even though substitution can succeed for one
    144   // of them but fail for the other!
    145   template<typename ...Ts> void h(S<X<Ts>...>) {} // expected-note {{previous}}
    146   template<typename ...Ts> void h(S<Y<Ts, sizeof(Ts)>...>) {} // expected-error {{redefinition}}
    147 }
    148