Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
      3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
      4 
      5 template<typename T>
      6 void call_f0(T x) {
      7   x.Base::f0();
      8 }
      9 
     10 struct Base {
     11   void f0();
     12 };
     13 
     14 struct X0 : Base {
     15   typedef Base CrazyBase;
     16 };
     17 
     18 void test_f0(X0 x0) {
     19   call_f0(x0);
     20 }
     21 
     22 template<typename TheBase, typename T>
     23 void call_f0_through_typedef(T x) {
     24   typedef TheBase Base2;
     25   x.Base2::f0();
     26 }
     27 
     28 void test_f0_through_typedef(X0 x0) {
     29   call_f0_through_typedef<Base>(x0);
     30 }
     31 
     32 template<typename TheBase, typename T>
     33 void call_f0_through_typedef2(T x) {
     34   typedef TheBase CrazyBase;
     35 #if __cplusplus <= 199711L
     36   // expected-note@-2 {{lookup from the current scope refers here}}
     37 #endif
     38 
     39   x.CrazyBase::f0(); // expected-error 2{{no member named}}
     40 #if __cplusplus <= 199711L
     41   // expected-error@-2 {{lookup of 'CrazyBase' in member access expression is ambiguous}}
     42 #endif
     43 
     44 }
     45 
     46 struct OtherBase { };
     47 
     48 struct X1 : Base, OtherBase {
     49   typedef OtherBase CrazyBase;
     50 #if __cplusplus <= 199711L
     51   // expected-note@-2 {{lookup in the object type 'X1' refers here}}
     52 #endif
     53 };
     54 
     55 void test_f0_through_typedef2(X0 x0, X1 x1) {
     56   call_f0_through_typedef2<Base>(x0);
     57   call_f0_through_typedef2<OtherBase>(x1); // expected-note{{instantiation}}
     58   call_f0_through_typedef2<Base>(x1); // expected-note{{instantiation}}
     59 }
     60 
     61 
     62 struct X2 {
     63   operator int() const;
     64 };
     65 
     66 template<typename T, typename U>
     67 T convert(const U& value) {
     68   return value.operator T(); // expected-error{{operator long}}
     69 }
     70 
     71 void test_convert(X2 x2) {
     72   convert<int>(x2);
     73   convert<long>(x2); // expected-note{{instantiation}}
     74 }
     75 
     76 template<typename T>
     77 void destruct(T* ptr) {
     78   ptr->~T();
     79   ptr->T::~T();
     80 }
     81 
     82 template<typename T>
     83 void destruct_intptr(int *ip) {
     84   ip->~T();
     85   ip->T::~T();
     86 }
     87 
     88 void test_destruct(X2 *x2p, int *ip) {
     89   destruct(x2p);
     90   destruct(ip);
     91   destruct_intptr<int>(ip);
     92 }
     93 
     94 // PR5220
     95 class X3 {
     96 protected:
     97   template <int> float* &f0();
     98   template <int> const float* &f0() const;
     99   void f1() {
    100     (void)static_cast<float*>(f0<0>());
    101   }
    102   void f1() const{
    103     (void)f0<0>();
    104   }
    105 };
    106 
    107 // Fun with template instantiation and conversions
    108 struct X4 {
    109   int& member();
    110   float& member() const;
    111 };
    112 
    113 template<typename T>
    114 struct X5 {
    115   void f(T* ptr) { int& ir = ptr->member(); }
    116   void g(T* ptr) { float& fr = ptr->member(); }
    117 };
    118 
    119 void test_X5(X5<X4> x5, X5<const X4> x5c, X4 *xp, const X4 *cxp) {
    120   x5.f(xp);
    121   x5c.g(cxp);
    122 }
    123 
    124 // In theory we can do overload resolution at template-definition time on this.
    125 // We should at least not assert.
    126 namespace test4 {
    127   struct Base {
    128     template <class T> void foo() {}
    129   };
    130 
    131   template <class T> struct Foo : Base {
    132     void test() {
    133       foo<int>();
    134     }
    135   };
    136 }
    137 
    138 namespace test5 {
    139   template<typename T>
    140   struct X {
    141     using T::value;
    142 
    143     T &getValue() {
    144       return &value;
    145     }
    146   };
    147 }
    148 
    149 // PR8739
    150 namespace test6 {
    151   struct A {};
    152   struct B {};
    153   template <class T> class Base;
    154   template <class T> class Derived : public Base<T> {
    155     A *field;
    156     void get(B **ptr) {
    157       // It's okay if at some point we figure out how to diagnose this
    158       // at instantiation time.
    159       *ptr = field;
    160     }
    161   };
    162 }
    163