[PATCH] D29912: [MS ABI] Correctly mangling vbase destructors

2017-02-13 Thread David Majnemer via Phabricator via cfe-commits
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

2017-02-13 Thread Reid Kleckner via Phabricator via cfe-commits
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

2017-02-13 Thread David Majnemer via Phabricator via cfe-commits
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