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