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