summaryrefslogtreecommitdiff
path: root/clang/test/SemaTemplate/dependent-base-classes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaTemplate/dependent-base-classes.cpp')
-rw-r--r--clang/test/SemaTemplate/dependent-base-classes.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/dependent-base-classes.cpp b/clang/test/SemaTemplate/dependent-base-classes.cpp
new file mode 100644
index 0000000..895eacc
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-base-classes.cpp
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, typename U>
+struct X0 : T::template apply<U> {
+ X0(U u) : T::template apply<U>(u) { }
+};
+
+template<typename T, typename U>
+struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}}
+
+template<typename T>
+struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}}
+
+namespace PR6031 {
+ template<typename T>
+ struct A;
+
+ template <class X>
+ struct C { };
+
+ template <class TT>
+ struct II {
+ typedef typename A<TT>::type type;
+ };
+
+ template <class TT>
+ struct FI : II<TT>
+ {
+ C<typename FI::type> a;
+ };
+
+ template <class TT>
+ struct FI2
+ {
+ C<typename FI2::type> a; // expected-error{{no type named 'type' in 'FI2<TT>'}} \
+ // expected-error{{C++ requires a type specifier for all declarations}}
+ };
+
+ template<typename T>
+ struct Base {
+ class Nested { };
+ template<typename U> struct MemberTemplate { };
+ int a;
+ };
+
+ template<typename T>
+ struct HasDepBase : Base<T> {
+ int foo() {
+ class HasDepBase::Nested nested;
+ typedef typename HasDepBase::template MemberTemplate<T>::type type;
+ return HasDepBase::a;
+ }
+ };
+
+ template<typename T>
+ struct NoDepBase {
+ int foo() {
+ class NoDepBase::Nested nested; // expected-error{{no class named 'Nested' in 'NoDepBase<T>'}}
+ typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{'MemberTemplate' following the 'template' keyword does not refer to a template}} \
+ // FIXME: expected-error{{unqualified-id}}
+ return NoDepBase::a; // expected-error{{no member named 'a' in 'NoDepBase<T>'}}
+ }
+ };
+}
+
+namespace Ambig {
+ template<typename T>
+ struct Base1 {
+ typedef int type; // expected-note{{member found by ambiguous name lookup}}
+ };
+
+ struct Base2 {
+ typedef float type; // expected-note{{member found by ambiguous name lookup}}
+ };
+
+ template<typename T>
+ struct Derived : Base1<T>, Base2 {
+ typedef typename Derived::type type; // expected-error{{member 'type' found in multiple base classes of different types}}
+ type *foo(float *fp) { return fp; }
+ };
+
+ Derived<int> di; // expected-note{{instantiation of}}
+}
+
+namespace PR6081 {
+ template<typename T>
+ struct A { };
+
+ template<typename T>
+ class B : public A<T>
+ {
+ public:
+ template< class X >
+ void f0(const X & k)
+ {
+ this->template f1<int>()(k);
+ }
+ };
+
+ template<typename T>
+ class C
+ {
+ public:
+ template< class X >
+ void f0(const X & k)
+ {
+ this->template f1<int>()(k); // expected-error{{'f1' following the 'template' keyword does not refer to a template}} \
+ // FIXME: expected-error{{unqualified-id}} \
+ // expected-error{{function-style cast or type construction}} \
+ // expected-error{{expected expression}}
+ }
+ };
+}
+
+namespace PR6413 {
+ template <typename T> class Base_A { };
+
+ class Base_B { };
+
+ template <typename T>
+ class Derived
+ : public virtual Base_A<T>
+ , public virtual Base_B
+ { };
+}
+
+namespace PR5812 {
+ template <class T> struct Base {
+ Base* p;
+ };
+
+ template <class T> struct Derived: public Base<T> {
+ typename Derived::Base* p; // meaning Derived::Base<T>
+ };
+
+ Derived<int> di;
+}