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 6template<typename T> 7struct 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 17X<int> f() { return 0; } 18 19struct XField { 20 X<float(int)> xf; // expected-note{{in instantiation of template class 'X<float (int)>' requested here}} 21}; 22 23void 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 28void 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 36void 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 41void 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 48template<typename T> 49struct X1 { }; 50 51template<typename T> 52struct X2 : public T { }; 53 54void refbind_base(X2<X1<int> > &x2) { 55 X1<int> &x1 = x2; 56} 57 58// Enumerate constructors for user-defined conversion. 59template<typename T> 60struct X3 { 61 X3(T); 62}; 63 64void enum_constructors(X1<float> &x1) { 65 X3<X1<float> > x3 = x1; 66} 67 68namespace 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 85namespace 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 100namespace 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 120namespace 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 129namespace 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