170 lines
4.1 KiB
C++
170 lines
4.1 KiB
C++
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
|
|
// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s
|
|
|
|
namespace test0 {
|
|
namespace N { }
|
|
|
|
template<typename T>
|
|
struct A {
|
|
void f();
|
|
};
|
|
|
|
template<typename T>
|
|
struct B : A<T> {
|
|
using A<T>::f;
|
|
|
|
void g() {
|
|
using namespace N;
|
|
f();
|
|
}
|
|
};
|
|
|
|
template struct B<int>;
|
|
}
|
|
|
|
namespace test1 {
|
|
template <class Derived> struct Visitor1 {
|
|
void Visit(struct Object1*);
|
|
};
|
|
template <class Derived> struct Visitor2 {
|
|
void Visit(struct Object2*); // expected-note {{candidate function}}
|
|
};
|
|
|
|
template <class Derived> struct JoinVisitor
|
|
: Visitor1<Derived>, Visitor2<Derived> {
|
|
typedef Visitor1<Derived> Base1;
|
|
typedef Visitor2<Derived> Base2;
|
|
|
|
void Visit(struct Object1*); // expected-note {{candidate function}}
|
|
using Base2::Visit;
|
|
};
|
|
|
|
class Knot : public JoinVisitor<Knot> {
|
|
};
|
|
|
|
void test() {
|
|
Knot().Visit((struct Object1*) 0);
|
|
Knot().Visit((struct Object2*) 0);
|
|
Knot().Visit((struct Object3*) 0); // expected-error {{no matching member function for call}}
|
|
}
|
|
}
|
|
|
|
// PR5847
|
|
namespace test2 {
|
|
namespace ns {
|
|
void foo();
|
|
}
|
|
|
|
template <class T> void bar(T* ptr) {
|
|
using ns::foo;
|
|
foo();
|
|
}
|
|
|
|
template void bar(char *);
|
|
}
|
|
|
|
namespace test3 {
|
|
template <typename T> struct t {
|
|
struct s1 {
|
|
T f1() const;
|
|
};
|
|
struct s2 : s1 {
|
|
using s1::f1;
|
|
T f1() const;
|
|
};
|
|
};
|
|
|
|
void f2()
|
|
{
|
|
t<int>::s2 a;
|
|
t<int>::s2 const & b = a;
|
|
b.f1();
|
|
}
|
|
}
|
|
|
|
namespace PR16936 {
|
|
// Make sure both using decls are properly considered for
|
|
// overload resolution.
|
|
template<class> struct A {
|
|
void access(int);
|
|
};
|
|
template<class> struct B {
|
|
void access();
|
|
};
|
|
template<class CELL> struct X : public A<CELL>, public B<CELL> {
|
|
using A<CELL>::access;
|
|
using B<CELL>::access;
|
|
|
|
void f() {
|
|
access(0);
|
|
}
|
|
};
|
|
|
|
void f() {
|
|
X<int> x;
|
|
x.f();
|
|
}
|
|
}
|
|
|
|
namespace pr21923 {
|
|
template <typename> struct Base {
|
|
int field;
|
|
void method();
|
|
};
|
|
template <typename Scalar> struct Derived : Base<Scalar> {
|
|
using Base<Scalar>::field;
|
|
using Base<Scalar>::method;
|
|
static void m_fn1() {
|
|
// expected-error@+1 {{invalid use of member 'field' in static member function}}
|
|
(void)field;
|
|
// expected-error@+1 {{invalid use of member 'field' in static member function}}
|
|
(void)&field;
|
|
// expected-error@+1 {{call to non-static member function without an object argument}}
|
|
(void)method;
|
|
// expected-error@+1 {{call to non-static member function without an object argument}}
|
|
(void)&method;
|
|
// expected-error@+1 {{call to non-static member function without an object argument}}
|
|
method();
|
|
(void)&Base<Scalar>::field;
|
|
(void)&Base<Scalar>::method;
|
|
}
|
|
#if __cplusplus >= 201103L
|
|
// These usages are OK in C++11 due to the unevaluated context.
|
|
enum { TheSize = sizeof(field) };
|
|
typedef decltype(field) U;
|
|
#else
|
|
// expected-error@+1 {{invalid use of non-static data member 'field'}}
|
|
enum { TheSize = sizeof(field) };
|
|
#endif
|
|
};
|
|
|
|
#if __cplusplus < 201103L
|
|
// C++98 has an extra note for TheSize.
|
|
// expected-note@+2 {{requested here}}
|
|
#endif
|
|
template class Derived<int>; // expected-note {{requested here}}
|
|
|
|
// This is interesting because we form an UnresolvedLookupExpr in the static
|
|
// function template and an UnresolvedMemberExpr in the instance function
|
|
// template. As a result, we get slightly different behavior.
|
|
struct UnresolvedTemplateNames {
|
|
template <typename> void maybe_static();
|
|
#if __cplusplus < 201103L
|
|
// expected-warning@+2 {{default template arguments for a function template are a C++11 extension}}
|
|
#endif
|
|
template <typename T, typename T::type = 0> static void maybe_static();
|
|
|
|
template <typename T>
|
|
void instance_method() { (void)maybe_static<T>(); }
|
|
template <typename T>
|
|
static void static_method() {
|
|
// expected-error@+1 {{call to non-static member function without an object argument}}
|
|
(void)maybe_static<T>();
|
|
}
|
|
};
|
|
void force_instantiation(UnresolvedTemplateNames x) {
|
|
x.instance_method<int>();
|
|
UnresolvedTemplateNames::static_method<int>(); // expected-note {{requested here}}
|
|
}
|
|
} // pr21923
|