The first attached patch creates a emitCXXStructor function and makes
the existing emitCXXConstructor and emitCXXDestructor static helpers.

The next patch makes it be a method of CGCXXABI. For now with
identical implementations in Itanium and Microsoft.

The objective is that in subsequent patches we can

* Simplify each implementation a bit.
* Change the Itanium one to use comdats being sure the Microsoft one
  is not changed.

Cheers,
Rafael
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 6244c3b..aa53691 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -196,33 +196,35 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
   return false;
 }
 
-void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor,
-                                       CXXCtorType ctorType) {
-  if (!getTarget().getCXXABI().hasConstructorVariants()) {
-    // If there are no constructor variants, always emit the complete destructor.
-    ctorType = Ctor_Complete;
+static void emitCXXConstructor(CodeGenModule &CGM,
+                               const CXXConstructorDecl *ctor,
+                               StructorType ctorType) {
+  if (!CGM.getTarget().getCXXABI().hasConstructorVariants()) {
+    // If there are no constructor variants, always emit the complete
+    // destructor.
+    ctorType = StructorType::Complete;
   } else if (!ctor->getParent()->getNumVBases() &&
-             (ctorType == Ctor_Complete || ctorType == Ctor_Base)) {
+             (ctorType == StructorType::Complete ||
+              ctorType == StructorType::Base)) {
     // The complete constructor is equivalent to the base constructor
     // for classes with no virtual bases.  Try to emit it as an alias.
-    bool ProducedAlias =
-        !TryEmitDefinitionAsAlias(GlobalDecl(ctor, Ctor_Complete),
-                                  GlobalDecl(ctor, Ctor_Base), true);
-    if (ctorType == Ctor_Complete && ProducedAlias)
+    bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias(
+        GlobalDecl(ctor, Ctor_Complete), GlobalDecl(ctor, Ctor_Base), true);
+    if (ctorType == StructorType::Complete && ProducedAlias)
       return;
   }
 
   const CGFunctionInfo &fnInfo =
-      getTypes().arrangeCXXStructorDeclaration(ctor, getFromCtorType(ctorType));
+      CGM.getTypes().arrangeCXXStructorDeclaration(ctor, ctorType);
 
-  auto *fn = cast<llvm::Function>(getAddrOfCXXStructor(
-      ctor, getFromCtorType(ctorType), &fnInfo, nullptr, true));
-  setFunctionLinkage(GlobalDecl(ctor, ctorType), fn);
+  auto *fn = cast<llvm::Function>(
+      CGM.getAddrOfCXXStructor(ctor, ctorType, &fnInfo, nullptr, true));
+  GlobalDecl GD(ctor, toCXXCtorType(ctorType));
+  CGM.setFunctionLinkage(GD, fn);
+  CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo);
 
-  CodeGenFunction(*this).GenerateCode(GlobalDecl(ctor, ctorType), fn, fnInfo);
-
-  setFunctionDefinitionAttributes(ctor, fn);
-  SetLLVMFunctionAttributesForDefinition(ctor, fn);
+  CGM.setFunctionDefinitionAttributes(ctor, fn);
+  CGM.SetLLVMFunctionAttributesForDefinition(ctor, fn);
 }
 
 llvm::GlobalValue *CodeGenModule::getAddrOfCXXStructor(
@@ -251,20 +253,19 @@ llvm::GlobalValue *CodeGenModule::getAddrOfCXXStructor(
                                                       DontDefer));
 }
 
-void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,
-                                      CXXDtorType dtorType) {
+static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor,
+                              StructorType dtorType) {
   // The complete destructor is equivalent to the base destructor for
   // classes with no virtual bases, so try to emit it as an alias.
   if (!dtor->getParent()->getNumVBases() &&
-      (dtorType == Dtor_Complete || dtorType == Dtor_Base)) {
-    bool ProducedAlias =
-        !TryEmitDefinitionAsAlias(GlobalDecl(dtor, Dtor_Complete),
-                                  GlobalDecl(dtor, Dtor_Base), true);
+      (dtorType == StructorType::Complete || dtorType == StructorType::Base)) {
+    bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias(
+        GlobalDecl(dtor, Dtor_Complete), GlobalDecl(dtor, Dtor_Base), true);
     if (ProducedAlias) {
-      if (dtorType == Dtor_Complete)
+      if (dtorType == StructorType::Complete)
         return;
       if (dtor->isVirtual())
-        getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete));
+        CGM.getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete));
     }
   }
 
@@ -272,20 +273,30 @@ void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,
   // base class if there is exactly one non-virtual base class with a
   // non-trivial destructor, there are no fields with a non-trivial
   // destructor, and the body of the destructor is trivial.
-  if (dtorType == Dtor_Base && !TryEmitBaseDestructorAsAlias(dtor))
+  if (dtorType == StructorType::Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
     return;
 
   const CGFunctionInfo &fnInfo =
-      getTypes().arrangeCXXStructorDeclaration(dtor, getFromDtorType(dtorType));
+      CGM.getTypes().arrangeCXXStructorDeclaration(dtor, dtorType);
+
+  auto *fn = cast<llvm::Function>(
+      CGM.getAddrOfCXXStructor(dtor, dtorType, &fnInfo, nullptr, true));
 
-  auto *fn = cast<llvm::Function>(getAddrOfCXXStructor(
-      dtor, getFromDtorType(dtorType), &fnInfo, nullptr, true));
-  setFunctionLinkage(GlobalDecl(dtor, dtorType), fn);
+  GlobalDecl GD(dtor, toCXXDtorType(dtorType));
+  CGM.setFunctionLinkage(GD, fn);
+  CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo);
 
-  CodeGenFunction(*this).GenerateCode(GlobalDecl(dtor, dtorType), fn, fnInfo);
+  CGM.setFunctionDefinitionAttributes(dtor, fn);
+  CGM.SetLLVMFunctionAttributesForDefinition(dtor, fn);
+}
 
-  setFunctionDefinitionAttributes(dtor, fn);
-  SetLLVMFunctionAttributesForDefinition(dtor, fn);
+void CodeGenModule::emitCXXStructor(const CXXMethodDecl *MD,
+                                    StructorType Type) {
+  if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
+    emitCXXConstructor(*this, CD, Type);
+    return;
+  }
+  emitCXXDestructor(*this, cast<CXXDestructorDecl>(MD), Type);
 }
 
 static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF,
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 7ea787d..b9986fc 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1404,9 +1404,9 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
       // Make sure to emit the definition(s) before we emit the thunks.
       // This is necessary for the generation of certain thunks.
       if (const auto *CD = dyn_cast<CXXConstructorDecl>(Method))
-        EmitCXXConstructor(CD, GD.getCtorType());
+        emitCXXStructor(CD, getFromCtorType(GD.getCtorType()));
       else if (const auto *DD = dyn_cast<CXXDestructorDecl>(Method))
-        EmitCXXDestructor(DD, GD.getDtorType());
+        emitCXXStructor(DD, getFromDtorType(GD.getDtorType()));
       else
         EmitGlobalFunctionDefinition(GD, GV);
 
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 3b4417b..1ae09c8 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -1044,6 +1044,14 @@ public:
   /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
+  bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
+                                bool InEveryTU);
+  bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
+
+  /// Set attributes for a global definition.
+  void setFunctionDefinitionAttributes(const FunctionDecl *D,
+                                       llvm::Function *F);
+
 private:
   llvm::GlobalValue *GetGlobalValue(StringRef Ref);
 
@@ -1064,10 +1072,6 @@ private:
 
   void setNonAliasAttributes(const Decl *D, llvm::GlobalObject *GO);
 
-  /// Set attributes for a global definition.
-  void setFunctionDefinitionAttributes(const FunctionDecl *D,
-                                       llvm::Function *F);
-
   /// Set function attributes for a function declaration.
   void SetFunctionAttributes(GlobalDecl GD,
                              llvm::Function *F,
@@ -1083,19 +1087,13 @@ private:
   
   // C++ related functions.
 
-  bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target,
-                                bool InEveryTU);
-  bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
-
   void EmitNamespace(const NamespaceDecl *D);
   void EmitLinkageSpec(const LinkageSpecDecl *D);
   void CompleteDIClassType(const CXXMethodDecl* D);
 
-  /// Emit a single constructor with the given type from a C++ constructor Decl.
-  void EmitCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type);
-
-  /// Emit a single destructor with the given type from a C++ destructor Decl.
-  void EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type);
+  /// Emit a single constructor/destructor with the given type from a C++
+  /// constructor Decl.
+  void emitCXXStructor(const CXXMethodDecl *D, StructorType Type);
 
   /// \brief Emit the function that initializes C++ thread_local variables.
   void EmitCXXThreadLocalInitFunc();
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index aa53691..58611e8 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -196,37 +196,6 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
   return false;
 }
 
-static void emitCXXConstructor(CodeGenModule &CGM,
-                               const CXXConstructorDecl *ctor,
-                               StructorType ctorType) {
-  if (!CGM.getTarget().getCXXABI().hasConstructorVariants()) {
-    // If there are no constructor variants, always emit the complete
-    // destructor.
-    ctorType = StructorType::Complete;
-  } else if (!ctor->getParent()->getNumVBases() &&
-             (ctorType == StructorType::Complete ||
-              ctorType == StructorType::Base)) {
-    // The complete constructor is equivalent to the base constructor
-    // for classes with no virtual bases.  Try to emit it as an alias.
-    bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias(
-        GlobalDecl(ctor, Ctor_Complete), GlobalDecl(ctor, Ctor_Base), true);
-    if (ctorType == StructorType::Complete && ProducedAlias)
-      return;
-  }
-
-  const CGFunctionInfo &fnInfo =
-      CGM.getTypes().arrangeCXXStructorDeclaration(ctor, ctorType);
-
-  auto *fn = cast<llvm::Function>(
-      CGM.getAddrOfCXXStructor(ctor, ctorType, &fnInfo, nullptr, true));
-  GlobalDecl GD(ctor, toCXXCtorType(ctorType));
-  CGM.setFunctionLinkage(GD, fn);
-  CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo);
-
-  CGM.setFunctionDefinitionAttributes(ctor, fn);
-  CGM.SetLLVMFunctionAttributesForDefinition(ctor, fn);
-}
-
 llvm::GlobalValue *CodeGenModule::getAddrOfCXXStructor(
     const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo,
     llvm::FunctionType *FnType, bool DontDefer) {
@@ -253,52 +222,6 @@ llvm::GlobalValue *CodeGenModule::getAddrOfCXXStructor(
                                                       DontDefer));
 }
 
-static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor,
-                              StructorType dtorType) {
-  // The complete destructor is equivalent to the base destructor for
-  // classes with no virtual bases, so try to emit it as an alias.
-  if (!dtor->getParent()->getNumVBases() &&
-      (dtorType == StructorType::Complete || dtorType == StructorType::Base)) {
-    bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias(
-        GlobalDecl(dtor, Dtor_Complete), GlobalDecl(dtor, Dtor_Base), true);
-    if (ProducedAlias) {
-      if (dtorType == StructorType::Complete)
-        return;
-      if (dtor->isVirtual())
-        CGM.getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete));
-    }
-  }
-
-  // The base destructor is equivalent to the base destructor of its
-  // base class if there is exactly one non-virtual base class with a
-  // non-trivial destructor, there are no fields with a non-trivial
-  // destructor, and the body of the destructor is trivial.
-  if (dtorType == StructorType::Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
-    return;
-
-  const CGFunctionInfo &fnInfo =
-      CGM.getTypes().arrangeCXXStructorDeclaration(dtor, dtorType);
-
-  auto *fn = cast<llvm::Function>(
-      CGM.getAddrOfCXXStructor(dtor, dtorType, &fnInfo, nullptr, true));
-
-  GlobalDecl GD(dtor, toCXXDtorType(dtorType));
-  CGM.setFunctionLinkage(GD, fn);
-  CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo);
-
-  CGM.setFunctionDefinitionAttributes(dtor, fn);
-  CGM.SetLLVMFunctionAttributesForDefinition(dtor, fn);
-}
-
-void CodeGenModule::emitCXXStructor(const CXXMethodDecl *MD,
-                                    StructorType Type) {
-  if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
-    emitCXXConstructor(*this, CD, Type);
-    return;
-  }
-  emitCXXDestructor(*this, cast<CXXDestructorDecl>(MD), Type);
-}
-
 static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF,
                                               GlobalDecl GD,
                                               llvm::Type *Ty,
diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h
index fe33179..23d0949 100644
--- a/lib/CodeGen/CGCXXABI.h
+++ b/lib/CodeGen/CGCXXABI.h
@@ -501,6 +501,10 @@ public:
   virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
                                               const VarDecl *VD,
                                               QualType LValType);
+
+  /// Emit a single constructor/destructor with the given type from a C++
+  /// constructor Decl.
+  virtual void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) = 0;
 };
 
 // Create an instance of a C++ ABI class:
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index b9986fc..9938c24 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1404,9 +1404,9 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
       // Make sure to emit the definition(s) before we emit the thunks.
       // This is necessary for the generation of certain thunks.
       if (const auto *CD = dyn_cast<CXXConstructorDecl>(Method))
-        emitCXXStructor(CD, getFromCtorType(GD.getCtorType()));
+        ABI->emitCXXStructor(CD, getFromCtorType(GD.getCtorType()));
       else if (const auto *DD = dyn_cast<CXXDestructorDecl>(Method))
-        emitCXXStructor(DD, getFromDtorType(GD.getDtorType()));
+        ABI->emitCXXStructor(DD, getFromDtorType(GD.getDtorType()));
       else
         EmitGlobalFunctionDefinition(GD, GV);
 
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 1ae09c8..f0daa51 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -1091,10 +1091,6 @@ private:
   void EmitLinkageSpec(const LinkageSpecDecl *D);
   void CompleteDIClassType(const CXXMethodDecl* D);
 
-  /// Emit a single constructor/destructor with the given type from a C++
-  /// constructor Decl.
-  void emitCXXStructor(const CXXMethodDecl *D, StructorType Type);
-
   /// \brief Emit the function that initializes C++ thread_local variables.
   void EmitCXXThreadLocalInitFunc();
 
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index 25e2715..c6b3bcd 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -268,6 +268,8 @@ public:
   classifyRTTIUniqueness(QualType CanTy,
                          llvm::GlobalValue::LinkageTypes Linkage) const;
   friend class ItaniumRTTIBuilder;
+
+  void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
 };
 
 class ARMCXXABI : public ItaniumCXXABI {
@@ -2990,3 +2992,80 @@ ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
   assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
   return RUK_NonUniqueVisible;
 }
+
+static void emitCXXConstructor(CodeGenModule &CGM,
+                               const CXXConstructorDecl *ctor,
+                               StructorType ctorType) {
+  if (!CGM.getTarget().getCXXABI().hasConstructorVariants()) {
+    // If there are no constructor variants, always emit the complete
+    // destructor.
+    ctorType = StructorType::Complete;
+  } else if (!ctor->getParent()->getNumVBases() &&
+             (ctorType == StructorType::Complete ||
+              ctorType == StructorType::Base)) {
+    // The complete constructor is equivalent to the base constructor
+    // for classes with no virtual bases.  Try to emit it as an alias.
+    bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias(
+        GlobalDecl(ctor, Ctor_Complete), GlobalDecl(ctor, Ctor_Base), true);
+    if (ctorType == StructorType::Complete && ProducedAlias)
+      return;
+  }
+
+  const CGFunctionInfo &fnInfo =
+      CGM.getTypes().arrangeCXXStructorDeclaration(ctor, ctorType);
+
+  auto *fn = cast<llvm::Function>(
+      CGM.getAddrOfCXXStructor(ctor, ctorType, &fnInfo, nullptr, true));
+  GlobalDecl GD(ctor, toCXXCtorType(ctorType));
+  CGM.setFunctionLinkage(GD, fn);
+  CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo);
+
+  CGM.setFunctionDefinitionAttributes(ctor, fn);
+  CGM.SetLLVMFunctionAttributesForDefinition(ctor, fn);
+}
+
+static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor,
+                              StructorType dtorType) {
+  // The complete destructor is equivalent to the base destructor for
+  // classes with no virtual bases, so try to emit it as an alias.
+  if (!dtor->getParent()->getNumVBases() &&
+      (dtorType == StructorType::Complete || dtorType == StructorType::Base)) {
+    bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias(
+        GlobalDecl(dtor, Dtor_Complete), GlobalDecl(dtor, Dtor_Base), true);
+    if (ProducedAlias) {
+      if (dtorType == StructorType::Complete)
+        return;
+      if (dtor->isVirtual())
+        CGM.getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete));
+    }
+  }
+
+  // The base destructor is equivalent to the base destructor of its
+  // base class if there is exactly one non-virtual base class with a
+  // non-trivial destructor, there are no fields with a non-trivial
+  // destructor, and the body of the destructor is trivial.
+  if (dtorType == StructorType::Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
+    return;
+
+  const CGFunctionInfo &fnInfo =
+      CGM.getTypes().arrangeCXXStructorDeclaration(dtor, dtorType);
+
+  auto *fn = cast<llvm::Function>(
+      CGM.getAddrOfCXXStructor(dtor, dtorType, &fnInfo, nullptr, true));
+
+  GlobalDecl GD(dtor, toCXXDtorType(dtorType));
+  CGM.setFunctionLinkage(GD, fn);
+  CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo);
+
+  CGM.setFunctionDefinitionAttributes(dtor, fn);
+  CGM.SetLLVMFunctionAttributesForDefinition(dtor, fn);
+}
+
+void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD,
+                                    StructorType Type) {
+  if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
+    emitCXXConstructor(CGM, CD, Type);
+    return;
+  }
+  emitCXXDestructor(CGM, cast<CXXDestructorDecl>(MD), Type);
+}
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 173099a..6043413 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -515,6 +515,8 @@ public:
                                   llvm::Value *&This, llvm::Value *MemPtr,
                                   const MemberPointerType *MPT) override;
 
+  void emitCXXStructor(const CXXMethodDecl *MD, StructorType Type) override;
+
 private:
   typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
   typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
@@ -2860,3 +2862,80 @@ MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
                                             const VPtrInfo *Info) {
   return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
 }
+
+static void emitCXXConstructor(CodeGenModule &CGM,
+                               const CXXConstructorDecl *ctor,
+                               StructorType ctorType) {
+  if (!CGM.getTarget().getCXXABI().hasConstructorVariants()) {
+    // If there are no constructor variants, always emit the complete
+    // destructor.
+    ctorType = StructorType::Complete;
+  } else if (!ctor->getParent()->getNumVBases() &&
+             (ctorType == StructorType::Complete ||
+              ctorType == StructorType::Base)) {
+    // The complete constructor is equivalent to the base constructor
+    // for classes with no virtual bases.  Try to emit it as an alias.
+    bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias(
+        GlobalDecl(ctor, Ctor_Complete), GlobalDecl(ctor, Ctor_Base), true);
+    if (ctorType == StructorType::Complete && ProducedAlias)
+      return;
+  }
+
+  const CGFunctionInfo &fnInfo =
+      CGM.getTypes().arrangeCXXStructorDeclaration(ctor, ctorType);
+
+  auto *fn = cast<llvm::Function>(
+      CGM.getAddrOfCXXStructor(ctor, ctorType, &fnInfo, nullptr, true));
+  GlobalDecl GD(ctor, toCXXCtorType(ctorType));
+  CGM.setFunctionLinkage(GD, fn);
+  CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo);
+
+  CGM.setFunctionDefinitionAttributes(ctor, fn);
+  CGM.SetLLVMFunctionAttributesForDefinition(ctor, fn);
+}
+
+static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor,
+                              StructorType dtorType) {
+  // The complete destructor is equivalent to the base destructor for
+  // classes with no virtual bases, so try to emit it as an alias.
+  if (!dtor->getParent()->getNumVBases() &&
+      (dtorType == StructorType::Complete || dtorType == StructorType::Base)) {
+    bool ProducedAlias = !CGM.TryEmitDefinitionAsAlias(
+        GlobalDecl(dtor, Dtor_Complete), GlobalDecl(dtor, Dtor_Base), true);
+    if (ProducedAlias) {
+      if (dtorType == StructorType::Complete)
+        return;
+      if (dtor->isVirtual())
+        CGM.getVTables().EmitThunks(GlobalDecl(dtor, Dtor_Complete));
+    }
+  }
+
+  // The base destructor is equivalent to the base destructor of its
+  // base class if there is exactly one non-virtual base class with a
+  // non-trivial destructor, there are no fields with a non-trivial
+  // destructor, and the body of the destructor is trivial.
+  if (dtorType == StructorType::Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
+    return;
+
+  const CGFunctionInfo &fnInfo =
+      CGM.getTypes().arrangeCXXStructorDeclaration(dtor, dtorType);
+
+  auto *fn = cast<llvm::Function>(
+      CGM.getAddrOfCXXStructor(dtor, dtorType, &fnInfo, nullptr, true));
+
+  GlobalDecl GD(dtor, toCXXDtorType(dtorType));
+  CGM.setFunctionLinkage(GD, fn);
+  CodeGenFunction(CGM).GenerateCode(GD, fn, fnInfo);
+
+  CGM.setFunctionDefinitionAttributes(dtor, fn);
+  CGM.SetLLVMFunctionAttributesForDefinition(dtor, fn);
+}
+
+void MicrosoftCXXABI::emitCXXStructor(const CXXMethodDecl *MD,
+                                      StructorType Type) {
+  if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
+    emitCXXConstructor(CGM, CD, Type);
+    return;
+  }
+  emitCXXDestructor(CGM, cast<CXXDestructorDecl>(MD), Type);
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to