blob: a2cb0491732795f1e5d13ccc9312a6307a54674b [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s
Douglas Gregore7450f52009-03-24 19:52:54 +00002
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)'}} \
Sebastian Redl59fc2692010-04-10 10:14:54 +000014 // expected-error{{data member instantiated with function type 'float (float)'}} \
15 // expected-error{{data member instantiated with function type 'long (long)'}}
Douglas Gregore7450f52009-03-24 19:52:54 +000016};
17
18X<int> f() { return 0; }
19
20struct XField {
John McCall7c2342d2010-03-10 11:27:22 +000021 X<float(int)> xf; // expected-note{{in instantiation of template class 'X<float (int)>' requested here}}
Douglas Gregore7450f52009-03-24 19:52:54 +000022};
23
24void test_subscript(X<double> *ptr1, X<int(int)> *ptr2, int i) {
25 (void)ptr1[i];
John McCall7c2342d2010-03-10 11:27:22 +000026 (void)ptr2[i]; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
Douglas Gregore7450f52009-03-24 19:52:54 +000027}
28
29void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
30 X<char(char)> *ptr3, X<short(short)> *ptr4) {
31 (void)(ptr1 + 5);
32 // FIXME: if I drop the ')' after void, below, it still parses (!)
33 (void)(5 + ptr2);
John McCall7c2342d2010-03-10 11:27:22 +000034 (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
35 (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
Douglas Gregore7450f52009-03-24 19:52:54 +000036}
37
38void test_new() {
39 (void)new X<float>(0);
John McCall7c2342d2010-03-10 11:27:22 +000040 (void)new X<float(float)>; // expected-note{{in instantiation of template class 'X<float (float)>' requested here}}
Douglas Gregore7450f52009-03-24 19:52:54 +000041}
42
43void test_memptr(X<long> *p1, long X<long>::*pm1,
Douglas Gregor3f5b61c2009-05-14 00:28:11 +000044 X<long(long)> *p2,
45 long (X<long(long)>::*pm2)(long)) {
Douglas Gregore7450f52009-03-24 19:52:54 +000046 (void)(p1->*pm1);
Sebastian Redl59fc2692010-04-10 10:14:54 +000047 (void)((p2->*pm2)(0)); // expected-note{{in instantiation of template class 'X<long (long)>' requested here}}
Douglas Gregore7450f52009-03-24 19:52:54 +000048}
Douglas Gregor393896f2009-11-05 13:06:35 +000049
50// Reference binding to a base
51template<typename T>
52struct X1 { };
53
54template<typename T>
55struct X2 : public T { };
56
57void refbind_base(X2<X1<int> > &x2) {
58 X1<int> &x1 = x2;
59}
60
61// Enumerate constructors for user-defined conversion.
62template<typename T>
63struct X3 {
64 X3(T);
65};
66
67void enum_constructors(X1<float> &x1) {
68 X3<X1<float> > x3 = x1;
69}
Douglas Gregor7c1e98f2010-03-01 15:56:25 +000070
71namespace PR6376 {
72 template<typename T, typename U> struct W { };
73
74 template<typename T>
75 struct X {
76 template<typename U>
77 struct apply {
78 typedef W<T, U> type;
79 };
80 };
81
82 template<typename T, typename U>
83 struct Y : public X<T>::template apply<U>::type { };
84
85 template struct Y<int, float>;
86}
Douglas Gregorf86fcb32010-04-24 21:09:25 +000087
88namespace TemporaryObjectCopy {
89 // Make sure we instantiate classes when we create a temporary copy.
90 template<typename T>
91 struct X {
92 X(T);
93 };
94
95 template<typename T>
96 void f(T t) {
97 const X<int> &x = X<int>(t);
98 }
99
100 template void f(int);
101}
Douglas Gregor6b6d01f2010-05-07 19:42:26 +0000102
103namespace PR7080 {
104 template <class T, class U>
105 class X
106 {
107 typedef char true_t;
108 class false_t { char dummy[2]; };
109 static true_t dispatch(U);
110 static false_t dispatch(...);
111 static T trigger();
112 public:
113 enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
114 };
115
116 template <class T>
117 class rv : public T
118 { };
119
120 bool x = X<int, rv<int>&>::value;
121}