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 
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 
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 
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   // FIXME: if I drop the ')' after void, below, it still parses (!)
32   (void)(5 + ptr2);
33   (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
34   (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
35 }
36 
37 void test_new() {
38   (void)new X<float>(0);
39   (void)new X<float(float)>; // expected-note{{in instantiation of template class 'X<float (float)>' requested here}}
40 }
41 
42 void test_memptr(X<long> *p1, long X<long>::*pm1,
43                  X<long(long)> *p2,
44                  long (X<long(long)>::*pm2)(long)) {
45   (void)(p1->*pm1);
46 }
47 
48 // Reference binding to a base
49 template<typename T>
50 struct X1 { };
51 
52 template<typename T>
53 struct X2 : public T { };
54 
55 void refbind_base(X2<X1<int> > &x2) {
56   X1<int> &x1 = x2;
57 }
58 
59 // Enumerate constructors for user-defined conversion.
60 template<typename T>
61 struct X3 {
62   X3(T);
63 };
64 
65 void enum_constructors(X1<float> &x1) {
66   X3<X1<float> > x3 = x1;
67 }
68 
69 namespace PR6376 {
70   template<typename T, typename U> struct W { };
71 
72   template<typename T>
73   struct X {
74     template<typename U>
75     struct apply {
76       typedef W<T, U> type;
77     };
78   };
79 
80   template<typename T, typename U>
81   struct Y : public X<T>::template apply<U>::type { };
82 
83   template struct Y<int, float>;
84 }
85 
86 namespace TemporaryObjectCopy {
87   // Make sure we instantiate classes when we create a temporary copy.
88   template<typename T>
89   struct X {
90     X(T);
91   };
92 
93   template<typename T>
94   void f(T t) {
95     const X<int> &x = X<int>(t);
96   }
97 
98   template void f(int);
99 }
100 
101 namespace PR7080 {
102   template <class T, class U>
103   class X
104   {
105     typedef char true_t;
106     class false_t { char dummy[2]; };
107     static true_t dispatch(U);
108     static false_t dispatch(...);
109     static T trigger();
110   public:
111     enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
112   };
113 
114   template <class T>
115   class rv : public T
116   { };
117 
118   bool x = X<int, rv<int>&>::value;
119 }
120 
121 namespace pr7199 {
122   template <class T> class A; // expected-note {{template is declared here}}
123   template <class T> class B {
124     class A<T>::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A<int>'}}
125   };
126 
127   template class B<int>; // expected-note {{in instantiation}}
128 }
129 
130 namespace PR8425 {
131   template <typename T>
132   class BaseT {};
133 
134   template <typename T>
135   class DerivedT : public BaseT<T> {};
136 
137   template <typename T>
138   class FromT {
139   public:
140     operator DerivedT<T>() const { return DerivedT<T>(); }
141   };
142 
143   void test() {
144     FromT<int> ft;
145     BaseT<int> bt(ft);
146   }
147 }
148 
149