1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3template<typename T, typename U>
4struct X0 : T::template apply<U> {
5  X0(U u) : T::template apply<U>(u) { }
6};
7
8template<typename T, typename U>
9struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}}
10
11template<typename T>
12struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}}
13
14namespace PR6031 {
15  template<typename T>
16  struct A;
17
18  template <class X>
19  struct C { };
20
21  template <class TT>
22  struct II {
23    typedef typename A<TT>::type type;
24  };
25
26  template <class TT>
27  struct FI : II<TT>
28  {
29    C<typename FI::type> a;
30  };
31
32  template <class TT>
33  struct FI2
34  {
35    C<typename FI2::type> a; // expected-error{{no type named 'type' in 'FI2<TT>'}}
36  };
37
38  template<typename T>
39  struct Base {
40    class Nested { };
41    template<typename U> struct MemberTemplate { };
42    int a;
43  };
44
45  template<typename T>
46  struct HasDepBase : Base<T> {
47    int foo() {
48      class HasDepBase::Nested nested;
49      typedef typename HasDepBase::template MemberTemplate<T>::type type;
50      return HasDepBase::a;
51    }
52  };
53
54  template<typename T>
55  struct NoDepBase {
56    int foo() {
57      class NoDepBase::Nested nested; // expected-error{{no class named 'Nested' in 'NoDepBase<T>'}}
58      typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{'MemberTemplate' following the 'template' keyword does not refer to a template}} \
59      // FIXME: expected-error{{unqualified-id}}
60      return NoDepBase::a; // expected-error{{no member named 'a' in 'NoDepBase<T>'}}
61    }
62  };
63}
64
65namespace Ambig {
66  template<typename T>
67  struct Base1 {
68    typedef int type; // expected-note{{member found by ambiguous name lookup}}
69  };
70
71  struct Base2 {
72    typedef float type; // expected-note{{member found by ambiguous name lookup}}
73  };
74
75  template<typename T>
76  struct Derived : Base1<T>, Base2 {
77    typedef typename Derived::type type; // expected-error{{member 'type' found in multiple base classes of different types}}
78    type *foo(float *fp) { return fp; }
79  };
80
81  Derived<int> di; // expected-note{{instantiation of}}
82}
83
84namespace PR6081 {
85  template<typename T>
86  struct A { };
87
88  template<typename T>
89  class B : public A<T>
90  {
91  public:
92    template< class X >
93    void f0(const X & k)
94    {
95      this->template f1<int>()(k);
96    }
97  };
98
99  template<typename T>
100  class C
101  {
102  public:
103    template< class X >
104    void f0(const X & k)
105    {
106      this->template f1<int>()(k); // expected-error{{'f1' following the 'template' keyword does not refer to a template}} \
107      // FIXME: expected-error{{unqualified-id}} \
108      // expected-error{{function-style cast or type construction}} \
109      // expected-error{{expected expression}}
110    }
111  };
112}
113
114namespace PR6413 {
115  template <typename T> class Base_A { };
116
117  class Base_B { };
118
119  template <typename T>
120  class Derived
121    : public virtual Base_A<T>
122    , public virtual Base_B
123  { };
124}
125
126namespace PR5812 {
127  template <class T> struct Base {
128    Base* p;
129  };
130
131  template <class T> struct Derived: public Base<T> {
132    typename Derived::Base* p; // meaning Derived::Base<T>
133  };
134
135  Derived<int> di;
136}
137