instantiate-complete.cpp revision 7d14d389f0539545715e756629127c1fe5a4773a
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 // FIXME: if I drop the ')' after void, below, it still parses (!) 32 (void)(5 + ptr2); 33 (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}} 34 (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}} 35} 36 37void test_new() { 38 (void)new X<float>(0); 39 (void)new X<float(float)>; // expected-note{{in instantiation of template class 'X<float (float)>' requested here}} 40} 41 42void test_memptr(X<long> *p1, long X<long>::*pm1, 43 X<long(long)> *p2, 44 long (X<long(long)>::*pm2)(long)) { 45 (void)(p1->*pm1); 46} 47 48// Reference binding to a base 49template<typename T> 50struct X1 { }; 51 52template<typename T> 53struct X2 : public T { }; 54 55void refbind_base(X2<X1<int> > &x2) { 56 X1<int> &x1 = x2; 57} 58 59// Enumerate constructors for user-defined conversion. 60template<typename T> 61struct X3 { 62 X3(T); 63}; 64 65void enum_constructors(X1<float> &x1) { 66 X3<X1<float> > x3 = x1; 67} 68 69namespace PR6376 { 70 template<typename T, typename U> struct W { }; 71 72 template<typename T> 73 struct X { 74 template<typename U> 75 struct apply { 76 typedef W<T, U> type; 77 }; 78 }; 79 80 template<typename T, typename U> 81 struct Y : public X<T>::template apply<U>::type { }; 82 83 template struct Y<int, float>; 84} 85 86namespace TemporaryObjectCopy { 87 // Make sure we instantiate classes when we create a temporary copy. 88 template<typename T> 89 struct X { 90 X(T); 91 }; 92 93 template<typename T> 94 void f(T t) { 95 const X<int> &x = X<int>(t); 96 } 97 98 template void f(int); 99} 100 101namespace PR7080 { 102 template <class T, class U> 103 class X 104 { 105 typedef char true_t; 106 class false_t { char dummy[2]; }; 107 static true_t dispatch(U); 108 static false_t dispatch(...); 109 static T trigger(); 110 public: 111 enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; 112 }; 113 114 template <class T> 115 class rv : public T 116 { }; 117 118 bool x = X<int, rv<int>&>::value; 119} 120 121namespace pr7199 { 122 template <class T> class A; // expected-note {{template is declared here}} 123 template <class T> class B { 124 class A<T>::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A<int>'}} 125 }; 126 127 template class B<int>; // expected-note {{in instantiation}} 128} 129 130namespace PR8425 { 131 template <typename T> 132 class BaseT {}; 133 134 template <typename T> 135 class DerivedT : public BaseT<T> {}; 136 137 template <typename T> 138 class FromT { 139 public: 140 operator DerivedT<T>() const { return DerivedT<T>(); } 141 }; 142 143 void test() { 144 FromT<int> ft; 145 BaseT<int> bt(ft); 146 } 147} 148 149