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