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
f()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
test_subscript(X<double> * ptr1,X<int (int)> * ptr2,int i)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
test_arith(X<signed char> * ptr1,X<unsigned char> * ptr2,X<char (char)> * ptr3,X<short (short)> * ptr4)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
test_new()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
test_memptr(X<long> * p1,long X<long>::* pm1,X<long (long)> * p2,long (X<long (long)>::* pm2)(long))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
refbind_base(X2<X1<int>> & x2)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
enum_constructors(X1<float> & x1)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>
f(T 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:
operator DerivedT<T>() const139 operator DerivedT<T>() const { return DerivedT<T>(); }
140 };
141
test()142 void test() {
143 FromT<int> ft;
144 BaseT<int> bt(ft);
145 }
146 }
147