1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 // This test concerns the identity of dependent types within the
4 // canonical type system, specifically focusing on the difference
5 // between members of the current instantiation and members of an
6 // unknown specialization. This considers C++ [temp.type], which
7 // specifies type equivalence within a template, and C++0x
8 // [temp.dep.type], which defines what it means to be a member of the
9 // current instantiation.
10 
11 template<typename T, typename U>
12 struct X0 {
13   typedef T T_type;
14   typedef U U_type;
15 
16   void f0(T&); // expected-note{{previous}}
17   void f0(typename X0::U_type&);
18   void f0(typename X0::T_type&); // expected-error{{redecl}}
19 
20   void f1(T&); // expected-note{{previous}}
21   void f1(typename X0::U_type&);
22   void f1(typename X0<T, U>::T_type&); // expected-error{{redecl}}
23 
24   void f2(T&); // expected-note{{previous}}
25   void f2(typename X0::U_type&);
26   void f2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
27 
28   void f3(T&); // expected-note{{previous}}
29   void f3(typename X0::U_type&);
30   void f3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
31 
32   struct X1 {
33     typedef T my_T_type;
34 
35     void g0(T&); // expected-note{{previous}}
36     void g0(typename X0::U_type&);
37     void g0(typename X0::T_type&); // expected-error{{redecl}}
38 
39     void g1(T&); // expected-note{{previous}}
40     void g1(typename X0::U_type&);
41     void g1(typename X0<T, U>::T_type&); // expected-error{{redecl}}
42 
43     void g2(T&); // expected-note{{previous}}
44     void g2(typename X0::U_type&);
45     void g2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
46 
47     void g3(T&); // expected-note{{previous}}
48     void g3(typename X0::U_type&);
49     void g3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
50 
51     void g4(T&); // expected-note{{previous}}
52     void g4(typename X0::U_type&);
53     void g4(typename X1::my_T_type&); // expected-error{{redecl}}
54 
55     void g5(T&); // expected-note{{previous}}
56     void g5(typename X0::U_type&);
57     void g5(typename X0::X1::my_T_type&); // expected-error{{redecl}}
58 
59     void g6(T&); // expected-note{{previous}}
60     void g6(typename X0::U_type&);
61     void g6(typename X0<T, U>::X1::my_T_type&); // expected-error{{redecl}}
62 
63     void g7(T&); // expected-note{{previous}}
64     void g7(typename X0::U_type&);
65     void g7(typename ::X0<typename X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}}
66 
67     void g8(T&); // expected-note{{previous}}
68     void g8(typename X0<U, T_type>::T_type&);
69     void g8(typename ::X0<typename X0<T_type, U>::X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}}
70   };
71 };
72 
73 
74 template<typename T, typename U>
75 struct X0<T*, U*> {
76   typedef T T_type;
77   typedef U U_type;
78   typedef T* Tptr;
79   typedef U* Uptr;
80 
81   void f0(T&); // expected-note{{previous}}
82   void f0(typename X0::U_type&);
83   void f0(typename X0::T_type&); // expected-error{{redecl}}
84 
85   void f1(T&); // expected-note{{previous}}
86   void f1(typename X0::U_type&);
87   void f1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}}
88 
89   void f2(T&); // expected-note{{previous}}
90   void f2(typename X0::U_type&);
91   void f2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
92 
93   void f3(T&); // expected-note{{previous}}
94   void f3(typename X0::U_type&);
95   void f3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
96 
97   void f4(T&); // expected-note{{previous}}
98   void f4(typename X0::U_type&);
99   void f4(typename ::X0<Tptr, Uptr>::T_type&); // expected-error{{redecl}}
100 
101   void f5(X0*); // expected-note{{previous}}
102   void f5(::X0<T, U>*);
103   void f5(::X0<T*, U*>*); // expected-error{{redecl}}
104 
105   struct X2 {
106     typedef T my_T_type;
107 
108     void g0(T&); // expected-note{{previous}}
109     void g0(typename X0::U_type&);
110     void g0(typename X0::T_type&); // expected-error{{redecl}}
111 
112     void g1(T&); // expected-note{{previous}}
113     void g1(typename X0::U_type&);
114     void g1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}}
115 
116     void g2(T&); // expected-note{{previous}}
117     void g2(typename X0::U_type&);
118     void g2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
119 
120     void g3(T&); // expected-note{{previous}}
121     void g3(typename X0::U_type&);
122     void g3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
123 
124     void g4(T&); // expected-note{{previous}}
125     void g4(typename X0::U_type&);
126     void g4(typename X2::my_T_type&); // expected-error{{redecl}}
127 
128     void g5(T&); // expected-note{{previous}}
129     void g5(typename X0::U_type&);
130     void g5(typename X0::X2::my_T_type&); // expected-error{{redecl}}
131 
132     void g6(T&); // expected-note{{previous}}
133     void g6(typename X0::U_type&);
134     void g6(typename X0<T*, U*>::X2::my_T_type&); // expected-error{{redecl}}
135 
136     void g7(T&); // expected-note{{previous}}
137     void g7(typename X0::U_type&);
138     void g7(typename ::X0<typename X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}}
139 
140     void g8(T&); // expected-note{{previous}}
141     void g8(typename X0<U, T_type>::T_type&);
142     void g8(typename ::X0<typename X0<T_type*, U*>::X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}}
143   };
144 };
145 
146 template<typename T>
147 struct X1 {
148   static int *a;
149   void f(float *b) {
150     X1<T>::a = b; // expected-error{{incompatible}}
151     X1<T*>::a = b;
152   }
153 };
154 
155 namespace ConstantInCurrentInstantiation {
156   template<typename T>
157   struct X {
158     static const int value = 2;
159     static int array[value];
160   };
161 
162   template<typename T> const int X<T>::value;
163 
164   template<typename T>
165   int X<T>::array[X<T>::value] = { 1, 2 };
166 }
167 
168 namespace Expressions {
169   template <bool b>
170   struct Bool {
171     enum anonymous_enum { value = b };
172   };
173   struct True : public Bool<true> {};
174   struct False : public Bool<false> {};
175 
176   template <typename T1, typename T2>
177   struct Is_Same : public False {};
178   template <typename T>
179   struct Is_Same<T, T> : public True {};
180 
181   template <bool b, typename T = void>
182   struct Enable_If {};
183   template <typename T>
184   struct Enable_If<true, T>  {
185     typedef T type;
186   };
187 
188   template <typename T>
189   class Class {
190   public:
191     template <typename U>
192     typename Enable_If<Is_Same<U, Class>::value, void>::type
193     foo();
194   };
195 
196 
197   template <typename T>
198   template <typename U>
199   typename Enable_If<Is_Same<U, Class<T> >::value, void>::type
200   Class<T>::foo() {}
201 }
202 
203 namespace PR9255 {
204   template<typename T>
205   class X0  {
206   public:
207     class Inner1;
208 
209     class Inner2  {
210     public:
211       void f()
212       {
213         Inner1::f.g();
214       }
215     };
216   };
217 }
218 
219 namespace rdar10194295 {
220   template<typename XT>
221   class X {
222   public:
223     enum Enum { Yes, No };
224     template<Enum> void foo();
225     template<Enum> class Inner;
226   };
227 
228   template<typename XT>
229   template<typename X<XT>::Enum>
230   void X<XT>::foo()
231   {
232   }
233 
234   template<typename XT>
235   template<typename X<XT>::Enum>
236   class X<XT>::Inner { };
237 }
238 
239 namespace RebuildDependentScopeDeclRefExpr {
240   template<int> struct N {};
241   template<typename T> struct X {
242     static const int thing = 0;
243     N<thing> data();
244     N<thing> foo();
245   };
246   template<typename T> N<X<T>::thing> X<T>::data() {}
247   // FIXME: We should issue a typo-correction here.
248   template<typename T> N<X<T>::think> X<T>::foo() {} // expected-error {{no member named 'think' in 'X<T>'}}
249 }
250