Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -Wno-microsoft -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
      2 
      3 struct U;
      4 static_assert(sizeof(void (U::*)()) == 2 * sizeof(void*) + 2 * sizeof(int), "");
      5 
      6 struct A { int a; };
      7 struct B { int b; };
      8 struct I { union { struct { int a, b; }; }; };
      9 
     10 struct S             { int a, b; void f(); virtual void g(); };
     11 struct M : A, B      { int a, b; void f(); virtual void g(); };
     12 struct V : virtual A { int a, b; void f(); virtual void g(); };
     13 struct U             { int a, b; void f(); virtual void g(); };
     14 
     15 struct C        { virtual void f(); };
     16 struct D        { virtual void g(); };
     17 struct O : C, D { virtual void g(); }; // override of non-primary
     18 
     19 // Test data member pointers.
     20 template <typename T, int T::*F>
     21 int ReadField(T &o) {
     22   return F ? o.*F : 0;
     23 }
     24 
     25 // Redeclare some of the classes so that the implicit attribute goes on the most
     26 // recent redeclaration rather than the definition.
     27 struct V;
     28 
     29 void ReadFields() {
     30   A a;
     31   I i;
     32   S s;
     33   M m;
     34   V v;
     35   U u;
     36   ReadField<S, &S::a>(s);
     37   ReadField<M, &M::a>(m);
     38   ReadField<V, &V::a>(v);
     39   ReadField<U, &U::a>(u);
     40   ReadField<S, &S::b>(s);
     41   ReadField<M, &M::b>(m);
     42   ReadField<V, &V::b>(v);
     43   ReadField<U, &U::b>(u);
     44   ReadField<S, nullptr>(s);
     45   ReadField<M, nullptr>(m);
     46   ReadField<V, nullptr>(v);
     47   ReadField<U, nullptr>(u);
     48 
     49   // Non-polymorphic null data memptr vs first field memptr.
     50   ReadField<A, &A::a>(a);
     51   ReadField<A, nullptr>(a);
     52 
     53   // Indirect fields injected from anonymous unions and structs
     54   ReadField<I, &I::a>(i);
     55   ReadField<I, &I::b>(i);
     56 }
     57 
     58 // CHECK-LABEL: define {{.*}}ReadFields
     59 // CHECK: call {{.*}} @"\01??$ReadField@US@@$03@@YAHAAUS@@@Z"
     60 // CHECK: call {{.*}} @"\01??$ReadField@UM@@$0M@@@YAHAAUM@@@Z"
     61 // CHECK: call {{.*}} @"\01??$ReadField@UV@@$F7A@@@YAHAAUV@@@Z"
     62 // CHECK: call {{.*}} @"\01??$ReadField@UU@@$G3A@A@@@YAHAAUU@@@Z"
     63 // CHECK: call {{.*}} @"\01??$ReadField@US@@$07@@YAHAAUS@@@Z"
     64 // CHECK: call {{.*}} @"\01??$ReadField@UM@@$0BA@@@YAHAAUM@@@Z"
     65 // CHECK: call {{.*}} @"\01??$ReadField@UV@@$FM@A@@@YAHAAUV@@@Z"
     66 // CHECK: call {{.*}} @"\01??$ReadField@UU@@$G7A@A@@@YAHAAUU@@@Z"
     67 
     68 // MSVC mangles null member pointers in function templates wrong, but it gets
     69 // them right in class templates.
     70 // CHECK: call {{.*}} @"\01??$ReadField@US@@$0A@@@YAHAAUS@@@Z"
     71 // CHECK: call {{.*}} @"\01??$ReadField@UM@@$0A@@@YAHAAUM@@@Z"
     72 // CHECK: call {{.*}} @"\01??$ReadField@UV@@$0A@@@YAHAAUV@@@Z"
     73 // CHECK: call {{.*}} @"\01??$ReadField@UU@@$0A@@@YAHAAUU@@@Z"
     74 
     75 // Non-polymorphic null data memptr vs first field memptr.  MSVC mangles these
     76 // the same.
     77 // CHECK: call {{.*}} @"\01??$ReadField@UA@@$0A@@@YAHAAUA@@@Z"
     78 // CHECK: call {{.*}} @"\01??$ReadField@UA@@$0?0@@YAHAAUA@@@Z"
     79 
     80 // Indirect fields are handled as-if they were simply members of their enclosing
     81 // record.
     82 // CHECK: call {{.*}} @"\01??$ReadField@UI@@$0A@@@YAHAAUI@@@Z"
     83 // CHECK: call {{.*}} @"\01??$ReadField@UI@@$03@@YAHAAUI@@@Z"
     84 
     85 // Test member function pointers.
     86 template <typename T, void (T::*MFP)()>
     87 void CallMethod(T &o) {
     88   (o.*MFP)();
     89 }
     90 
     91 void CallMethods() {
     92   S s;
     93   M m;
     94   V v;
     95   U u;
     96   O o;
     97 
     98   // Non-virtual methods.
     99   CallMethod<S, &S::f>(s);
    100   CallMethod<M, &M::f>(m);
    101   CallMethod<V, &V::f>(v);
    102   CallMethod<U, &U::f>(u);
    103 
    104   // Virtual methods requiring thunk mangling.
    105   CallMethod<S, &S::g>(s);
    106   CallMethod<M, &M::g>(m);
    107   CallMethod<V, &V::g>(v);
    108   CallMethod<U, &U::g>(u);
    109 
    110   // A member pointer for a non-primary vbase will have a non-zero this
    111   // adjustment.
    112   CallMethod<O, &O::g>(o);
    113 
    114   // Null member pointers.
    115   CallMethod<S, nullptr>(s);
    116   CallMethod<M, nullptr>(m);
    117   CallMethod<V, nullptr>(v);
    118   CallMethod<U, nullptr>(u);
    119 }
    120 
    121 // CHECK-LABEL: define {{.*}}CallMethods
    122 // CHECK: call {{.*}} @"\01??$CallMethod@US@@$1?f@1@QAEXXZ@@YAXAAUS@@@Z"
    123 // CHECK: call {{.*}} @"\01??$CallMethod@UM@@$H?f@1@QAEXXZA@@@YAXAAUM@@@Z"
    124 // CHECK: call {{.*}} @"\01??$CallMethod@UV@@$I?f@1@QAEXXZA@A@@@YAXAAUV@@@Z"
    125 // CHECK: call {{.*}} @"\01??$CallMethod@UU@@$J?f@1@QAEXXZA@A@A@@@YAXAAUU@@@Z"
    126 
    127 // PR17034: MSVC reuses the same thunk for every virtual g method because they
    128 // are all at vftable offset zero.  They then mangle the name of the first thunk
    129 // created into the name of the template instantiation, which is definitely a
    130 // bug.  We don't follow them here.  Instead of ?_91@ backref below, they would
    131 // get ?_9S@@ in every instantiation after the first.
    132 
    133 // CHECK: call {{.*}} @"\01??$CallMethod@US@@$1??_91@$BA@AE@@YAXAAUS@@@Z"
    134 // CHECK: call {{.*}} @"\01??$CallMethod@UM@@$H??_91@$BA@AEA@@@YAXAAUM@@@Z"
    135 // CHECK: call {{.*}} @"\01??$CallMethod@UV@@$I??_91@$BA@AEA@A@@@YAXAAUV@@@Z"
    136 // CHECK: call {{.*}} @"\01??$CallMethod@UU@@$J??_91@$BA@AEA@A@A@@@YAXAAUU@@@Z"
    137 
    138 // CHECK: call {{.*}} @"\01??$CallMethod@UO@@$H??_91@$BA@AE3@@YAXAAUO@@@Z"
    139 
    140 // CHECK: call {{.*}} @"\01??$CallMethod@US@@$0A@@@YAXAAUS@@@Z"
    141 // CHECK: call {{.*}} @"\01??$CallMethod@UM@@$0A@@@YAXAAUM@@@Z"
    142 // CHECK: call {{.*}} @"\01??$CallMethod@UV@@$0A@@@YAXAAUV@@@Z"
    143 // CHECK: call {{.*}} @"\01??$CallMethod@UU@@$0A@@@YAXAAUU@@@Z"
    144 
    145 namespace NegativeNVOffset {
    146 struct A {};
    147 struct B : virtual A {};
    148 struct C : B {
    149   virtual void f();
    150 };
    151 }
    152 
    153 template void CallMethod<NegativeNVOffset::C, &NegativeNVOffset::C::f>(NegativeNVOffset::C &);
    154 
    155 // CHECK-LABEL: define {{.*}} @"\01??$CallMethod@UC@NegativeNVOffset@@$I??_912@$BA@AEPPPPPPPM@A@@@YAXAAUC@NegativeNVOffset@@@Z"
    156