llvm-project/clang/test/SemaTemplate/instantiate-using-decl.cpp

170 lines
4.1 KiB
C++
Raw Normal View History

// 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