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