dependent-base-classes.cpp revision 38ff6ad6adbbef01b0edb403f5343adc91bc1f21
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{{missing 'template' keyword prior to dependent template name 'T::apply'}}
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 'struct PR6031::FI2'}} \
36        // expected-error{{C++ requires a type specifier for all declarations}}
37  };
38
39  template<typename T>
40  struct Base {
41    class Nested { };
42    template<typename U> struct MemberTemplate { };
43    int a;
44  };
45
46  template<typename T>
47  struct HasDepBase : Base<T> {
48    int foo() {
49      class HasDepBase::Nested nested;
50      typedef typename HasDepBase::template MemberTemplate<T>::type type;
51      return HasDepBase::a;
52    }
53  };
54
55  template<typename T>
56  struct NoDepBase {
57    int foo() {
58      class NoDepBase::Nested nested; // expected-error{{'Nested' does not name a tag member in the specified scope}}
59      typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{'MemberTemplate' following the 'template' keyword does not refer to a template}} \
60      // FIXME: expected-error{{unqualified-id}}
61      return NoDepBase::a; // expected-error{{no member named 'a' in 'struct PR6031::NoDepBase'}}
62    }
63  };
64}
65
66namespace Ambig {
67  template<typename T>
68  struct Base1 {
69    typedef int type; // expected-note{{member found by ambiguous name lookup}}
70  };
71
72  struct Base2 {
73    typedef float type; // expected-note{{member found by ambiguous name lookup}}
74  };
75
76  template<typename T>
77  struct Derived : Base1<T>, Base2 {
78    typedef typename Derived::type type; // expected-error{{member 'type' found in multiple base classes of different types}}
79    type *foo(float *fp) { return fp; }
80  };
81
82  Derived<int> di; // expected-note{{instantiation of}}
83}
84
85namespace PR6081 {
86  template<typename T>
87  struct A { };
88
89  template<typename T>
90  class B : public A<T>
91  {
92  public:
93    template< class X >
94    void f0(const X & k)
95    {
96      this->template f1<int>()(k);
97    }
98  };
99
100  template<typename T>
101  class C
102  {
103  public:
104    template< class X >
105    void f0(const X & k)
106    {
107      this->template f1<int>()(k); // expected-error{{'f1' following the 'template' keyword does not refer to a template}} \
108      // FIXME: expected-error{{unqualified-id}}
109    }
110  };
111}
112
113namespace PR6413 {
114  template <typename T> class Base_A { };
115
116  class Base_B { };
117
118  template <typename T>
119  class Derived
120    : public virtual Base_A<T>
121    , public virtual Base_B
122  { };
123}
124
125namespace PR5812 {
126  template <class T> struct Base {
127    Base* p;
128  };
129
130  template <class T> struct Derived: public Base<T> {
131    typename Derived::Base* p; // meaning Derived::Base<T>
132  };
133
134  Derived<int> di;
135}
136