13573b2c84372d9484296fa658f5276f6c09acb92Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
2b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor
3374cbbcce032a22039f208baab7778e2f1f4a0a3Douglas Gregor// This test concerns the identity of dependent types within the
4374cbbcce032a22039f208baab7778e2f1f4a0a3Douglas Gregor// canonical type system. This corresponds to C++ [temp.type], which
5374cbbcce032a22039f208baab7778e2f1f4a0a3Douglas Gregor// specifies type equivalence within a template.
6374cbbcce032a22039f208baab7778e2f1f4a0a3Douglas Gregor//
7374cbbcce032a22039f208baab7778e2f1f4a0a3Douglas Gregor// FIXME: template template parameters
8374cbbcce032a22039f208baab7778e2f1f4a0a3Douglas Gregor
9c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregornamespace N {
10c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  template<typename T>
11c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  struct X2 {
12c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor    template<typename U>
13c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor    struct apply {
14c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor      typedef U* type;
15c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor    };
16c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  };
17c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor}
18c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor
19c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregornamespace Nalias = N;
20c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor
21b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregortemplate<typename T>
22b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregorstruct X0 { };
23b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor
24c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregorusing namespace N;
25c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor
26b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregortemplate<typename T, typename U>
27b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregorstruct X1 {
28b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  typedef T type;
29905406bd99b8498873a045f93ef196df6fe6cc69Douglas Gregor  typedef U U_type;
30b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor
31b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f0(T); // expected-note{{previous}}
32b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f0(U);
33b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f0(type); // expected-error{{redeclar}}
34b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor
35b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f1(T*); // expected-note{{previous}}
36b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f1(U*);
37b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f1(type*); // expected-error{{redeclar}}
38b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor
39b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f2(X0<T>*); // expected-note{{previous}}
40b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f2(X0<U>*);
41b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f2(X0<type>*); // expected-error{{redeclar}}
42b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor
43b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f3(X0<T>*); // expected-note{{previous}}
44b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f3(X0<U>*);
45b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f3(::X0<type>*); // expected-error{{redeclar}}
46b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor
47905406bd99b8498873a045f93ef196df6fe6cc69Douglas Gregor  void f4(typename T::template apply<U>*); // expected-note{{previous}}
48b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f4(typename U::template apply<U>*);
49b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f4(typename type::template apply<T>*);
50905406bd99b8498873a045f93ef196df6fe6cc69Douglas Gregor  void f4(typename type::template apply<U_type>*); // expected-error{{redeclar}}
51b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor
52905406bd99b8498873a045f93ef196df6fe6cc69Douglas Gregor  void f5(typename T::template apply<U>::type*); // expected-note{{previous}}
53b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f5(typename U::template apply<U>::type*);
54b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f5(typename U::template apply<T>::type*);
55b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor  void f5(typename type::template apply<T>::type*);
56905406bd99b8498873a045f93ef196df6fe6cc69Douglas Gregor  void f5(typename type::template apply<U_type>::type*); // expected-error{{redeclar}}
57c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor
58c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f6(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
59c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f6(typename N::X2<U>::template apply<U> *);
60c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f6(typename N::X2<U>::template apply<T> *);
61c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f6(typename ::N::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
62c03d3303fb298ae86bf5d5d6c98755928fdbde00Douglas Gregor
63c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f7(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
64c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f7(typename N::X2<U>::template apply<U> *);
65c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f7(typename N::X2<U>::template apply<T> *);
66c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f7(typename X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
67c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor
68c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f8(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
69c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f8(typename N::X2<U>::template apply<U> *);
70c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f8(typename N::X2<U>::template apply<T> *);
71c964fb2a3b6dcb3a01f974a33b7be543d31fa285Douglas Gregor  void f8(typename ::Nalias::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
72b88ba4173268f00ef39cfa6c6804d43ef510646dDouglas Gregor};
73d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor
74d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregornamespace PR6851 {
75d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor  template <bool v>
76d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor  struct S;
77d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor
78d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor  struct N {
79d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor    template <bool w>
80d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor    S< S<w>::cond && 1 > foo();
81d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor  };
82d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor
83d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor  struct Alien;
84d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor  bool operator&&(const Alien&, const Alien&);
85d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor
86d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor  template <bool w>
87d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor  S< S<w>::cond && 1 > N::foo() { }
88d83686bcce42cab1184da1f9c6980c238510edd6Douglas Gregor}
896ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor
906ff237965f97c96152e52fee566f03af687d86aaDouglas Gregornamespace PR7460 {
916ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor  template <typename T>
926ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor  struct TemplateClass2
936ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor  {
946ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor    enum { SIZE = 100 };
956ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor    static T member[SIZE];
966ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor  };
976ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor
986ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor  template <typename T>
996ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor  T TemplateClass2<T>::member[TemplateClass2<T>::SIZE];
1006ff237965f97c96152e52fee566f03af687d86aaDouglas Gregor}
101651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace PR18275 {
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T> struct A {
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void f(const int);
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void g(int);
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void h(const T);
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    void i(T);
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
109651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T>
111651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void A<T>::f(int x) { x = 0; }
112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T>
114651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void A<T>::g(const int x) { x = 0; } // expected-error {{not assignable}}
115651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T>
117651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void A<T>::h(T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type.
118651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
119651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T>
120651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void A<T>::i(const T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type.
121651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
122651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template struct A<int>;
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template struct A<int[1]>;
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
125