https://github.com/Fznamznon created 
https://github.com/llvm/llvm-project/pull/121490

None

>From 2a63bcb5b63f3a8fbeb206fbdbcfc1a328054fe0 Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishcha...@intel.com>
Date: Thu, 12 Dec 2024 08:57:37 -0800
Subject: [PATCH 1/6] Add rough body emission

---
 clang/lib/CodeGen/CGCXXABI.cpp |  15 +++++
 clang/lib/CodeGen/CGCXXABI.h   |   6 ++
 clang/lib/CodeGen/CGClass.cpp  | 109 ++++++++++++++++++++++++++++++---
 3 files changed, 121 insertions(+), 9 deletions(-)

diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index 7c6dfc3e59d8c0..e562e263abaa5f 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -273,6 +273,21 @@ void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, 
Address ptr,
   numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
 }
 
+void CGCXXABI::ReadArrayCookie(CodeGenFunction &CGF, Address ptr,
+                               QualType eltTy, llvm::Value *&numElements,
+                               llvm::Value *&allocPtr, CharUnits &cookieSize) {
+  // FIXME
+  // Assert that we have a cookie.
+
+  // Derive a char* in the same address space as the pointer.
+  ptr = ptr.withElementType(CGF.Int8Ty);
+
+  cookieSize = getArrayCookieSizeImpl(eltTy);
+  Address allocAddr = CGF.Builder.CreateConstInBoundsByteGEP(ptr, -cookieSize);
+  allocPtr = allocAddr.emitRawPointer(CGF);
+  numElements = readArrayCookieImpl(CGF, allocAddr, cookieSize);
+}
+
 llvm::Value *CGCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
                                            Address ptr,
                                            CharUnits cookieSize) {
diff --git a/clang/lib/CodeGen/CGCXXABI.h b/clang/lib/CodeGen/CGCXXABI.h
index 687ff7fb844445..382ad11f504b81 100644
--- a/clang/lib/CodeGen/CGCXXABI.h
+++ b/clang/lib/CodeGen/CGCXXABI.h
@@ -575,6 +575,12 @@ class CGCXXABI {
                                QualType ElementType, llvm::Value *&NumElements,
                                llvm::Value *&AllocPtr, CharUnits &CookieSize);
 
+  /// Reads the array cookie associated with the given pointer,
+  /// that should have one.
+  virtual void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr,
+                               QualType ElementType, llvm::Value *&NumElements,
+                               llvm::Value *&AllocPtr, CharUnits &CookieSize);
+
   /// Return whether the given global decl needs a VTT parameter.
   virtual bool NeedsVTTParameter(GlobalDecl GD);
 
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index c45688bd1ed3ce..05944db7247fec 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1433,6 +1433,88 @@ static bool 
CanSkipVTablePointerInitialization(CodeGenFunction &CGF,
   return true;
 }
 
+namespace {
+llvm::Value *LoadThisForDtorDelete(CodeGenFunction &CGF,
+                                   const CXXDestructorDecl *DD) {
+  if (Expr *ThisArg = DD->getOperatorDeleteThisArg())
+    return CGF.EmitScalarExpr(ThisArg);
+  return CGF.LoadCXXThis();
+}
+}
+
+void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD,
+                                  CodeGenFunction &CGF,
+                                  llvm::Value *ShouldDeleteCondition,
+                                  bool ReturnAfterDelete) {
+  Address ThisPtr = CGF.LoadCXXThisAddress();
+  // llvm::Value *ThisPtr = LoadThisForDtorDelete(CGF, DD);
+  // llvm::BasicBlock *End = CGF.createBasicBlock("dtor.end");
+  llvm::BasicBlock *ScalarBB = CGF.createBasicBlock("dtor.scalar");
+  llvm::BasicBlock *callDeleteBB =
+      CGF.createBasicBlock("dtor.call_delete_after_array_destroy");
+  llvm::BasicBlock *VectorBB = CGF.createBasicBlock("dtor.vector");
+  auto *CondTy = cast<llvm::IntegerType>(ShouldDeleteCondition->getType());
+  llvm::Value *CheckTheBitForArrayDestroy = CGF.Builder.CreateAnd(
+      ShouldDeleteCondition,
+      llvm::Constant::getIntegerValue(CondTy, 
llvm::APInt(CondTy->getBitWidth(),
+                                                          /*val=*/2)));
+  llvm::Value *ShouldDestroyArray =
+      CGF.Builder.CreateIsNull(CheckTheBitForArrayDestroy);
+  CGF.Builder.CreateCondBr(ShouldDestroyArray, ScalarBB, VectorBB);
+
+  CGF.EmitBlock(VectorBB);
+
+  llvm::Value *numElements = nullptr;
+  llvm::Value *allocatedPtr = nullptr;
+  CharUnits cookieSize;
+  QualType EltTy = DD->getThisType()->getPointeeType();
+  CGF.CGM.getCXXABI().ReadArrayCookie(CGF, ThisPtr, EltTy, numElements,
+                                      allocatedPtr, cookieSize);
+
+  // Destroy the elements.
+  QualType::DestructionKind dtorKind = EltTy.isDestructedType();
+
+  assert(dtorKind);
+  assert(numElements && "no element count for a type with a destructor!");
+
+  CharUnits elementSize = CGF.getContext().getTypeSizeInChars(EltTy);
+  CharUnits elementAlign =
+      ThisPtr.getAlignment().alignmentOfArrayElement(elementSize);
+
+  llvm::Value *arrayBegin = ThisPtr.emitRawPointer(CGF);
+  llvm::Value *arrayEnd = CGF.Builder.CreateInBoundsGEP(
+      ThisPtr.getElementType(), arrayBegin, numElements, "delete.end");
+
+  // Note that it is legal to allocate a zero-length array, and we
+  // can never fold the check away because the length should always
+  // come from a cookie.
+  CGF.emitArrayDestroy(arrayBegin, arrayEnd, EltTy, elementAlign,
+                       CGF.getDestroyer(dtorKind),
+                       /*checkZeroLength*/ true, CGF.needsEHCleanup(dtorKind));
+
+  llvm::BasicBlock *VectorBBCont = CGF.createBasicBlock("dtor.vector.cont");
+  CGF.EmitBlock(VectorBBCont);
+
+  llvm::Value *CheckTheBitForDeleteCall = CGF.Builder.CreateAnd(
+      ShouldDeleteCondition,
+      llvm::Constant::getIntegerValue(CondTy, 
llvm::APInt(CondTy->getBitWidth(),
+                                                          /*val=*/1)));
+
+  llvm::Value *ShouldCallDelete =
+      CGF.Builder.CreateIsNull(CheckTheBitForDeleteCall);
+  CGF.Builder.CreateCondBr(ShouldCallDelete, CGF.ReturnBlock.getBlock(),
+                           callDeleteBB);
+  CGF.EmitBlock(callDeleteBB);
+  const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
+  const CXXRecordDecl *ClassDecl = Dtor->getParent();
+  CGF.EmitDeleteCall(Dtor->getOperatorDelete(), allocatedPtr,
+                     CGF.getContext().getTagDeclType(ClassDecl));
+
+  // FIXME figure how to go to the end properly
+  CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
+  CGF.EmitBlock(ScalarBB);
+}
+
 /// EmitDestructorBody - Emits the body of the current destructor.
 void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
   const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CurGD.getDecl());
@@ -1463,6 +1545,10 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList 
&Args) {
   // possible to delegate the destructor body to the complete
   // destructor.  Do so.
   if (DtorType == Dtor_Deleting) {
+    if (CXXStructorImplicitParamValue) {
+      EmitConditionalArrayDtorCall(Dtor, *this, CXXStructorImplicitParamValue,
+                                   false);
+    }
     RunCleanupsScope DtorEpilogue(*this);
     EnterDtorCleanups(Dtor, Dtor_Deleting);
     if (HaveInsertPoint()) {
@@ -1567,12 +1653,12 @@ void 
CodeGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
 }
 
 namespace {
-  llvm::Value *LoadThisForDtorDelete(CodeGenFunction &CGF,
-                                     const CXXDestructorDecl *DD) {
-    if (Expr *ThisArg = DD->getOperatorDeleteThisArg())
-      return CGF.EmitScalarExpr(ThisArg);
-    return CGF.LoadCXXThis();
-  }
+  // llvm::Value *LoadThisForDtorDelete(CodeGenFunction &CGF,
+  //                                    const CXXDestructorDecl *DD) {
+  //   if (Expr *ThisArg = DD->getOperatorDeleteThisArg())
+  //     return CGF.EmitScalarExpr(ThisArg);
+  //   return CGF.LoadCXXThis();
+  // }
 
   /// Call the operator delete associated with the current destructor.
   struct CallDtorDelete final : EHScopeStack::Cleanup {
@@ -1592,8 +1678,12 @@ namespace {
                                      bool ReturnAfterDelete) {
     llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete");
     llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue");
-    llvm::Value *ShouldCallDelete
-      = CGF.Builder.CreateIsNull(ShouldDeleteCondition);
+    auto *CondTy = cast<llvm::IntegerType>(ShouldDeleteCondition->getType());
+    llvm::Value *CheckTheBit = CGF.Builder.CreateAnd(
+        ShouldDeleteCondition, llvm::Constant::getIntegerValue(
+                                   CondTy, llvm::APInt(CondTy->getBitWidth(),
+                                                       /*val=*/1)));
+    llvm::Value *ShouldCallDelete = CGF.Builder.CreateIsNull(CheckTheBit);
     CGF.Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
 
     CGF.EmitBlock(callDeleteBB);
@@ -1857,9 +1947,10 @@ void CodeGenFunction::EnterDtorCleanups(const 
CXXDestructorDecl *DD,
       if (DD->getOperatorDelete()->isDestroyingOperatorDelete())
         EmitConditionalDtorDeleteCall(*this, CXXStructorImplicitParamValue,
                                       /*ReturnAfterDelete*/true);
-      else
+      else {
         EHStack.pushCleanup<CallDtorDeleteConditional>(
             NormalAndEHCleanup, CXXStructorImplicitParamValue);
+      }
     } else {
       if (DD->getOperatorDelete()->isDestroyingOperatorDelete()) {
         const CXXRecordDecl *ClassDecl = DD->getParent();

>From 81e7dfce788d74c3718a573b3ba3a8d7e70594cb Mon Sep 17 00:00:00 2001
From: "Manna, Soumi" <soumi.ma...@intel.com>
Date: Tue, 13 Aug 2024 07:34:36 -0700
Subject: [PATCH 2/6] Add support for MSVC vector deleting destructors

---
 clang/include/clang/Basic/ABI.h       |  3 +-
 clang/lib/AST/ItaniumMangle.cpp       |  2 +
 clang/lib/AST/MicrosoftMangle.cpp     |  6 +--
 clang/lib/AST/VTableBuilder.cpp       | 74 ++++++++++++++++++++-------
 clang/lib/CodeGen/CGCXX.cpp           | 25 ++++++++-
 clang/lib/CodeGen/CGClass.cpp         |  1 +
 clang/lib/CodeGen/CodeGenModule.h     |  1 +
 clang/lib/CodeGen/MicrosoftCXXABI.cpp | 13 +++--
 8 files changed, 97 insertions(+), 28 deletions(-)

diff --git a/clang/include/clang/Basic/ABI.h b/clang/include/clang/Basic/ABI.h
index 231bad799a42cb..be44f437b8b55e 100644
--- a/clang/include/clang/Basic/ABI.h
+++ b/clang/include/clang/Basic/ABI.h
@@ -34,7 +34,8 @@ enum CXXDtorType {
     Dtor_Deleting, ///< Deleting dtor
     Dtor_Complete, ///< Complete object dtor
     Dtor_Base,     ///< Base object dtor
-    Dtor_Comdat    ///< The COMDAT used for dtors
+    Dtor_Comdat,   ///< The COMDAT used for dtors
+    Dtor_VectorDeleting ///< Vector deleting dtor
 };
 
 } // end namespace clang
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 47aa9b40dab845..827e22724fa55a 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -5994,6 +5994,8 @@ void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
   case Dtor_Comdat:
     Out << "D5";
     break;
+  case Dtor_VectorDeleting:
+    llvm_unreachable("Itanium ABI does not use vector deleting dtors");
   }
 }
 
diff --git a/clang/lib/AST/MicrosoftMangle.cpp 
b/clang/lib/AST/MicrosoftMangle.cpp
index edeeaeaa9ae17c..54c377dd132482 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1484,8 +1484,7 @@ void 
MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
   // <operator-name> ::= ?_G # scalar deleting destructor
   case Dtor_Deleting: Out << "?_G"; return;
   // <operator-name> ::= ?_E # vector deleting destructor
-  // FIXME: Add a vector deleting dtor type.  It goes in the vtable, so we need
-  // it.
+  case Dtor_VectorDeleting: Out << "?_E"; return;
   case Dtor_Comdat:
     llvm_unreachable("not expecting a COMDAT");
   }
@@ -2919,7 +2918,8 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const 
FunctionType *T,
     if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
       // The scalar deleting destructor takes an extra int argument which is 
not
       // reflected in the AST.
-      if (StructorType == Dtor_Deleting) {
+      if (StructorType == Dtor_Deleting || StructorType == 
Dtor_VectorDeleting) {
+        // The deleting destructors take an extra int arguments.
         Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
         return;
       }
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index e941c3bedb0a7e..9c62535b7ca4b1 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -1341,10 +1341,14 @@ void ItaniumVTableBuilder::AddMethod(const 
CXXMethodDecl *MD,
   if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
     assert(ReturnAdjustment.isEmpty() &&
            "Destructor can't have return adjustment!");
-
-    // Add both the complete destructor and the deleting destructor.
-    Components.push_back(VTableComponent::MakeCompleteDtor(DD));
-    Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+    if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+      // Add both the complete destructor and the deleting destructor.
+      Components.push_back(VTableComponent::MakeCompleteDtor(DD));
+      Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+    } else {
+      // Add the vector deleting destructor.
+      Components.push_back(VTableComponent::MakeDeletingDtor(DD));
+    }  
   } else {
     // Add the return adjustment if necessary.
     if (!ReturnAdjustment.isEmpty())
@@ -1733,10 +1737,15 @@ void 
ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables(
       const CXXMethodDecl *MD = I.first;
       const MethodInfo &MI = I.second;
       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-        MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]
-            = MI.VTableIndex - AddressPoint;
-        MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)]
-            = MI.VTableIndex + 1 - AddressPoint;
+       if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+          MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]
+              = MI.VTableIndex - AddressPoint;
+          MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)]
+              = MI.VTableIndex + 1 - AddressPoint;
+       } else {
+         MethodVTableIndices[GlobalDecl(DD, Dtor_VectorDeleting)]
+             = MI.VTableIndex + 1 - AddressPoint;
+       }  
       } else {
         MethodVTableIndices[MD] = MI.VTableIndex - AddressPoint;
       }
@@ -2071,6 +2080,8 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
       DD->printQualifiedName(Out);
       if (IsComplete)
         Out << "() [complete]";
+      else if (Context.getTargetInfo().getCXXABI().isMicrosoft())
+        Out << "() [vector deleting]";
       else
         Out << "() [deleting]";
 
@@ -2246,12 +2257,27 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) 
{
         PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
 
     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-      GlobalDecl GD(DD, Dtor_Complete);
-      assert(MethodVTableIndices.count(GD));
-      uint64_t VTableIndex = MethodVTableIndices[GD];
-      IndicesMap[VTableIndex] = MethodName + " [complete]";
-      IndicesMap[VTableIndex + 1] = MethodName + " [deleting]";
+      if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+        // For Itanium ABI, add entries for both complete and deleting 
destructors.
+       GlobalDecl CompleteGD(DD, Dtor_Complete);
+        assert(MethodVTableIndices.count(CompleteGD));
+        uint64_t CompleteIndex = MethodVTableIndices[CompleteGD];
+        IndicesMap[CompleteIndex] = MethodName + " [complete]";
+
+        GlobalDecl DeletingGD(DD, Dtor_Deleting);
+        assert(MethodVTableIndices.count(DeletingGD));
+        uint64_t DeletingIndex = MethodVTableIndices[DeletingGD];
+        IndicesMap[DeletingIndex] = MethodName + " [deleting]";
+      } else {
+       // For Microsoft ABI, add an entry for the vector deleting destructor.
+        // Ensure that the index calculation is correct for the Microsoft ABI.
+       GlobalDecl VectorDeletingGD(DD, Dtor_VectorDeleting);
+        assert(MethodVTableIndices.count(VectorDeletingGD));
+        uint64_t VectorDeletingIndex = MethodVTableIndices[VectorDeletingGD];
+        IndicesMap[VectorDeletingIndex] = MethodName + " [vector deleting]";
+      }
     } else {
+      // For other virtual member functions, add an entry with the method name.
       assert(MethodVTableIndices.count(MD));
       IndicesMap[MethodVTableIndices[MD]] = MethodName;
     }
@@ -2655,7 +2681,11 @@ class VFTableBuilder {
       MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.getVBaseWithVPtr(),
                                 WhichVFPtr.NonVirtualOffset, MI.VFTableIndex);
       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-        MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc;
+       if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+          MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc;
+       } else {
+         MethodVFTableLocations[GlobalDecl(DD, Dtor_VectorDeleting)] = Loc;
+       }  
       } else {
         MethodVFTableLocations[MD] = Loc;
       }
@@ -3285,7 +3315,10 @@ void VFTableBuilder::dumpLayout(raw_ostream &Out) {
       const CXXDestructorDecl *DD = Component.getDestructorDecl();
 
       DD->printQualifiedName(Out);
-      Out << "() [scalar deleting]";
+      if (Context.getTargetInfo().getCXXABI().isMicrosoft())
+        Out << "() [vector deleting]";
+      else
+      Out << "() [deleting]";
 
       if (DD->isPureVirtual())
         Out << " [pure]";
@@ -3756,7 +3789,7 @@ void MicrosoftVTableContext::dumpMethodLocations(
         PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
 
     if (isa<CXXDestructorDecl>(MD)) {
-      IndicesMap[I.second] = MethodName + " [scalar deleting]";
+      IndicesMap[I.second] = MethodName + " [vector deleting]";
     } else {
       IndicesMap[I.second] = MethodName;
     }
@@ -3872,8 +3905,13 @@ MethodVFTableLocation
 MicrosoftVTableContext::getMethodVFTableLocation(GlobalDecl GD) {
   assert(hasVtableSlot(cast<CXXMethodDecl>(GD.getDecl())) &&
          "Only use this method for virtual methods or dtors");
-  if (isa<CXXDestructorDecl>(GD.getDecl()))
-    assert(GD.getDtorType() == Dtor_Deleting);
+  if (isa<CXXDestructorDecl>(GD.getDecl())) {
+    if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+      assert(GD.getDtorType() == Dtor_Deleting);
+    } else {
+      assert(GD.getDtorType() == Dtor_VectorDeleting);
+    }  
+  }  
 
   GD = GD.getCanonicalDecl();
 
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 78a7b021855b7e..419d38d94e9604 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -175,7 +175,10 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const 
CXXDestructorDecl *D) {
   // requires explicit comdat support in the IL.
   if (llvm::GlobalValue::isWeakForLinker(TargetLinkage))
     return true;
-
+/*
+  EmitDefinitionAsAlias(AliasDecl, TargetDecl);
+  return false;
+*/
   // Create the alias with no name.
   auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "",
                                           Aliasee, &getModule());
@@ -200,8 +203,26 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const 
CXXDestructorDecl *D) {
 
   return false;
 }
-
+/*
+/// Emit a definition as a global alias for another definition, 
unconditionally.
+/// Use this function with care as it can produce invalid aliases.  Generally
+/// this function should be used only where there is an ABI requirement to emit
+/// an alias.
+void CodeGenModule::EmitDefinitionAsAlias(GlobalDecl AliasDecl,
+                                          GlobalDecl TargetDecl) {
+  llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl);
+}
+*/
 llvm::Function *CodeGenModule::codegenCXXStructor(GlobalDecl GD) {
+  /*
+  // The Microsoft ABI requires that the vector deleting destructor
+  // be weak aliased to the scalar deleting destructor.
+  // TODO: emission of the vector deleting destructor (when required).
+  if (getTarget().getCXXABI().isMicrosoft() && GD.getDtorType() == 
Dtor_VectorDeleting) {
+    EmitDefinitionAsAlias(GlobalDecl(dtor, Dtor_VectorDeleting),
+                          GlobalDecl(dtor, Dtor_Deleting));
+    return;
+  } */
   const CGFunctionInfo &FnInfo = getTypes().arrangeCXXStructorDeclaration(GD);
   auto *Fn = cast<llvm::Function>(
       getAddrOfCXXStructor(GD, &FnInfo, /*FnType=*/nullptr,
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 05944db7247fec..75a2157723db3c 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1577,6 +1577,7 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList 
&Args) {
   switch (DtorType) {
   case Dtor_Comdat: llvm_unreachable("not expecting a COMDAT");
   case Dtor_Deleting: llvm_unreachable("already handled deleting case");
+  case Dtor_VectorDeleting: llvm_unreachable("already handled vector deleting 
case");
 
   case Dtor_Complete:
     assert((Body || getTarget().getCXXABI().isMicrosoft()) &&
diff --git a/clang/lib/CodeGen/CodeGenModule.h 
b/clang/lib/CodeGen/CodeGenModule.h
index 741b0f17da6584..ac285a63d69c25 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1485,6 +1485,7 @@ class CodeGenModule : public CodeGenTypeCache {
   void EmitGlobal(GlobalDecl D);
 
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
+  void EmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target);
 
   llvm::GlobalValue *GetGlobalValue(StringRef Ref);
 
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp 
b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index d587daac5a88a9..4a4c4fbc569526 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -71,7 +71,8 @@ class MicrosoftCXXABI : public CGCXXABI {
       case Dtor_Complete:
       case Dtor_Deleting:
         return true;
-
+      case Dtor_VectorDeleting:
+       return true;
       case Dtor_Base:
         return false;
 
@@ -1090,7 +1091,8 @@ bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const {
 
 static bool isDeletingDtor(GlobalDecl GD) {
   return isa<CXXDestructorDecl>(GD.getDecl()) &&
-         GD.getDtorType() == Dtor_Deleting;
+         (GD.getDtorType() == Dtor_Deleting ||
+          GD.getDtorType() == Dtor_VectorDeleting);
 }
 
 bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {
@@ -1341,7 +1343,8 @@ MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
   AddedStructorArgCounts Added;
   // TODO: 'for base' flag
   if (isa<CXXDestructorDecl>(GD.getDecl()) &&
-      GD.getDtorType() == Dtor_Deleting) {
+      (GD.getDtorType() == Dtor_Deleting ||
+       GD.getDtorType() == Dtor_VectorDeleting)) {
     // The scalar deleting destructor takes an implicit int parameter.
     ArgTys.push_back(getContext().IntTy);
     ++Added.Suffix;
@@ -1407,6 +1410,8 @@ llvm::GlobalValue::LinkageTypes 
MicrosoftCXXABI::getCXXDestructorLinkage(
     // and are emitted everywhere they are used. They are internal if the class
     // is internal.
     return llvm::GlobalValue::LinkOnceODRLinkage;
+  case Dtor_VectorDeleting:
+    return llvm::GlobalValue::WeakAnyLinkage;
   case Dtor_Comdat:
     llvm_unreachable("MS C++ ABI does not support comdat dtors");
   }
@@ -2004,7 +2009,7 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
 
   // We have only one destructor in the vftable but can get both behaviors
   // by passing an implicit int parameter.
-  GlobalDecl GD(Dtor, Dtor_Deleting);
+  GlobalDecl GD(Dtor, Dtor_VectorDeleting);
   const CGFunctionInfo *FInfo =
       &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
   llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);

>From 45151cd5946b609739522c5d8da34ab272dc5e77 Mon Sep 17 00:00:00 2001
From: "Manna, Soumi" <soumi.ma...@intel.com>
Date: Tue, 13 Aug 2024 08:22:34 -0700
Subject: [PATCH 3/6] Fix fiormat

---
 clang/include/clang/Basic/ABI.h   | 10 +++++-----
 clang/lib/AST/MicrosoftMangle.cpp |  7 +++++--
 clang/lib/AST/VTableBuilder.cpp   | 25 +++++++++++++------------
 3 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/clang/include/clang/Basic/ABI.h b/clang/include/clang/Basic/ABI.h
index be44f437b8b55e..3d3d94d7c8485b 100644
--- a/clang/include/clang/Basic/ABI.h
+++ b/clang/include/clang/Basic/ABI.h
@@ -31,11 +31,11 @@ enum CXXCtorType {
 
 /// C++ destructor types.
 enum CXXDtorType {
-    Dtor_Deleting, ///< Deleting dtor
-    Dtor_Complete, ///< Complete object dtor
-    Dtor_Base,     ///< Base object dtor
-    Dtor_Comdat,   ///< The COMDAT used for dtors
-    Dtor_VectorDeleting ///< Vector deleting dtor
+  Dtor_Deleting, ///< Deleting dtor
+  Dtor_Complete, ///< Complete object dtor
+  Dtor_Base,     ///< Base object dtor
+  Dtor_Comdat,   ///< The COMDAT used for dtors
+  Dtor_VectorDeleting ///< Vector deleting dtor
 };
 
 } // end namespace clang
diff --git a/clang/lib/AST/MicrosoftMangle.cpp 
b/clang/lib/AST/MicrosoftMangle.cpp
index 54c377dd132482..0dfb054cf05eff 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1484,7 +1484,9 @@ void 
MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
   // <operator-name> ::= ?_G # scalar deleting destructor
   case Dtor_Deleting: Out << "?_G"; return;
   // <operator-name> ::= ?_E # vector deleting destructor
-  case Dtor_VectorDeleting: Out << "?_E"; return;
+  case Dtor_VectorDeleting:
+    Out << "?_E";
+    return;
   case Dtor_Comdat:
     llvm_unreachable("not expecting a COMDAT");
   }
@@ -2918,7 +2920,8 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const 
FunctionType *T,
     if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
       // The scalar deleting destructor takes an extra int argument which is 
not
       // reflected in the AST.
-      if (StructorType == Dtor_Deleting || StructorType == 
Dtor_VectorDeleting) {
+      if (StructorType == Dtor_Deleting ||
+          StructorType == Dtor_VectorDeleting) {
         // The deleting destructors take an extra int arguments.
         Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
         return;
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index 9c62535b7ca4b1..900975115e16c0 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -1348,7 +1348,7 @@ void ItaniumVTableBuilder::AddMethod(const CXXMethodDecl 
*MD,
     } else {
       // Add the vector deleting destructor.
       Components.push_back(VTableComponent::MakeDeletingDtor(DD));
-    }  
+    }
   } else {
     // Add the return adjustment if necessary.
     if (!ReturnAdjustment.isEmpty())
@@ -1738,14 +1738,14 @@ void 
ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables(
       const MethodInfo &MI = I.second;
       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
        if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-          MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]
-              = MI.VTableIndex - AddressPoint;
-          MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)]
-              = MI.VTableIndex + 1 - AddressPoint;
-       } else {
-         MethodVTableIndices[GlobalDecl(DD, Dtor_VectorDeleting)]
-             = MI.VTableIndex + 1 - AddressPoint;
-       }  
+         MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] =
+             MI.VTableIndex - AddressPoint;
+         MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] =
+              MI.VTableIndex + 1 - AddressPoint;
+        } else {
+          MethodVTableIndices[GlobalDecl(DD, Dtor_VectorDeleting)] =
+              MI.VTableIndex + 1 - AddressPoint;
+       }
       } else {
         MethodVTableIndices[MD] = MI.VTableIndex - AddressPoint;
       }
@@ -2258,9 +2258,10 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
 
     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
       if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-        // For Itanium ABI, add entries for both complete and deleting 
destructors.
-       GlobalDecl CompleteGD(DD, Dtor_Complete);
-        assert(MethodVTableIndices.count(CompleteGD));
+       // For Itanium ABI, add entries for both complete and deleting
+       // destructors.
+        GlobalDecl CompleteGD(DD, Dtor_Complete);
+       assert(MethodVTableIndices.count(CompleteGD));
         uint64_t CompleteIndex = MethodVTableIndices[CompleteGD];
         IndicesMap[CompleteIndex] = MethodName + " [complete]";
 

>From 733b22510d6b27bd97bdb150fe1da89bac88a13d Mon Sep 17 00:00:00 2001
From: "Manna, Soumi" <soumi.ma...@intel.com>
Date: Tue, 17 Sep 2024 08:17:32 -0700
Subject: [PATCH 4/6] Add support for EmitDefinitionAsAlias()

---
 clang/lib/CodeGen/CGCXX.cpp | 56 ++++++++++++++++++++++++++++++-------
 1 file changed, 46 insertions(+), 10 deletions(-)

diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 419d38d94e9604..bac4d3fb307d25 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -203,26 +203,62 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const 
CXXDestructorDecl *D) {
 
   return false;
 }
-/*
+
 /// Emit a definition as a global alias for another definition, 
unconditionally.
 /// Use this function with care as it can produce invalid aliases.  Generally
 /// this function should be used only where there is an ABI requirement to emit
 /// an alias.
-void CodeGenModule::EmitDefinitionAsAlias(GlobalDecl AliasDecl,
-                                          GlobalDecl TargetDecl) {
+void CodeGenModule::EmitDefinitionAsAlias(GlobalDecl AliasDecl, GlobalDecl 
TargetDecl) {
+  // Get the mangled names for the alias and the target.
+  StringRef AliasName = getMangledName(AliasDecl);
+  StringRef TargetName = getMangledName(TargetDecl);
+
+  // Get the LLVM function for the target.
+  llvm::Function *TargetFunction = 
cast<llvm::Function>(GetOrCreateLLVMFunction(
+        TargetName, /*FnType=*/nullptr, TargetDecl, /*ForVTable=*/false,
+      /*DontDefer=*/true, /*IsThunk=*/false, 
/*ExtraAttrs=*/llvm::AttributeList(),
+      ForDefinition));
+
+  // Determine the linkage type for the alias.
   llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl);
+
+  // Ensure that the target has the correct linkage.
+  TargetFunction->setLinkage(Linkage);
+  llvm::Type *ElementType = TargetFunction->getValueType();
+  llvm::GlobalAlias *GA = llvm::GlobalAlias::create(
+     ElementType, // Type of the aliased value
+     0, // Address space, usually 0 for the default address space
+     Linkage, // Linkage of the alias
+     AliasName, // Name of the alias
+     TargetFunction, // The aliased value
+     &getModule()); // The module in which to create the alias
+
+  // Set any additional necessary attributes for the alias.
+  SetCommonAttributes(AliasDecl, GA);
 }
-*/
+
 llvm::Function *CodeGenModule::codegenCXXStructor(GlobalDecl GD) {
-  /*
   // The Microsoft ABI requires that the vector deleting destructor
   // be weak aliased to the scalar deleting destructor.
-  // TODO: emission of the vector deleting destructor (when required).
   if (getTarget().getCXXABI().isMicrosoft() && GD.getDtorType() == 
Dtor_VectorDeleting) {
-    EmitDefinitionAsAlias(GlobalDecl(dtor, Dtor_VectorDeleting),
-                          GlobalDecl(dtor, Dtor_Deleting));
-    return;
-  } */
+    const CXXDestructorDecl *DtorDecl = cast<CXXDestructorDecl>(GD.getDecl());
+
+    // Create GlobalDecl objects with the correct type for the vector and 
scalar deleting destructors.
+    GlobalDecl VectorDtorGD(DtorDecl, Dtor_VectorDeleting);
+    GlobalDecl ScalarDtorGD(DtorDecl, Dtor_Deleting);
+
+    // Emit an alias from the vector deleting destructor to the scalar 
deleting destructor.
+    EmitDefinitionAsAlias(VectorDtorGD, ScalarDtorGD);
+
+    // Return the scalar deleting destructor, which is now aliased by the 
vector deleting destructor.
+    // Use the mangled name of the scalar deleting destructor.
+    StringRef MangledName = getMangledName(ScalarDtorGD);
+    return cast<llvm::Function>(GetOrCreateLLVMFunction(
+        MangledName, /*FnType=*/nullptr,
+       ScalarDtorGD, /*ForVTable=*/false,
+        /*DontDefer=*/true, /*IsThunk=*/false, 
/*ExtraAttrs=*/llvm::AttributeList(),
+        ForDefinition));
+  }
   const CGFunctionInfo &FnInfo = getTypes().arrangeCXXStructorDeclaration(GD);
   auto *Fn = cast<llvm::Function>(
       getAddrOfCXXStructor(GD, &FnInfo, /*FnType=*/nullptr,

>From d4be52989e8292818c70436841abf9cc64aa04da Mon Sep 17 00:00:00 2001
From: "Manna, Soumi" <soumi.ma...@intel.com>
Date: Tue, 8 Oct 2024 06:37:12 -0700
Subject: [PATCH 5/6] Address review commnets

---
 clang/include/clang/Basic/ABI.h   |  8 ++---
 clang/lib/AST/MicrosoftMangle.cpp |  9 +++---
 clang/lib/AST/VTableBuilder.cpp   | 54 ++++++++-----------------------
 clang/lib/CodeGen/CGCXX.cpp       |  4 ---
 4 files changed, 21 insertions(+), 54 deletions(-)

diff --git a/clang/include/clang/Basic/ABI.h b/clang/include/clang/Basic/ABI.h
index 3d3d94d7c8485b..48969e4f295c36 100644
--- a/clang/include/clang/Basic/ABI.h
+++ b/clang/include/clang/Basic/ABI.h
@@ -31,10 +31,10 @@ enum CXXCtorType {
 
 /// C++ destructor types.
 enum CXXDtorType {
-  Dtor_Deleting, ///< Deleting dtor
-  Dtor_Complete, ///< Complete object dtor
-  Dtor_Base,     ///< Base object dtor
-  Dtor_Comdat,   ///< The COMDAT used for dtors
+  Dtor_Deleting,      ///< Deleting dtor
+  Dtor_Complete,      ///< Complete object dtor
+  Dtor_Base,          ///< Base object dtor
+  Dtor_Comdat,        ///< The COMDAT used for dtors
   Dtor_VectorDeleting ///< Vector deleting dtor
 };
 
diff --git a/clang/lib/AST/MicrosoftMangle.cpp 
b/clang/lib/AST/MicrosoftMangle.cpp
index 0dfb054cf05eff..0f878c2de653bf 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1484,9 +1484,7 @@ void 
MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {
   // <operator-name> ::= ?_G # scalar deleting destructor
   case Dtor_Deleting: Out << "?_G"; return;
   // <operator-name> ::= ?_E # vector deleting destructor
-  case Dtor_VectorDeleting:
-    Out << "?_E";
-    return;
+  case Dtor_VectorDeleting: Out << "?_E"; return;
   case Dtor_Comdat:
     llvm_unreachable("not expecting a COMDAT");
   }
@@ -2918,11 +2916,12 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const 
FunctionType *T,
   //               ::= @ # structors (they have no declared return type)
   if (IsStructor) {
     if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
-      // The scalar deleting destructor takes an extra int argument which is 
not
+      // The deleting destructors take an extra argument of type int that 
indicates
+      // whether the storage for the object should be deleted and whether a 
single
+      // object or an array of objects is being destroyed. This extra argument 
is not
       // reflected in the AST.
       if (StructorType == Dtor_Deleting ||
           StructorType == Dtor_VectorDeleting) {
-        // The deleting destructors take an extra int arguments.
         Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
         return;
       }
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index 900975115e16c0..d256802403952f 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -1341,14 +1341,9 @@ void ItaniumVTableBuilder::AddMethod(const CXXMethodDecl 
*MD,
   if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
     assert(ReturnAdjustment.isEmpty() &&
            "Destructor can't have return adjustment!");
-    if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-      // Add both the complete destructor and the deleting destructor.
-      Components.push_back(VTableComponent::MakeCompleteDtor(DD));
-      Components.push_back(VTableComponent::MakeDeletingDtor(DD));
-    } else {
-      // Add the vector deleting destructor.
-      Components.push_back(VTableComponent::MakeDeletingDtor(DD));
-    }
+    // Add both the complete destructor and the deleting destructor.
+    Components.push_back(VTableComponent::MakeCompleteDtor(DD));
+    Components.push_back(VTableComponent::MakeDeletingDtor(DD));
   } else {
     // Add the return adjustment if necessary.
     if (!ReturnAdjustment.isEmpty())
@@ -1737,15 +1732,10 @@ void 
ItaniumVTableBuilder::LayoutPrimaryAndSecondaryVTables(
       const CXXMethodDecl *MD = I.first;
       const MethodInfo &MI = I.second;
       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-       if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-         MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)] =
-             MI.VTableIndex - AddressPoint;
-         MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)] =
-              MI.VTableIndex + 1 - AddressPoint;
-        } else {
-          MethodVTableIndices[GlobalDecl(DD, Dtor_VectorDeleting)] =
-              MI.VTableIndex + 1 - AddressPoint;
-       }
+       MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]
+            = MI.VTableIndex - AddressPoint;
+        MethodVTableIndices[GlobalDecl(DD, Dtor_Deleting)]
+            = MI.VTableIndex + 1 - AddressPoint;
       } else {
         MethodVTableIndices[MD] = MI.VTableIndex - AddressPoint;
       }
@@ -2080,8 +2070,6 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
       DD->printQualifiedName(Out);
       if (IsComplete)
         Out << "() [complete]";
-      else if (Context.getTargetInfo().getCXXABI().isMicrosoft())
-        Out << "() [vector deleting]";
       else
         Out << "() [deleting]";
 
@@ -2257,28 +2245,12 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) 
{
         PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
 
     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-      if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-       // For Itanium ABI, add entries for both complete and deleting
-       // destructors.
-        GlobalDecl CompleteGD(DD, Dtor_Complete);
-       assert(MethodVTableIndices.count(CompleteGD));
-        uint64_t CompleteIndex = MethodVTableIndices[CompleteGD];
-        IndicesMap[CompleteIndex] = MethodName + " [complete]";
-
-        GlobalDecl DeletingGD(DD, Dtor_Deleting);
-        assert(MethodVTableIndices.count(DeletingGD));
-        uint64_t DeletingIndex = MethodVTableIndices[DeletingGD];
-        IndicesMap[DeletingIndex] = MethodName + " [deleting]";
-      } else {
-       // For Microsoft ABI, add an entry for the vector deleting destructor.
-        // Ensure that the index calculation is correct for the Microsoft ABI.
-       GlobalDecl VectorDeletingGD(DD, Dtor_VectorDeleting);
-        assert(MethodVTableIndices.count(VectorDeletingGD));
-        uint64_t VectorDeletingIndex = MethodVTableIndices[VectorDeletingGD];
-        IndicesMap[VectorDeletingIndex] = MethodName + " [vector deleting]";
-      }
+      GlobalDecl GD(DD, Dtor_Complete);
+      assert(MethodVTableIndices.count(GD));
+      uint64_t VTableIndex = MethodVTableIndices[GD];
+      IndicesMap[VTableIndex] = MethodName + " [complete]";
+      IndicesMap[VTableIndex + 1] = MethodName + " [deleting]";
     } else {
-      // For other virtual member functions, add an entry with the method name.
       assert(MethodVTableIndices.count(MD));
       IndicesMap[MethodVTableIndices[MD]] = MethodName;
     }
@@ -3790,7 +3762,7 @@ void MicrosoftVTableContext::dumpMethodLocations(
         PredefinedIdentKind::PrettyFunctionNoVirtual, MD);
 
     if (isa<CXXDestructorDecl>(MD)) {
-      IndicesMap[I.second] = MethodName + " [vector deleting]";
+      IndicesMap[I.second] = MethodName + " [deleting]";
     } else {
       IndicesMap[I.second] = MethodName;
     }
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index bac4d3fb307d25..bef6b120f77aa4 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -175,10 +175,6 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const 
CXXDestructorDecl *D) {
   // requires explicit comdat support in the IL.
   if (llvm::GlobalValue::isWeakForLinker(TargetLinkage))
     return true;
-/*
-  EmitDefinitionAsAlias(AliasDecl, TargetDecl);
-  return false;
-*/
   // Create the alias with no name.
   auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "",
                                           Aliasee, &getModule());

>From 2c388dbea786ce8fcbeb2e7a8eb4dfaff72a1dae Mon Sep 17 00:00:00 2001
From: "Podchishchaeva, Mariya" <mariya.podchishcha...@intel.com>
Date: Mon, 23 Dec 2024 07:42:06 -0800
Subject: [PATCH 6/6] Tweak implementation to make the functions to appear

---
 clang/include/clang/AST/VTableBuilder.h |  2 +-
 clang/lib/AST/VTableBuilder.cpp         | 17 ++++-----
 clang/lib/CodeGen/CGCXX.cpp             | 47 +++++++++----------------
 clang/lib/CodeGen/CGClass.cpp           |  4 +--
 clang/lib/CodeGen/MicrosoftCXXABI.cpp   | 14 ++++----
 5 files changed, 35 insertions(+), 49 deletions(-)

diff --git a/clang/include/clang/AST/VTableBuilder.h 
b/clang/include/clang/AST/VTableBuilder.h
index a5de41dbc22f14..07217677d2b021 100644
--- a/clang/include/clang/AST/VTableBuilder.h
+++ b/clang/include/clang/AST/VTableBuilder.h
@@ -161,7 +161,7 @@ class VTableComponent {
     case CK_CompleteDtorPointer:
       return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Complete);
     case CK_DeletingDtorPointer:
-      return GlobalDecl(DtorDecl, CXXDtorType::Dtor_Deleting);
+      return GlobalDecl(DtorDecl, CXXDtorType::Dtor_VectorDeleting);
     case CK_VCallOffset:
     case CK_VBaseOffset:
     case CK_OffsetToTop:
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index d256802403952f..d2a3128c28d7f5 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -2654,11 +2654,11 @@ class VFTableBuilder {
       MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.getVBaseWithVPtr(),
                                 WhichVFPtr.NonVirtualOffset, MI.VFTableIndex);
       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-       if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+        if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
           MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc;
-       } else {
-         MethodVFTableLocations[GlobalDecl(DD, Dtor_VectorDeleting)] = Loc;
-       }  
+        } else {
+          MethodVFTableLocations[GlobalDecl(DD, Dtor_VectorDeleting)] = Loc;
+        }
       } else {
         MethodVFTableLocations[MD] = Loc;
       }
@@ -3879,12 +3879,9 @@ 
MicrosoftVTableContext::getMethodVFTableLocation(GlobalDecl GD) {
   assert(hasVtableSlot(cast<CXXMethodDecl>(GD.getDecl())) &&
          "Only use this method for virtual methods or dtors");
   if (isa<CXXDestructorDecl>(GD.getDecl())) {
-    if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-      assert(GD.getDtorType() == Dtor_Deleting);
-    } else {
-      assert(GD.getDtorType() == Dtor_VectorDeleting);
-    }  
-  }  
+    assert(GD.getDtorType() == Dtor_Deleting ||
+           GD.getDtorType() == Dtor_VectorDeleting);
+  }
 
   GD = GD.getCanonicalDecl();
 
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index bef6b120f77aa4..2c83a87897f1ac 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -205,55 +205,42 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const 
CXXDestructorDecl *D) {
 /// this function should be used only where there is an ABI requirement to emit
 /// an alias.
 void CodeGenModule::EmitDefinitionAsAlias(GlobalDecl AliasDecl, GlobalDecl 
TargetDecl) {
-  // Get the mangled names for the alias and the target.
-  StringRef AliasName = getMangledName(AliasDecl);
-  StringRef TargetName = getMangledName(TargetDecl);
 
-  // Get the LLVM function for the target.
-  llvm::Function *TargetFunction = 
cast<llvm::Function>(GetOrCreateLLVMFunction(
-        TargetName, /*FnType=*/nullptr, TargetDecl, /*ForVTable=*/false,
-      /*DontDefer=*/true, /*IsThunk=*/false, 
/*ExtraAttrs=*/llvm::AttributeList(),
-      ForDefinition));
+  // Derive the type for the alias.
+  llvm::PointerType *AliasValueType =
+      getTypes().GetFunctionType(AliasDecl)->getPointerTo();
+  auto *Aliasee = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
 
   // Determine the linkage type for the alias.
   llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl);
 
-  // Ensure that the target has the correct linkage.
-  TargetFunction->setLinkage(Linkage);
-  llvm::Type *ElementType = TargetFunction->getValueType();
-  llvm::GlobalAlias *GA = llvm::GlobalAlias::create(
-     ElementType, // Type of the aliased value
-     0, // Address space, usually 0 for the default address space
-     Linkage, // Linkage of the alias
-     AliasName, // Name of the alias
-     TargetFunction, // The aliased value
-     &getModule()); // The module in which to create the alias
+  // Create the alias with no name.
+  auto *Alias = llvm::GlobalAlias::create(AliasValueType, 0, Linkage, "",
+                                          Aliasee, &getModule());
+  // Destructors are always unnamed_addr.
+  Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
   // Set any additional necessary attributes for the alias.
-  SetCommonAttributes(AliasDecl, GA);
+  SetCommonAttributes(AliasDecl, Alias);
 }
 
 llvm::Function *CodeGenModule::codegenCXXStructor(GlobalDecl GD) {
   // The Microsoft ABI requires that the vector deleting destructor
   // be weak aliased to the scalar deleting destructor.
-  if (getTarget().getCXXABI().isMicrosoft() && GD.getDtorType() == 
Dtor_VectorDeleting) {
+  auto Dtor = dyn_cast<CXXDestructorDecl>(GD.getDecl());
+  if (Dtor && getTarget().getCXXABI().isMicrosoft() &&
+      GD.getDtorType() == Dtor_VectorDeleting) {
     const CXXDestructorDecl *DtorDecl = cast<CXXDestructorDecl>(GD.getDecl());
 
-    // Create GlobalDecl objects with the correct type for the vector and 
scalar deleting destructors.
+    // Create GlobalDecl objects with the correct type for the vector and 
scalar
+    // deleting destructors.
     GlobalDecl VectorDtorGD(DtorDecl, Dtor_VectorDeleting);
     GlobalDecl ScalarDtorGD(DtorDecl, Dtor_Deleting);
 
-    // Emit an alias from the vector deleting destructor to the scalar 
deleting destructor.
+    // Emit an alias from the vector deleting destructor to the scalar deleting
+    // destructor.
     EmitDefinitionAsAlias(VectorDtorGD, ScalarDtorGD);
 
-    // Return the scalar deleting destructor, which is now aliased by the 
vector deleting destructor.
-    // Use the mangled name of the scalar deleting destructor.
-    StringRef MangledName = getMangledName(ScalarDtorGD);
-    return cast<llvm::Function>(GetOrCreateLLVMFunction(
-        MangledName, /*FnType=*/nullptr,
-       ScalarDtorGD, /*ForVTable=*/false,
-        /*DontDefer=*/true, /*IsThunk=*/false, 
/*ExtraAttrs=*/llvm::AttributeList(),
-        ForDefinition));
   }
   const CGFunctionInfo &FnInfo = getTypes().arrangeCXXStructorDeclaration(GD);
   auto *Fn = cast<llvm::Function>(
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 75a2157723db3c..8b9cdf91111c94 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -1544,8 +1544,8 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList 
&Args) {
   // outside of the function-try-block, which means it's always
   // possible to delegate the destructor body to the complete
   // destructor.  Do so.
-  if (DtorType == Dtor_Deleting) {
-    if (CXXStructorImplicitParamValue) {
+  if (DtorType == Dtor_Deleting || DtorType == Dtor_VectorDeleting) {
+    if (CXXStructorImplicitParamValue && DtorType == Dtor_VectorDeleting) {
       EmitConditionalArrayDtorCall(Dtor, *this, CXXStructorImplicitParamValue,
                                    false);
     }
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp 
b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 4a4c4fbc569526..efa61fa41f3f88 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -70,9 +70,8 @@ class MicrosoftCXXABI : public CGCXXABI {
       switch (GD.getDtorType()) {
       case Dtor_Complete:
       case Dtor_Deleting:
-        return true;
       case Dtor_VectorDeleting:
-       return true;
+        return true;
       case Dtor_Base:
         return false;
 
@@ -261,7 +260,7 @@ class MicrosoftCXXABI : public CGCXXABI {
 
         // There's only Dtor_Deleting in vftable but it shares the this
         // adjustment with the base one, so look up the deleting one instead.
-        LookupGD = GlobalDecl(DD, Dtor_Deleting);
+        LookupGD = GlobalDecl(DD, Dtor_VectorDeleting);
       }
       MethodVFTableLocation ML =
           CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
@@ -895,7 +894,8 @@ void 
MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
   // FIXME: Provide a source location here even though there's no
   // CXXMemberCallExpr for dtor call.
   bool UseGlobalDelete = DE->isGlobalDelete();
-  CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
+  // FIXME check that vector deletion is actually required.
+  CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_VectorDeleting;
   llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
                                                   /*CallOrInvoke=*/nullptr);
   if (UseGlobalDelete)
@@ -1443,7 +1443,7 @@ 
MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
 
     // There's no Dtor_Base in vftable but it shares the this adjustment with
     // the deleting one, so look it up instead.
-    GD = GlobalDecl(DD, Dtor_Deleting);
+    GD = GlobalDecl(DD, Dtor_VectorDeleting);
   }
 
   MethodVFTableLocation ML =
@@ -2015,10 +2015,12 @@ llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
   llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
   CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
 
+  bool UseGlobalDelete = D->isGlobalDelete();
+  bool CallDelete = !UseGlobalDelete;
   ASTContext &Context = getContext();
   llvm::Value *ImplicitParam = llvm::ConstantInt::get(
       llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()),
-      DtorType == Dtor_Deleting);
+      2 * (DtorType == Dtor_VectorDeleting) + CallDelete);
 
   QualType ThisTy;
   if (CE) {

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to