1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -fdump-vtable-layouts -o %t.ll > %t 2f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=EMITS-VFTABLE %s < %t.ll 3f4a2713aSLionel Sambuc // RUN: FileCheck --check-prefix=NO-VFTABLE %s < %t.ll 4*0a6a1f1dSLionel Sambuc // RUN: FileCheck %s < %t 5f4a2713aSLionel Sambuc 6f4a2713aSLionel Sambuc struct A { 7*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'A' (3 entries) 8*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void A::f() 9*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void A::g() 10*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void A::h() 11*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable indices for 'A' (3 entries) 12*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void A::f() 13*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void A::g() 14*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void A::h() 15f4a2713aSLionel Sambuc 16f4a2713aSLionel Sambuc virtual void f(); 17f4a2713aSLionel Sambuc virtual void g(); 18f4a2713aSLionel Sambuc virtual void h(); 19f4a2713aSLionel Sambuc int ia; 20f4a2713aSLionel Sambuc }; 21f4a2713aSLionel Sambuc A a; 22f4a2713aSLionel Sambuc // EMITS-VFTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*] use(A * obj)23*0a6a1f1dSLionel Sambucvoid use(A *obj) { obj->f(); } 24f4a2713aSLionel Sambuc 25f4a2713aSLionel Sambuc struct B : A { 26*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'A' in 'B' (5 entries) 27*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void B::f() 28*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void A::g() 29*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void A::h() 30*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void B::i() 31*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | void B::j() 32*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable indices for 'B' (3 entries) 33*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void B::f() 34*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void B::i() 35*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | void B::j() 36f4a2713aSLionel Sambuc 37f4a2713aSLionel Sambuc virtual void f(); // overrides A::f() 38f4a2713aSLionel Sambuc virtual void i(); 39f4a2713aSLionel Sambuc virtual void j(); 40f4a2713aSLionel Sambuc }; 41f4a2713aSLionel Sambuc B b; 42f4a2713aSLionel Sambuc // EMITS-VFTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*] use(B * obj)43*0a6a1f1dSLionel Sambucvoid use(B *obj) { obj->f(); } 44f4a2713aSLionel Sambuc 45f4a2713aSLionel Sambuc struct C { 46*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'C' (2 entries) 47*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | C::~C() [scalar deleting] 48*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void C::f() 49*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable indices for 'C' (2 entries). 50*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | C::~C() [scalar deleting] 51*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void C::f() 52f4a2713aSLionel Sambuc 53f4a2713aSLionel Sambuc virtual ~C(); 54f4a2713aSLionel Sambuc virtual void f(); 55f4a2713aSLionel Sambuc }; f()56f4a2713aSLionel Sambucvoid C::f() {} 57f4a2713aSLionel Sambuc // NO-VFTABLE-NOT: @"\01??_7C@@6B@" use(C * obj)58*0a6a1f1dSLionel Sambucvoid use(C *obj) { obj->f(); } 59f4a2713aSLionel Sambuc 60f4a2713aSLionel Sambuc struct D { 61*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'D' (2 entries) 62*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void D::f() 63*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | D::~D() [scalar deleting] 64*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable indices for 'D' (2 entries) 65*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void D::f() 66*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | D::~D() [scalar deleting] 67f4a2713aSLionel Sambuc 68f4a2713aSLionel Sambuc virtual void f(); 69f4a2713aSLionel Sambuc virtual ~D(); 70f4a2713aSLionel Sambuc }; 71f4a2713aSLionel Sambuc D d; 72f4a2713aSLionel Sambuc // EMITS-VFTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*] use(D * obj)73*0a6a1f1dSLionel Sambucvoid use(D *obj) { obj->f(); } 74f4a2713aSLionel Sambuc 75f4a2713aSLionel Sambuc struct E : A { 76*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'A' in 'E' (5 entries) 77*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void A::f() 78*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void A::g() 79*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void A::h() 80*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | E::~E() [scalar deleting] 81*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | void E::i() 82*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable indices for 'E' (2 entries). 83*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | E::~E() [scalar deleting] 84*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | void E::i() 85f4a2713aSLionel Sambuc 86f4a2713aSLionel Sambuc // ~E would be the key method, but it isn't used, and MS ABI has no key 87f4a2713aSLionel Sambuc // methods. 88f4a2713aSLionel Sambuc virtual ~E(); 89f4a2713aSLionel Sambuc virtual void i(); 90f4a2713aSLionel Sambuc }; i()91f4a2713aSLionel Sambucvoid E::i() {} 92f4a2713aSLionel Sambuc // NO-VFTABLE-NOT: @"\01??_7E@@6B@" use(E * obj)93*0a6a1f1dSLionel Sambucvoid use(E *obj) { obj->i(); } 94f4a2713aSLionel Sambuc 95f4a2713aSLionel Sambuc struct F : A { 96*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'A' in 'F' (5 entries) 97*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void A::f() 98*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void A::g() 99*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void A::h() 100*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void F::i() 101*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | F::~F() [scalar deleting] 102*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable indices for 'F' (2 entries). 103*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void F::i() 104*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | F::~F() [scalar deleting] 105f4a2713aSLionel Sambuc 106f4a2713aSLionel Sambuc virtual void i(); 107f4a2713aSLionel Sambuc virtual ~F(); 108f4a2713aSLionel Sambuc }; 109f4a2713aSLionel Sambuc F f; 110f4a2713aSLionel Sambuc // EMITS-VFTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*] use(F * obj)111*0a6a1f1dSLionel Sambucvoid use(F *obj) { obj->i(); } 112f4a2713aSLionel Sambuc 113f4a2713aSLionel Sambuc struct G : E { 114*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'A' in 'E' in 'G' (6 entries) 115*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void G::f() 116*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void A::g() 117*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void A::h() 118*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | G::~G() [scalar deleting] 119*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | void E::i() 120*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 5 | void G::j() 121*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable indices for 'G' (3 entries). 122*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void G::f() 123*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | G::~G() [scalar deleting] 124*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 5 | void G::j() 125f4a2713aSLionel Sambuc 126f4a2713aSLionel Sambuc virtual void f(); // overrides A::f() 127f4a2713aSLionel Sambuc virtual ~G(); 128f4a2713aSLionel Sambuc virtual void j(); 129f4a2713aSLionel Sambuc }; j()130f4a2713aSLionel Sambucvoid G::j() {} 131f4a2713aSLionel Sambuc // NO-VFTABLE-NOT: @"\01??_7G@@6B@" use(G * obj)132*0a6a1f1dSLionel Sambucvoid use(G *obj) { obj->j(); } 133f4a2713aSLionel Sambuc 134f4a2713aSLionel Sambuc // Test that the usual Itanium-style key method does not emit a vtable. 135f4a2713aSLionel Sambuc struct H { 136f4a2713aSLionel Sambuc virtual void f(); 137f4a2713aSLionel Sambuc }; f()138f4a2713aSLionel Sambucvoid H::f() {} 139f4a2713aSLionel Sambuc // NO-VFTABLE-NOT: @"\01??_7H@@6B@" 140f4a2713aSLionel Sambuc 141f4a2713aSLionel Sambuc struct Empty { }; 142f4a2713aSLionel Sambuc 143f4a2713aSLionel Sambuc struct I : Empty { 144*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'I' (2 entries) 145*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void I::f() 146*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void I::g() 147f4a2713aSLionel Sambuc virtual void f(); 148f4a2713aSLionel Sambuc virtual void g(); 149f4a2713aSLionel Sambuc }; 150f4a2713aSLionel Sambuc 151f4a2713aSLionel Sambuc I i; use(I * obj)152*0a6a1f1dSLionel Sambucvoid use(I *obj) { obj->f(); } 153f4a2713aSLionel Sambuc 154f4a2713aSLionel Sambuc struct J { 155*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'J' (6 entries) 156*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void J::foo(long) 157*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void J::foo(int) 158*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void J::foo(short) 159*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void J::bar(long) 160*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | void J::bar(int) 161*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 5 | void J::bar(short) 162f4a2713aSLionel Sambuc virtual void foo(short); 163f4a2713aSLionel Sambuc virtual void bar(short); 164f4a2713aSLionel Sambuc virtual void foo(int); 165f4a2713aSLionel Sambuc virtual void bar(int); 166f4a2713aSLionel Sambuc virtual void foo(long); 167f4a2713aSLionel Sambuc virtual void bar(long); 168f4a2713aSLionel Sambuc }; 169f4a2713aSLionel Sambuc 170f4a2713aSLionel Sambuc J j; use(J * obj)171*0a6a1f1dSLionel Sambucvoid use(J *obj) { obj->foo(42); } 172f4a2713aSLionel Sambuc 173f4a2713aSLionel Sambuc struct K : J { 174*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'J' in 'K' (9 entries) 175*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void J::foo(long) 176*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void J::foo(int) 177*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void J::foo(short) 178*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void J::bar(long) 179*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | void J::bar(int) 180*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 5 | void J::bar(short) 181*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 6 | void K::bar(double) 182*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 7 | void K::bar(float) 183*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 8 | void K::foo(float) 184f4a2713aSLionel Sambuc virtual void bar(float); 185f4a2713aSLionel Sambuc virtual void foo(float); 186f4a2713aSLionel Sambuc virtual void bar(double); 187f4a2713aSLionel Sambuc }; 188f4a2713aSLionel Sambuc 189f4a2713aSLionel Sambuc K k; use(K * obj)190*0a6a1f1dSLionel Sambucvoid use(K *obj) { obj->foo(42.0f); } 191f4a2713aSLionel Sambuc 192f4a2713aSLionel Sambuc struct L : J { 193*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'J' in 'L' (9 entries) 194*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void J::foo(long) 195*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void L::foo(int) 196*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void J::foo(short) 197*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void J::bar(long) 198*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | void J::bar(int) 199*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 5 | void J::bar(short) 200*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 6 | void L::foo(float) 201*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 7 | void L::bar(double) 202*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 8 | void L::bar(float) 203f4a2713aSLionel Sambuc 204f4a2713aSLionel Sambuc // This case is interesting. Since the J::foo(int) override is the first method in 205f4a2713aSLionel Sambuc // the class, foo(float) precedes the bar(double) and bar(float) in the vftable. 206f4a2713aSLionel Sambuc virtual void foo(int); 207f4a2713aSLionel Sambuc virtual void bar(float); 208f4a2713aSLionel Sambuc virtual void foo(float); 209f4a2713aSLionel Sambuc virtual void bar(double); 210f4a2713aSLionel Sambuc }; 211f4a2713aSLionel Sambuc 212f4a2713aSLionel Sambuc L l; use(L * obj)213*0a6a1f1dSLionel Sambucvoid use(L *obj) { obj->foo(42.0f); } 214f4a2713aSLionel Sambuc 215f4a2713aSLionel Sambuc struct M : J { 216*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'J' in 'M' (11 entries) 217*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void J::foo(long) 218*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void M::foo(int) 219*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void J::foo(short) 220*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void J::bar(long) 221*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 4 | void J::bar(int) 222*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 5 | void J::bar(short) 223*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 6 | void M::foo(float) 224*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 7 | void M::spam(long) 225*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 8 | void M::spam(int) 226*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 9 | void M::bar(double) 227*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 10 | void M::bar(float) 228f4a2713aSLionel Sambuc 229f4a2713aSLionel Sambuc virtual void foo(int); 230f4a2713aSLionel Sambuc virtual void spam(int); 231f4a2713aSLionel Sambuc virtual void bar(float); 232f4a2713aSLionel Sambuc virtual void bar(double); 233f4a2713aSLionel Sambuc virtual void foo(float); 234f4a2713aSLionel Sambuc virtual void spam(long); 235f4a2713aSLionel Sambuc }; 236f4a2713aSLionel Sambuc 237f4a2713aSLionel Sambuc M m; use(M * obj)238*0a6a1f1dSLionel Sambucvoid use(M *obj) { obj->foo(42.0f); } 239f4a2713aSLionel Sambuc 240f4a2713aSLionel Sambuc struct N { 241*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'N' (4 entries) 242*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void N::operator+(int) 243*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void N::operator+(short) 244*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void N::operator*(int) 245*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void N::operator*(short) 246f4a2713aSLionel Sambuc virtual void operator+(short); 247f4a2713aSLionel Sambuc virtual void operator*(short); 248f4a2713aSLionel Sambuc virtual void operator+(int); 249f4a2713aSLionel Sambuc virtual void operator*(int); 250f4a2713aSLionel Sambuc }; 251f4a2713aSLionel Sambuc 252f4a2713aSLionel Sambuc N n; use(N * obj)253*0a6a1f1dSLionel Sambucvoid use(N *obj) { obj->operator+(42); } 254*0a6a1f1dSLionel Sambuc 255*0a6a1f1dSLionel Sambuc struct O { virtual A *f(); }; 256*0a6a1f1dSLionel Sambuc struct P : O { virtual B *f(); }; 257*0a6a1f1dSLionel Sambuc P p; use(O * obj)258*0a6a1f1dSLionel Sambucvoid use(O *obj) { obj->f(); } use(P * obj)259*0a6a1f1dSLionel Sambucvoid use(P *obj) { obj->f(); } 260*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'O' (1 entry) 261*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | A *O::f() 262*0a6a1f1dSLionel Sambuc 263*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'O' in 'P' (1 entry) 264*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | B *P::f() 265*0a6a1f1dSLionel Sambuc 266*0a6a1f1dSLionel Sambuc struct Q { 267*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'Q' (2 entries) 268*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void Q::foo(int) 269*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void Q::bar(int) 270*0a6a1f1dSLionel Sambuc void foo(short); 271*0a6a1f1dSLionel Sambuc void bar(short); 272*0a6a1f1dSLionel Sambuc virtual void bar(int); 273*0a6a1f1dSLionel Sambuc virtual void foo(int); 274*0a6a1f1dSLionel Sambuc }; 275*0a6a1f1dSLionel Sambuc 276*0a6a1f1dSLionel Sambuc Q q; use(Q * obj)277*0a6a1f1dSLionel Sambucvoid use(Q *obj) { obj->foo(42); } 278*0a6a1f1dSLionel Sambuc 279*0a6a1f1dSLionel Sambuc // Inherited non-virtual overloads don't participate in the ordering. 280*0a6a1f1dSLionel Sambuc struct R : Q { 281*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'Q' in 'R' (4 entries) 282*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void Q::foo(int) 283*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 1 | void Q::bar(int) 284*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 2 | void R::bar(long) 285*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 3 | void R::foo(long) 286*0a6a1f1dSLionel Sambuc virtual void bar(long); 287*0a6a1f1dSLionel Sambuc virtual void foo(long); 288*0a6a1f1dSLionel Sambuc }; 289*0a6a1f1dSLionel Sambuc 290*0a6a1f1dSLionel Sambuc R r; use(R * obj)291*0a6a1f1dSLionel Sambucvoid use(R *obj) { obj->foo(42l); } 292*0a6a1f1dSLionel Sambuc 293*0a6a1f1dSLionel Sambuc struct S { 294*0a6a1f1dSLionel Sambuc // CHECK-LABEL: VFTable for 'S' (1 entry). 295*0a6a1f1dSLionel Sambuc // CHECK-NEXT: 0 | void S::f() [deleted] 296*0a6a1f1dSLionel Sambuc virtual void f() = delete; 297*0a6a1f1dSLionel Sambuc S(); 298*0a6a1f1dSLionel Sambuc // EMITS-VFTABLE-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast (void ()* @_purecall to i8*)] 299*0a6a1f1dSLionel Sambuc }; 300*0a6a1f1dSLionel Sambuc S()301*0a6a1f1dSLionel SambucS::S() {} 302