1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
2*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -verify %s
3f4a2713aSLionel Sambuc
4f4a2713aSLionel Sambuc // Tests various places where requiring a complete type involves
5f4a2713aSLionel Sambuc // instantiation of that type.
6f4a2713aSLionel Sambuc
7f4a2713aSLionel Sambuc template<typename T>
8f4a2713aSLionel Sambuc struct X {
9f4a2713aSLionel Sambuc X(T);
10f4a2713aSLionel Sambuc
11*0a6a1f1dSLionel Sambuc #ifdef MSABI
12*0a6a1f1dSLionel Sambuc // expected-error@+2{{data member instantiated with function type 'long (long)'}}
13*0a6a1f1dSLionel Sambuc #endif
14f4a2713aSLionel Sambuc T f; // expected-error{{data member instantiated with function type 'float (int)'}} \
15f4a2713aSLionel Sambuc // expected-error{{data member instantiated with function type 'int (int)'}} \
16f4a2713aSLionel Sambuc // expected-error{{data member instantiated with function type 'char (char)'}} \
17f4a2713aSLionel Sambuc // expected-error{{data member instantiated with function type 'short (short)'}} \
18f4a2713aSLionel Sambuc // expected-error{{data member instantiated with function type 'float (float)'}}
19f4a2713aSLionel Sambuc };
20f4a2713aSLionel Sambuc
f()21f4a2713aSLionel Sambuc X<int> f() { return 0; }
22f4a2713aSLionel Sambuc
23f4a2713aSLionel Sambuc struct XField {
24f4a2713aSLionel Sambuc X<float(int)> xf; // expected-note{{in instantiation of template class 'X<float (int)>' requested here}}
25f4a2713aSLionel Sambuc };
26f4a2713aSLionel Sambuc
test_subscript(X<double> * ptr1,X<int (int)> * ptr2,int i)27f4a2713aSLionel Sambuc void test_subscript(X<double> *ptr1, X<int(int)> *ptr2, int i) {
28f4a2713aSLionel Sambuc (void)ptr1[i];
29f4a2713aSLionel Sambuc (void)ptr2[i]; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
30f4a2713aSLionel Sambuc }
31f4a2713aSLionel Sambuc
test_arith(X<signed char> * ptr1,X<unsigned char> * ptr2,X<char (char)> * ptr3,X<short (short)> * ptr4)32f4a2713aSLionel Sambuc void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
33f4a2713aSLionel Sambuc X<char(char)> *ptr3, X<short(short)> *ptr4) {
34f4a2713aSLionel Sambuc (void)(ptr1 + 5);
35f4a2713aSLionel Sambuc (void)(5 + ptr2);
36f4a2713aSLionel Sambuc (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
37f4a2713aSLionel Sambuc (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
38f4a2713aSLionel Sambuc }
39f4a2713aSLionel Sambuc
test_new()40f4a2713aSLionel Sambuc void test_new() {
41f4a2713aSLionel Sambuc (void)new X<float>(0);
42f4a2713aSLionel Sambuc (void)new X<float(float)>; // expected-note{{in instantiation of template class 'X<float (float)>' requested here}}
43f4a2713aSLionel Sambuc }
44f4a2713aSLionel Sambuc
test_memptr(X<long> * p1,long X<long>::* pm1,X<long (long)> * p2,long (X<long (long)>::* pm2)(long))45f4a2713aSLionel Sambuc void test_memptr(X<long> *p1, long X<long>::*pm1,
46f4a2713aSLionel Sambuc X<long(long)> *p2,
47*0a6a1f1dSLionel Sambuc #ifdef MSABI
48*0a6a1f1dSLionel Sambuc long (X<long(long)>::*pm2)(long)) { // expected-note{{in instantiation of template class 'X<long (long)>' requested here}}
49*0a6a1f1dSLionel Sambuc #else
50f4a2713aSLionel Sambuc long (X<long(long)>::*pm2)(long)) {
51*0a6a1f1dSLionel Sambuc #endif
52f4a2713aSLionel Sambuc (void)(p1->*pm1);
53f4a2713aSLionel Sambuc }
54f4a2713aSLionel Sambuc
55f4a2713aSLionel Sambuc // Reference binding to a base
56f4a2713aSLionel Sambuc template<typename T>
57f4a2713aSLionel Sambuc struct X1 { };
58f4a2713aSLionel Sambuc
59f4a2713aSLionel Sambuc template<typename T>
60f4a2713aSLionel Sambuc struct X2 : public T { };
61f4a2713aSLionel Sambuc
62f4a2713aSLionel Sambuc void refbind_base(X2<X1<int> > &x2) {
63f4a2713aSLionel Sambuc X1<int> &x1 = x2;
64f4a2713aSLionel Sambuc }
65f4a2713aSLionel Sambuc
66f4a2713aSLionel Sambuc // Enumerate constructors for user-defined conversion.
67f4a2713aSLionel Sambuc template<typename T>
68f4a2713aSLionel Sambuc struct X3 {
69f4a2713aSLionel Sambuc X3(T);
70f4a2713aSLionel Sambuc };
71f4a2713aSLionel Sambuc
72f4a2713aSLionel Sambuc void enum_constructors(X1<float> &x1) {
73f4a2713aSLionel Sambuc X3<X1<float> > x3 = x1;
74f4a2713aSLionel Sambuc }
75f4a2713aSLionel Sambuc
76f4a2713aSLionel Sambuc namespace PR6376 {
77f4a2713aSLionel Sambuc template<typename T, typename U> struct W { };
78f4a2713aSLionel Sambuc
79f4a2713aSLionel Sambuc template<typename T>
80f4a2713aSLionel Sambuc struct X {
81f4a2713aSLionel Sambuc template<typename U>
82f4a2713aSLionel Sambuc struct apply {
83f4a2713aSLionel Sambuc typedef W<T, U> type;
84f4a2713aSLionel Sambuc };
85f4a2713aSLionel Sambuc };
86f4a2713aSLionel Sambuc
87f4a2713aSLionel Sambuc template<typename T, typename U>
88f4a2713aSLionel Sambuc struct Y : public X<T>::template apply<U>::type { };
89f4a2713aSLionel Sambuc
90f4a2713aSLionel Sambuc template struct Y<int, float>;
91f4a2713aSLionel Sambuc }
92f4a2713aSLionel Sambuc
93f4a2713aSLionel Sambuc namespace TemporaryObjectCopy {
94f4a2713aSLionel Sambuc // Make sure we instantiate classes when we create a temporary copy.
95f4a2713aSLionel Sambuc template<typename T>
96f4a2713aSLionel Sambuc struct X {
97f4a2713aSLionel Sambuc X(T);
98f4a2713aSLionel Sambuc };
99f4a2713aSLionel Sambuc
100f4a2713aSLionel Sambuc template<typename T>
101f4a2713aSLionel Sambuc void f(T t) {
102f4a2713aSLionel Sambuc const X<int> &x = X<int>(t);
103f4a2713aSLionel Sambuc }
104f4a2713aSLionel Sambuc
105f4a2713aSLionel Sambuc template void f(int);
106f4a2713aSLionel Sambuc }
107f4a2713aSLionel Sambuc
108f4a2713aSLionel Sambuc namespace PR7080 {
109f4a2713aSLionel Sambuc template <class T, class U>
110f4a2713aSLionel Sambuc class X
111f4a2713aSLionel Sambuc {
112f4a2713aSLionel Sambuc typedef char true_t;
113f4a2713aSLionel Sambuc class false_t { char dummy[2]; };
114f4a2713aSLionel Sambuc static true_t dispatch(U);
115f4a2713aSLionel Sambuc static false_t dispatch(...);
116f4a2713aSLionel Sambuc static T trigger();
117f4a2713aSLionel Sambuc public:
118f4a2713aSLionel Sambuc enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
119f4a2713aSLionel Sambuc };
120f4a2713aSLionel Sambuc
121f4a2713aSLionel Sambuc template <class T>
122f4a2713aSLionel Sambuc class rv : public T
123f4a2713aSLionel Sambuc { };
124f4a2713aSLionel Sambuc
125f4a2713aSLionel Sambuc bool x = X<int, rv<int>&>::value;
126f4a2713aSLionel Sambuc }
127f4a2713aSLionel Sambuc
128f4a2713aSLionel Sambuc namespace pr7199 {
129f4a2713aSLionel Sambuc template <class T> class A; // expected-note {{template is declared here}}
130f4a2713aSLionel Sambuc template <class T> class B {
131f4a2713aSLionel Sambuc class A<T>::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A<int>'}}
132f4a2713aSLionel Sambuc };
133f4a2713aSLionel Sambuc
134f4a2713aSLionel Sambuc template class B<int>; // expected-note {{in instantiation}}
135f4a2713aSLionel Sambuc }
136f4a2713aSLionel Sambuc
137f4a2713aSLionel Sambuc namespace PR8425 {
138f4a2713aSLionel Sambuc template <typename T>
139f4a2713aSLionel Sambuc class BaseT {};
140f4a2713aSLionel Sambuc
141f4a2713aSLionel Sambuc template <typename T>
142f4a2713aSLionel Sambuc class DerivedT : public BaseT<T> {};
143f4a2713aSLionel Sambuc
144f4a2713aSLionel Sambuc template <typename T>
145f4a2713aSLionel Sambuc class FromT {
146f4a2713aSLionel Sambuc public:
147f4a2713aSLionel Sambuc operator DerivedT<T>() const { return DerivedT<T>(); }
148f4a2713aSLionel Sambuc };
149f4a2713aSLionel Sambuc
150f4a2713aSLionel Sambuc void test() {
151f4a2713aSLionel Sambuc FromT<int> ft;
152f4a2713aSLionel Sambuc BaseT<int> bt(ft);
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc }
155