| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- // RUN: %clang_cc1 -fsyntax-only -verify %s
- template<typename T>
- void call_f0(T x) {
- x.Base::f0();
- }
- struct Base {
- void f0();
- };
- struct X0 : Base {
- typedef Base CrazyBase;
- };
- void test_f0(X0 x0) {
- call_f0(x0);
- }
- template<typename TheBase, typename T>
- void call_f0_through_typedef(T x) {
- typedef TheBase Base2;
- x.Base2::f0();
- }
- void test_f0_through_typedef(X0 x0) {
- call_f0_through_typedef<Base>(x0);
- }
- template<typename TheBase, typename T>
- void call_f0_through_typedef2(T x) {
- typedef TheBase CrazyBase; // expected-note{{current scope}}
- x.CrazyBase::f0(); // expected-error{{ambiguous}} \
- // expected-error 2{{no member named}}
- }
- struct OtherBase { };
- struct X1 : Base, OtherBase {
- typedef OtherBase CrazyBase; // expected-note{{object type}}
- };
- void test_f0_through_typedef2(X0 x0, X1 x1) {
- call_f0_through_typedef2<Base>(x0);
- call_f0_through_typedef2<OtherBase>(x1); // expected-note{{instantiation}}
- call_f0_through_typedef2<Base>(x1); // expected-note{{instantiation}}
- }
- struct X2 {
- operator int() const;
- };
- template<typename T, typename U>
- T convert(const U& value) {
- return value.operator T(); // expected-error{{operator long}}
- }
- void test_convert(X2 x2) {
- convert<int>(x2);
- convert<long>(x2); // expected-note{{instantiation}}
- }
- template<typename T>
- void destruct(T* ptr) {
- ptr->~T();
- ptr->T::~T();
- }
- template<typename T>
- void destruct_intptr(int *ip) {
- ip->~T();
- ip->T::~T();
- }
- void test_destruct(X2 *x2p, int *ip) {
- destruct(x2p);
- destruct(ip);
- destruct_intptr<int>(ip);
- }
- // PR5220
- class X3 {
- protected:
- template <int> float* &f0();
- template <int> const float* &f0() const;
- void f1() {
- (void)static_cast<float*>(f0<0>());
- }
- void f1() const{
- (void)f0<0>();
- }
- };
- // Fun with template instantiation and conversions
- struct X4 {
- int& member();
- float& member() const;
- };
- template<typename T>
- struct X5 {
- void f(T* ptr) { int& ir = ptr->member(); }
- void g(T* ptr) { float& fr = ptr->member(); }
- };
- void test_X5(X5<X4> x5, X5<const X4> x5c, X4 *xp, const X4 *cxp) {
- x5.f(xp);
- x5c.g(cxp);
- }
- // In theory we can do overload resolution at template-definition time on this.
- // We should at least not assert.
- namespace test4 {
- struct Base {
- template <class T> void foo() {}
- };
- template <class T> struct Foo : Base {
- void test() {
- foo<int>();
- }
- };
- }
- namespace test5 {
- template<typename T>
- struct X {
- using T::value;
- T &getValue() {
- return &value;
- }
- };
- }
- // PR8739
- namespace test6 {
- struct A {};
- struct B {};
- template <class T> class Base;
- template <class T> class Derived : public Base<T> {
- A *field;
- void get(B **ptr) {
- // It's okay if at some point we figure out how to diagnose this
- // at instantiation time.
- *ptr = field;
- }
- };
- }
|