Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 
      3 // Tests various places where requiring a complete type involves
      4 // instantiation of that type.
      5 
      6 template<typename T>
      7 struct X {
      8   X(T);
      9 
     10   T f; // expected-error{{data member instantiated with function type 'float (int)'}} \
     11        // expected-error{{data member instantiated with function type 'int (int)'}} \
     12        // expected-error{{data member instantiated with function type 'char (char)'}} \
     13        // expected-error{{data member instantiated with function type 'short (short)'}} \
     14        // expected-error{{data member instantiated with function type 'float (float)'}}
     15 };
     16 
     17 X<int> f() { return 0; }
     18 
     19 struct XField {
     20   X<float(int)> xf; // expected-note{{in instantiation of template class 'X<float (int)>' requested here}}
     21 };
     22 
     23 void test_subscript(X<double> *ptr1, X<int(int)> *ptr2, int i) {
     24   (void)ptr1[i];
     25   (void)ptr2[i]; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
     26 }
     27 
     28 void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
     29                 X<char(char)> *ptr3, X<short(short)> *ptr4) {
     30   (void)(ptr1 + 5);
     31   (void)(5 + ptr2);
     32   (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
     33   (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
     34 }
     35 
     36 void test_new() {
     37   (void)new X<float>(0);
     38   (void)new X<float(float)>; // expected-note{{in instantiation of template class 'X<float (float)>' requested here}}
     39 }
     40 
     41 void test_memptr(X<long> *p1, long X<long>::*pm1,
     42                  X<long(long)> *p2,
     43                  long (X<long(long)>::*pm2)(long)) {
     44   (void)(p1->*pm1);
     45 }
     46 
     47 // Reference binding to a base
     48 template<typename T>
     49 struct X1 { };
     50 
     51 template<typename T>
     52 struct X2 : public T { };
     53 
     54 void refbind_base(X2<X1<int> > &x2) {
     55   X1<int> &x1 = x2;
     56 }
     57 
     58 // Enumerate constructors for user-defined conversion.
     59 template<typename T>
     60 struct X3 {
     61   X3(T);
     62 };
     63 
     64 void enum_constructors(X1<float> &x1) {
     65   X3<X1<float> > x3 = x1;
     66 }
     67 
     68 namespace PR6376 {
     69   template<typename T, typename U> struct W { };
     70 
     71   template<typename T>
     72   struct X {
     73     template<typename U>
     74     struct apply {
     75       typedef W<T, U> type;
     76     };
     77   };
     78 
     79   template<typename T, typename U>
     80   struct Y : public X<T>::template apply<U>::type { };
     81 
     82   template struct Y<int, float>;
     83 }
     84 
     85 namespace TemporaryObjectCopy {
     86   // Make sure we instantiate classes when we create a temporary copy.
     87   template<typename T>
     88   struct X {
     89     X(T);
     90   };
     91 
     92   template<typename T>
     93   void f(T t) {
     94     const X<int> &x = X<int>(t);
     95   }
     96 
     97   template void f(int);
     98 }
     99 
    100 namespace PR7080 {
    101   template <class T, class U>
    102   class X
    103   {
    104     typedef char true_t;
    105     class false_t { char dummy[2]; };
    106     static true_t dispatch(U);
    107     static false_t dispatch(...);
    108     static T trigger();
    109   public:
    110     enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
    111   };
    112 
    113   template <class T>
    114   class rv : public T
    115   { };
    116 
    117   bool x = X<int, rv<int>&>::value;
    118 }
    119 
    120 namespace pr7199 {
    121   template <class T> class A; // expected-note {{template is declared here}}
    122   template <class T> class B {
    123     class A<T>::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A<int>'}}
    124   };
    125 
    126   template class B<int>; // expected-note {{in instantiation}}
    127 }
    128 
    129 namespace PR8425 {
    130   template <typename T>
    131   class BaseT {};
    132 
    133   template <typename T>
    134   class DerivedT : public BaseT<T> {};
    135 
    136   template <typename T>
    137   class FromT {
    138   public:
    139     operator DerivedT<T>() const { return DerivedT<T>(); }
    140   };
    141 
    142   void test() {
    143     FromT<int> ft;
    144     BaseT<int> bt(ft);
    145   }
    146 }
    147