Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 template<typename T, typename U>
      3 struct is_same {
      4   static const bool value = false;
      5 };
      6 
      7 template<typename T>
      8 struct is_same<T, T> {
      9   static const bool value = true;
     10 };
     11 
     12 template<typename MetaFun, typename T1, typename T2>
     13 struct metafun_apply2 {
     14   typedef typename MetaFun::template apply<T1, T2> inner;
     15   typedef typename inner::type type;
     16 };
     17 
     18 template<typename T, typename U> struct pair;
     19 
     20 struct make_pair {
     21   template<typename T1, typename T2>
     22   struct apply {
     23     typedef pair<T1, T2> type;
     24   };
     25 };
     26 
     27 int a0[is_same<metafun_apply2<make_pair, int, float>::type,
     28                pair<int, float> >::value? 1 : -1];
     29 int a1[is_same<
     30          typename make_pair::template apply<int, float>, // expected-warning{{'template' keyword outside of a template}} \
     31        // expected-warning{{'typename' occurs outside of a template}}
     32          make_pair::apply<int, float>
     33        >::value? 1 : -1];
     34 
     35 template<typename MetaFun>
     36 struct swap_and_apply2 {
     37   template<typename T1, typename T2>
     38   struct apply {
     39     typedef typename MetaFun::template apply<T2, T1> new_metafun;
     40     typedef typename new_metafun::type type;
     41   };
     42 };
     43 
     44 int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type,
     45                pair<float, int> >::value? 1 : -1];
     46 
     47 template<typename MetaFun>
     48 struct swap_and_apply2b {
     49   template<typename T1, typename T2>
     50   struct apply {
     51     typedef typename MetaFun::template apply<T2, T1>::type type;
     52   };
     53 };
     54 
     55 int a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type,
     56                pair<float, int> >::value? 1 : -1];
     57 
     58 template<typename T>
     59 struct X0 {
     60   template<typename U, typename V>
     61   struct Inner;
     62 
     63   void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
     64   void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}
     65 
     66   void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
     67   void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}
     68 
     69   void f2(typename X0<T>::Inner<T*, T&>::type); // expected-note{{here}}
     70   void f2(typename X0<T>::template Inner<T*, T&>::type); // expected-error{{redecl}}
     71 };
     72 
     73 namespace PR6236 {
     74   template<typename T, typename U> struct S { };
     75 
     76   template<typename T> struct S<T, T> {
     77     template<typename U> struct K { };
     78 
     79     void f() {
     80       typedef typename S<T, T>::template K<T> Foo;
     81     }
     82   };
     83 }
     84 
     85 namespace PR6268 {
     86   template <typename T>
     87   struct Outer {
     88     template <typename U>
     89     struct Inner {};
     90 
     91     template <typename U>
     92     typename Outer<T>::template Inner<U>
     93     foo(typename Outer<T>::template Inner<U>);
     94   };
     95 
     96   template <typename T>
     97   template <typename U>
     98   typename Outer<T>::template Inner<U>
     99   Outer<T>::foo(typename Outer<T>::template Inner<U>) {
    100     return Inner<U>();
    101   }
    102 }
    103 
    104 namespace PR6463 {
    105   struct B { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
    106   struct C { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
    107 
    108   template<typename T>
    109   struct A : B, C {
    110     type& a(); // expected-error{{found in multiple base classes}}
    111     int x;
    112   };
    113 
    114   // FIXME: Improve source location info here.
    115   template<typename T>
    116   typename A<T>::type& A<T>::a() { // expected-error{{found in multiple base classes}}
    117     return x;
    118   }
    119 }
    120 
    121 namespace PR7419 {
    122   template <typename T> struct S {
    123     typedef typename T::Y T2;
    124     typedef typename T2::Z T3;
    125     typedef typename T3::W T4;
    126     T4 *f();
    127 
    128     typedef typename T::template Y<int> TT2;
    129     typedef typename TT2::template Z<float> TT3;
    130     typedef typename TT3::template W<double> TT4;
    131     TT4 g();
    132   };
    133 
    134   template <typename T> typename T::Y::Z::W *S<T>::f() { }
    135   template <typename T> typename T::template Y<int>::template Z<float>::template W<double> S<T>::g() { }
    136 }
    137 
    138 namespace rdar8740998 {
    139   template<typename T>
    140   struct X : public T {
    141     using T::iterator; // expected-note{{add 'typename' to treat this using declaration as a type}} \
    142     // expected-error{{dependent using declaration resolved to type without 'typename'}}
    143 
    144     void f() {
    145       typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}}
    146     }
    147   };
    148 
    149   struct HasIterator {
    150     typedef int *iterator; // expected-note{{target of using declaration}}
    151   };
    152 
    153   void test_X(X<HasIterator> xi) { // expected-note{{in instantiation of template class}}
    154     xi.f();
    155   }
    156 }
    157 
    158 namespace rdar9068589 {
    159   // From GCC PR c++/13950
    160   template <class T> struct Base {};
    161   template <class T> struct Derived: public Base<T> {
    162     typename Derived::template Base<double>* p1;
    163   };
    164 }
    165