162 lines · cpp
1// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 >%t 2>&12// RUN: FileCheck --check-prefix=MANGLING %s < %t3// RUN: FileCheck --check-prefix=XMANGLING %s < %t4// RUN: FileCheck --check-prefix=CODEGEN %s < %t5// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 2>&1 | FileCheck --check-prefix=MANGLING-X64 %s6 7void foo(void *);8 9struct A {10 virtual ~A();11 virtual void public_f();12 // Make sure we don't emit unneeded thunks:13 // XMANGLING-NOT: @"?public_f@A@@QAEXXZ"14 protected:15 virtual void protected_f();16 private:17 virtual void private_f();18};19 20struct B {21 virtual ~B();22 virtual void public_f();23 protected:24 virtual void protected_f();25 private:26 virtual void private_f();27};28 29 30struct C : A, B {31 C();32 33 virtual ~C();34 // MANGLING-DAG: declare {{.*}} @"??1C@@UAE@XZ"({{.*}})35 // MANGLING-DAG: define {{.*}} @"??_GC@@UAEPAXI@Z"({{.*}})36 // MANGLING-DAG: define {{.*}} @"??_EC@@W3AEPAXI@Z"({{.*}}) {{.*}} comdat37 // MANGLING-X64-DAG: declare {{.*}} @"??1C@@UEAA@XZ"({{.*}})38 // MANGLING-X64-DAG: define {{.*}} @"??_GC@@UEAAPEAXI@Z"({{.*}})39 // MANGLING-X64-DAG: define {{.*}} @"??_EC@@W7EAAPEAXI@Z"({{.*}}) {{.*}} comdat40 41 // Overrides public_f() of two subobjects with distinct vfptrs, thus needs a thunk.42 virtual void public_f();43 // MANGLING-DAG: @"?public_f@C@@UAEXXZ"44 // MANGLING-DAG: @"?public_f@C@@W3AEXXZ"45 // MANGLING-X64-DAG: @"?public_f@C@@UEAAXXZ"46 // MANGLING-X64-DAG: @"?public_f@C@@W7EAAXXZ"47 protected:48 virtual void protected_f();49 // MANGLING-DAG: @"?protected_f@C@@MAEXXZ"50 // MANGLING-DAG: @"?protected_f@C@@O3AEXXZ"51 // MANGLING-X64-DAG: @"?protected_f@C@@MEAAXXZ"52 // MANGLING-X64-DAG: @"?protected_f@C@@O7EAAXXZ"53 54 private:55 virtual void private_f();56 // MANGLING-DAG: @"?private_f@C@@EAEXXZ"57 // MANGLING-DAG: @"?private_f@C@@G3AEXXZ"58 // MANGLING-X64-DAG: @"?private_f@C@@EEAAXXZ"59 // MANGLING-X64-DAG: @"?private_f@C@@G7EAAXXZ"60};61 62C::C() {} // Emits vftable and forces thunk generation.63 64// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc noundef ptr @"??_EC@@W3AEPAXI@Z"(ptr noundef %this, i32 noundef %should_call_delete) {{.*}} comdat65// CODEGEN: getelementptr i8, ptr {{.*}}, i32 -466// FIXME: should actually call _EC, not _GC.67// CODEGEN: call x86_thiscallcc noundef ptr @"??_GC@@UAEPAXI@Z"68// CODEGEN: ret69 70// CODEGEN-LABEL: define linkonce_odr dso_local x86_thiscallcc void @"?public_f@C@@W3AEXXZ"(ptr71// CODEGEN: getelementptr i8, ptr {{.*}}, i32 -472// CODEGEN: call x86_thiscallcc void @"?public_f@C@@UAEXXZ"(ptr73// CODEGEN: ret74 75void zoo(C* obj) {76 delete obj;77}78 79struct D {80 virtual B* goo();81};82 83struct E : D {84 E();85 virtual C* goo();86 // MANGLING-DAG: @"?goo@E@@UAEPAUC@@XZ"87 // MANGLING-DAG: @"?goo@E@@QAEPAUB@@XZ"88 // MANGLING-X64-DAG: @"?goo@E@@UEAAPEAUC@@XZ"89 // MANGLING-X64-DAG: @"?goo@E@@QEAAPEAUB@@XZ"90};91 92E::E() {} // Emits vftable and forces thunk generation.93 94// CODEGEN-LABEL: define weak_odr dso_local x86_thiscallcc noundef ptr @"?goo@E@@QAEPAUB@@XZ"{{.*}} comdat95// CODEGEN: call x86_thiscallcc noundef ptr @"?goo@E@@UAEPAUC@@XZ"96// CODEGEN: getelementptr inbounds i8, ptr {{.*}}, i32 497// CODEGEN: ret98 99struct F : virtual A, virtual B {100 virtual void own_method();101 virtual ~F();102};103 104F f; // Just make sure we don't crash, e.g. mangling the complete dtor.105 106struct G : C { };107 108struct H : E {109 virtual G* goo();110 // MANGLING-DAG: @"?goo@H@@UAEPAUG@@XZ"111 // MANGLING-DAG: @"?goo@H@@QAEPAUB@@XZ"112 // MANGLING-DAG: @"?goo@H@@QAEPAUC@@XZ"113 // MANGLING-X64-DAG: @"?goo@H@@UEAAPEAUG@@XZ"114 // MANGLING-X64-DAG: @"?goo@H@@QEAAPEAUB@@XZ"115 // MANGLING-X64-DAG: @"?goo@H@@QEAAPEAUC@@XZ"116};117 118H h;119 120struct I : D {121 I();122 virtual F* goo();123};124 125I::I() {} // Emits vftable and forces thunk generation.126 127// CODEGEN-LABEL: define weak_odr dso_local x86_thiscallcc noundef ptr @"?goo@I@@QAEPAUB@@XZ"{{.*}} comdat128// CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc noundef ptr @"?goo@I@@UAEPAUF@@XZ"129// CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8, ptr %[[ORIG_RET]], i32 4130// CODEGEN: %[[VBTABLE:.*]] = load ptr, ptr %[[VBPTR_i8]]131// CODEGEN: %[[VBASE_OFFSET_PTR:.*]] = getelementptr inbounds i32, ptr %[[VBTABLE]], i32 2132// CODEGEN: %[[VBASE_OFFSET:.*]] = load i32, ptr %[[VBASE_OFFSET_PTR]]133// CODEGEN: %[[RES_i8:.*]] = getelementptr inbounds i8, ptr %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]]134// CODEGEN: phi ptr {{.*}} %[[RES_i8]]135// CODEGEN: ret ptr136 137namespace CrashOnThunksForAttributedType {138// We used to crash on this because the type of foo is an AttributedType, not139// FunctionType, and we had to look through the sugar.140struct A {141 virtual void __stdcall foo();142};143struct B {144 virtual void __stdcall foo();145};146struct C : A, B {147 virtual void __stdcall foo();148};149C c;150}151 152namespace {153struct E : D {154 E();155 virtual C* goo();156};157E::E() {}158E e;159// Class with internal linkage has internal linkage thunks.160// CODEGEN: define internal x86_thiscallcc noundef ptr @"?goo@E@?A0x{{[^@]*}}@@QAEPAUB@@XZ"161}162