[PATCH] D29912: [MS ABI] Correctly mangling vbase destructors
This revision was automatically updated to reflect the committed changes. Closed by commit rL295010: [MS ABI] Correctly mangling vbase destructors (authored by majnemer). Changed prior to commit: https://reviews.llvm.org/D29912?vs=88258=88280#toc Repository: rL LLVM https://reviews.llvm.org/D29912 Files: cfe/trunk/lib/AST/MicrosoftMangle.cpp cfe/trunk/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp cfe/trunk/test/CodeGenCXX/exceptions-cxx-new.cpp cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-structors.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-throw.cpp cfe/trunk/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp cfe/trunk/test/CodeGenCXX/regcall.cpp Index: cfe/trunk/lib/AST/MicrosoftMangle.cpp === --- cfe/trunk/lib/AST/MicrosoftMangle.cpp +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp @@ -1890,14 +1890,18 @@ // ::= // ::= @ # structors (they have no declared return type) if (IsStructor) { -if (isa(D) && isStructorDecl(D) && -StructorType == Dtor_Deleting) { - // The scalar deleting destructor takes an extra int argument. - // However, the FunctionType generated has 0 arguments. - // FIXME: This is a temporary hack. - // Maybe should fix the FunctionType creation instead? - Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z"); - return; +if (isa(D) && isStructorDecl(D)) { + // The scalar deleting destructor takes an extra int argument which is not + // reflected in the AST. + if (StructorType == Dtor_Deleting) { +Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z"); +return; + } + // The vbase destructor returns void which is not reflected in the AST. + if (StructorType == Dtor_Complete) { +Out << "XXZ"; +return; + } } if (IsCtorClosure) { // Default constructor closure and copy constructor closure both return @@ -2005,29 +2009,36 @@ // ::= Y # global near // ::= Z # global far if (const CXXMethodDecl *MD = dyn_cast(FD)) { +bool IsVirtual = MD->isVirtual(); +// When mangling vbase destructor variants, ignore whether or not the +// underlying destructor was defined to be virtual. +if (isa(MD) && isStructorDecl(MD) && +StructorType == Dtor_Complete) { + IsVirtual = false; +} switch (MD->getAccess()) { case AS_none: llvm_unreachable("Unsupported access specifier"); case AS_private: if (MD->isStatic()) Out << 'C'; -else if (MD->isVirtual()) +else if (IsVirtual) Out << 'E'; else Out << 'A'; break; case AS_protected: if (MD->isStatic()) Out << 'K'; -else if (MD->isVirtual()) +else if (IsVirtual) Out << 'M'; else Out << 'I'; break; case AS_public: if (MD->isStatic()) Out << 'S'; -else if (MD->isVirtual()) +else if (IsVirtual) Out << 'U'; else Out << 'Q'; Index: cfe/trunk/test/CodeGenCXX/exceptions-cxx-new.cpp === --- cfe/trunk/test/CodeGenCXX/exceptions-cxx-new.cpp +++ cfe/trunk/test/CodeGenCXX/exceptions-cxx-new.cpp @@ -55,12 +55,12 @@ // CHECK: to label %[[LEAVE_FUNC:.*]] unwind label %[[CLEANUP:.*]] // CHECK: [[LEAVE_FUNC]] -// CHECK: call x86_thiscallcc void @"\01??_DCleanup@@QAE@XZ"( +// CHECK: call x86_thiscallcc void @"\01??_DCleanup@@QAEXXZ"( // CHECK: ret void // CHECK: [[CLEANUP]] // CHECK: %[[CLEANUPPAD:.*]] = cleanuppad within none [] -// CHECK: call x86_thiscallcc void @"\01??_DCleanup@@QAE@XZ"( +// CHECK: call x86_thiscallcc void @"\01??_DCleanup@@QAEXXZ"( // CHECK: cleanupret from %[[CLEANUPPAD]] unwind to caller Index: cfe/trunk/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp === --- cfe/trunk/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp +++ cfe/trunk/test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp @@ -5,10 +5,10 @@ struct __declspec(dllexport) U : S, T { virtual ~U(); }; // CHECK-LABEL: define {{.*}} @"\01??_GS@@UAEPAXI@Z" -// CHECK: call x86_thiscallcc void @"\01??_DS@@UAE@XZ"(%struct.S* %this1){{.*}}!dbg !{{[0-9]+}} +// CHECK: call x86_thiscallcc void @"\01??_DS@@QAEXXZ"(%struct.S* %this1){{.*}}!dbg !{{[0-9]+}} // CHECK-LABEL: define {{.*}} @"\01??_GT@@UAEPAXI@Z" -// CHECK: call x86_thiscallcc void @"\01??_DT@@UAE@XZ"(%struct.T* %this1){{.*}}!dbg !{{[0-9]+}} +// CHECK: call x86_thiscallcc void @"\01??_DT@@QAEXXZ"(%struct.T* %this1){{.*}}!dbg !{{[0-9]+}} // CHECK-LABEL: define {{.*}} @"\01??_GU@@UAEPAXI@Z" -// CHECK: call x86_thiscallcc void @"\01??_DU@@UAE@XZ"(%struct.U*
[PATCH] D29912: [MS ABI] Correctly mangling vbase destructors
rnk accepted this revision. rnk added a comment. This revision is now accepted and ready to land. lgtm, thanks! https://reviews.llvm.org/D29912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D29912: [MS ABI] Correctly mangling vbase destructors
majnemer created this revision. They are a little bit of a special case in the mangling. They are always mangled without taking into account their virtual-ness of the destructor. They are also mangled to return void, unlike the actual destructor. This fixes PR31931. https://reviews.llvm.org/D29912 Files: lib/AST/MicrosoftMangle.cpp test/CodeGenCXX/debug-info-ms-dtor-thunks.cpp test/CodeGenCXX/exceptions-cxx-new.cpp test/CodeGenCXX/inheriting-constructor.cpp test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp test/CodeGenCXX/microsoft-abi-structors.cpp test/CodeGenCXX/microsoft-abi-throw.cpp test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp test/CodeGenCXX/regcall.cpp Index: test/CodeGenCXX/regcall.cpp === --- test/CodeGenCXX/regcall.cpp +++ test/CodeGenCXX/regcall.cpp @@ -47,8 +47,8 @@ // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD2Ev // CHECK-LIN-DAG: define linkonce_odr x86_regcallcc void @_ZN10test_classD1Ev // Windows ignores calling convention on constructor/destructors. - // CHECK-WIN64-DAG: define linkonce_odr void @"\01??_Dtest_class@@QEAA@XZ" - // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_Dtest_class@@QAE@XZ" + // CHECK-WIN64-DAG: define linkonce_odr void @"\01??_Dtest_class@@QEAAXXZ" + // CHECK-WIN32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_Dtest_class@@QAEXXZ" test_class& __regcall operator+=(const test_class&){ return *this; Index: test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp === --- test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp +++ test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp @@ -84,7 +84,7 @@ // CHECK: ret - // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* + // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** {{.*}} // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* // CHECK2: %[[B_i8:.*]] = getelementptr i8, i8* %[[THIS_i8]], i32 8 @@ -102,7 +102,7 @@ // CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* // CHECK2: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4 // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] - // CHECK2: call x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* %[[THIS]]) + // CHECK2: call x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* %[[THIS]]) // ... // CHECK2: ret } @@ -208,7 +208,7 @@ B b; // CHECK: call x86_thiscallcc %struct.B* @"\01??0B@@QAE@XZ"(%struct.B* %[[B:.*]], i32 1) // CHECK-NOT: getelementptr - // CHECK: call x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* %[[B]]) + // CHECK: call x86_thiscallcc void @"\01??_DB@@QAEXXZ"(%struct.B* %[[B]]) // CHECK: ret } Index: test/CodeGenCXX/microsoft-abi-throw.cpp === --- test/CodeGenCXX/microsoft-abi-throw.cpp +++ test/CodeGenCXX/microsoft-abi-throw.cpp @@ -12,7 +12,7 @@ // CHECK-DAG: @"\01??_R0?AUV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUV@@\00" }, comdat // CHECK-DAG: @"_CT??_R0?AUV@@@81044" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUV@@@8" to i8*), i32 0, i32 4, i32 4, i32 1, i8* null }, section ".xdata", comdat // CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44", %eh.CatchableType* @"_CT??_R0?AUM@@@818", %eh.CatchableType* @"_CT??_R0?AUV@@@81044"] }, section ".xdata", comdat -// CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAE@XZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat +// CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAEXXZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat // CHECK-DAG: @"_CT??_R0?AUDefault@@@8??_ODefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor13* @"\01??_R0?AUDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Default*, %struct.Default*)* @"\01??_ODefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat // CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast