brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 3078c5a Raw
156 lines · cpp
1// RUN: %clang_cc1 -Wno-microsoft -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s2 3struct U;4static_assert(sizeof(void (U::*)()) == 2 * sizeof(void*) + 2 * sizeof(int), "");5 6struct A { int a; };7struct B { int b; };8struct I { union { struct { int a, b; }; }; };9 10struct S             { int a, b; void f(); virtual void g(); };11struct M : A, B      { int a, b; void f(); virtual void g(); };12struct V : virtual A { int a, b; void f(); virtual void g(); };13struct U             { int a, b; void f(); virtual void g(); };14 15struct C        { virtual void f(); };16struct D        { virtual void g(); };17struct O : C, D { virtual void g(); }; // override of non-primary18 19// Test data member pointers.20template <typename T, int T::*F>21int 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 most26// recent redeclaration rather than the definition.27struct V;28 29void 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 structs54  ReadField<I, &I::a>(i);55  ReadField<I, &I::b>(i);56}57 58// CHECK-LABEL: define {{.*}}ReadFields59// CHECK: call {{.*}} @"??$ReadField@US@@$03@@YAHAAUS@@@Z"60// CHECK: call {{.*}} @"??$ReadField@UM@@$0M@@@YAHAAUM@@@Z"61// CHECK: call {{.*}} @"??$ReadField@UV@@$F7A@@@YAHAAUV@@@Z"62// CHECK: call {{.*}} @"??$ReadField@UU@@$G3A@A@@@YAHAAUU@@@Z"63// CHECK: call {{.*}} @"??$ReadField@US@@$07@@YAHAAUS@@@Z"64// CHECK: call {{.*}} @"??$ReadField@UM@@$0BA@@@YAHAAUM@@@Z"65// CHECK: call {{.*}} @"??$ReadField@UV@@$FM@A@@@YAHAAUV@@@Z"66// CHECK: call {{.*}} @"??$ReadField@UU@@$G7A@A@@@YAHAAUU@@@Z"67 68// MSVC mangles null member pointers in function templates wrong, but it gets69// them right in class templates.70// CHECK: call {{.*}} @"??$ReadField@US@@$0A@@@YAHAAUS@@@Z"71// CHECK: call {{.*}} @"??$ReadField@UM@@$0A@@@YAHAAUM@@@Z"72// CHECK: call {{.*}} @"??$ReadField@UV@@$0A@@@YAHAAUV@@@Z"73// CHECK: call {{.*}} @"??$ReadField@UU@@$0A@@@YAHAAUU@@@Z"74 75// Non-polymorphic null data memptr vs first field memptr.  MSVC mangles these76// the same.77// CHECK: call {{.*}} @"??$ReadField@UA@@$0A@@@YAHAAUA@@@Z"78// CHECK: call {{.*}} @"??$ReadField@UA@@$0?0@@YAHAAUA@@@Z"79 80// Indirect fields are handled as-if they were simply members of their enclosing81// record.82// CHECK: call {{.*}} @"??$ReadField@UI@@$0A@@@YAHAAUI@@@Z"83// CHECK: call {{.*}} @"??$ReadField@UI@@$03@@YAHAAUI@@@Z"84 85// Test member function pointers.86template <typename T, void (T::*MFP)()>87void CallMethod(T &o) {88  (o.*MFP)();89}90 91void 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 this111  // 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 {{.*}}CallMethods122// CHECK: call {{.*}} @"??$CallMethod@US@@$1?f@1@QAEXXZ@@YAXAAUS@@@Z"123// CHECK: call {{.*}} @"??$CallMethod@UM@@$H?f@1@QAEXXZA@@@YAXAAUM@@@Z"124// CHECK: call {{.*}} @"??$CallMethod@UV@@$I?f@1@QAEXXZA@A@@@YAXAAUV@@@Z"125// CHECK: call {{.*}} @"??$CallMethod@UU@@$J?f@1@QAEXXZA@A@A@@@YAXAAUU@@@Z"126 127// PR17034: MSVC reuses the same thunk for every virtual g method because they128// are all at vftable offset zero.  They then mangle the name of the first thunk129// created into the name of the template instantiation, which is definitely a130// bug.  We don't follow them here.  Instead of ?_91@ backref below, they would131// get ?_9S@@ in every instantiation after the first.132 133// CHECK: call {{.*}} @"??$CallMethod@US@@$1??_91@$BA@AE@@YAXAAUS@@@Z"134// CHECK: call {{.*}} @"??$CallMethod@UM@@$H??_91@$BA@AEA@@@YAXAAUM@@@Z"135// CHECK: call {{.*}} @"??$CallMethod@UV@@$I??_91@$BA@AEA@A@@@YAXAAUV@@@Z"136// CHECK: call {{.*}} @"??$CallMethod@UU@@$J??_91@$BA@AEA@A@A@@@YAXAAUU@@@Z"137 138// CHECK: call {{.*}} @"??$CallMethod@UO@@$H??_91@$BA@AE3@@YAXAAUO@@@Z"139 140// CHECK: call {{.*}} @"??$CallMethod@US@@$0A@@@YAXAAUS@@@Z"141// CHECK: call {{.*}} @"??$CallMethod@UM@@$0A@@@YAXAAUM@@@Z"142// CHECK: call {{.*}} @"??$CallMethod@UV@@$0A@@@YAXAAUV@@@Z"143// CHECK: call {{.*}} @"??$CallMethod@UU@@$0A@@@YAXAAUU@@@Z"144 145namespace NegativeNVOffset {146struct A {};147struct B : virtual A {};148struct C : B {149  virtual void f();150};151}152 153template void CallMethod<NegativeNVOffset::C, &NegativeNVOffset::C::f>(NegativeNVOffset::C &);154 155// CHECK-LABEL: define {{.*}} @"??$CallMethod@UC@NegativeNVOffset@@$I??_912@$BA@AEPPPPPPPM@A@@@YAXAAUC@NegativeNVOffset@@@Z"156