1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
26946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregortemplate<typename T, typename U>
36946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregorstruct is_same {
46946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  static const bool value = false;
56946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor};
66946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
76946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregortemplate<typename T>
86946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregorstruct is_same<T, T> {
96946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  static const bool value = true;
106946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor};
116946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
126946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregortemplate<typename MetaFun, typename T1, typename T2>
136946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregorstruct metafun_apply2 {
146946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  typedef typename MetaFun::template apply<T1, T2> inner;
156946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  typedef typename inner::type type;
166946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor};
176946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
186946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregortemplate<typename T, typename U> struct pair;
196946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
206946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregorstruct make_pair {
216946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  template<typename T1, typename T2>
226946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  struct apply {
236946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor    typedef pair<T1, T2> type;
246946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  };
256946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor};
266946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
276946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregorint a0[is_same<metafun_apply2<make_pair, int, float>::type,
286946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor               pair<int, float> >::value? 1 : -1];
296946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregorint a1[is_same<
301a15dae8be2b28e02b6639aa92b832465c5be420Douglas Gregor         typename make_pair::template apply<int, float>, // expected-warning{{'template' keyword outside of a template}} \
311a15dae8be2b28e02b6639aa92b832465c5be420Douglas Gregor       // expected-warning{{'typename' occurs outside of a template}}
326946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor         make_pair::apply<int, float>
336946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor       >::value? 1 : -1];
346946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
356946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregortemplate<typename MetaFun>
366946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregorstruct swap_and_apply2 {
376946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  template<typename T1, typename T2>
386946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  struct apply {
396946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor    typedef typename MetaFun::template apply<T2, T1> new_metafun;
406946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor    typedef typename new_metafun::type type;
416946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  };
426946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor};
436946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
446946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregorint a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type,
456946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor               pair<float, int> >::value? 1 : -1];
466946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
47ae4406744024feee732cb8742572377e9646cd5bDouglas Gregortemplate<typename MetaFun>
48ae4406744024feee732cb8742572377e9646cd5bDouglas Gregorstruct swap_and_apply2b {
49ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor  template<typename T1, typename T2>
50ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor  struct apply {
51ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor    typedef typename MetaFun::template apply<T2, T1>::type type;
52ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor  };
53ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor};
54ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor
55ae4406744024feee732cb8742572377e9646cd5bDouglas Gregorint a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type,
56ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor               pair<float, int> >::value? 1 : -1];
57ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor
586946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregortemplate<typename T>
596946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregorstruct X0 {
606946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  template<typename U, typename V>
616946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  struct Inner;
626946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
636946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
646946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}
656946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor
666946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
676946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor  void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}
68ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor
69ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor  void f2(typename X0<T>::Inner<T*, T&>::type); // expected-note{{here}}
70ae4406744024feee732cb8742572377e9646cd5bDouglas Gregor  void f2(typename X0<T>::template Inner<T*, T&>::type); // expected-error{{redecl}}
716946baf3542dcb1ed0d98d0fdda451d1c39a49c2Douglas Gregor};
72a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor
73a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregornamespace PR6236 {
74a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor  template<typename T, typename U> struct S { };
75a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor
76a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor  template<typename T> struct S<T, T> {
77a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor    template<typename U> struct K { };
78a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor
79a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor    void f() {
80a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor      typedef typename S<T, T>::template K<T> Foo;
81a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor    }
82a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor  };
83a4e8c2a65a985782344a818d356c40d117fc4f12Douglas Gregor}
84ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor
85ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregornamespace PR6268 {
86ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor  template <typename T>
87ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor  struct Outer {
88ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor    template <typename U>
89ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor    struct Inner {};
90ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor
91ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor    template <typename U>
92ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor    typename Outer<T>::template Inner<U>
93ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor    foo(typename Outer<T>::template Inner<U>);
94ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor  };
95ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor
96ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor  template <typename T>
97ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor  template <typename U>
98ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor  typename Outer<T>::template Inner<U>
99ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor  Outer<T>::foo(typename Outer<T>::template Inner<U>) {
100ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor    return Inner<U>();
101ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor  }
102ae6288981b77d6230bf62055d3bb6380580aa1e8Douglas Gregor}
103a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor
104a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregornamespace PR6463 {
105a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor  struct B { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
106a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor  struct C { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
107a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor
108a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor  template<typename T>
109a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor  struct A : B, C {
110a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor    type& a(); // expected-error{{found in multiple base classes}}
111a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor    int x;
112a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor  };
113a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor
114a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor  // FIXME: Improve source location info here.
115a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor  template<typename T>
116a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor  typename A<T>::type& A<T>::a() { // expected-error{{found in multiple base classes}}
11763b4385822857374d035128dff3feac131465496John McCall    return x;
118a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor  }
119a50ce325b1ddd2bcbbfc1082ac93f3861d0a3a3dDouglas Gregor}
120264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor
121264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregornamespace PR7419 {
122264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor  template <typename T> struct S {
123264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor    typedef typename T::Y T2;
124264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor    typedef typename T2::Z T3;
125264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor    typedef typename T3::W T4;
126264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor    T4 *f();
127264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor
128264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor    typedef typename T::template Y<int> TT2;
129264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor    typedef typename TT2::template Z<float> TT3;
130264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor    typedef typename TT3::template W<double> TT4;
131264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor    TT4 g();
132264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor  };
133264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor
134264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor  template <typename T> typename T::Y::Z::W *S<T>::f() { }
135264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor  template <typename T> typename T::template Y<int>::template Z<float>::template W<double> S<T>::g() { }
136264bf66d55563dd86a3d7e06738aa427de512d2cDouglas Gregor}
137d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor
138d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregornamespace rdar8740998 {
139d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor  template<typename T>
140d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor  struct X : public T {
141d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor    using T::iterator; // expected-note{{add 'typename' to treat this using declaration as a type}} \
142d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor    // expected-error{{dependent using declaration resolved to type without 'typename'}}
143d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor
144d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor    void f() {
145d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor      typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}}
146d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor    }
147d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor  };
148d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor
149d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor  struct HasIterator {
150d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor    typedef int *iterator; // expected-note{{target of using declaration}}
151d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor  };
152d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor
153d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor  void test_X(X<HasIterator> xi) { // expected-note{{in instantiation of template class}}
154d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor    xi.f();
155d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor  }
156d95450421ee3b7cebfb18ce1312310d6c703431cDouglas Gregor}
157ef24c4b85e354255240bbbc21772098e6c3f6ae8Douglas Gregor
158ef24c4b85e354255240bbbc21772098e6c3f6ae8Douglas Gregornamespace rdar9068589 {
159ef24c4b85e354255240bbbc21772098e6c3f6ae8Douglas Gregor  // From GCC PR c++/13950
160ef24c4b85e354255240bbbc21772098e6c3f6ae8Douglas Gregor  template <class T> struct Base {};
161ef24c4b85e354255240bbbc21772098e6c3f6ae8Douglas Gregor  template <class T> struct Derived: public Base<T> {
162ef24c4b85e354255240bbbc21772098e6c3f6ae8Douglas Gregor    typename Derived::template Base<double>* p1;
163ef24c4b85e354255240bbbc21772098e6c3f6ae8Douglas Gregor  };
164ef24c4b85e354255240bbbc21772098e6c3f6ae8Douglas Gregor}
165