forked from OSchip/llvm-project
134 lines
3.8 KiB
C++
134 lines
3.8 KiB
C++
// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 >%t 2>&1
|
|
// RUN: FileCheck --check-prefix=MANGLING %s < %t
|
|
// RUN: FileCheck --check-prefix=XMANGLING %s < %t
|
|
// RUN: FileCheck --check-prefix=CODEGEN %s < %t
|
|
// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 2>&1 | FileCheck --check-prefix=MANGLING-X64 %s
|
|
|
|
void foo(void *);
|
|
|
|
struct A {
|
|
virtual ~A();
|
|
virtual void public_f();
|
|
// Make sure we don't emit unneeded thunks:
|
|
// XMANGLING-NOT: @"\01?public_f@A@@QAEXXZ"
|
|
protected:
|
|
virtual void protected_f();
|
|
private:
|
|
virtual void private_f();
|
|
};
|
|
|
|
struct B {
|
|
virtual ~B();
|
|
virtual void public_f();
|
|
protected:
|
|
virtual void protected_f();
|
|
private:
|
|
virtual void private_f();
|
|
};
|
|
|
|
|
|
struct C : A, B {
|
|
C();
|
|
|
|
virtual ~C();
|
|
// MANGLING-DAG: @"\01??1C@@UAE@XZ"
|
|
// MANGLING-DAG: @"\01??_GC@@UAEPAXI@Z"
|
|
// MANGLING-DAG: @"\01??_EC@@W3AEPAXI@Z"
|
|
// MANGLING-X64-DAG: @"\01??1C@@UEAA@XZ"
|
|
// MANGLING-X64-DAG: @"\01??_GC@@UEAAPEAXI@Z"
|
|
// MANGLING-X64-DAG: @"\01??_EC@@W7EAAPEAXI@Z"
|
|
|
|
// Overrides public_f() of two subobjects with distinct vfptrs, thus needs a thunk.
|
|
virtual void public_f();
|
|
// MANGLING-DAG: @"\01?public_f@C@@UAEXXZ"
|
|
// MANGLING-DAG: @"\01?public_f@C@@W3AEXXZ"
|
|
// MANGLING-X64-DAG: @"\01?public_f@C@@UEAAXXZ"
|
|
// MANGLING-X64-DAG: @"\01?public_f@C@@W7EAAXXZ"
|
|
protected:
|
|
virtual void protected_f();
|
|
// MANGLING-DAG: @"\01?protected_f@C@@MAEXXZ"
|
|
// MANGLING-DAG: @"\01?protected_f@C@@O3AEXXZ"
|
|
// MANGLING-X64-DAG: @"\01?protected_f@C@@MEAAXXZ"
|
|
// MANGLING-X64-DAG: @"\01?protected_f@C@@O7EAAXXZ"
|
|
|
|
private:
|
|
virtual void private_f();
|
|
// MANGLING-DAG: @"\01?private_f@C@@EAEXXZ"
|
|
// MANGLING-DAG: @"\01?private_f@C@@G3AEXXZ"
|
|
// MANGLING-X64-DAG: @"\01?private_f@C@@EEAAXXZ"
|
|
// MANGLING-X64-DAG: @"\01?private_f@C@@G7EAAXXZ"
|
|
};
|
|
|
|
C::C() {} // Emits vftable and forces thunk generation.
|
|
|
|
// CODEGEN: define weak x86_thiscallcc void @"\01??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete)
|
|
// CODEGEN: getelementptr inbounds i8* {{.*}}, i64 -4
|
|
// FIXME: should actually call _EC, not _GC.
|
|
// CODEGEN: call x86_thiscallcc void @"\01??_GC@@UAEPAXI@Z"
|
|
// CODEGEN: ret
|
|
|
|
// CODEGEN: define weak x86_thiscallcc void @"\01?public_f@C@@W3AEXXZ"(%struct.C*
|
|
// CODEGEN: getelementptr inbounds i8* {{.*}}, i64 -4
|
|
// CODEGEN: call x86_thiscallcc void @"\01?public_f@C@@UAEXXZ"(%struct.C*
|
|
// CODEGEN: ret
|
|
|
|
void zoo(C* obj) {
|
|
delete obj;
|
|
}
|
|
|
|
struct D {
|
|
virtual B* goo();
|
|
};
|
|
|
|
struct E : D {
|
|
virtual C* goo();
|
|
// MANGLING-DAG: @"\01?goo@E@@UAEPAUC@@XZ"
|
|
// MANGLING-DAG: @"\01?goo@E@@QAEPAUB@@XZ"
|
|
// MANGLING-X64-DAG: @"\01?goo@E@@UEAAPEAUC@@XZ"
|
|
// MANGLING-X64-DAG: @"\01?goo@E@@QEAAPEAUB@@XZ"
|
|
};
|
|
|
|
E e; // Emits vftable and forces thunk generation.
|
|
|
|
// CODEGEN: define weak x86_thiscallcc %struct.C* @"\01?goo@E@@QAEPAUB@@XZ"
|
|
// CODEGEN: call x86_thiscallcc %struct.C* @"\01?goo@E@@UAEPAUC@@XZ"
|
|
// CODEGEN: getelementptr inbounds i8* {{.*}}, i64 4
|
|
// CODEGEN: ret
|
|
|
|
struct F : virtual A, virtual B {
|
|
virtual ~F();
|
|
};
|
|
|
|
F f; // Just make sure we don't crash, e.g. mangling the complete dtor.
|
|
|
|
struct G : C { };
|
|
|
|
struct H : E {
|
|
virtual G* goo();
|
|
// MANGLING-DAG: @"\01?goo@H@@UAEPAUG@@XZ"
|
|
// MANGLING-DAG: @"\01?goo@H@@QAEPAUB@@XZ"
|
|
// MANGLING-DAG: @"\01?goo@H@@QAEPAUC@@XZ"
|
|
// MANGLING-X64-DAG: @"\01?goo@H@@UEAAPEAUG@@XZ"
|
|
// MANGLING-X64-DAG: @"\01?goo@H@@QEAAPEAUB@@XZ"
|
|
// MANGLING-X64-DAG: @"\01?goo@H@@QEAAPEAUC@@XZ"
|
|
};
|
|
|
|
H h;
|
|
|
|
// FIXME: Write vtordisp adjusting thunk tests
|
|
|
|
namespace CrashOnThunksForAttributedType {
|
|
// We used to crash on this because the type of foo is an AttributedType, not
|
|
// FunctionType, and we had to look through the sugar.
|
|
struct A {
|
|
virtual void __stdcall foo();
|
|
};
|
|
struct B {
|
|
virtual void __stdcall foo();
|
|
};
|
|
struct C : A, B {
|
|
virtual void __stdcall foo();
|
|
};
|
|
C c;
|
|
}
|