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 membmers 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
11template<typename T, typename U>
12struct 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
74template<typename T, typename U>
75struct 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
146template<typename T>
147struct 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
155namespace 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
168namespace 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
203namespace 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
219namespace 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