xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/MicrosoftCXXABI.cpp (revision 5deeebd8c6ca991269e72902a7a62cada57947f6)
10b57cec5SDimitry Andric //===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This provides C++ code generation targeting the Microsoft Visual C++ ABI.
100b57cec5SDimitry Andric // The class in this file generates structures that follow the Microsoft
110b57cec5SDimitry Andric // Visual C++ ABI, which is actually not very well documented at all outside
120b57cec5SDimitry Andric // of Microsoft.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric 
1606c3fb27SDimitry Andric #include "ABIInfo.h"
170b57cec5SDimitry Andric #include "CGCXXABI.h"
180b57cec5SDimitry Andric #include "CGCleanup.h"
190b57cec5SDimitry Andric #include "CGVTables.h"
200b57cec5SDimitry Andric #include "CodeGenModule.h"
210b57cec5SDimitry Andric #include "CodeGenTypes.h"
220b57cec5SDimitry Andric #include "TargetInfo.h"
23480093f4SDimitry Andric #include "clang/AST/Attr.h"
24480093f4SDimitry Andric #include "clang/AST/CXXInheritance.h"
250b57cec5SDimitry Andric #include "clang/AST/Decl.h"
260b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
270b57cec5SDimitry Andric #include "clang/AST/StmtCXX.h"
280b57cec5SDimitry Andric #include "clang/AST/VTableBuilder.h"
29480093f4SDimitry Andric #include "clang/CodeGen/ConstantInitBuilder.h"
300b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
310b57cec5SDimitry Andric #include "llvm/ADT/StringSet.h"
320b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric using namespace clang;
350b57cec5SDimitry Andric using namespace CodeGen;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric namespace {
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric /// Holds all the vbtable globals for a given class.
400b57cec5SDimitry Andric struct VBTableGlobals {
410b57cec5SDimitry Andric   const VPtrInfoVector *VBTables;
420b57cec5SDimitry Andric   SmallVector<llvm::GlobalVariable *, 2> Globals;
430b57cec5SDimitry Andric };
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric class MicrosoftCXXABI : public CGCXXABI {
460b57cec5SDimitry Andric public:
470b57cec5SDimitry Andric   MicrosoftCXXABI(CodeGenModule &CGM)
480b57cec5SDimitry Andric       : CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
490b57cec5SDimitry Andric         ClassHierarchyDescriptorType(nullptr),
500b57cec5SDimitry Andric         CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
5181ad6265SDimitry Andric         ThrowInfoType(nullptr) {
5281ad6265SDimitry Andric     assert(!(CGM.getLangOpts().isExplicitDefaultVisibilityExportMapping() ||
5381ad6265SDimitry Andric              CGM.getLangOpts().isAllDefaultVisibilityExportMapping()) &&
5481ad6265SDimitry Andric            "visibility export mapping option unimplemented in this ABI");
5581ad6265SDimitry Andric   }
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   bool HasThisReturn(GlobalDecl GD) const override;
580b57cec5SDimitry Andric   bool hasMostDerivedReturn(GlobalDecl GD) const override;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   bool classifyReturnType(CGFunctionInfo &FI) const override;
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override;
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   bool isSRetParameterAfterThis() const override { return true; }
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   bool isThisCompleteObject(GlobalDecl GD) const override {
670b57cec5SDimitry Andric     // The Microsoft ABI doesn't use separate complete-object vs.
680b57cec5SDimitry Andric     // base-object variants of constructors, but it does of destructors.
690b57cec5SDimitry Andric     if (isa<CXXDestructorDecl>(GD.getDecl())) {
700b57cec5SDimitry Andric       switch (GD.getDtorType()) {
710b57cec5SDimitry Andric       case Dtor_Complete:
720b57cec5SDimitry Andric       case Dtor_Deleting:
730b57cec5SDimitry Andric         return true;
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric       case Dtor_Base:
760b57cec5SDimitry Andric         return false;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric       case Dtor_Comdat: llvm_unreachable("emitting dtor comdat as function?");
790b57cec5SDimitry Andric       }
800b57cec5SDimitry Andric       llvm_unreachable("bad dtor kind");
810b57cec5SDimitry Andric     }
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric     // No other kinds.
840b57cec5SDimitry Andric     return false;
850b57cec5SDimitry Andric   }
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   size_t getSrcArgforCopyCtor(const CXXConstructorDecl *CD,
880b57cec5SDimitry Andric                               FunctionArgList &Args) const override {
890b57cec5SDimitry Andric     assert(Args.size() >= 2 &&
900b57cec5SDimitry Andric            "expected the arglist to have at least two args!");
910b57cec5SDimitry Andric     // The 'most_derived' parameter goes second if the ctor is variadic and
920b57cec5SDimitry Andric     // has v-bases.
930b57cec5SDimitry Andric     if (CD->getParent()->getNumVBases() > 0 &&
940b57cec5SDimitry Andric         CD->getType()->castAs<FunctionProtoType>()->isVariadic())
950b57cec5SDimitry Andric       return 2;
960b57cec5SDimitry Andric     return 1;
970b57cec5SDimitry Andric   }
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   std::vector<CharUnits> getVBPtrOffsets(const CXXRecordDecl *RD) override {
1000b57cec5SDimitry Andric     std::vector<CharUnits> VBPtrOffsets;
1010b57cec5SDimitry Andric     const ASTContext &Context = getContext();
1020b57cec5SDimitry Andric     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric     const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1050b57cec5SDimitry Andric     for (const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
1060b57cec5SDimitry Andric       const ASTRecordLayout &SubobjectLayout =
1070b57cec5SDimitry Andric           Context.getASTRecordLayout(VBT->IntroducingObject);
1080b57cec5SDimitry Andric       CharUnits Offs = VBT->NonVirtualOffset;
1090b57cec5SDimitry Andric       Offs += SubobjectLayout.getVBPtrOffset();
1100b57cec5SDimitry Andric       if (VBT->getVBaseWithVPtr())
1110b57cec5SDimitry Andric         Offs += Layout.getVBaseClassOffset(VBT->getVBaseWithVPtr());
1120b57cec5SDimitry Andric       VBPtrOffsets.push_back(Offs);
1130b57cec5SDimitry Andric     }
1140b57cec5SDimitry Andric     llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
1150b57cec5SDimitry Andric     return VBPtrOffsets;
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   StringRef GetPureVirtualCallName() override { return "_purecall"; }
1190b57cec5SDimitry Andric   StringRef GetDeletedVirtualCallName() override { return "_purecall"; }
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE,
1220b57cec5SDimitry Andric                                Address Ptr, QualType ElementType,
1230b57cec5SDimitry Andric                                const CXXDestructorDecl *Dtor) override;
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
1260b57cec5SDimitry Andric   void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) override;
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override;
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
1310b57cec5SDimitry Andric                                                    const VPtrInfo &Info);
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
1340b57cec5SDimitry Andric   CatchTypeInfo
1350b57cec5SDimitry Andric   getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) override;
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   /// MSVC needs an extra flag to indicate a catchall.
1380b57cec5SDimitry Andric   CatchTypeInfo getCatchAllTypeInfo() override {
139fe6060f1SDimitry Andric     // For -EHa catch(...) must handle HW exception
140fe6060f1SDimitry Andric     // Adjective = HT_IsStdDotDot (0x40), only catch C++ exceptions
141fe6060f1SDimitry Andric     if (getContext().getLangOpts().EHAsynch)
142fe6060f1SDimitry Andric       return CatchTypeInfo{nullptr, 0};
143fe6060f1SDimitry Andric     else
1440b57cec5SDimitry Andric       return CatchTypeInfo{nullptr, 0x40};
1450b57cec5SDimitry Andric   }
1460b57cec5SDimitry Andric 
1470fca6ea1SDimitry Andric   bool shouldTypeidBeNullChecked(QualType SrcRecordTy) override;
1480b57cec5SDimitry Andric   void EmitBadTypeidCall(CodeGenFunction &CGF) override;
1490b57cec5SDimitry Andric   llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
1500b57cec5SDimitry Andric                           Address ThisPtr,
1510b57cec5SDimitry Andric                           llvm::Type *StdTypeInfoPtrTy) override;
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric   bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
1540b57cec5SDimitry Andric                                           QualType SrcRecordTy) override;
1550b57cec5SDimitry Andric 
15606c3fb27SDimitry Andric   bool shouldEmitExactDynamicCast(QualType DestRecordTy) override {
15706c3fb27SDimitry Andric     // TODO: Add support for exact dynamic_casts.
15806c3fb27SDimitry Andric     return false;
15906c3fb27SDimitry Andric   }
16006c3fb27SDimitry Andric   llvm::Value *emitExactDynamicCast(CodeGenFunction &CGF, Address Value,
16106c3fb27SDimitry Andric                                     QualType SrcRecordTy, QualType DestTy,
16206c3fb27SDimitry Andric                                     QualType DestRecordTy,
16306c3fb27SDimitry Andric                                     llvm::BasicBlock *CastSuccess,
16406c3fb27SDimitry Andric                                     llvm::BasicBlock *CastFail) override {
16506c3fb27SDimitry Andric     llvm_unreachable("unsupported");
16606c3fb27SDimitry Andric   }
16706c3fb27SDimitry Andric 
16806c3fb27SDimitry Andric   llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address Value,
1690b57cec5SDimitry Andric                                    QualType SrcRecordTy, QualType DestTy,
1700b57cec5SDimitry Andric                                    QualType DestRecordTy,
1710b57cec5SDimitry Andric                                    llvm::BasicBlock *CastEnd) override;
1720b57cec5SDimitry Andric 
17306c3fb27SDimitry Andric   llvm::Value *emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,
17406c3fb27SDimitry Andric                                      QualType SrcRecordTy) override;
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   bool EmitBadCastCall(CodeGenFunction &CGF) override;
1770b57cec5SDimitry Andric   bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const override {
1780b57cec5SDimitry Andric     return false;
1790b57cec5SDimitry Andric   }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   llvm::Value *
1820b57cec5SDimitry Andric   GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
1830b57cec5SDimitry Andric                             const CXXRecordDecl *ClassDecl,
1840b57cec5SDimitry Andric                             const CXXRecordDecl *BaseClassDecl) override;
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   llvm::BasicBlock *
1870b57cec5SDimitry Andric   EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
1880b57cec5SDimitry Andric                                 const CXXRecordDecl *RD) override;
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric   llvm::BasicBlock *
1910b57cec5SDimitry Andric   EmitDtorCompleteObjectHandler(CodeGenFunction &CGF);
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF,
1940b57cec5SDimitry Andric                                               const CXXRecordDecl *RD) override;
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   void EmitCXXConstructors(const CXXConstructorDecl *D) override;
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric   // Background on MSVC destructors
1990b57cec5SDimitry Andric   // ==============================
2000b57cec5SDimitry Andric   //
2010b57cec5SDimitry Andric   // Both Itanium and MSVC ABIs have destructor variants.  The variant names
2020b57cec5SDimitry Andric   // roughly correspond in the following way:
2030b57cec5SDimitry Andric   //   Itanium       Microsoft
2040b57cec5SDimitry Andric   //   Base       -> no name, just ~Class
2050b57cec5SDimitry Andric   //   Complete   -> vbase destructor
2060b57cec5SDimitry Andric   //   Deleting   -> scalar deleting destructor
2070b57cec5SDimitry Andric   //                 vector deleting destructor
2080b57cec5SDimitry Andric   //
2090b57cec5SDimitry Andric   // The base and complete destructors are the same as in Itanium, although the
2100b57cec5SDimitry Andric   // complete destructor does not accept a VTT parameter when there are virtual
2110b57cec5SDimitry Andric   // bases.  A separate mechanism involving vtordisps is used to ensure that
2120b57cec5SDimitry Andric   // virtual methods of destroyed subobjects are not called.
2130b57cec5SDimitry Andric   //
2140b57cec5SDimitry Andric   // The deleting destructors accept an i32 bitfield as a second parameter.  Bit
2150b57cec5SDimitry Andric   // 1 indicates if the memory should be deleted.  Bit 2 indicates if the this
2160b57cec5SDimitry Andric   // pointer points to an array.  The scalar deleting destructor assumes that
2170b57cec5SDimitry Andric   // bit 2 is zero, and therefore does not contain a loop.
2180b57cec5SDimitry Andric   //
2190b57cec5SDimitry Andric   // For virtual destructors, only one entry is reserved in the vftable, and it
2200b57cec5SDimitry Andric   // always points to the vector deleting destructor.  The vector deleting
2210b57cec5SDimitry Andric   // destructor is the most general, so it can be used to destroy objects in
2220b57cec5SDimitry Andric   // place, delete single heap objects, or delete arrays.
2230b57cec5SDimitry Andric   //
2240b57cec5SDimitry Andric   // A TU defining a non-inline destructor is only guaranteed to emit a base
2250b57cec5SDimitry Andric   // destructor, and all of the other variants are emitted on an as-needed basis
2260b57cec5SDimitry Andric   // in COMDATs.  Because a non-base destructor can be emitted in a TU that
2270b57cec5SDimitry Andric   // lacks a definition for the destructor, non-base destructors must always
2280b57cec5SDimitry Andric   // delegate to or alias the base destructor.
2290b57cec5SDimitry Andric 
2305ffd83dbSDimitry Andric   AddedStructorArgCounts
2310b57cec5SDimitry Andric   buildStructorSignature(GlobalDecl GD,
2320b57cec5SDimitry Andric                          SmallVectorImpl<CanQualType> &ArgTys) override;
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   /// Non-base dtors should be emitted as delegating thunks in this ABI.
2350b57cec5SDimitry Andric   bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
2360b57cec5SDimitry Andric                               CXXDtorType DT) const override {
2370b57cec5SDimitry Andric     return DT != Dtor_Base;
2380b57cec5SDimitry Andric   }
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
2410b57cec5SDimitry Andric                                   const CXXDestructorDecl *Dtor,
2420b57cec5SDimitry Andric                                   CXXDtorType DT) const override;
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   llvm::GlobalValue::LinkageTypes
2450b57cec5SDimitry Andric   getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor,
2460b57cec5SDimitry Andric                           CXXDtorType DT) const override;
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   void EmitCXXDestructors(const CXXDestructorDecl *D) override;
2490b57cec5SDimitry Andric 
2501ac55f4cSDimitry Andric   const CXXRecordDecl *getThisArgumentTypeForMethod(GlobalDecl GD) override {
2511ac55f4cSDimitry Andric     auto *MD = cast<CXXMethodDecl>(GD.getDecl());
2521ac55f4cSDimitry Andric 
2531ac55f4cSDimitry Andric     if (MD->isVirtual()) {
2541ac55f4cSDimitry Andric       GlobalDecl LookupGD = GD;
2551ac55f4cSDimitry Andric       if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
2561ac55f4cSDimitry Andric         // Complete dtors take a pointer to the complete object,
2571ac55f4cSDimitry Andric         // thus don't need adjustment.
2581ac55f4cSDimitry Andric         if (GD.getDtorType() == Dtor_Complete)
2591ac55f4cSDimitry Andric           return MD->getParent();
2601ac55f4cSDimitry Andric 
2611ac55f4cSDimitry Andric         // There's only Dtor_Deleting in vftable but it shares the this
2621ac55f4cSDimitry Andric         // adjustment with the base one, so look up the deleting one instead.
2631ac55f4cSDimitry Andric         LookupGD = GlobalDecl(DD, Dtor_Deleting);
2641ac55f4cSDimitry Andric       }
2650b57cec5SDimitry Andric       MethodVFTableLocation ML =
2661ac55f4cSDimitry Andric           CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
2671ac55f4cSDimitry Andric 
2680b57cec5SDimitry Andric       // The vbases might be ordered differently in the final overrider object
2690b57cec5SDimitry Andric       // and the complete object, so the "this" argument may sometimes point to
2700b57cec5SDimitry Andric       // memory that has no particular type (e.g. past the complete object).
2710b57cec5SDimitry Andric       // In this case, we just use a generic pointer type.
2720b57cec5SDimitry Andric       // FIXME: might want to have a more precise type in the non-virtual
2730b57cec5SDimitry Andric       // multiple inheritance case.
2740b57cec5SDimitry Andric       if (ML.VBase || !ML.VFPtrOffset.isZero())
2750b57cec5SDimitry Andric         return nullptr;
2760b57cec5SDimitry Andric     }
2770b57cec5SDimitry Andric     return MD->getParent();
2780b57cec5SDimitry Andric   }
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   Address
2810b57cec5SDimitry Andric   adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD,
2820b57cec5SDimitry Andric                                            Address This,
2830b57cec5SDimitry Andric                                            bool VirtualCall) override;
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
2860b57cec5SDimitry Andric                                  FunctionArgList &Params) override;
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric   void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
2890b57cec5SDimitry Andric 
2905ffd83dbSDimitry Andric   AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
2915ffd83dbSDimitry Andric                                                const CXXConstructorDecl *D,
2925ffd83dbSDimitry Andric                                                CXXCtorType Type,
2935ffd83dbSDimitry Andric                                                bool ForVirtualBase,
2945ffd83dbSDimitry Andric                                                bool Delegating) override;
2955ffd83dbSDimitry Andric 
2965ffd83dbSDimitry Andric   llvm::Value *getCXXDestructorImplicitParam(CodeGenFunction &CGF,
2975ffd83dbSDimitry Andric                                              const CXXDestructorDecl *DD,
2985ffd83dbSDimitry Andric                                              CXXDtorType Type,
2995ffd83dbSDimitry Andric                                              bool ForVirtualBase,
3005ffd83dbSDimitry Andric                                              bool Delegating) override;
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric   void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
3030b57cec5SDimitry Andric                           CXXDtorType Type, bool ForVirtualBase,
3040b57cec5SDimitry Andric                           bool Delegating, Address This,
3050b57cec5SDimitry Andric                           QualType ThisTy) override;
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric   void emitVTableTypeMetadata(const VPtrInfo &Info, const CXXRecordDecl *RD,
3080b57cec5SDimitry Andric                               llvm::GlobalVariable *VTable);
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   void emitVTableDefinitions(CodeGenVTables &CGVT,
3110b57cec5SDimitry Andric                              const CXXRecordDecl *RD) override;
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric   bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
3140b57cec5SDimitry Andric                                            CodeGenFunction::VPtr Vptr) override;
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   /// Don't initialize vptrs if dynamic class
317bdd1243dSDimitry Andric   /// is marked with the 'novtable' attribute.
3180b57cec5SDimitry Andric   bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) override {
3190b57cec5SDimitry Andric     return !VTableClass->hasAttr<MSNoVTableAttr>();
3200b57cec5SDimitry Andric   }
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   llvm::Constant *
3230b57cec5SDimitry Andric   getVTableAddressPoint(BaseSubobject Base,
3240b57cec5SDimitry Andric                         const CXXRecordDecl *VTableClass) override;
3250b57cec5SDimitry Andric 
3260b57cec5SDimitry Andric   llvm::Value *getVTableAddressPointInStructor(
3270b57cec5SDimitry Andric       CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
3280b57cec5SDimitry Andric       BaseSubobject Base, const CXXRecordDecl *NearestVBase) override;
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
3310b57cec5SDimitry Andric                                         CharUnits VPtrOffset) override;
3320b57cec5SDimitry Andric 
3330b57cec5SDimitry Andric   CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
3340b57cec5SDimitry Andric                                      Address This, llvm::Type *Ty,
3350b57cec5SDimitry Andric                                      SourceLocation Loc) override;
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric   llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
3380b57cec5SDimitry Andric                                          const CXXDestructorDecl *Dtor,
3390b57cec5SDimitry Andric                                          CXXDtorType DtorType, Address This,
3400b57cec5SDimitry Andric                                          DeleteOrMemberCallExpr E) override;
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
3430b57cec5SDimitry Andric                                         CallArgList &CallArgs) override {
3440b57cec5SDimitry Andric     assert(GD.getDtorType() == Dtor_Deleting &&
3450b57cec5SDimitry Andric            "Only deleting destructor thunks are available in this ABI");
3460b57cec5SDimitry Andric     CallArgs.add(RValue::get(getStructorImplicitParamValue(CGF)),
3470b57cec5SDimitry Andric                  getContext().IntTy);
3480b57cec5SDimitry Andric   }
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric   void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric   llvm::GlobalVariable *
3530b57cec5SDimitry Andric   getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
3540b57cec5SDimitry Andric                    llvm::GlobalVariable::LinkageTypes Linkage);
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric   llvm::GlobalVariable *
3570b57cec5SDimitry Andric   getAddrOfVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
3580b57cec5SDimitry Andric                                   const CXXRecordDecl *DstRD) {
3590b57cec5SDimitry Andric     SmallString<256> OutName;
3600b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(OutName);
3610b57cec5SDimitry Andric     getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
3620b57cec5SDimitry Andric     StringRef MangledName = OutName.str();
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric     if (auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
3650b57cec5SDimitry Andric       return VDispMap;
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric     MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
3680b57cec5SDimitry Andric     unsigned NumEntries = 1 + SrcRD->getNumVBases();
3690b57cec5SDimitry Andric     SmallVector<llvm::Constant *, 4> Map(NumEntries,
3700b57cec5SDimitry Andric                                          llvm::UndefValue::get(CGM.IntTy));
3710b57cec5SDimitry Andric     Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
3720b57cec5SDimitry Andric     bool AnyDifferent = false;
3730b57cec5SDimitry Andric     for (const auto &I : SrcRD->vbases()) {
3740b57cec5SDimitry Andric       const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
3750b57cec5SDimitry Andric       if (!DstRD->isVirtuallyDerivedFrom(VBase))
3760b57cec5SDimitry Andric         continue;
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric       unsigned SrcVBIndex = VTContext.getVBTableIndex(SrcRD, VBase);
3790b57cec5SDimitry Andric       unsigned DstVBIndex = VTContext.getVBTableIndex(DstRD, VBase);
3800b57cec5SDimitry Andric       Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
3810b57cec5SDimitry Andric       AnyDifferent |= SrcVBIndex != DstVBIndex;
3820b57cec5SDimitry Andric     }
3830b57cec5SDimitry Andric     // This map would be useless, don't use it.
3840b57cec5SDimitry Andric     if (!AnyDifferent)
3850b57cec5SDimitry Andric       return nullptr;
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric     llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy, Map.size());
3880b57cec5SDimitry Andric     llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy, Map);
3890b57cec5SDimitry Andric     llvm::GlobalValue::LinkageTypes Linkage =
3900b57cec5SDimitry Andric         SrcRD->isExternallyVisible() && DstRD->isExternallyVisible()
3910b57cec5SDimitry Andric             ? llvm::GlobalValue::LinkOnceODRLinkage
3920b57cec5SDimitry Andric             : llvm::GlobalValue::InternalLinkage;
3930b57cec5SDimitry Andric     auto *VDispMap = new llvm::GlobalVariable(
3940b57cec5SDimitry Andric         CGM.getModule(), VDispMapTy, /*isConstant=*/true, Linkage,
3950b57cec5SDimitry Andric         /*Initializer=*/Init, MangledName);
3960b57cec5SDimitry Andric     return VDispMap;
3970b57cec5SDimitry Andric   }
3980b57cec5SDimitry Andric 
3990b57cec5SDimitry Andric   void emitVBTableDefinition(const VPtrInfo &VBT, const CXXRecordDecl *RD,
4000b57cec5SDimitry Andric                              llvm::GlobalVariable *GV) const;
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric   void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
4030b57cec5SDimitry Andric                        GlobalDecl GD, bool ReturnAdjustment) override {
4040b57cec5SDimitry Andric     GVALinkage Linkage =
4050b57cec5SDimitry Andric         getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.getDecl()));
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric     if (Linkage == GVA_Internal)
4080b57cec5SDimitry Andric       Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
4090b57cec5SDimitry Andric     else if (ReturnAdjustment)
4100b57cec5SDimitry Andric       Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
4110b57cec5SDimitry Andric     else
4120b57cec5SDimitry Andric       Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
4130b57cec5SDimitry Andric   }
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric   bool exportThunk() override { return false; }
4160b57cec5SDimitry Andric 
4170b57cec5SDimitry Andric   llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
4180fca6ea1SDimitry Andric                                      const CXXRecordDecl * /*UnadjustedClass*/,
4190fca6ea1SDimitry Andric                                      const ThunkInfo &TI) override;
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric   llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
4220fca6ea1SDimitry Andric                                        const CXXRecordDecl * /*UnadjustedClass*/,
4230b57cec5SDimitry Andric                                        const ReturnAdjustment &RA) override;
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric   void EmitThreadLocalInitFuncs(
4260b57cec5SDimitry Andric       CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
4270b57cec5SDimitry Andric       ArrayRef<llvm::Function *> CXXThreadLocalInits,
4280b57cec5SDimitry Andric       ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override;
4290b57cec5SDimitry Andric 
430a7dea167SDimitry Andric   bool usesThreadWrapperFunction(const VarDecl *VD) const override {
43104eeddc0SDimitry Andric     return getContext().getLangOpts().isCompatibleWithMSVC(
43204eeddc0SDimitry Andric                LangOptions::MSVC2019_5) &&
43304eeddc0SDimitry Andric            (!isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD));
434a7dea167SDimitry Andric   }
4350b57cec5SDimitry Andric   LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,
4360b57cec5SDimitry Andric                                       QualType LValType) override;
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
4390b57cec5SDimitry Andric                        llvm::GlobalVariable *DeclPtr,
4400b57cec5SDimitry Andric                        bool PerformInit) override;
4410b57cec5SDimitry Andric   void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
4420b57cec5SDimitry Andric                           llvm::FunctionCallee Dtor,
4430b57cec5SDimitry Andric                           llvm::Constant *Addr) override;
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric   // ==== Notes on array cookies =========
4460b57cec5SDimitry Andric   //
4470b57cec5SDimitry Andric   // MSVC seems to only use cookies when the class has a destructor; a
4480b57cec5SDimitry Andric   // two-argument usual array deallocation function isn't sufficient.
4490b57cec5SDimitry Andric   //
4500b57cec5SDimitry Andric   // For example, this code prints "100" and "1":
4510b57cec5SDimitry Andric   //   struct A {
4520b57cec5SDimitry Andric   //     char x;
4530b57cec5SDimitry Andric   //     void *operator new[](size_t sz) {
4540b57cec5SDimitry Andric   //       printf("%u\n", sz);
4550b57cec5SDimitry Andric   //       return malloc(sz);
4560b57cec5SDimitry Andric   //     }
4570b57cec5SDimitry Andric   //     void operator delete[](void *p, size_t sz) {
4580b57cec5SDimitry Andric   //       printf("%u\n", sz);
4590b57cec5SDimitry Andric   //       free(p);
4600b57cec5SDimitry Andric   //     }
4610b57cec5SDimitry Andric   //   };
4620b57cec5SDimitry Andric   //   int main() {
4630b57cec5SDimitry Andric   //     A *p = new A[100];
4640b57cec5SDimitry Andric   //     delete[] p;
4650b57cec5SDimitry Andric   //   }
4660b57cec5SDimitry Andric   // Whereas it prints "104" and "104" if you give A a destructor.
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   bool requiresArrayCookie(const CXXDeleteExpr *expr,
4690b57cec5SDimitry Andric                            QualType elementType) override;
4700b57cec5SDimitry Andric   bool requiresArrayCookie(const CXXNewExpr *expr) override;
4710b57cec5SDimitry Andric   CharUnits getArrayCookieSizeImpl(QualType type) override;
4720b57cec5SDimitry Andric   Address InitializeArrayCookie(CodeGenFunction &CGF,
4730b57cec5SDimitry Andric                                 Address NewPtr,
4740b57cec5SDimitry Andric                                 llvm::Value *NumElements,
4750b57cec5SDimitry Andric                                 const CXXNewExpr *expr,
4760b57cec5SDimitry Andric                                 QualType ElementType) override;
4770b57cec5SDimitry Andric   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
4780b57cec5SDimitry Andric                                    Address allocPtr,
4790b57cec5SDimitry Andric                                    CharUnits cookieSize) override;
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric   friend struct MSRTTIBuilder;
4820b57cec5SDimitry Andric 
4830b57cec5SDimitry Andric   bool isImageRelative() const {
484bdd1243dSDimitry Andric     return CGM.getTarget().getPointerWidth(LangAS::Default) == 64;
4850b57cec5SDimitry Andric   }
4860b57cec5SDimitry Andric 
4870b57cec5SDimitry Andric   // 5 routines for constructing the llvm types for MS RTTI structs.
4880b57cec5SDimitry Andric   llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
4890b57cec5SDimitry Andric     llvm::SmallString<32> TDTypeName("rtti.TypeDescriptor");
4900b57cec5SDimitry Andric     TDTypeName += llvm::utostr(TypeInfoString.size());
4910b57cec5SDimitry Andric     llvm::StructType *&TypeDescriptorType =
4920b57cec5SDimitry Andric         TypeDescriptorTypeMap[TypeInfoString.size()];
4930b57cec5SDimitry Andric     if (TypeDescriptorType)
4940b57cec5SDimitry Andric       return TypeDescriptorType;
4950b57cec5SDimitry Andric     llvm::Type *FieldTypes[] = {
4960b57cec5SDimitry Andric         CGM.Int8PtrPtrTy,
4970b57cec5SDimitry Andric         CGM.Int8PtrTy,
4980b57cec5SDimitry Andric         llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
4990b57cec5SDimitry Andric     TypeDescriptorType =
5000b57cec5SDimitry Andric         llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, TDTypeName);
5010b57cec5SDimitry Andric     return TypeDescriptorType;
5020b57cec5SDimitry Andric   }
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric   llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
5050b57cec5SDimitry Andric     if (!isImageRelative())
5060b57cec5SDimitry Andric       return PtrType;
5070b57cec5SDimitry Andric     return CGM.IntTy;
5080b57cec5SDimitry Andric   }
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric   llvm::StructType *getBaseClassDescriptorType() {
5110b57cec5SDimitry Andric     if (BaseClassDescriptorType)
5120b57cec5SDimitry Andric       return BaseClassDescriptorType;
5130b57cec5SDimitry Andric     llvm::Type *FieldTypes[] = {
5140b57cec5SDimitry Andric         getImageRelativeType(CGM.Int8PtrTy),
5150b57cec5SDimitry Andric         CGM.IntTy,
5160b57cec5SDimitry Andric         CGM.IntTy,
5170b57cec5SDimitry Andric         CGM.IntTy,
5180b57cec5SDimitry Andric         CGM.IntTy,
5190b57cec5SDimitry Andric         CGM.IntTy,
5200b57cec5SDimitry Andric         getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
5210b57cec5SDimitry Andric     };
5220b57cec5SDimitry Andric     BaseClassDescriptorType = llvm::StructType::create(
5230b57cec5SDimitry Andric         CGM.getLLVMContext(), FieldTypes, "rtti.BaseClassDescriptor");
5240b57cec5SDimitry Andric     return BaseClassDescriptorType;
5250b57cec5SDimitry Andric   }
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric   llvm::StructType *getClassHierarchyDescriptorType() {
5280b57cec5SDimitry Andric     if (ClassHierarchyDescriptorType)
5290b57cec5SDimitry Andric       return ClassHierarchyDescriptorType;
5300b57cec5SDimitry Andric     // Forward-declare RTTIClassHierarchyDescriptor to break a cycle.
5310b57cec5SDimitry Andric     ClassHierarchyDescriptorType = llvm::StructType::create(
5320b57cec5SDimitry Andric         CGM.getLLVMContext(), "rtti.ClassHierarchyDescriptor");
5330b57cec5SDimitry Andric     llvm::Type *FieldTypes[] = {
5340b57cec5SDimitry Andric         CGM.IntTy,
5350b57cec5SDimitry Andric         CGM.IntTy,
5360b57cec5SDimitry Andric         CGM.IntTy,
5370b57cec5SDimitry Andric         getImageRelativeType(
5380b57cec5SDimitry Andric             getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
5390b57cec5SDimitry Andric     };
5400b57cec5SDimitry Andric     ClassHierarchyDescriptorType->setBody(FieldTypes);
5410b57cec5SDimitry Andric     return ClassHierarchyDescriptorType;
5420b57cec5SDimitry Andric   }
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric   llvm::StructType *getCompleteObjectLocatorType() {
5450b57cec5SDimitry Andric     if (CompleteObjectLocatorType)
5460b57cec5SDimitry Andric       return CompleteObjectLocatorType;
5470b57cec5SDimitry Andric     CompleteObjectLocatorType = llvm::StructType::create(
5480b57cec5SDimitry Andric         CGM.getLLVMContext(), "rtti.CompleteObjectLocator");
5490b57cec5SDimitry Andric     llvm::Type *FieldTypes[] = {
5500b57cec5SDimitry Andric         CGM.IntTy,
5510b57cec5SDimitry Andric         CGM.IntTy,
5520b57cec5SDimitry Andric         CGM.IntTy,
5530b57cec5SDimitry Andric         getImageRelativeType(CGM.Int8PtrTy),
5540b57cec5SDimitry Andric         getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
5550b57cec5SDimitry Andric         getImageRelativeType(CompleteObjectLocatorType),
5560b57cec5SDimitry Andric     };
5570b57cec5SDimitry Andric     llvm::ArrayRef<llvm::Type *> FieldTypesRef(FieldTypes);
5580b57cec5SDimitry Andric     if (!isImageRelative())
5590b57cec5SDimitry Andric       FieldTypesRef = FieldTypesRef.drop_back();
5600b57cec5SDimitry Andric     CompleteObjectLocatorType->setBody(FieldTypesRef);
5610b57cec5SDimitry Andric     return CompleteObjectLocatorType;
5620b57cec5SDimitry Andric   }
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric   llvm::GlobalVariable *getImageBase() {
5650b57cec5SDimitry Andric     StringRef Name = "__ImageBase";
5660b57cec5SDimitry Andric     if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
5670b57cec5SDimitry Andric       return GV;
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric     auto *GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
5700b57cec5SDimitry Andric                                         /*isConstant=*/true,
5710b57cec5SDimitry Andric                                         llvm::GlobalValue::ExternalLinkage,
5720b57cec5SDimitry Andric                                         /*Initializer=*/nullptr, Name);
5730b57cec5SDimitry Andric     CGM.setDSOLocal(GV);
5740b57cec5SDimitry Andric     return GV;
5750b57cec5SDimitry Andric   }
5760b57cec5SDimitry Andric 
5770b57cec5SDimitry Andric   llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
5780b57cec5SDimitry Andric     if (!isImageRelative())
5790b57cec5SDimitry Andric       return PtrVal;
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric     if (PtrVal->isNullValue())
5820b57cec5SDimitry Andric       return llvm::Constant::getNullValue(CGM.IntTy);
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric     llvm::Constant *ImageBaseAsInt =
5850b57cec5SDimitry Andric         llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
5860b57cec5SDimitry Andric     llvm::Constant *PtrValAsInt =
5870b57cec5SDimitry Andric         llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
5880b57cec5SDimitry Andric     llvm::Constant *Diff =
5890b57cec5SDimitry Andric         llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
5900b57cec5SDimitry Andric                                    /*HasNUW=*/true, /*HasNSW=*/true);
5910b57cec5SDimitry Andric     return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
5920b57cec5SDimitry Andric   }
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric private:
5950b57cec5SDimitry Andric   MicrosoftMangleContext &getMangleContext() {
5960b57cec5SDimitry Andric     return cast<MicrosoftMangleContext>(CodeGen::CGCXXABI::getMangleContext());
5970b57cec5SDimitry Andric   }
5980b57cec5SDimitry Andric 
5990b57cec5SDimitry Andric   llvm::Constant *getZeroInt() {
6000b57cec5SDimitry Andric     return llvm::ConstantInt::get(CGM.IntTy, 0);
6010b57cec5SDimitry Andric   }
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric   llvm::Constant *getAllOnesInt() {
6040b57cec5SDimitry Andric     return  llvm::Constant::getAllOnesValue(CGM.IntTy);
6050b57cec5SDimitry Andric   }
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric   CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) override;
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric   void
6100b57cec5SDimitry Andric   GetNullMemberPointerFields(const MemberPointerType *MPT,
6110b57cec5SDimitry Andric                              llvm::SmallVectorImpl<llvm::Constant *> &fields);
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric   /// Shared code for virtual base adjustment.  Returns the offset from
6140b57cec5SDimitry Andric   /// the vbptr to the virtual base.  Optionally returns the address of the
6150b57cec5SDimitry Andric   /// vbptr itself.
6160b57cec5SDimitry Andric   llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
6170b57cec5SDimitry Andric                                        Address Base,
6180b57cec5SDimitry Andric                                        llvm::Value *VBPtrOffset,
6190b57cec5SDimitry Andric                                        llvm::Value *VBTableOffset,
6200b57cec5SDimitry Andric                                        llvm::Value **VBPtr = nullptr);
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric   llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
6230b57cec5SDimitry Andric                                        Address Base,
6240b57cec5SDimitry Andric                                        int32_t VBPtrOffset,
6250b57cec5SDimitry Andric                                        int32_t VBTableOffset,
6260b57cec5SDimitry Andric                                        llvm::Value **VBPtr = nullptr) {
6270b57cec5SDimitry Andric     assert(VBTableOffset % 4 == 0 && "should be byte offset into table of i32s");
6280b57cec5SDimitry Andric     llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
6290b57cec5SDimitry Andric                 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
6300b57cec5SDimitry Andric     return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
6310b57cec5SDimitry Andric   }
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric   std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
6340b57cec5SDimitry Andric   performBaseAdjustment(CodeGenFunction &CGF, Address Value,
6350b57cec5SDimitry Andric                         QualType SrcRecordTy);
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric   /// Performs a full virtual base adjustment.  Used to dereference
6380b57cec5SDimitry Andric   /// pointers to members of virtual bases.
6390b57cec5SDimitry Andric   llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const Expr *E,
6400b57cec5SDimitry Andric                                  const CXXRecordDecl *RD, Address Base,
6410b57cec5SDimitry Andric                                  llvm::Value *VirtualBaseAdjustmentOffset,
6420b57cec5SDimitry Andric                                  llvm::Value *VBPtrOffset /* optional */);
6430b57cec5SDimitry Andric 
6440b57cec5SDimitry Andric   /// Emits a full member pointer with the fields common to data and
6450b57cec5SDimitry Andric   /// function member pointers.
6460b57cec5SDimitry Andric   llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
6470b57cec5SDimitry Andric                                         bool IsMemberFunction,
6480b57cec5SDimitry Andric                                         const CXXRecordDecl *RD,
6490b57cec5SDimitry Andric                                         CharUnits NonVirtualBaseAdjustment,
6500b57cec5SDimitry Andric                                         unsigned VBTableIndex);
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric   bool MemberPointerConstantIsNull(const MemberPointerType *MPT,
6530b57cec5SDimitry Andric                                    llvm::Constant *MP);
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric   /// - Initialize all vbptrs of 'this' with RD as the complete type.
6560b57cec5SDimitry Andric   void EmitVBPtrStores(CodeGenFunction &CGF, const CXXRecordDecl *RD);
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric   /// Caching wrapper around VBTableBuilder::enumerateVBTables().
6590b57cec5SDimitry Andric   const VBTableGlobals &enumerateVBTables(const CXXRecordDecl *RD);
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric   /// Generate a thunk for calling a virtual member function MD.
6620b57cec5SDimitry Andric   llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
6630b57cec5SDimitry Andric                                          const MethodVFTableLocation &ML);
6640b57cec5SDimitry Andric 
665c14a5a88SDimitry Andric   llvm::Constant *EmitMemberDataPointer(const CXXRecordDecl *RD,
666c14a5a88SDimitry Andric                                         CharUnits offset);
667c14a5a88SDimitry Andric 
6680b57cec5SDimitry Andric public:
6690b57cec5SDimitry Andric   llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric   bool isZeroInitializable(const MemberPointerType *MPT) override;
6720b57cec5SDimitry Andric 
6730b57cec5SDimitry Andric   bool isMemberPointerConvertible(const MemberPointerType *MPT) const override {
6740b57cec5SDimitry Andric     const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
6750b57cec5SDimitry Andric     return RD->hasAttr<MSInheritanceAttr>();
6760b57cec5SDimitry Andric   }
6770b57cec5SDimitry Andric 
6780b57cec5SDimitry Andric   llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override;
6790b57cec5SDimitry Andric 
6800b57cec5SDimitry Andric   llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
6810b57cec5SDimitry Andric                                         CharUnits offset) override;
6820b57cec5SDimitry Andric   llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD) override;
6830b57cec5SDimitry Andric   llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override;
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric   llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
6860b57cec5SDimitry Andric                                            llvm::Value *L,
6870b57cec5SDimitry Andric                                            llvm::Value *R,
6880b57cec5SDimitry Andric                                            const MemberPointerType *MPT,
6890b57cec5SDimitry Andric                                            bool Inequality) override;
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric   llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
6920b57cec5SDimitry Andric                                           llvm::Value *MemPtr,
6930b57cec5SDimitry Andric                                           const MemberPointerType *MPT) override;
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric   llvm::Value *
6960b57cec5SDimitry Andric   EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
6970b57cec5SDimitry Andric                                Address Base, llvm::Value *MemPtr,
6980b57cec5SDimitry Andric                                const MemberPointerType *MPT) override;
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   llvm::Value *EmitNonNullMemberPointerConversion(
7010b57cec5SDimitry Andric       const MemberPointerType *SrcTy, const MemberPointerType *DstTy,
7020b57cec5SDimitry Andric       CastKind CK, CastExpr::path_const_iterator PathBegin,
7030b57cec5SDimitry Andric       CastExpr::path_const_iterator PathEnd, llvm::Value *Src,
7040b57cec5SDimitry Andric       CGBuilderTy &Builder);
7050b57cec5SDimitry Andric 
7060b57cec5SDimitry Andric   llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
7070b57cec5SDimitry Andric                                            const CastExpr *E,
7080b57cec5SDimitry Andric                                            llvm::Value *Src) override;
7090b57cec5SDimitry Andric 
7100b57cec5SDimitry Andric   llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
7110b57cec5SDimitry Andric                                               llvm::Constant *Src) override;
7120b57cec5SDimitry Andric 
7130b57cec5SDimitry Andric   llvm::Constant *EmitMemberPointerConversion(
7140b57cec5SDimitry Andric       const MemberPointerType *SrcTy, const MemberPointerType *DstTy,
7150b57cec5SDimitry Andric       CastKind CK, CastExpr::path_const_iterator PathBegin,
7160b57cec5SDimitry Andric       CastExpr::path_const_iterator PathEnd, llvm::Constant *Src);
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric   CGCallee
7190b57cec5SDimitry Andric   EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E,
7200b57cec5SDimitry Andric                                   Address This, llvm::Value *&ThisPtrForCall,
7210b57cec5SDimitry Andric                                   llvm::Value *MemPtr,
7220b57cec5SDimitry Andric                                   const MemberPointerType *MPT) override;
7230b57cec5SDimitry Andric 
7240b57cec5SDimitry Andric   void emitCXXStructor(GlobalDecl GD) override;
7250b57cec5SDimitry Andric 
7260b57cec5SDimitry Andric   llvm::StructType *getCatchableTypeType() {
7270b57cec5SDimitry Andric     if (CatchableTypeType)
7280b57cec5SDimitry Andric       return CatchableTypeType;
7290b57cec5SDimitry Andric     llvm::Type *FieldTypes[] = {
7300b57cec5SDimitry Andric         CGM.IntTy,                           // Flags
7310b57cec5SDimitry Andric         getImageRelativeType(CGM.Int8PtrTy), // TypeDescriptor
7320b57cec5SDimitry Andric         CGM.IntTy,                           // NonVirtualAdjustment
7330b57cec5SDimitry Andric         CGM.IntTy,                           // OffsetToVBPtr
7340b57cec5SDimitry Andric         CGM.IntTy,                           // VBTableIndex
7350b57cec5SDimitry Andric         CGM.IntTy,                           // Size
7360b57cec5SDimitry Andric         getImageRelativeType(CGM.Int8PtrTy)  // CopyCtor
7370b57cec5SDimitry Andric     };
7380b57cec5SDimitry Andric     CatchableTypeType = llvm::StructType::create(
7390b57cec5SDimitry Andric         CGM.getLLVMContext(), FieldTypes, "eh.CatchableType");
7400b57cec5SDimitry Andric     return CatchableTypeType;
7410b57cec5SDimitry Andric   }
7420b57cec5SDimitry Andric 
7430b57cec5SDimitry Andric   llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
7440b57cec5SDimitry Andric     llvm::StructType *&CatchableTypeArrayType =
7450b57cec5SDimitry Andric         CatchableTypeArrayTypeMap[NumEntries];
7460b57cec5SDimitry Andric     if (CatchableTypeArrayType)
7470b57cec5SDimitry Andric       return CatchableTypeArrayType;
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric     llvm::SmallString<23> CTATypeName("eh.CatchableTypeArray.");
7500b57cec5SDimitry Andric     CTATypeName += llvm::utostr(NumEntries);
7510b57cec5SDimitry Andric     llvm::Type *CTType =
7520b57cec5SDimitry Andric         getImageRelativeType(getCatchableTypeType()->getPointerTo());
7530b57cec5SDimitry Andric     llvm::Type *FieldTypes[] = {
7540b57cec5SDimitry Andric         CGM.IntTy,                               // NumEntries
7550b57cec5SDimitry Andric         llvm::ArrayType::get(CTType, NumEntries) // CatchableTypes
7560b57cec5SDimitry Andric     };
7570b57cec5SDimitry Andric     CatchableTypeArrayType =
7580b57cec5SDimitry Andric         llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, CTATypeName);
7590b57cec5SDimitry Andric     return CatchableTypeArrayType;
7600b57cec5SDimitry Andric   }
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric   llvm::StructType *getThrowInfoType() {
7630b57cec5SDimitry Andric     if (ThrowInfoType)
7640b57cec5SDimitry Andric       return ThrowInfoType;
7650b57cec5SDimitry Andric     llvm::Type *FieldTypes[] = {
7660b57cec5SDimitry Andric         CGM.IntTy,                           // Flags
7670b57cec5SDimitry Andric         getImageRelativeType(CGM.Int8PtrTy), // CleanupFn
7680b57cec5SDimitry Andric         getImageRelativeType(CGM.Int8PtrTy), // ForwardCompat
7690b57cec5SDimitry Andric         getImageRelativeType(CGM.Int8PtrTy)  // CatchableTypeArray
7700b57cec5SDimitry Andric     };
7710b57cec5SDimitry Andric     ThrowInfoType = llvm::StructType::create(CGM.getLLVMContext(), FieldTypes,
7720b57cec5SDimitry Andric                                              "eh.ThrowInfo");
7730b57cec5SDimitry Andric     return ThrowInfoType;
7740b57cec5SDimitry Andric   }
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric   llvm::FunctionCallee getThrowFn() {
7770b57cec5SDimitry Andric     // _CxxThrowException is passed an exception object and a ThrowInfo object
7780b57cec5SDimitry Andric     // which describes the exception.
7790b57cec5SDimitry Andric     llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
7800b57cec5SDimitry Andric     llvm::FunctionType *FTy =
7810b57cec5SDimitry Andric         llvm::FunctionType::get(CGM.VoidTy, Args, /*isVarArg=*/false);
7820b57cec5SDimitry Andric     llvm::FunctionCallee Throw =
7830b57cec5SDimitry Andric         CGM.CreateRuntimeFunction(FTy, "_CxxThrowException");
7840b57cec5SDimitry Andric     // _CxxThrowException is stdcall on 32-bit x86 platforms.
7850b57cec5SDimitry Andric     if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
7860b57cec5SDimitry Andric       if (auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
7870b57cec5SDimitry Andric         Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
7880b57cec5SDimitry Andric     }
7890b57cec5SDimitry Andric     return Throw;
7900b57cec5SDimitry Andric   }
7910b57cec5SDimitry Andric 
7920b57cec5SDimitry Andric   llvm::Function *getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
7930b57cec5SDimitry Andric                                           CXXCtorType CT);
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric   llvm::Constant *getCatchableType(QualType T,
7960b57cec5SDimitry Andric                                    uint32_t NVOffset = 0,
7970b57cec5SDimitry Andric                                    int32_t VBPtrOffset = -1,
7980b57cec5SDimitry Andric                                    uint32_t VBIndex = 0);
7990b57cec5SDimitry Andric 
8000b57cec5SDimitry Andric   llvm::GlobalVariable *getCatchableTypeArray(QualType T);
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric   llvm::GlobalVariable *getThrowInfo(QualType T) override;
8030b57cec5SDimitry Andric 
8040b57cec5SDimitry Andric   std::pair<llvm::Value *, const CXXRecordDecl *>
8050b57cec5SDimitry Andric   LoadVTablePtr(CodeGenFunction &CGF, Address This,
8060b57cec5SDimitry Andric                 const CXXRecordDecl *RD) override;
8070b57cec5SDimitry Andric 
808972a253aSDimitry Andric   bool
809e8d8bef9SDimitry Andric   isPermittedToBeHomogeneousAggregate(const CXXRecordDecl *RD) const override;
810e8d8bef9SDimitry Andric 
8110b57cec5SDimitry Andric private:
8120b57cec5SDimitry Andric   typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
8130b57cec5SDimitry Andric   typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
8140b57cec5SDimitry Andric   typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
8150b57cec5SDimitry Andric   /// All the vftables that have been referenced.
8160b57cec5SDimitry Andric   VFTablesMapTy VFTablesMap;
8170b57cec5SDimitry Andric   VTablesMapTy VTablesMap;
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   /// This set holds the record decls we've deferred vtable emission for.
8200b57cec5SDimitry Andric   llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric 
8230b57cec5SDimitry Andric   /// All the vbtables which have been referenced.
8240b57cec5SDimitry Andric   llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric   /// Info on the global variable used to guard initialization of static locals.
8270b57cec5SDimitry Andric   /// The BitIndex field is only used for externally invisible declarations.
8280b57cec5SDimitry Andric   struct GuardInfo {
8295f757f3fSDimitry Andric     GuardInfo() = default;
8305f757f3fSDimitry Andric     llvm::GlobalVariable *Guard = nullptr;
8315f757f3fSDimitry Andric     unsigned BitIndex = 0;
8320b57cec5SDimitry Andric   };
8330b57cec5SDimitry Andric 
8340b57cec5SDimitry Andric   /// Map from DeclContext to the current guard variable.  We assume that the
8350b57cec5SDimitry Andric   /// AST is visited in source code order.
8360b57cec5SDimitry Andric   llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
8370b57cec5SDimitry Andric   llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
8380b57cec5SDimitry Andric   llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric   llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
8410b57cec5SDimitry Andric   llvm::StructType *BaseClassDescriptorType;
8420b57cec5SDimitry Andric   llvm::StructType *ClassHierarchyDescriptorType;
8430b57cec5SDimitry Andric   llvm::StructType *CompleteObjectLocatorType;
8440b57cec5SDimitry Andric 
8450b57cec5SDimitry Andric   llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric   llvm::StructType *CatchableTypeType;
8480b57cec5SDimitry Andric   llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
8490b57cec5SDimitry Andric   llvm::StructType *ThrowInfoType;
8500b57cec5SDimitry Andric };
8510b57cec5SDimitry Andric 
8520b57cec5SDimitry Andric }
8530b57cec5SDimitry Andric 
8540b57cec5SDimitry Andric CGCXXABI::RecordArgABI
8550b57cec5SDimitry Andric MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
856e8d8bef9SDimitry Andric   // Use the default C calling convention rules for things that can be passed in
857e8d8bef9SDimitry Andric   // registers, i.e. non-trivially copyable records or records marked with
858e8d8bef9SDimitry Andric   // [[trivial_abi]].
859e8d8bef9SDimitry Andric   if (RD->canPassInRegisters())
860e8d8bef9SDimitry Andric     return RAA_Default;
861e8d8bef9SDimitry Andric 
8620b57cec5SDimitry Andric   switch (CGM.getTarget().getTriple().getArch()) {
8630b57cec5SDimitry Andric   default:
8640b57cec5SDimitry Andric     // FIXME: Implement for other architectures.
865e8d8bef9SDimitry Andric     return RAA_Indirect;
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric   case llvm::Triple::thumb:
868e8d8bef9SDimitry Andric     // Pass things indirectly for now because it is simple.
8690b57cec5SDimitry Andric     // FIXME: This is incompatible with MSVC for arguments with a dtor and no
8700b57cec5SDimitry Andric     // copy ctor.
871e8d8bef9SDimitry Andric     return RAA_Indirect;
8720b57cec5SDimitry Andric 
873e8d8bef9SDimitry Andric   case llvm::Triple::x86: {
874e8d8bef9SDimitry Andric     // If the argument has *required* alignment greater than four bytes, pass
875e8d8bef9SDimitry Andric     // it indirectly. Prior to MSVC version 19.14, passing overaligned
876e8d8bef9SDimitry Andric     // arguments was not supported and resulted in a compiler error. In 19.14
877e8d8bef9SDimitry Andric     // and later versions, such arguments are now passed indirectly.
878e8d8bef9SDimitry Andric     TypeInfo Info = getContext().getTypeInfo(RD->getTypeForDecl());
879349cc55cSDimitry Andric     if (Info.isAlignRequired() && Info.Align > 4)
880e8d8bef9SDimitry Andric       return RAA_Indirect;
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric     // If C++ prohibits us from making a copy, construct the arguments directly
8830b57cec5SDimitry Andric     // into argument memory.
8840b57cec5SDimitry Andric     return RAA_DirectInMemory;
885e8d8bef9SDimitry Andric   }
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric   case llvm::Triple::x86_64:
8880b57cec5SDimitry Andric   case llvm::Triple::aarch64:
889e8d8bef9SDimitry Andric     return RAA_Indirect;
8900b57cec5SDimitry Andric   }
8910b57cec5SDimitry Andric 
8920b57cec5SDimitry Andric   llvm_unreachable("invalid enum");
8930b57cec5SDimitry Andric }
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric void MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
8960b57cec5SDimitry Andric                                               const CXXDeleteExpr *DE,
8970b57cec5SDimitry Andric                                               Address Ptr,
8980b57cec5SDimitry Andric                                               QualType ElementType,
8990b57cec5SDimitry Andric                                               const CXXDestructorDecl *Dtor) {
9000b57cec5SDimitry Andric   // FIXME: Provide a source location here even though there's no
9010b57cec5SDimitry Andric   // CXXMemberCallExpr for dtor call.
9020b57cec5SDimitry Andric   bool UseGlobalDelete = DE->isGlobalDelete();
9030b57cec5SDimitry Andric   CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
9040b57cec5SDimitry Andric   llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
9050b57cec5SDimitry Andric   if (UseGlobalDelete)
9060b57cec5SDimitry Andric     CGF.EmitDeleteCall(DE->getOperatorDelete(), MDThis, ElementType);
9070b57cec5SDimitry Andric }
9080b57cec5SDimitry Andric 
9090b57cec5SDimitry Andric void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
9100b57cec5SDimitry Andric   llvm::Value *Args[] = {
9110b57cec5SDimitry Andric       llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
9120b57cec5SDimitry Andric       llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
9130b57cec5SDimitry Andric   llvm::FunctionCallee Fn = getThrowFn();
9140b57cec5SDimitry Andric   if (isNoReturn)
9150b57cec5SDimitry Andric     CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, Args);
9160b57cec5SDimitry Andric   else
9170b57cec5SDimitry Andric     CGF.EmitRuntimeCallOrInvoke(Fn, Args);
9180b57cec5SDimitry Andric }
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
9210b57cec5SDimitry Andric                                      const CXXCatchStmt *S) {
9220b57cec5SDimitry Andric   // In the MS ABI, the runtime handles the copy, and the catch handler is
9230b57cec5SDimitry Andric   // responsible for destruction.
9240b57cec5SDimitry Andric   VarDecl *CatchParam = S->getExceptionDecl();
9250b57cec5SDimitry Andric   llvm::BasicBlock *CatchPadBB = CGF.Builder.GetInsertBlock();
9260b57cec5SDimitry Andric   llvm::CatchPadInst *CPI =
9270b57cec5SDimitry Andric       cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
9280b57cec5SDimitry Andric   CGF.CurrentFuncletPad = CPI;
9290b57cec5SDimitry Andric 
9300b57cec5SDimitry Andric   // If this is a catch-all or the catch parameter is unnamed, we don't need to
9310b57cec5SDimitry Andric   // emit an alloca to the object.
9320b57cec5SDimitry Andric   if (!CatchParam || !CatchParam->getDeclName()) {
9330b57cec5SDimitry Andric     CGF.EHStack.pushCleanup<CatchRetScope>(NormalCleanup, CPI);
9340b57cec5SDimitry Andric     return;
9350b57cec5SDimitry Andric   }
9360b57cec5SDimitry Andric 
9370b57cec5SDimitry Andric   CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam);
9380fca6ea1SDimitry Andric   CPI->setArgOperand(2, var.getObjectAddress(CGF).emitRawPointer(CGF));
9390b57cec5SDimitry Andric   CGF.EHStack.pushCleanup<CatchRetScope>(NormalCleanup, CPI);
9400b57cec5SDimitry Andric   CGF.EmitAutoVarCleanups(var);
9410b57cec5SDimitry Andric }
9420b57cec5SDimitry Andric 
9430b57cec5SDimitry Andric /// We need to perform a generic polymorphic operation (like a typeid
9440b57cec5SDimitry Andric /// or a cast), which requires an object with a vfptr.  Adjust the
9450b57cec5SDimitry Andric /// address to point to an object with a vfptr.
9460b57cec5SDimitry Andric std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
9470b57cec5SDimitry Andric MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
9480b57cec5SDimitry Andric                                        QualType SrcRecordTy) {
94906c3fb27SDimitry Andric   Value = Value.withElementType(CGF.Int8Ty);
9500b57cec5SDimitry Andric   const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
9510b57cec5SDimitry Andric   const ASTContext &Context = getContext();
9520b57cec5SDimitry Andric 
9530b57cec5SDimitry Andric   // If the class itself has a vfptr, great.  This check implicitly
9540b57cec5SDimitry Andric   // covers non-virtual base subobjects: a class with its own virtual
9550b57cec5SDimitry Andric   // functions would be a candidate to be a primary base.
9560b57cec5SDimitry Andric   if (Context.getASTRecordLayout(SrcDecl).hasExtendableVFPtr())
9570b57cec5SDimitry Andric     return std::make_tuple(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0),
9580b57cec5SDimitry Andric                            SrcDecl);
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric   // Okay, one of the vbases must have a vfptr, or else this isn't
9610b57cec5SDimitry Andric   // actually a polymorphic class.
9620b57cec5SDimitry Andric   const CXXRecordDecl *PolymorphicBase = nullptr;
9630b57cec5SDimitry Andric   for (auto &Base : SrcDecl->vbases()) {
9640b57cec5SDimitry Andric     const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
9650b57cec5SDimitry Andric     if (Context.getASTRecordLayout(BaseDecl).hasExtendableVFPtr()) {
9660b57cec5SDimitry Andric       PolymorphicBase = BaseDecl;
9670b57cec5SDimitry Andric       break;
9680b57cec5SDimitry Andric     }
9690b57cec5SDimitry Andric   }
9700b57cec5SDimitry Andric   assert(PolymorphicBase && "polymorphic class has no apparent vfptr?");
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric   llvm::Value *Offset =
9730b57cec5SDimitry Andric     GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase);
974fe6060f1SDimitry Andric   llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP(
9750fca6ea1SDimitry Andric       Value.getElementType(), Value.emitRawPointer(CGF), Offset);
9760b57cec5SDimitry Andric   CharUnits VBaseAlign =
9770b57cec5SDimitry Andric     CGF.CGM.getVBaseAlignment(Value.getAlignment(), SrcDecl, PolymorphicBase);
97881ad6265SDimitry Andric   return std::make_tuple(Address(Ptr, CGF.Int8Ty, VBaseAlign), Offset,
97981ad6265SDimitry Andric                          PolymorphicBase);
9800b57cec5SDimitry Andric }
9810b57cec5SDimitry Andric 
9820fca6ea1SDimitry Andric bool MicrosoftCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
9830b57cec5SDimitry Andric   const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
9840fca6ea1SDimitry Andric   return !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
9850b57cec5SDimitry Andric }
9860b57cec5SDimitry Andric 
9870b57cec5SDimitry Andric static llvm::CallBase *emitRTtypeidCall(CodeGenFunction &CGF,
9880b57cec5SDimitry Andric                                         llvm::Value *Argument) {
9890b57cec5SDimitry Andric   llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
9900b57cec5SDimitry Andric   llvm::FunctionType *FTy =
9910b57cec5SDimitry Andric       llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false);
9920b57cec5SDimitry Andric   llvm::Value *Args[] = {Argument};
9930b57cec5SDimitry Andric   llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(FTy, "__RTtypeid");
9940b57cec5SDimitry Andric   return CGF.EmitRuntimeCallOrInvoke(Fn, Args);
9950b57cec5SDimitry Andric }
9960b57cec5SDimitry Andric 
9970b57cec5SDimitry Andric void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
9980b57cec5SDimitry Andric   llvm::CallBase *Call =
9990b57cec5SDimitry Andric       emitRTtypeidCall(CGF, llvm::Constant::getNullValue(CGM.VoidPtrTy));
10000b57cec5SDimitry Andric   Call->setDoesNotReturn();
10010b57cec5SDimitry Andric   CGF.Builder.CreateUnreachable();
10020b57cec5SDimitry Andric }
10030b57cec5SDimitry Andric 
10040b57cec5SDimitry Andric llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
10050b57cec5SDimitry Andric                                          QualType SrcRecordTy,
10060b57cec5SDimitry Andric                                          Address ThisPtr,
10070b57cec5SDimitry Andric                                          llvm::Type *StdTypeInfoPtrTy) {
10080b57cec5SDimitry Andric   std::tie(ThisPtr, std::ignore, std::ignore) =
10090b57cec5SDimitry Andric       performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
10100fca6ea1SDimitry Andric   llvm::CallBase *Typeid = emitRTtypeidCall(CGF, ThisPtr.emitRawPointer(CGF));
10110b57cec5SDimitry Andric   return CGF.Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
10120b57cec5SDimitry Andric }
10130b57cec5SDimitry Andric 
10140b57cec5SDimitry Andric bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
10150b57cec5SDimitry Andric                                                          QualType SrcRecordTy) {
10160b57cec5SDimitry Andric   const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
10170b57cec5SDimitry Andric   return SrcIsPtr &&
10180b57cec5SDimitry Andric          !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
10190b57cec5SDimitry Andric }
10200b57cec5SDimitry Andric 
102106c3fb27SDimitry Andric llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
102206c3fb27SDimitry Andric     CodeGenFunction &CGF, Address This, QualType SrcRecordTy, QualType DestTy,
102306c3fb27SDimitry Andric     QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
10240b57cec5SDimitry Andric   llvm::Value *SrcRTTI =
10250b57cec5SDimitry Andric       CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
10260b57cec5SDimitry Andric   llvm::Value *DestRTTI =
10270b57cec5SDimitry Andric       CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
10280b57cec5SDimitry Andric 
10290b57cec5SDimitry Andric   llvm::Value *Offset;
10300b57cec5SDimitry Andric   std::tie(This, Offset, std::ignore) =
10310b57cec5SDimitry Andric       performBaseAdjustment(CGF, This, SrcRecordTy);
10320fca6ea1SDimitry Andric   llvm::Value *ThisPtr = This.emitRawPointer(CGF);
10330b57cec5SDimitry Andric   Offset = CGF.Builder.CreateTrunc(Offset, CGF.Int32Ty);
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric   // PVOID __RTDynamicCast(
10360b57cec5SDimitry Andric   //   PVOID inptr,
10370b57cec5SDimitry Andric   //   LONG VfDelta,
10380b57cec5SDimitry Andric   //   PVOID SrcType,
10390b57cec5SDimitry Andric   //   PVOID TargetType,
10400b57cec5SDimitry Andric   //   BOOL isReference)
10410b57cec5SDimitry Andric   llvm::Type *ArgTypes[] = {CGF.Int8PtrTy, CGF.Int32Ty, CGF.Int8PtrTy,
10420b57cec5SDimitry Andric                             CGF.Int8PtrTy, CGF.Int32Ty};
10430b57cec5SDimitry Andric   llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction(
10440b57cec5SDimitry Andric       llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
10450b57cec5SDimitry Andric       "__RTDynamicCast");
10460b57cec5SDimitry Andric   llvm::Value *Args[] = {
10470b57cec5SDimitry Andric       ThisPtr, Offset, SrcRTTI, DestRTTI,
10480b57cec5SDimitry Andric       llvm::ConstantInt::get(CGF.Int32Ty, DestTy->isReferenceType())};
104906c3fb27SDimitry Andric   return CGF.EmitRuntimeCallOrInvoke(Function, Args);
10500b57cec5SDimitry Andric }
10510b57cec5SDimitry Andric 
105206c3fb27SDimitry Andric llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
105306c3fb27SDimitry Andric                                                     Address Value,
105406c3fb27SDimitry Andric                                                     QualType SrcRecordTy) {
10550b57cec5SDimitry Andric   std::tie(Value, std::ignore, std::ignore) =
10560b57cec5SDimitry Andric       performBaseAdjustment(CGF, Value, SrcRecordTy);
10570b57cec5SDimitry Andric 
10580b57cec5SDimitry Andric   // PVOID __RTCastToVoid(
10590b57cec5SDimitry Andric   //   PVOID inptr)
10600b57cec5SDimitry Andric   llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
10610b57cec5SDimitry Andric   llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction(
10620b57cec5SDimitry Andric       llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
10630b57cec5SDimitry Andric       "__RTCastToVoid");
10640fca6ea1SDimitry Andric   llvm::Value *Args[] = {Value.emitRawPointer(CGF)};
10650b57cec5SDimitry Andric   return CGF.EmitRuntimeCall(Function, Args);
10660b57cec5SDimitry Andric }
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric bool MicrosoftCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
10690b57cec5SDimitry Andric   return false;
10700b57cec5SDimitry Andric }
10710b57cec5SDimitry Andric 
10720b57cec5SDimitry Andric llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
10730b57cec5SDimitry Andric     CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl,
10740b57cec5SDimitry Andric     const CXXRecordDecl *BaseClassDecl) {
10750b57cec5SDimitry Andric   const ASTContext &Context = getContext();
10760b57cec5SDimitry Andric   int64_t VBPtrChars =
10770b57cec5SDimitry Andric       Context.getASTRecordLayout(ClassDecl).getVBPtrOffset().getQuantity();
10780b57cec5SDimitry Andric   llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
10790b57cec5SDimitry Andric   CharUnits IntSize = Context.getTypeSizeInChars(Context.IntTy);
10800b57cec5SDimitry Andric   CharUnits VBTableChars =
10810b57cec5SDimitry Andric       IntSize *
10820b57cec5SDimitry Andric       CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
10830b57cec5SDimitry Andric   llvm::Value *VBTableOffset =
10840b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, VBTableChars.getQuantity());
10850b57cec5SDimitry Andric 
10860b57cec5SDimitry Andric   llvm::Value *VBPtrToNewBase =
10870b57cec5SDimitry Andric       GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
10880b57cec5SDimitry Andric   VBPtrToNewBase =
10890b57cec5SDimitry Andric       CGF.Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
10900b57cec5SDimitry Andric   return CGF.Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
10910b57cec5SDimitry Andric }
10920b57cec5SDimitry Andric 
10930b57cec5SDimitry Andric bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const {
10940b57cec5SDimitry Andric   return isa<CXXConstructorDecl>(GD.getDecl());
10950b57cec5SDimitry Andric }
10960b57cec5SDimitry Andric 
10970b57cec5SDimitry Andric static bool isDeletingDtor(GlobalDecl GD) {
10980b57cec5SDimitry Andric   return isa<CXXDestructorDecl>(GD.getDecl()) &&
10990b57cec5SDimitry Andric          GD.getDtorType() == Dtor_Deleting;
11000b57cec5SDimitry Andric }
11010b57cec5SDimitry Andric 
11020b57cec5SDimitry Andric bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {
11030b57cec5SDimitry Andric   return isDeletingDtor(GD);
11040b57cec5SDimitry Andric }
11050b57cec5SDimitry Andric 
110606c3fb27SDimitry Andric static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
110706c3fb27SDimitry Andric                              CodeGenModule &CGM) {
110806c3fb27SDimitry Andric   // On AArch64, HVAs that can be passed in registers can also be returned
110906c3fb27SDimitry Andric   // in registers. (Note this is using the MSVC definition of an HVA; see
111006c3fb27SDimitry Andric   // isPermittedToBeHomogeneousAggregate().)
111106c3fb27SDimitry Andric   const Type *Base = nullptr;
111206c3fb27SDimitry Andric   uint64_t NumElts = 0;
111306c3fb27SDimitry Andric   if (CGM.getTarget().getTriple().isAArch64() &&
1114*5deeebd8SDimitry Andric       CGM.getABIInfo().isHomogeneousAggregate(Ty, Base, NumElts) &&
111506c3fb27SDimitry Andric       isa<VectorType>(Base)) {
111606c3fb27SDimitry Andric     return true;
111706c3fb27SDimitry Andric   }
111806c3fb27SDimitry Andric 
1119bdd1243dSDimitry Andric   // We use the C++14 definition of an aggregate, so we also
11200b57cec5SDimitry Andric   // check for:
11210b57cec5SDimitry Andric   //   No private or protected non static data members.
11220b57cec5SDimitry Andric   //   No base classes
11230b57cec5SDimitry Andric   //   No virtual functions
11240b57cec5SDimitry Andric   // Additionally, we need to ensure that there is a trivial copy assignment
11250fca6ea1SDimitry Andric   // operator, a trivial destructor, no user-provided constructors and no
11260fca6ea1SDimitry Andric   // deleted copy assignment operator.
11270fca6ea1SDimitry Andric 
11280fca6ea1SDimitry Andric   // We need to cover two cases when checking for a deleted copy assignment
11290fca6ea1SDimitry Andric   // operator.
11300fca6ea1SDimitry Andric   //
11310fca6ea1SDimitry Andric   // struct S { int& r; };
11320fca6ea1SDimitry Andric   // The above will have an implicit copy assignment operator that is deleted
11330fca6ea1SDimitry Andric   // and there will not be a `CXXMethodDecl` for the copy assignment operator.
11340fca6ea1SDimitry Andric   // This is handled by the `needsImplicitCopyAssignment()` check below.
11350fca6ea1SDimitry Andric   //
11360fca6ea1SDimitry Andric   // struct S { S& operator=(const S&) = delete; int i; };
11370fca6ea1SDimitry Andric   // The above will not have an implicit copy assignment operator that is
11380fca6ea1SDimitry Andric   // deleted but there is a deleted `CXXMethodDecl` for the declared copy
11390fca6ea1SDimitry Andric   // assignment operator. This is handled by the `isDeleted()` check below.
11400fca6ea1SDimitry Andric 
11410b57cec5SDimitry Andric   if (RD->hasProtectedFields() || RD->hasPrivateFields())
1142e8d8bef9SDimitry Andric     return false;
11430b57cec5SDimitry Andric   if (RD->getNumBases() > 0)
1144e8d8bef9SDimitry Andric     return false;
11450b57cec5SDimitry Andric   if (RD->isPolymorphic())
1146e8d8bef9SDimitry Andric     return false;
11470b57cec5SDimitry Andric   if (RD->hasNonTrivialCopyAssignment())
1148e8d8bef9SDimitry Andric     return false;
11490fca6ea1SDimitry Andric   if (RD->needsImplicitCopyAssignment() && !RD->hasSimpleCopyAssignment())
11500fca6ea1SDimitry Andric     return false;
11515678d1d9SDimitry Andric   for (const Decl *D : RD->decls()) {
11525678d1d9SDimitry Andric     if (auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
11530b57cec5SDimitry Andric       if (Ctor->isUserProvided())
11540b57cec5SDimitry Andric         return false;
11555678d1d9SDimitry Andric     } else if (auto *Template = dyn_cast<FunctionTemplateDecl>(D)) {
11565678d1d9SDimitry Andric       if (isa<CXXConstructorDecl>(Template->getTemplatedDecl()))
11575678d1d9SDimitry Andric         return false;
11580fca6ea1SDimitry Andric     } else if (auto *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
11590fca6ea1SDimitry Andric       if (MethodDecl->isCopyAssignmentOperator() && MethodDecl->isDeleted())
11600fca6ea1SDimitry Andric         return false;
11615678d1d9SDimitry Andric     }
11625678d1d9SDimitry Andric   }
1163e8d8bef9SDimitry Andric   if (RD->hasNonTrivialDestructor())
1164e8d8bef9SDimitry Andric     return false;
1165e8d8bef9SDimitry Andric   return true;
11660b57cec5SDimitry Andric }
11670b57cec5SDimitry Andric 
11680b57cec5SDimitry Andric bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
11690b57cec5SDimitry Andric   const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();
11700b57cec5SDimitry Andric   if (!RD)
11710b57cec5SDimitry Andric     return false;
11720b57cec5SDimitry Andric 
117306c3fb27SDimitry Andric   bool isTrivialForABI = RD->canPassInRegisters() &&
117406c3fb27SDimitry Andric                          isTrivialForMSVC(RD, FI.getReturnType(), CGM);
11750b57cec5SDimitry Andric 
1176e8d8bef9SDimitry Andric   // MSVC always returns structs indirectly from C++ instance methods.
1177e8d8bef9SDimitry Andric   bool isIndirectReturn = !isTrivialForABI || FI.isInstanceMethod();
1178e8d8bef9SDimitry Andric 
1179e8d8bef9SDimitry Andric   if (isIndirectReturn) {
11800b57cec5SDimitry Andric     CharUnits Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
11810b57cec5SDimitry Andric     FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
11820b57cec5SDimitry Andric 
1183e8d8bef9SDimitry Andric     // MSVC always passes `this` before the `sret` parameter.
1184e8d8bef9SDimitry Andric     FI.getReturnInfo().setSRetAfterThis(FI.isInstanceMethod());
1185e8d8bef9SDimitry Andric 
1186e8d8bef9SDimitry Andric     // On AArch64, use the `inreg` attribute if the object is considered to not
1187e8d8bef9SDimitry Andric     // be trivially copyable, or if this is an instance method struct return.
1188bdd1243dSDimitry Andric     FI.getReturnInfo().setInReg(CGM.getTarget().getTriple().isAArch64());
11890b57cec5SDimitry Andric 
11900b57cec5SDimitry Andric     return true;
11910b57cec5SDimitry Andric   }
11920b57cec5SDimitry Andric 
11930b57cec5SDimitry Andric   // Otherwise, use the C ABI rules.
11940b57cec5SDimitry Andric   return false;
11950b57cec5SDimitry Andric }
11960b57cec5SDimitry Andric 
11970b57cec5SDimitry Andric llvm::BasicBlock *
11980b57cec5SDimitry Andric MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
11990b57cec5SDimitry Andric                                                const CXXRecordDecl *RD) {
12000b57cec5SDimitry Andric   llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
12010b57cec5SDimitry Andric   assert(IsMostDerivedClass &&
12020b57cec5SDimitry Andric          "ctor for a class with virtual bases must have an implicit parameter");
12030b57cec5SDimitry Andric   llvm::Value *IsCompleteObject =
12040b57cec5SDimitry Andric     CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object");
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric   llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases");
12070b57cec5SDimitry Andric   llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases");
12080b57cec5SDimitry Andric   CGF.Builder.CreateCondBr(IsCompleteObject,
12090b57cec5SDimitry Andric                            CallVbaseCtorsBB, SkipVbaseCtorsBB);
12100b57cec5SDimitry Andric 
12110b57cec5SDimitry Andric   CGF.EmitBlock(CallVbaseCtorsBB);
12120b57cec5SDimitry Andric 
12130b57cec5SDimitry Andric   // Fill in the vbtable pointers here.
12140b57cec5SDimitry Andric   EmitVBPtrStores(CGF, RD);
12150b57cec5SDimitry Andric 
12160b57cec5SDimitry Andric   // CGF will put the base ctor calls in this basic block for us later.
12170b57cec5SDimitry Andric 
12180b57cec5SDimitry Andric   return SkipVbaseCtorsBB;
12190b57cec5SDimitry Andric }
12200b57cec5SDimitry Andric 
12210b57cec5SDimitry Andric llvm::BasicBlock *
12220b57cec5SDimitry Andric MicrosoftCXXABI::EmitDtorCompleteObjectHandler(CodeGenFunction &CGF) {
12230b57cec5SDimitry Andric   llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
12240b57cec5SDimitry Andric   assert(IsMostDerivedClass &&
12250b57cec5SDimitry Andric          "ctor for a class with virtual bases must have an implicit parameter");
12260b57cec5SDimitry Andric   llvm::Value *IsCompleteObject =
12270b57cec5SDimitry Andric       CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object");
12280b57cec5SDimitry Andric 
12290b57cec5SDimitry Andric   llvm::BasicBlock *CallVbaseDtorsBB = CGF.createBasicBlock("Dtor.dtor_vbases");
12300b57cec5SDimitry Andric   llvm::BasicBlock *SkipVbaseDtorsBB = CGF.createBasicBlock("Dtor.skip_vbases");
12310b57cec5SDimitry Andric   CGF.Builder.CreateCondBr(IsCompleteObject,
12320b57cec5SDimitry Andric                            CallVbaseDtorsBB, SkipVbaseDtorsBB);
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric   CGF.EmitBlock(CallVbaseDtorsBB);
12350b57cec5SDimitry Andric   // CGF will put the base dtor calls in this basic block for us later.
12360b57cec5SDimitry Andric 
12370b57cec5SDimitry Andric   return SkipVbaseDtorsBB;
12380b57cec5SDimitry Andric }
12390b57cec5SDimitry Andric 
12400b57cec5SDimitry Andric void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
12410b57cec5SDimitry Andric     CodeGenFunction &CGF, const CXXRecordDecl *RD) {
12420b57cec5SDimitry Andric   // In most cases, an override for a vbase virtual method can adjust
12430b57cec5SDimitry Andric   // the "this" parameter by applying a constant offset.
12440b57cec5SDimitry Andric   // However, this is not enough while a constructor or a destructor of some
12450b57cec5SDimitry Andric   // class X is being executed if all the following conditions are met:
12460b57cec5SDimitry Andric   //  - X has virtual bases, (1)
12470b57cec5SDimitry Andric   //  - X overrides a virtual method M of a vbase Y, (2)
12480b57cec5SDimitry Andric   //  - X itself is a vbase of the most derived class.
12490b57cec5SDimitry Andric   //
12500b57cec5SDimitry Andric   // If (1) and (2) are true, the vtorDisp for vbase Y is a hidden member of X
12510b57cec5SDimitry Andric   // which holds the extra amount of "this" adjustment we must do when we use
12520b57cec5SDimitry Andric   // the X vftables (i.e. during X ctor or dtor).
12530b57cec5SDimitry Andric   // Outside the ctors and dtors, the values of vtorDisps are zero.
12540b57cec5SDimitry Andric 
12550b57cec5SDimitry Andric   const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
12560b57cec5SDimitry Andric   typedef ASTRecordLayout::VBaseOffsetsMapTy VBOffsets;
12570b57cec5SDimitry Andric   const VBOffsets &VBaseMap = Layout.getVBaseOffsetsMap();
12580b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
12590b57cec5SDimitry Andric 
12600b57cec5SDimitry Andric   llvm::Value *Int8This = nullptr;  // Initialize lazily.
12610b57cec5SDimitry Andric 
12620b57cec5SDimitry Andric   for (const CXXBaseSpecifier &S : RD->vbases()) {
12630b57cec5SDimitry Andric     const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
12640b57cec5SDimitry Andric     auto I = VBaseMap.find(VBase);
12650b57cec5SDimitry Andric     assert(I != VBaseMap.end());
12660b57cec5SDimitry Andric     if (!I->second.hasVtorDisp())
12670b57cec5SDimitry Andric       continue;
12680b57cec5SDimitry Andric 
12690b57cec5SDimitry Andric     llvm::Value *VBaseOffset =
12700b57cec5SDimitry Andric         GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
12710b57cec5SDimitry Andric     uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
12720b57cec5SDimitry Andric 
12730b57cec5SDimitry Andric     // vtorDisp_for_vbase = vbptr[vbase_idx] - offsetof(RD, vbase).
12740b57cec5SDimitry Andric     llvm::Value *VtorDispValue = Builder.CreateSub(
12750b57cec5SDimitry Andric         VBaseOffset, llvm::ConstantInt::get(CGM.PtrDiffTy, ConstantVBaseOffset),
12760b57cec5SDimitry Andric         "vtordisp.value");
12770b57cec5SDimitry Andric     VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.Int32Ty);
12780b57cec5SDimitry Andric 
12790b57cec5SDimitry Andric     if (!Int8This)
12805f757f3fSDimitry Andric       Int8This = getThisValue(CGF);
12815f757f3fSDimitry Andric 
1282fe6060f1SDimitry Andric     llvm::Value *VtorDispPtr =
1283fe6060f1SDimitry Andric         Builder.CreateInBoundsGEP(CGF.Int8Ty, Int8This, VBaseOffset);
12840b57cec5SDimitry Andric     // vtorDisp is always the 32-bits before the vbase in the class layout.
1285fe6060f1SDimitry Andric     VtorDispPtr = Builder.CreateConstGEP1_32(CGF.Int8Ty, VtorDispPtr, -4);
12860b57cec5SDimitry Andric 
12870b57cec5SDimitry Andric     Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
12880b57cec5SDimitry Andric                                CharUnits::fromQuantity(4));
12890b57cec5SDimitry Andric   }
12900b57cec5SDimitry Andric }
12910b57cec5SDimitry Andric 
12920b57cec5SDimitry Andric static bool hasDefaultCXXMethodCC(ASTContext &Context,
12930b57cec5SDimitry Andric                                   const CXXMethodDecl *MD) {
12940b57cec5SDimitry Andric   CallingConv ExpectedCallingConv = Context.getDefaultCallingConvention(
12950b57cec5SDimitry Andric       /*IsVariadic=*/false, /*IsCXXMethod=*/true);
12960b57cec5SDimitry Andric   CallingConv ActualCallingConv =
1297a7dea167SDimitry Andric       MD->getType()->castAs<FunctionProtoType>()->getCallConv();
12980b57cec5SDimitry Andric   return ExpectedCallingConv == ActualCallingConv;
12990b57cec5SDimitry Andric }
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric void MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
13020b57cec5SDimitry Andric   // There's only one constructor type in this ABI.
13030b57cec5SDimitry Andric   CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete));
13040b57cec5SDimitry Andric 
13050b57cec5SDimitry Andric   // Exported default constructors either have a simple call-site where they use
13060b57cec5SDimitry Andric   // the typical calling convention and have a single 'this' pointer for an
13070b57cec5SDimitry Andric   // argument -or- they get a wrapper function which appropriately thunks to the
13080b57cec5SDimitry Andric   // real default constructor.  This thunk is the default constructor closure.
1309e8d8bef9SDimitry Andric   if (D->hasAttr<DLLExportAttr>() && D->isDefaultConstructor() &&
1310e8d8bef9SDimitry Andric       D->isDefined()) {
13110b57cec5SDimitry Andric     if (!hasDefaultCXXMethodCC(getContext(), D) || D->getNumParams() != 0) {
13120b57cec5SDimitry Andric       llvm::Function *Fn = getAddrOfCXXCtorClosure(D, Ctor_DefaultClosure);
13130b57cec5SDimitry Andric       Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
13140b57cec5SDimitry Andric       CGM.setGVProperties(Fn, D);
13150b57cec5SDimitry Andric     }
13160b57cec5SDimitry Andric   }
1317e8d8bef9SDimitry Andric }
13180b57cec5SDimitry Andric 
13190b57cec5SDimitry Andric void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
13200b57cec5SDimitry Andric                                       const CXXRecordDecl *RD) {
13210b57cec5SDimitry Andric   Address This = getThisAddress(CGF);
132206c3fb27SDimitry Andric   This = This.withElementType(CGM.Int8Ty);
13230b57cec5SDimitry Andric   const ASTContext &Context = getContext();
13240b57cec5SDimitry Andric   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
13250b57cec5SDimitry Andric 
13260b57cec5SDimitry Andric   const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
13270b57cec5SDimitry Andric   for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
13280b57cec5SDimitry Andric     const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
13290b57cec5SDimitry Andric     llvm::GlobalVariable *GV = VBGlobals.Globals[I];
13300b57cec5SDimitry Andric     const ASTRecordLayout &SubobjectLayout =
13310b57cec5SDimitry Andric         Context.getASTRecordLayout(VBT->IntroducingObject);
13320b57cec5SDimitry Andric     CharUnits Offs = VBT->NonVirtualOffset;
13330b57cec5SDimitry Andric     Offs += SubobjectLayout.getVBPtrOffset();
13340b57cec5SDimitry Andric     if (VBT->getVBaseWithVPtr())
13350b57cec5SDimitry Andric       Offs += Layout.getVBaseClassOffset(VBT->getVBaseWithVPtr());
13360b57cec5SDimitry Andric     Address VBPtr = CGF.Builder.CreateConstInBoundsByteGEP(This, Offs);
13370b57cec5SDimitry Andric     llvm::Value *GVPtr =
13380b57cec5SDimitry Andric         CGF.Builder.CreateConstInBoundsGEP2_32(GV->getValueType(), GV, 0, 0);
133906c3fb27SDimitry Andric     VBPtr = VBPtr.withElementType(GVPtr->getType());
13400b57cec5SDimitry Andric     CGF.Builder.CreateStore(GVPtr, VBPtr);
13410b57cec5SDimitry Andric   }
13420b57cec5SDimitry Andric }
13430b57cec5SDimitry Andric 
13445ffd83dbSDimitry Andric CGCXXABI::AddedStructorArgCounts
13450b57cec5SDimitry Andric MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
13460b57cec5SDimitry Andric                                         SmallVectorImpl<CanQualType> &ArgTys) {
13475ffd83dbSDimitry Andric   AddedStructorArgCounts Added;
13480b57cec5SDimitry Andric   // TODO: 'for base' flag
13490b57cec5SDimitry Andric   if (isa<CXXDestructorDecl>(GD.getDecl()) &&
13500b57cec5SDimitry Andric       GD.getDtorType() == Dtor_Deleting) {
13510b57cec5SDimitry Andric     // The scalar deleting destructor takes an implicit int parameter.
13520b57cec5SDimitry Andric     ArgTys.push_back(getContext().IntTy);
13530b57cec5SDimitry Andric     ++Added.Suffix;
13540b57cec5SDimitry Andric   }
13550b57cec5SDimitry Andric   auto *CD = dyn_cast<CXXConstructorDecl>(GD.getDecl());
13560b57cec5SDimitry Andric   if (!CD)
13570b57cec5SDimitry Andric     return Added;
13580b57cec5SDimitry Andric 
13590b57cec5SDimitry Andric   // All parameters are already in place except is_most_derived, which goes
13600b57cec5SDimitry Andric   // after 'this' if it's variadic and last if it's not.
13610b57cec5SDimitry Andric 
13620b57cec5SDimitry Andric   const CXXRecordDecl *Class = CD->getParent();
13630b57cec5SDimitry Andric   const FunctionProtoType *FPT = CD->getType()->castAs<FunctionProtoType>();
13640b57cec5SDimitry Andric   if (Class->getNumVBases()) {
13650b57cec5SDimitry Andric     if (FPT->isVariadic()) {
13660b57cec5SDimitry Andric       ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
13670b57cec5SDimitry Andric       ++Added.Prefix;
13680b57cec5SDimitry Andric     } else {
13690b57cec5SDimitry Andric       ArgTys.push_back(getContext().IntTy);
13700b57cec5SDimitry Andric       ++Added.Suffix;
13710b57cec5SDimitry Andric     }
13720b57cec5SDimitry Andric   }
13730b57cec5SDimitry Andric 
13740b57cec5SDimitry Andric   return Added;
13750b57cec5SDimitry Andric }
13760b57cec5SDimitry Andric 
13770b57cec5SDimitry Andric void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
13780b57cec5SDimitry Andric                                                  const CXXDestructorDecl *Dtor,
13790b57cec5SDimitry Andric                                                  CXXDtorType DT) const {
13800b57cec5SDimitry Andric   // Deleting destructor variants are never imported or exported. Give them the
13810b57cec5SDimitry Andric   // default storage class.
13820b57cec5SDimitry Andric   if (DT == Dtor_Deleting) {
13830b57cec5SDimitry Andric     GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
13840b57cec5SDimitry Andric   } else {
13850b57cec5SDimitry Andric     const NamedDecl *ND = Dtor;
13860b57cec5SDimitry Andric     CGM.setDLLImportDLLExport(GV, ND);
13870b57cec5SDimitry Andric   }
13880b57cec5SDimitry Andric }
13890b57cec5SDimitry Andric 
13900b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
13910b57cec5SDimitry Andric     GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const {
13920b57cec5SDimitry Andric   // Internal things are always internal, regardless of attributes. After this,
13930b57cec5SDimitry Andric   // we know the thunk is externally visible.
13940b57cec5SDimitry Andric   if (Linkage == GVA_Internal)
13950b57cec5SDimitry Andric     return llvm::GlobalValue::InternalLinkage;
13960b57cec5SDimitry Andric 
13970b57cec5SDimitry Andric   switch (DT) {
13980b57cec5SDimitry Andric   case Dtor_Base:
13990b57cec5SDimitry Andric     // The base destructor most closely tracks the user-declared constructor, so
14000b57cec5SDimitry Andric     // we delegate back to the normal declarator case.
14018a4dda33SDimitry Andric     return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage);
14020b57cec5SDimitry Andric   case Dtor_Complete:
14030b57cec5SDimitry Andric     // The complete destructor is like an inline function, but it may be
14040b57cec5SDimitry Andric     // imported and therefore must be exported as well. This requires changing
14050b57cec5SDimitry Andric     // the linkage if a DLL attribute is present.
14060b57cec5SDimitry Andric     if (Dtor->hasAttr<DLLExportAttr>())
14070b57cec5SDimitry Andric       return llvm::GlobalValue::WeakODRLinkage;
14080b57cec5SDimitry Andric     if (Dtor->hasAttr<DLLImportAttr>())
14090b57cec5SDimitry Andric       return llvm::GlobalValue::AvailableExternallyLinkage;
14100b57cec5SDimitry Andric     return llvm::GlobalValue::LinkOnceODRLinkage;
14110b57cec5SDimitry Andric   case Dtor_Deleting:
14120b57cec5SDimitry Andric     // Deleting destructors are like inline functions. They have vague linkage
14130b57cec5SDimitry Andric     // and are emitted everywhere they are used. They are internal if the class
14140b57cec5SDimitry Andric     // is internal.
14150b57cec5SDimitry Andric     return llvm::GlobalValue::LinkOnceODRLinkage;
14160b57cec5SDimitry Andric   case Dtor_Comdat:
14170b57cec5SDimitry Andric     llvm_unreachable("MS C++ ABI does not support comdat dtors");
14180b57cec5SDimitry Andric   }
14190b57cec5SDimitry Andric   llvm_unreachable("invalid dtor type");
14200b57cec5SDimitry Andric }
14210b57cec5SDimitry Andric 
14220b57cec5SDimitry Andric void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
14230b57cec5SDimitry Andric   // The TU defining a dtor is only guaranteed to emit a base destructor.  All
14240b57cec5SDimitry Andric   // other destructor variants are delegating thunks.
14250b57cec5SDimitry Andric   CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));
1426480093f4SDimitry Andric 
1427480093f4SDimitry Andric   // If the class is dllexported, emit the complete (vbase) destructor wherever
1428480093f4SDimitry Andric   // the base dtor is emitted.
1429480093f4SDimitry Andric   // FIXME: To match MSVC, this should only be done when the class is exported
1430480093f4SDimitry Andric   // with -fdllexport-inlines enabled.
1431480093f4SDimitry Andric   if (D->getParent()->getNumVBases() > 0 && D->hasAttr<DLLExportAttr>())
1432480093f4SDimitry Andric     CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete));
14330b57cec5SDimitry Andric }
14340b57cec5SDimitry Andric 
14350b57cec5SDimitry Andric CharUnits
14360b57cec5SDimitry Andric MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
14370b57cec5SDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric   if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
14400b57cec5SDimitry Andric     // Complete destructors take a pointer to the complete object as a
14410b57cec5SDimitry Andric     // parameter, thus don't need this adjustment.
14420b57cec5SDimitry Andric     if (GD.getDtorType() == Dtor_Complete)
14430b57cec5SDimitry Andric       return CharUnits();
14440b57cec5SDimitry Andric 
14450b57cec5SDimitry Andric     // There's no Dtor_Base in vftable but it shares the this adjustment with
14460b57cec5SDimitry Andric     // the deleting one, so look it up instead.
14470b57cec5SDimitry Andric     GD = GlobalDecl(DD, Dtor_Deleting);
14480b57cec5SDimitry Andric   }
14490b57cec5SDimitry Andric 
14500b57cec5SDimitry Andric   MethodVFTableLocation ML =
14510b57cec5SDimitry Andric       CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
14520b57cec5SDimitry Andric   CharUnits Adjustment = ML.VFPtrOffset;
14530b57cec5SDimitry Andric 
14540b57cec5SDimitry Andric   // Normal virtual instance methods need to adjust from the vfptr that first
14550b57cec5SDimitry Andric   // defined the virtual method to the virtual base subobject, but destructors
14560b57cec5SDimitry Andric   // do not.  The vector deleting destructor thunk applies this adjustment for
14570b57cec5SDimitry Andric   // us if necessary.
14580b57cec5SDimitry Andric   if (isa<CXXDestructorDecl>(MD))
14590b57cec5SDimitry Andric     Adjustment = CharUnits::Zero();
14600b57cec5SDimitry Andric 
14610b57cec5SDimitry Andric   if (ML.VBase) {
14620b57cec5SDimitry Andric     const ASTRecordLayout &DerivedLayout =
14630b57cec5SDimitry Andric         getContext().getASTRecordLayout(MD->getParent());
14640b57cec5SDimitry Andric     Adjustment += DerivedLayout.getVBaseClassOffset(ML.VBase);
14650b57cec5SDimitry Andric   }
14660b57cec5SDimitry Andric 
14670b57cec5SDimitry Andric   return Adjustment;
14680b57cec5SDimitry Andric }
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
14710b57cec5SDimitry Andric     CodeGenFunction &CGF, GlobalDecl GD, Address This,
14720b57cec5SDimitry Andric     bool VirtualCall) {
14730b57cec5SDimitry Andric   if (!VirtualCall) {
14740b57cec5SDimitry Andric     // If the call of a virtual function is not virtual, we just have to
14750b57cec5SDimitry Andric     // compensate for the adjustment the virtual function does in its prologue.
14760b57cec5SDimitry Andric     CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
14770b57cec5SDimitry Andric     if (Adjustment.isZero())
14780b57cec5SDimitry Andric       return This;
14790b57cec5SDimitry Andric 
148006c3fb27SDimitry Andric     This = This.withElementType(CGF.Int8Ty);
14810b57cec5SDimitry Andric     assert(Adjustment.isPositive());
14820b57cec5SDimitry Andric     return CGF.Builder.CreateConstByteGEP(This, Adjustment);
14830b57cec5SDimitry Andric   }
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
14860b57cec5SDimitry Andric 
14870b57cec5SDimitry Andric   GlobalDecl LookupGD = GD;
14880b57cec5SDimitry Andric   if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
14890b57cec5SDimitry Andric     // Complete dtors take a pointer to the complete object,
14900b57cec5SDimitry Andric     // thus don't need adjustment.
14910b57cec5SDimitry Andric     if (GD.getDtorType() == Dtor_Complete)
14920b57cec5SDimitry Andric       return This;
14930b57cec5SDimitry Andric 
14940b57cec5SDimitry Andric     // There's only Dtor_Deleting in vftable but it shares the this adjustment
14950b57cec5SDimitry Andric     // with the base one, so look up the deleting one instead.
14960b57cec5SDimitry Andric     LookupGD = GlobalDecl(DD, Dtor_Deleting);
14970b57cec5SDimitry Andric   }
14980b57cec5SDimitry Andric   MethodVFTableLocation ML =
14990b57cec5SDimitry Andric       CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
15000b57cec5SDimitry Andric 
15010b57cec5SDimitry Andric   CharUnits StaticOffset = ML.VFPtrOffset;
15020b57cec5SDimitry Andric 
15030b57cec5SDimitry Andric   // Base destructors expect 'this' to point to the beginning of the base
15040b57cec5SDimitry Andric   // subobject, not the first vfptr that happens to contain the virtual dtor.
15050b57cec5SDimitry Andric   // However, we still need to apply the virtual base adjustment.
15060b57cec5SDimitry Andric   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
15070b57cec5SDimitry Andric     StaticOffset = CharUnits::Zero();
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric   Address Result = This;
15100b57cec5SDimitry Andric   if (ML.VBase) {
151106c3fb27SDimitry Andric     Result = Result.withElementType(CGF.Int8Ty);
15120b57cec5SDimitry Andric 
15130b57cec5SDimitry Andric     const CXXRecordDecl *Derived = MD->getParent();
15140b57cec5SDimitry Andric     const CXXRecordDecl *VBase = ML.VBase;
15150b57cec5SDimitry Andric     llvm::Value *VBaseOffset =
15160b57cec5SDimitry Andric       GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1517fe6060f1SDimitry Andric     llvm::Value *VBasePtr = CGF.Builder.CreateInBoundsGEP(
15180fca6ea1SDimitry Andric         Result.getElementType(), Result.emitRawPointer(CGF), VBaseOffset);
15190b57cec5SDimitry Andric     CharUnits VBaseAlign =
15200b57cec5SDimitry Andric       CGF.CGM.getVBaseAlignment(Result.getAlignment(), Derived, VBase);
152181ad6265SDimitry Andric     Result = Address(VBasePtr, CGF.Int8Ty, VBaseAlign);
15220b57cec5SDimitry Andric   }
15230b57cec5SDimitry Andric   if (!StaticOffset.isZero()) {
15240b57cec5SDimitry Andric     assert(StaticOffset.isPositive());
152506c3fb27SDimitry Andric     Result = Result.withElementType(CGF.Int8Ty);
15260b57cec5SDimitry Andric     if (ML.VBase) {
15270b57cec5SDimitry Andric       // Non-virtual adjustment might result in a pointer outside the allocated
15280b57cec5SDimitry Andric       // object, e.g. if the final overrider class is laid out after the virtual
15290b57cec5SDimitry Andric       // base that declares a method in the most derived class.
15300b57cec5SDimitry Andric       // FIXME: Update the code that emits this adjustment in thunks prologues.
15310b57cec5SDimitry Andric       Result = CGF.Builder.CreateConstByteGEP(Result, StaticOffset);
15320b57cec5SDimitry Andric     } else {
15330b57cec5SDimitry Andric       Result = CGF.Builder.CreateConstInBoundsByteGEP(Result, StaticOffset);
15340b57cec5SDimitry Andric     }
15350b57cec5SDimitry Andric   }
15360b57cec5SDimitry Andric   return Result;
15370b57cec5SDimitry Andric }
15380b57cec5SDimitry Andric 
15390b57cec5SDimitry Andric void MicrosoftCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
15400b57cec5SDimitry Andric                                                 QualType &ResTy,
15410b57cec5SDimitry Andric                                                 FunctionArgList &Params) {
15420b57cec5SDimitry Andric   ASTContext &Context = getContext();
15430b57cec5SDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
15440b57cec5SDimitry Andric   assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
15450b57cec5SDimitry Andric   if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
15460b57cec5SDimitry Andric     auto *IsMostDerived = ImplicitParamDecl::Create(
15470b57cec5SDimitry Andric         Context, /*DC=*/nullptr, CGF.CurGD.getDecl()->getLocation(),
15480b57cec5SDimitry Andric         &Context.Idents.get("is_most_derived"), Context.IntTy,
15495f757f3fSDimitry Andric         ImplicitParamKind::Other);
15500b57cec5SDimitry Andric     // The 'most_derived' parameter goes second if the ctor is variadic and last
15510b57cec5SDimitry Andric     // if it's not.  Dtors can't be variadic.
15520b57cec5SDimitry Andric     const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
15530b57cec5SDimitry Andric     if (FPT->isVariadic())
15540b57cec5SDimitry Andric       Params.insert(Params.begin() + 1, IsMostDerived);
15550b57cec5SDimitry Andric     else
15560b57cec5SDimitry Andric       Params.push_back(IsMostDerived);
15570b57cec5SDimitry Andric     getStructorImplicitParamDecl(CGF) = IsMostDerived;
15580b57cec5SDimitry Andric   } else if (isDeletingDtor(CGF.CurGD)) {
15590b57cec5SDimitry Andric     auto *ShouldDelete = ImplicitParamDecl::Create(
15600b57cec5SDimitry Andric         Context, /*DC=*/nullptr, CGF.CurGD.getDecl()->getLocation(),
15610b57cec5SDimitry Andric         &Context.Idents.get("should_call_delete"), Context.IntTy,
15625f757f3fSDimitry Andric         ImplicitParamKind::Other);
15630b57cec5SDimitry Andric     Params.push_back(ShouldDelete);
15640b57cec5SDimitry Andric     getStructorImplicitParamDecl(CGF) = ShouldDelete;
15650b57cec5SDimitry Andric   }
15660b57cec5SDimitry Andric }
15670b57cec5SDimitry Andric 
15680b57cec5SDimitry Andric void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
15690b57cec5SDimitry Andric   // Naked functions have no prolog.
15700b57cec5SDimitry Andric   if (CGF.CurFuncDecl && CGF.CurFuncDecl->hasAttr<NakedAttr>())
15710b57cec5SDimitry Andric     return;
15720b57cec5SDimitry Andric 
15730b57cec5SDimitry Andric   // Overridden virtual methods of non-primary bases need to adjust the incoming
15740b57cec5SDimitry Andric   // 'this' pointer in the prologue. In this hierarchy, C::b will subtract
15750b57cec5SDimitry Andric   // sizeof(void*) to adjust from B* to C*:
15760b57cec5SDimitry Andric   //   struct A { virtual void a(); };
15770b57cec5SDimitry Andric   //   struct B { virtual void b(); };
15780b57cec5SDimitry Andric   //   struct C : A, B { virtual void b(); };
15790b57cec5SDimitry Andric   //
15800b57cec5SDimitry Andric   // Leave the value stored in the 'this' alloca unadjusted, so that the
15810b57cec5SDimitry Andric   // debugger sees the unadjusted value. Microsoft debuggers require this, and
15820b57cec5SDimitry Andric   // will apply the ThisAdjustment in the method type information.
15830b57cec5SDimitry Andric   // FIXME: Do something better for DWARF debuggers, which won't expect this,
15840b57cec5SDimitry Andric   // without making our codegen depend on debug info settings.
15850b57cec5SDimitry Andric   llvm::Value *This = loadIncomingCXXThis(CGF);
15860b57cec5SDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
15870b57cec5SDimitry Andric   if (!CGF.CurFuncIsThunk && MD->isVirtual()) {
15880b57cec5SDimitry Andric     CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.CurGD);
15890b57cec5SDimitry Andric     if (!Adjustment.isZero()) {
15900b57cec5SDimitry Andric       assert(Adjustment.isPositive());
15910b57cec5SDimitry Andric       This = CGF.Builder.CreateConstInBoundsGEP1_32(CGF.Int8Ty, This,
15920b57cec5SDimitry Andric                                                     -Adjustment.getQuantity());
15930b57cec5SDimitry Andric     }
15940b57cec5SDimitry Andric   }
15950b57cec5SDimitry Andric   setCXXABIThisValue(CGF, This);
15960b57cec5SDimitry Andric 
15970b57cec5SDimitry Andric   // If this is a function that the ABI specifies returns 'this', initialize
15980b57cec5SDimitry Andric   // the return slot to 'this' at the start of the function.
15990b57cec5SDimitry Andric   //
16000b57cec5SDimitry Andric   // Unlike the setting of return types, this is done within the ABI
16010b57cec5SDimitry Andric   // implementation instead of by clients of CGCXXABI because:
16020b57cec5SDimitry Andric   // 1) getThisValue is currently protected
16030b57cec5SDimitry Andric   // 2) in theory, an ABI could implement 'this' returns some other way;
16040b57cec5SDimitry Andric   //    HasThisReturn only specifies a contract, not the implementation
160506c3fb27SDimitry Andric   if (HasThisReturn(CGF.CurGD) || hasMostDerivedReturn(CGF.CurGD))
16060b57cec5SDimitry Andric     CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
16070b57cec5SDimitry Andric 
16080b57cec5SDimitry Andric   if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
16090b57cec5SDimitry Andric     assert(getStructorImplicitParamDecl(CGF) &&
16100b57cec5SDimitry Andric            "no implicit parameter for a constructor with virtual bases?");
16110b57cec5SDimitry Andric     getStructorImplicitParamValue(CGF)
16120b57cec5SDimitry Andric       = CGF.Builder.CreateLoad(
16130b57cec5SDimitry Andric           CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
16140b57cec5SDimitry Andric           "is_most_derived");
16150b57cec5SDimitry Andric   }
16160b57cec5SDimitry Andric 
16170b57cec5SDimitry Andric   if (isDeletingDtor(CGF.CurGD)) {
16180b57cec5SDimitry Andric     assert(getStructorImplicitParamDecl(CGF) &&
16190b57cec5SDimitry Andric            "no implicit parameter for a deleting destructor?");
16200b57cec5SDimitry Andric     getStructorImplicitParamValue(CGF)
16210b57cec5SDimitry Andric       = CGF.Builder.CreateLoad(
16220b57cec5SDimitry Andric           CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
16230b57cec5SDimitry Andric           "should_call_delete");
16240b57cec5SDimitry Andric   }
16250b57cec5SDimitry Andric }
16260b57cec5SDimitry Andric 
16275ffd83dbSDimitry Andric CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs(
16280b57cec5SDimitry Andric     CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
16295ffd83dbSDimitry Andric     bool ForVirtualBase, bool Delegating) {
16300b57cec5SDimitry Andric   assert(Type == Ctor_Complete || Type == Ctor_Base);
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric   // Check if we need a 'most_derived' parameter.
16330b57cec5SDimitry Andric   if (!D->getParent()->getNumVBases())
16340b57cec5SDimitry Andric     return AddedStructorArgs{};
16350b57cec5SDimitry Andric 
16360b57cec5SDimitry Andric   // Add the 'most_derived' argument second if we are variadic or last if not.
16370b57cec5SDimitry Andric   const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
16380b57cec5SDimitry Andric   llvm::Value *MostDerivedArg;
16390b57cec5SDimitry Andric   if (Delegating) {
16400b57cec5SDimitry Andric     MostDerivedArg = getStructorImplicitParamValue(CGF);
16410b57cec5SDimitry Andric   } else {
16420b57cec5SDimitry Andric     MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
16430b57cec5SDimitry Andric   }
16440b57cec5SDimitry Andric   if (FPT->isVariadic()) {
16455ffd83dbSDimitry Andric     return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
16460b57cec5SDimitry Andric   }
16475ffd83dbSDimitry Andric   return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
16485ffd83dbSDimitry Andric }
16495ffd83dbSDimitry Andric 
16505ffd83dbSDimitry Andric llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
16515ffd83dbSDimitry Andric     CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type,
16525ffd83dbSDimitry Andric     bool ForVirtualBase, bool Delegating) {
16535ffd83dbSDimitry Andric   return nullptr;
16540b57cec5SDimitry Andric }
16550b57cec5SDimitry Andric 
16560b57cec5SDimitry Andric void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
16570b57cec5SDimitry Andric                                          const CXXDestructorDecl *DD,
16580b57cec5SDimitry Andric                                          CXXDtorType Type, bool ForVirtualBase,
16590b57cec5SDimitry Andric                                          bool Delegating, Address This,
16600b57cec5SDimitry Andric                                          QualType ThisTy) {
16610b57cec5SDimitry Andric   // Use the base destructor variant in place of the complete destructor variant
16620b57cec5SDimitry Andric   // if the class has no virtual bases. This effectively implements some of the
16630b57cec5SDimitry Andric   // -mconstructor-aliases optimization, but as part of the MS C++ ABI.
16640b57cec5SDimitry Andric   if (Type == Dtor_Complete && DD->getParent()->getNumVBases() == 0)
16650b57cec5SDimitry Andric     Type = Dtor_Base;
16660b57cec5SDimitry Andric 
16670b57cec5SDimitry Andric   GlobalDecl GD(DD, Type);
16680b57cec5SDimitry Andric   CGCallee Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD);
16690b57cec5SDimitry Andric 
16700b57cec5SDimitry Andric   if (DD->isVirtual()) {
16710b57cec5SDimitry Andric     assert(Type != CXXDtorType::Dtor_Deleting &&
16720b57cec5SDimitry Andric            "The deleting destructor should only be called via a virtual call");
16730b57cec5SDimitry Andric     This = adjustThisArgumentForVirtualFunctionCall(CGF, GlobalDecl(DD, Type),
16740b57cec5SDimitry Andric                                                     This, false);
16750b57cec5SDimitry Andric   }
16760b57cec5SDimitry Andric 
16770b57cec5SDimitry Andric   llvm::BasicBlock *BaseDtorEndBB = nullptr;
16780b57cec5SDimitry Andric   if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.CurCodeDecl)) {
16790b57cec5SDimitry Andric     BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
16800b57cec5SDimitry Andric   }
16810b57cec5SDimitry Andric 
16825ffd83dbSDimitry Andric   llvm::Value *Implicit =
16835ffd83dbSDimitry Andric       getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase,
16845ffd83dbSDimitry Andric                                     Delegating); // = nullptr
16850fca6ea1SDimitry Andric   CGF.EmitCXXDestructorCall(GD, Callee, CGF.getAsNaturalPointerTo(This, ThisTy),
16860fca6ea1SDimitry Andric                             ThisTy,
16875ffd83dbSDimitry Andric                             /*ImplicitParam=*/Implicit,
16880b57cec5SDimitry Andric                             /*ImplicitParamTy=*/QualType(), nullptr);
16890b57cec5SDimitry Andric   if (BaseDtorEndBB) {
16900b57cec5SDimitry Andric     // Complete object handler should continue to be the remaining
16910b57cec5SDimitry Andric     CGF.Builder.CreateBr(BaseDtorEndBB);
16920b57cec5SDimitry Andric     CGF.EmitBlock(BaseDtorEndBB);
16930b57cec5SDimitry Andric   }
16940b57cec5SDimitry Andric }
16950b57cec5SDimitry Andric 
16960b57cec5SDimitry Andric void MicrosoftCXXABI::emitVTableTypeMetadata(const VPtrInfo &Info,
16970b57cec5SDimitry Andric                                              const CXXRecordDecl *RD,
16980b57cec5SDimitry Andric                                              llvm::GlobalVariable *VTable) {
16995f757f3fSDimitry Andric   // Emit type metadata on vtables with LTO or IR instrumentation.
17005f757f3fSDimitry Andric   // In IR instrumentation, the type metadata could be used to find out vtable
17015f757f3fSDimitry Andric   // definitions (for type profiling) among all global variables.
17025f757f3fSDimitry Andric   if (!CGM.getCodeGenOpts().LTOUnit &&
17035f757f3fSDimitry Andric       !CGM.getCodeGenOpts().hasProfileIRInstr())
17040b57cec5SDimitry Andric     return;
17050b57cec5SDimitry Andric 
17065ffd83dbSDimitry Andric   // TODO: Should VirtualFunctionElimination also be supported here?
17075ffd83dbSDimitry Andric   // See similar handling in CodeGenModule::EmitVTableTypeMetadata.
17085ffd83dbSDimitry Andric   if (CGM.getCodeGenOpts().WholeProgramVTables) {
1709e8d8bef9SDimitry Andric     llvm::DenseSet<const CXXRecordDecl *> Visited;
17105ffd83dbSDimitry Andric     llvm::GlobalObject::VCallVisibility TypeVis =
1711e8d8bef9SDimitry Andric         CGM.GetVCallVisibilityLevel(RD, Visited);
17125ffd83dbSDimitry Andric     if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
17135ffd83dbSDimitry Andric       VTable->setVCallVisibilityMetadata(TypeVis);
17145ffd83dbSDimitry Andric   }
17155ffd83dbSDimitry Andric 
17160b57cec5SDimitry Andric   // The location of the first virtual function pointer in the virtual table,
17170b57cec5SDimitry Andric   // aka the "address point" on Itanium. This is at offset 0 if RTTI is
17180b57cec5SDimitry Andric   // disabled, or sizeof(void*) if RTTI is enabled.
17190b57cec5SDimitry Andric   CharUnits AddressPoint =
17200b57cec5SDimitry Andric       getContext().getLangOpts().RTTIData
17210b57cec5SDimitry Andric           ? getContext().toCharUnitsFromBits(
1722bdd1243dSDimitry Andric                 getContext().getTargetInfo().getPointerWidth(LangAS::Default))
17230b57cec5SDimitry Andric           : CharUnits::Zero();
17240b57cec5SDimitry Andric 
17250b57cec5SDimitry Andric   if (Info.PathToIntroducingObject.empty()) {
17260b57cec5SDimitry Andric     CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
17270b57cec5SDimitry Andric     return;
17280b57cec5SDimitry Andric   }
17290b57cec5SDimitry Andric 
17300b57cec5SDimitry Andric   // Add a bitset entry for the least derived base belonging to this vftable.
17310b57cec5SDimitry Andric   CGM.AddVTableTypeMetadata(VTable, AddressPoint,
17320b57cec5SDimitry Andric                             Info.PathToIntroducingObject.back());
17330b57cec5SDimitry Andric 
17340b57cec5SDimitry Andric   // Add a bitset entry for each derived class that is laid out at the same
17350b57cec5SDimitry Andric   // offset as the least derived base.
17360b57cec5SDimitry Andric   for (unsigned I = Info.PathToIntroducingObject.size() - 1; I != 0; --I) {
17370b57cec5SDimitry Andric     const CXXRecordDecl *DerivedRD = Info.PathToIntroducingObject[I - 1];
17380b57cec5SDimitry Andric     const CXXRecordDecl *BaseRD = Info.PathToIntroducingObject[I];
17390b57cec5SDimitry Andric 
17400b57cec5SDimitry Andric     const ASTRecordLayout &Layout =
17410b57cec5SDimitry Andric         getContext().getASTRecordLayout(DerivedRD);
17420b57cec5SDimitry Andric     CharUnits Offset;
17430b57cec5SDimitry Andric     auto VBI = Layout.getVBaseOffsetsMap().find(BaseRD);
17440b57cec5SDimitry Andric     if (VBI == Layout.getVBaseOffsetsMap().end())
17450b57cec5SDimitry Andric       Offset = Layout.getBaseClassOffset(BaseRD);
17460b57cec5SDimitry Andric     else
17470b57cec5SDimitry Andric       Offset = VBI->second.VBaseOffset;
17480b57cec5SDimitry Andric     if (!Offset.isZero())
17490b57cec5SDimitry Andric       return;
17500b57cec5SDimitry Andric     CGM.AddVTableTypeMetadata(VTable, AddressPoint, DerivedRD);
17510b57cec5SDimitry Andric   }
17520b57cec5SDimitry Andric 
17530b57cec5SDimitry Andric   // Finally do the same for the most derived class.
17540b57cec5SDimitry Andric   if (Info.FullOffsetInMDC.isZero())
17550b57cec5SDimitry Andric     CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
17560b57cec5SDimitry Andric }
17570b57cec5SDimitry Andric 
17580b57cec5SDimitry Andric void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
17590b57cec5SDimitry Andric                                             const CXXRecordDecl *RD) {
17600b57cec5SDimitry Andric   MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
17610b57cec5SDimitry Andric   const VPtrInfoVector &VFPtrs = VFTContext.getVFPtrOffsets(RD);
17620b57cec5SDimitry Andric 
17630b57cec5SDimitry Andric   for (const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
17640b57cec5SDimitry Andric     llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->FullOffsetInMDC);
17650b57cec5SDimitry Andric     if (VTable->hasInitializer())
17660b57cec5SDimitry Andric       continue;
17670b57cec5SDimitry Andric 
17680b57cec5SDimitry Andric     const VTableLayout &VTLayout =
17690b57cec5SDimitry Andric       VFTContext.getVFTableLayout(RD, Info->FullOffsetInMDC);
17700b57cec5SDimitry Andric 
17710b57cec5SDimitry Andric     llvm::Constant *RTTI = nullptr;
17720b57cec5SDimitry Andric     if (any_of(VTLayout.vtable_components(),
17730b57cec5SDimitry Andric                [](const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
17740b57cec5SDimitry Andric       RTTI = getMSCompleteObjectLocator(RD, *Info);
17750b57cec5SDimitry Andric 
17765ffd83dbSDimitry Andric     ConstantInitBuilder builder(CGM);
17775ffd83dbSDimitry Andric     auto components = builder.beginStruct();
17785ffd83dbSDimitry Andric     CGVT.createVTableInitializer(components, VTLayout, RTTI,
17795ffd83dbSDimitry Andric                                  VTable->hasLocalLinkage());
17805ffd83dbSDimitry Andric     components.finishAndSetAsInitializer(VTable);
17810b57cec5SDimitry Andric 
17820b57cec5SDimitry Andric     emitVTableTypeMetadata(*Info, RD, VTable);
17830b57cec5SDimitry Andric   }
17840b57cec5SDimitry Andric }
17850b57cec5SDimitry Andric 
17860b57cec5SDimitry Andric bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
17870b57cec5SDimitry Andric     CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
17880b57cec5SDimitry Andric   return Vptr.NearestVBase != nullptr;
17890b57cec5SDimitry Andric }
17900b57cec5SDimitry Andric 
17910b57cec5SDimitry Andric llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
17920b57cec5SDimitry Andric     CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
17930b57cec5SDimitry Andric     const CXXRecordDecl *NearestVBase) {
17940b57cec5SDimitry Andric   llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
17950b57cec5SDimitry Andric   if (!VTableAddressPoint) {
17960b57cec5SDimitry Andric     assert(Base.getBase()->getNumVBases() &&
17970b57cec5SDimitry Andric            !getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr());
17980b57cec5SDimitry Andric   }
17990b57cec5SDimitry Andric   return VTableAddressPoint;
18000b57cec5SDimitry Andric }
18010b57cec5SDimitry Andric 
18020b57cec5SDimitry Andric static void mangleVFTableName(MicrosoftMangleContext &MangleContext,
18030b57cec5SDimitry Andric                               const CXXRecordDecl *RD, const VPtrInfo &VFPtr,
18040b57cec5SDimitry Andric                               SmallString<256> &Name) {
18050b57cec5SDimitry Andric   llvm::raw_svector_ostream Out(Name);
18060b57cec5SDimitry Andric   MangleContext.mangleCXXVFTable(RD, VFPtr.MangledPath, Out);
18070b57cec5SDimitry Andric }
18080b57cec5SDimitry Andric 
18090b57cec5SDimitry Andric llvm::Constant *
18100b57cec5SDimitry Andric MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base,
18110b57cec5SDimitry Andric                                        const CXXRecordDecl *VTableClass) {
18120b57cec5SDimitry Andric   (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
18130b57cec5SDimitry Andric   VFTableIdTy ID(VTableClass, Base.getBaseOffset());
18140b57cec5SDimitry Andric   return VFTablesMap[ID];
18150b57cec5SDimitry Andric }
18160b57cec5SDimitry Andric 
18170b57cec5SDimitry Andric llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
18180b57cec5SDimitry Andric                                                        CharUnits VPtrOffset) {
18190b57cec5SDimitry Andric   // getAddrOfVTable may return 0 if asked to get an address of a vtable which
18200b57cec5SDimitry Andric   // shouldn't be used in the given record type. We want to cache this result in
18210b57cec5SDimitry Andric   // VFTablesMap, thus a simple zero check is not sufficient.
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric   VFTableIdTy ID(RD, VPtrOffset);
18240b57cec5SDimitry Andric   VTablesMapTy::iterator I;
18250b57cec5SDimitry Andric   bool Inserted;
18260b57cec5SDimitry Andric   std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID, nullptr));
18270b57cec5SDimitry Andric   if (!Inserted)
18280b57cec5SDimitry Andric     return I->second;
18290b57cec5SDimitry Andric 
18300b57cec5SDimitry Andric   llvm::GlobalVariable *&VTable = I->second;
18310b57cec5SDimitry Andric 
18320b57cec5SDimitry Andric   MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
18330b57cec5SDimitry Andric   const VPtrInfoVector &VFPtrs = VTContext.getVFPtrOffsets(RD);
18340b57cec5SDimitry Andric 
18350b57cec5SDimitry Andric   if (DeferredVFTables.insert(RD).second) {
18360b57cec5SDimitry Andric     // We haven't processed this record type before.
18370b57cec5SDimitry Andric     // Queue up this vtable for possible deferred emission.
18380b57cec5SDimitry Andric     CGM.addDeferredVTable(RD);
18390b57cec5SDimitry Andric 
18400b57cec5SDimitry Andric #ifndef NDEBUG
18410b57cec5SDimitry Andric     // Create all the vftables at once in order to make sure each vftable has
18420b57cec5SDimitry Andric     // a unique mangled name.
18430b57cec5SDimitry Andric     llvm::StringSet<> ObservedMangledNames;
18440b57cec5SDimitry Andric     for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
18450b57cec5SDimitry Andric       SmallString<256> Name;
18460b57cec5SDimitry Andric       mangleVFTableName(getMangleContext(), RD, *VFPtrs[J], Name);
18470b57cec5SDimitry Andric       if (!ObservedMangledNames.insert(Name.str()).second)
18480b57cec5SDimitry Andric         llvm_unreachable("Already saw this mangling before?");
18490b57cec5SDimitry Andric     }
18500b57cec5SDimitry Andric #endif
18510b57cec5SDimitry Andric   }
18520b57cec5SDimitry Andric 
1853349cc55cSDimitry Andric   const std::unique_ptr<VPtrInfo> *VFPtrI =
1854349cc55cSDimitry Andric       llvm::find_if(VFPtrs, [&](const std::unique_ptr<VPtrInfo> &VPI) {
18550b57cec5SDimitry Andric         return VPI->FullOffsetInMDC == VPtrOffset;
18560b57cec5SDimitry Andric       });
18570b57cec5SDimitry Andric   if (VFPtrI == VFPtrs.end()) {
18580b57cec5SDimitry Andric     VFTablesMap[ID] = nullptr;
18590b57cec5SDimitry Andric     return nullptr;
18600b57cec5SDimitry Andric   }
18610b57cec5SDimitry Andric   const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
18620b57cec5SDimitry Andric 
18630b57cec5SDimitry Andric   SmallString<256> VFTableName;
18640b57cec5SDimitry Andric   mangleVFTableName(getMangleContext(), RD, *VFPtr, VFTableName);
18650b57cec5SDimitry Andric 
18660b57cec5SDimitry Andric   // Classes marked __declspec(dllimport) need vftables generated on the
18670b57cec5SDimitry Andric   // import-side in order to support features like constexpr.  No other
18680b57cec5SDimitry Andric   // translation unit relies on the emission of the local vftable, translation
18690b57cec5SDimitry Andric   // units are expected to generate them as needed.
18700b57cec5SDimitry Andric   //
18710b57cec5SDimitry Andric   // Because of this unique behavior, we maintain this logic here instead of
18720b57cec5SDimitry Andric   // getVTableLinkage.
18730b57cec5SDimitry Andric   llvm::GlobalValue::LinkageTypes VFTableLinkage =
18740b57cec5SDimitry Andric       RD->hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
18750b57cec5SDimitry Andric                                    : CGM.getVTableLinkage(RD);
18760b57cec5SDimitry Andric   bool VFTableComesFromAnotherTU =
18770b57cec5SDimitry Andric       llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
18780b57cec5SDimitry Andric       llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
18790b57cec5SDimitry Andric   bool VTableAliasIsRequred =
18800b57cec5SDimitry Andric       !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
18810b57cec5SDimitry Andric 
18820b57cec5SDimitry Andric   if (llvm::GlobalValue *VFTable =
18830b57cec5SDimitry Andric           CGM.getModule().getNamedGlobal(VFTableName)) {
18840b57cec5SDimitry Andric     VFTablesMap[ID] = VFTable;
18850b57cec5SDimitry Andric     VTable = VTableAliasIsRequred
18860b57cec5SDimitry Andric                  ? cast<llvm::GlobalVariable>(
1887349cc55cSDimitry Andric                        cast<llvm::GlobalAlias>(VFTable)->getAliaseeObject())
18880b57cec5SDimitry Andric                  : cast<llvm::GlobalVariable>(VFTable);
18890b57cec5SDimitry Andric     return VTable;
18900b57cec5SDimitry Andric   }
18910b57cec5SDimitry Andric 
18920b57cec5SDimitry Andric   const VTableLayout &VTLayout =
18930b57cec5SDimitry Andric       VTContext.getVFTableLayout(RD, VFPtr->FullOffsetInMDC);
18940b57cec5SDimitry Andric   llvm::GlobalValue::LinkageTypes VTableLinkage =
18950b57cec5SDimitry Andric       VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
18960b57cec5SDimitry Andric 
18970b57cec5SDimitry Andric   StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
18980b57cec5SDimitry Andric 
18990b57cec5SDimitry Andric   llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
19000b57cec5SDimitry Andric 
19010b57cec5SDimitry Andric   // Create a backing variable for the contents of VTable.  The VTable may
19020b57cec5SDimitry Andric   // or may not include space for a pointer to RTTI data.
19030b57cec5SDimitry Andric   llvm::GlobalValue *VFTable;
19040b57cec5SDimitry Andric   VTable = new llvm::GlobalVariable(CGM.getModule(), VTableType,
19050b57cec5SDimitry Andric                                     /*isConstant=*/true, VTableLinkage,
19060b57cec5SDimitry Andric                                     /*Initializer=*/nullptr, VTableName);
19070b57cec5SDimitry Andric   VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
19080b57cec5SDimitry Andric 
19090b57cec5SDimitry Andric   llvm::Comdat *C = nullptr;
19100b57cec5SDimitry Andric   if (!VFTableComesFromAnotherTU &&
19115f757f3fSDimitry Andric       llvm::GlobalValue::isWeakForLinker(VFTableLinkage))
19120b57cec5SDimitry Andric     C = CGM.getModule().getOrInsertComdat(VFTableName.str());
19130b57cec5SDimitry Andric 
19140b57cec5SDimitry Andric   // Only insert a pointer into the VFTable for RTTI data if we are not
19150b57cec5SDimitry Andric   // importing it.  We never reference the RTTI data directly so there is no
19160b57cec5SDimitry Andric   // need to make room for it.
19170b57cec5SDimitry Andric   if (VTableAliasIsRequred) {
19180b57cec5SDimitry Andric     llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.Int32Ty, 0),
19190b57cec5SDimitry Andric                                  llvm::ConstantInt::get(CGM.Int32Ty, 0),
19200b57cec5SDimitry Andric                                  llvm::ConstantInt::get(CGM.Int32Ty, 1)};
19210b57cec5SDimitry Andric     // Create a GEP which points just after the first entry in the VFTable,
19220b57cec5SDimitry Andric     // this should be the location of the first virtual method.
19230b57cec5SDimitry Andric     llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
19240b57cec5SDimitry Andric         VTable->getValueType(), VTable, GEPIndices);
19250b57cec5SDimitry Andric     if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
19260b57cec5SDimitry Andric       VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
19270b57cec5SDimitry Andric       if (C)
19280b57cec5SDimitry Andric         C->setSelectionKind(llvm::Comdat::Largest);
19290b57cec5SDimitry Andric     }
19300b57cec5SDimitry Andric     VFTable = llvm::GlobalAlias::create(CGM.Int8PtrTy,
19310b57cec5SDimitry Andric                                         /*AddressSpace=*/0, VFTableLinkage,
19320b57cec5SDimitry Andric                                         VFTableName.str(), VTableGEP,
19330b57cec5SDimitry Andric                                         &CGM.getModule());
19340b57cec5SDimitry Andric     VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
19350b57cec5SDimitry Andric   } else {
19360b57cec5SDimitry Andric     // We don't need a GlobalAlias to be a symbol for the VTable if we won't
19370b57cec5SDimitry Andric     // be referencing any RTTI data.
19380b57cec5SDimitry Andric     // The GlobalVariable will end up being an appropriate definition of the
19390b57cec5SDimitry Andric     // VFTable.
19400b57cec5SDimitry Andric     VFTable = VTable;
19410b57cec5SDimitry Andric   }
19420b57cec5SDimitry Andric   if (C)
19430b57cec5SDimitry Andric     VTable->setComdat(C);
19440b57cec5SDimitry Andric 
19450b57cec5SDimitry Andric   if (RD->hasAttr<DLLExportAttr>())
19460b57cec5SDimitry Andric     VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
19470b57cec5SDimitry Andric 
19480b57cec5SDimitry Andric   VFTablesMap[ID] = VFTable;
19490b57cec5SDimitry Andric   return VTable;
19500b57cec5SDimitry Andric }
19510b57cec5SDimitry Andric 
19520b57cec5SDimitry Andric CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
19530b57cec5SDimitry Andric                                                     GlobalDecl GD,
19540b57cec5SDimitry Andric                                                     Address This,
19550b57cec5SDimitry Andric                                                     llvm::Type *Ty,
19560b57cec5SDimitry Andric                                                     SourceLocation Loc) {
19570b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
19580b57cec5SDimitry Andric 
1959fe6060f1SDimitry Andric   Ty = Ty->getPointerTo();
19600b57cec5SDimitry Andric   Address VPtr =
19610b57cec5SDimitry Andric       adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
19620b57cec5SDimitry Andric 
19630b57cec5SDimitry Andric   auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl());
1964fe6060f1SDimitry Andric   llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty->getPointerTo(),
1965fe6060f1SDimitry Andric                                          MethodDecl->getParent());
19660b57cec5SDimitry Andric 
19670b57cec5SDimitry Andric   MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
19680b57cec5SDimitry Andric   MethodVFTableLocation ML = VFTContext.getMethodVFTableLocation(GD);
19690b57cec5SDimitry Andric 
19700b57cec5SDimitry Andric   // Compute the identity of the most derived class whose virtual table is
19710b57cec5SDimitry Andric   // located at the MethodVFTableLocation ML.
19720b57cec5SDimitry Andric   auto getObjectWithVPtr = [&] {
19730b57cec5SDimitry Andric     return llvm::find_if(VFTContext.getVFPtrOffsets(
19740b57cec5SDimitry Andric                              ML.VBase ? ML.VBase : MethodDecl->getParent()),
19750b57cec5SDimitry Andric                          [&](const std::unique_ptr<VPtrInfo> &Info) {
19760b57cec5SDimitry Andric                            return Info->FullOffsetInMDC == ML.VFPtrOffset;
19770b57cec5SDimitry Andric                          })
19780b57cec5SDimitry Andric         ->get()
19790b57cec5SDimitry Andric         ->ObjectWithVPtr;
19800b57cec5SDimitry Andric   };
19810b57cec5SDimitry Andric 
19820b57cec5SDimitry Andric   llvm::Value *VFunc;
19830b57cec5SDimitry Andric   if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) {
19840b57cec5SDimitry Andric     VFunc = CGF.EmitVTableTypeCheckedLoad(
198581ad6265SDimitry Andric         getObjectWithVPtr(), VTable, Ty,
1986bdd1243dSDimitry Andric         ML.Index *
1987bdd1243dSDimitry Andric             CGM.getContext().getTargetInfo().getPointerWidth(LangAS::Default) /
1988bdd1243dSDimitry Andric             8);
19890b57cec5SDimitry Andric   } else {
19900b57cec5SDimitry Andric     if (CGM.getCodeGenOpts().PrepareForLTO)
19910b57cec5SDimitry Andric       CGF.EmitTypeMetadataCodeForVCall(getObjectWithVPtr(), VTable, Loc);
19920b57cec5SDimitry Andric 
19930b57cec5SDimitry Andric     llvm::Value *VFuncPtr =
1994fe6060f1SDimitry Andric         Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.Index, "vfn");
1995fe6060f1SDimitry Andric     VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.getPointerAlign());
19960b57cec5SDimitry Andric   }
19970b57cec5SDimitry Andric 
19980b57cec5SDimitry Andric   CGCallee Callee(GD, VFunc);
19990b57cec5SDimitry Andric   return Callee;
20000b57cec5SDimitry Andric }
20010b57cec5SDimitry Andric 
20020b57cec5SDimitry Andric llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
20030b57cec5SDimitry Andric     CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,
20040b57cec5SDimitry Andric     Address This, DeleteOrMemberCallExpr E) {
20050b57cec5SDimitry Andric   auto *CE = E.dyn_cast<const CXXMemberCallExpr *>();
20060b57cec5SDimitry Andric   auto *D = E.dyn_cast<const CXXDeleteExpr *>();
20070b57cec5SDimitry Andric   assert((CE != nullptr) ^ (D != nullptr));
20080b57cec5SDimitry Andric   assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
20090b57cec5SDimitry Andric   assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
20100b57cec5SDimitry Andric 
20110b57cec5SDimitry Andric   // We have only one destructor in the vftable but can get both behaviors
20120b57cec5SDimitry Andric   // by passing an implicit int parameter.
20130b57cec5SDimitry Andric   GlobalDecl GD(Dtor, Dtor_Deleting);
20140b57cec5SDimitry Andric   const CGFunctionInfo *FInfo =
20150b57cec5SDimitry Andric       &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
20160b57cec5SDimitry Andric   llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
20170b57cec5SDimitry Andric   CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
20180b57cec5SDimitry Andric 
20190b57cec5SDimitry Andric   ASTContext &Context = getContext();
20200b57cec5SDimitry Andric   llvm::Value *ImplicitParam = llvm::ConstantInt::get(
20210b57cec5SDimitry Andric       llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()),
20220b57cec5SDimitry Andric       DtorType == Dtor_Deleting);
20230b57cec5SDimitry Andric 
20240b57cec5SDimitry Andric   QualType ThisTy;
20250b57cec5SDimitry Andric   if (CE) {
20260b57cec5SDimitry Andric     ThisTy = CE->getObjectType();
20270b57cec5SDimitry Andric   } else {
20280b57cec5SDimitry Andric     ThisTy = D->getDestroyedType();
20290b57cec5SDimitry Andric   }
20300b57cec5SDimitry Andric 
20310b57cec5SDimitry Andric   This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
20320fca6ea1SDimitry Andric   RValue RV =
20330fca6ea1SDimitry Andric       CGF.EmitCXXDestructorCall(GD, Callee, This.emitRawPointer(CGF), ThisTy,
20340b57cec5SDimitry Andric                                 ImplicitParam, Context.IntTy, CE);
20350b57cec5SDimitry Andric   return RV.getScalarVal();
20360b57cec5SDimitry Andric }
20370b57cec5SDimitry Andric 
20380b57cec5SDimitry Andric const VBTableGlobals &
20390b57cec5SDimitry Andric MicrosoftCXXABI::enumerateVBTables(const CXXRecordDecl *RD) {
20400b57cec5SDimitry Andric   // At this layer, we can key the cache off of a single class, which is much
20410b57cec5SDimitry Andric   // easier than caching each vbtable individually.
20420b57cec5SDimitry Andric   llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
20430b57cec5SDimitry Andric   bool Added;
20440b57cec5SDimitry Andric   std::tie(Entry, Added) =
20450b57cec5SDimitry Andric       VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
20460b57cec5SDimitry Andric   VBTableGlobals &VBGlobals = Entry->second;
20470b57cec5SDimitry Andric   if (!Added)
20480b57cec5SDimitry Andric     return VBGlobals;
20490b57cec5SDimitry Andric 
20500b57cec5SDimitry Andric   MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
20510b57cec5SDimitry Andric   VBGlobals.VBTables = &Context.enumerateVBTables(RD);
20520b57cec5SDimitry Andric 
20530b57cec5SDimitry Andric   // Cache the globals for all vbtables so we don't have to recompute the
20540b57cec5SDimitry Andric   // mangled names.
20550b57cec5SDimitry Andric   llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
20560b57cec5SDimitry Andric   for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
20570b57cec5SDimitry Andric                                       E = VBGlobals.VBTables->end();
20580b57cec5SDimitry Andric        I != E; ++I) {
20590b57cec5SDimitry Andric     VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
20600b57cec5SDimitry Andric   }
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric   return VBGlobals;
20630b57cec5SDimitry Andric }
20640b57cec5SDimitry Andric 
20650b57cec5SDimitry Andric llvm::Function *
20660b57cec5SDimitry Andric MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
20670b57cec5SDimitry Andric                                         const MethodVFTableLocation &ML) {
20680b57cec5SDimitry Andric   assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
20690b57cec5SDimitry Andric          "can't form pointers to ctors or virtual dtors");
20700b57cec5SDimitry Andric 
20710b57cec5SDimitry Andric   // Calculate the mangled name.
20720b57cec5SDimitry Andric   SmallString<256> ThunkName;
20730b57cec5SDimitry Andric   llvm::raw_svector_ostream Out(ThunkName);
20740b57cec5SDimitry Andric   getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
20750b57cec5SDimitry Andric 
20760b57cec5SDimitry Andric   // If the thunk has been generated previously, just return it.
20770b57cec5SDimitry Andric   if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
20780b57cec5SDimitry Andric     return cast<llvm::Function>(GV);
20790b57cec5SDimitry Andric 
20800b57cec5SDimitry Andric   // Create the llvm::Function.
20810b57cec5SDimitry Andric   const CGFunctionInfo &FnInfo =
20820b57cec5SDimitry Andric       CGM.getTypes().arrangeUnprototypedMustTailThunk(MD);
20830b57cec5SDimitry Andric   llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
20840b57cec5SDimitry Andric   llvm::Function *ThunkFn =
20850b57cec5SDimitry Andric       llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
20860b57cec5SDimitry Andric                              ThunkName.str(), &CGM.getModule());
20870b57cec5SDimitry Andric   assert(ThunkFn->getName() == ThunkName && "name was uniqued!");
20880b57cec5SDimitry Andric 
20890b57cec5SDimitry Andric   ThunkFn->setLinkage(MD->isExternallyVisible()
20900b57cec5SDimitry Andric                           ? llvm::GlobalValue::LinkOnceODRLinkage
20910b57cec5SDimitry Andric                           : llvm::GlobalValue::InternalLinkage);
20920b57cec5SDimitry Andric   if (MD->isExternallyVisible())
20930b57cec5SDimitry Andric     ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
20940b57cec5SDimitry Andric 
2095fe6060f1SDimitry Andric   CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/false);
20960b57cec5SDimitry Andric   CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
20970b57cec5SDimitry Andric 
20980b57cec5SDimitry Andric   // Add the "thunk" attribute so that LLVM knows that the return type is
20990b57cec5SDimitry Andric   // meaningless. These thunks can be used to call functions with differing
21000b57cec5SDimitry Andric   // return types, and the caller is required to cast the prototype
21010b57cec5SDimitry Andric   // appropriately to extract the correct value.
21020b57cec5SDimitry Andric   ThunkFn->addFnAttr("thunk");
21030b57cec5SDimitry Andric 
21040b57cec5SDimitry Andric   // These thunks can be compared, so they are not unnamed.
21050b57cec5SDimitry Andric   ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
21060b57cec5SDimitry Andric 
21070b57cec5SDimitry Andric   // Start codegen.
21080b57cec5SDimitry Andric   CodeGenFunction CGF(CGM);
21090b57cec5SDimitry Andric   CGF.CurGD = GlobalDecl(MD);
21100b57cec5SDimitry Andric   CGF.CurFuncIsThunk = true;
21110b57cec5SDimitry Andric 
21120b57cec5SDimitry Andric   // Build FunctionArgs, but only include the implicit 'this' parameter
21130b57cec5SDimitry Andric   // declaration.
21140b57cec5SDimitry Andric   FunctionArgList FunctionArgs;
21150b57cec5SDimitry Andric   buildThisParam(CGF, FunctionArgs);
21160b57cec5SDimitry Andric 
21170b57cec5SDimitry Andric   // Start defining the function.
21180b57cec5SDimitry Andric   CGF.StartFunction(GlobalDecl(), FnInfo.getReturnType(), ThunkFn, FnInfo,
21190b57cec5SDimitry Andric                     FunctionArgs, MD->getLocation(), SourceLocation());
2120bdd1243dSDimitry Andric 
2121bdd1243dSDimitry Andric   ApplyDebugLocation AL(CGF, MD->getLocation());
21220b57cec5SDimitry Andric   setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
21230b57cec5SDimitry Andric 
21240b57cec5SDimitry Andric   // Load the vfptr and then callee from the vftable.  The callee should have
21250b57cec5SDimitry Andric   // adjusted 'this' so that the vfptr is at offset zero.
2126fe6060f1SDimitry Andric   llvm::Type *ThunkPtrTy = ThunkTy->getPointerTo();
21270b57cec5SDimitry Andric   llvm::Value *VTable = CGF.GetVTablePtr(
2128fe6060f1SDimitry Andric       getThisAddress(CGF), ThunkPtrTy->getPointerTo(), MD->getParent());
21290b57cec5SDimitry Andric 
2130fe6060f1SDimitry Andric   llvm::Value *VFuncPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
2131fe6060f1SDimitry Andric       ThunkPtrTy, VTable, ML.Index, "vfn");
21320b57cec5SDimitry Andric   llvm::Value *Callee =
2133fe6060f1SDimitry Andric     CGF.Builder.CreateAlignedLoad(ThunkPtrTy, VFuncPtr, CGF.getPointerAlign());
21340b57cec5SDimitry Andric 
21350b57cec5SDimitry Andric   CGF.EmitMustTailThunk(MD, getThisValue(CGF), {ThunkTy, Callee});
21360b57cec5SDimitry Andric 
21370b57cec5SDimitry Andric   return ThunkFn;
21380b57cec5SDimitry Andric }
21390b57cec5SDimitry Andric 
21400b57cec5SDimitry Andric void MicrosoftCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {
21410b57cec5SDimitry Andric   const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
21420b57cec5SDimitry Andric   for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
21430b57cec5SDimitry Andric     const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
21440b57cec5SDimitry Andric     llvm::GlobalVariable *GV = VBGlobals.Globals[I];
21450b57cec5SDimitry Andric     if (GV->isDeclaration())
21460b57cec5SDimitry Andric       emitVBTableDefinition(*VBT, RD, GV);
21470b57cec5SDimitry Andric   }
21480b57cec5SDimitry Andric }
21490b57cec5SDimitry Andric 
21500b57cec5SDimitry Andric llvm::GlobalVariable *
21510b57cec5SDimitry Andric MicrosoftCXXABI::getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
21520b57cec5SDimitry Andric                                   llvm::GlobalVariable::LinkageTypes Linkage) {
21530b57cec5SDimitry Andric   SmallString<256> OutName;
21540b57cec5SDimitry Andric   llvm::raw_svector_ostream Out(OutName);
21550b57cec5SDimitry Andric   getMangleContext().mangleCXXVBTable(RD, VBT.MangledPath, Out);
21560b57cec5SDimitry Andric   StringRef Name = OutName.str();
21570b57cec5SDimitry Andric 
21580b57cec5SDimitry Andric   llvm::ArrayType *VBTableType =
21590b57cec5SDimitry Andric       llvm::ArrayType::get(CGM.IntTy, 1 + VBT.ObjectWithVPtr->getNumVBases());
21600b57cec5SDimitry Andric 
21610b57cec5SDimitry Andric   assert(!CGM.getModule().getNamedGlobal(Name) &&
21620b57cec5SDimitry Andric          "vbtable with this name already exists: mangling bug?");
21630b57cec5SDimitry Andric   CharUnits Alignment =
21640b57cec5SDimitry Andric       CGM.getContext().getTypeAlignInChars(CGM.getContext().IntTy);
21650b57cec5SDimitry Andric   llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable(
2166bdd1243dSDimitry Andric       Name, VBTableType, Linkage, Alignment.getAsAlign());
21670b57cec5SDimitry Andric   GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
21680b57cec5SDimitry Andric 
21690b57cec5SDimitry Andric   if (RD->hasAttr<DLLImportAttr>())
21700b57cec5SDimitry Andric     GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
21710b57cec5SDimitry Andric   else if (RD->hasAttr<DLLExportAttr>())
21720b57cec5SDimitry Andric     GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
21730b57cec5SDimitry Andric 
21740b57cec5SDimitry Andric   if (!GV->hasExternalLinkage())
21750b57cec5SDimitry Andric     emitVBTableDefinition(VBT, RD, GV);
21760b57cec5SDimitry Andric 
21770b57cec5SDimitry Andric   return GV;
21780b57cec5SDimitry Andric }
21790b57cec5SDimitry Andric 
21800b57cec5SDimitry Andric void MicrosoftCXXABI::emitVBTableDefinition(const VPtrInfo &VBT,
21810b57cec5SDimitry Andric                                             const CXXRecordDecl *RD,
21820b57cec5SDimitry Andric                                             llvm::GlobalVariable *GV) const {
21830b57cec5SDimitry Andric   const CXXRecordDecl *ObjectWithVPtr = VBT.ObjectWithVPtr;
21840b57cec5SDimitry Andric 
21850b57cec5SDimitry Andric   assert(RD->getNumVBases() && ObjectWithVPtr->getNumVBases() &&
21860b57cec5SDimitry Andric          "should only emit vbtables for classes with vbtables");
21870b57cec5SDimitry Andric 
21880b57cec5SDimitry Andric   const ASTRecordLayout &BaseLayout =
21890b57cec5SDimitry Andric       getContext().getASTRecordLayout(VBT.IntroducingObject);
21900b57cec5SDimitry Andric   const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
21910b57cec5SDimitry Andric 
21920b57cec5SDimitry Andric   SmallVector<llvm::Constant *, 4> Offsets(1 + ObjectWithVPtr->getNumVBases(),
21930b57cec5SDimitry Andric                                            nullptr);
21940b57cec5SDimitry Andric 
21950b57cec5SDimitry Andric   // The offset from ObjectWithVPtr's vbptr to itself always leads.
21960b57cec5SDimitry Andric   CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
21970b57cec5SDimitry Andric   Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
21980b57cec5SDimitry Andric 
21990b57cec5SDimitry Andric   MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
22000b57cec5SDimitry Andric   for (const auto &I : ObjectWithVPtr->vbases()) {
22010b57cec5SDimitry Andric     const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
22020b57cec5SDimitry Andric     CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase);
22030b57cec5SDimitry Andric     assert(!Offset.isNegative());
22040b57cec5SDimitry Andric 
22050b57cec5SDimitry Andric     // Make it relative to the subobject vbptr.
22060b57cec5SDimitry Andric     CharUnits CompleteVBPtrOffset = VBT.NonVirtualOffset + VBPtrOffset;
22070b57cec5SDimitry Andric     if (VBT.getVBaseWithVPtr())
22080b57cec5SDimitry Andric       CompleteVBPtrOffset +=
22090b57cec5SDimitry Andric           DerivedLayout.getVBaseClassOffset(VBT.getVBaseWithVPtr());
22100b57cec5SDimitry Andric     Offset -= CompleteVBPtrOffset;
22110b57cec5SDimitry Andric 
22120b57cec5SDimitry Andric     unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
22130b57cec5SDimitry Andric     assert(Offsets[VBIndex] == nullptr && "The same vbindex seen twice?");
22140b57cec5SDimitry Andric     Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity());
22150b57cec5SDimitry Andric   }
22160b57cec5SDimitry Andric 
22170b57cec5SDimitry Andric   assert(Offsets.size() ==
2218fe6060f1SDimitry Andric          cast<llvm::ArrayType>(GV->getValueType())->getNumElements());
22190b57cec5SDimitry Andric   llvm::ArrayType *VBTableType =
22200b57cec5SDimitry Andric     llvm::ArrayType::get(CGM.IntTy, Offsets.size());
22210b57cec5SDimitry Andric   llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
22220b57cec5SDimitry Andric   GV->setInitializer(Init);
22230b57cec5SDimitry Andric 
22240b57cec5SDimitry Andric   if (RD->hasAttr<DLLImportAttr>())
22250b57cec5SDimitry Andric     GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
22260b57cec5SDimitry Andric }
22270b57cec5SDimitry Andric 
22280fca6ea1SDimitry Andric llvm::Value *MicrosoftCXXABI::performThisAdjustment(
22290fca6ea1SDimitry Andric     CodeGenFunction &CGF, Address This,
22300fca6ea1SDimitry Andric     const CXXRecordDecl * /*UnadjustedClass*/, const ThunkInfo &TI) {
22310fca6ea1SDimitry Andric   const ThisAdjustment &TA = TI.This;
22320b57cec5SDimitry Andric   if (TA.isEmpty())
22330fca6ea1SDimitry Andric     return This.emitRawPointer(CGF);
22340b57cec5SDimitry Andric 
223506c3fb27SDimitry Andric   This = This.withElementType(CGF.Int8Ty);
22360b57cec5SDimitry Andric 
22370b57cec5SDimitry Andric   llvm::Value *V;
22380b57cec5SDimitry Andric   if (TA.Virtual.isEmpty()) {
22390fca6ea1SDimitry Andric     V = This.emitRawPointer(CGF);
22400b57cec5SDimitry Andric   } else {
22410b57cec5SDimitry Andric     assert(TA.Virtual.Microsoft.VtordispOffset < 0);
22420b57cec5SDimitry Andric     // Adjust the this argument based on the vtordisp value.
22430b57cec5SDimitry Andric     Address VtorDispPtr =
22440b57cec5SDimitry Andric         CGF.Builder.CreateConstInBoundsByteGEP(This,
22450b57cec5SDimitry Andric                  CharUnits::fromQuantity(TA.Virtual.Microsoft.VtordispOffset));
224606c3fb27SDimitry Andric     VtorDispPtr = VtorDispPtr.withElementType(CGF.Int32Ty);
22470b57cec5SDimitry Andric     llvm::Value *VtorDisp = CGF.Builder.CreateLoad(VtorDispPtr, "vtordisp");
22480fca6ea1SDimitry Andric     V = CGF.Builder.CreateGEP(This.getElementType(), This.emitRawPointer(CGF),
22490b57cec5SDimitry Andric                               CGF.Builder.CreateNeg(VtorDisp));
22500b57cec5SDimitry Andric 
22510b57cec5SDimitry Andric     // Unfortunately, having applied the vtordisp means that we no
22520b57cec5SDimitry Andric     // longer really have a known alignment for the vbptr step.
22530b57cec5SDimitry Andric     // We'll assume the vbptr is pointer-aligned.
22540b57cec5SDimitry Andric 
22550b57cec5SDimitry Andric     if (TA.Virtual.Microsoft.VBPtrOffset) {
22560b57cec5SDimitry Andric       // If the final overrider is defined in a virtual base other than the one
22570b57cec5SDimitry Andric       // that holds the vfptr, we have to use a vtordispex thunk which looks up
22580b57cec5SDimitry Andric       // the vbtable of the derived class.
22590b57cec5SDimitry Andric       assert(TA.Virtual.Microsoft.VBPtrOffset > 0);
22600b57cec5SDimitry Andric       assert(TA.Virtual.Microsoft.VBOffsetOffset >= 0);
22610b57cec5SDimitry Andric       llvm::Value *VBPtr;
226281ad6265SDimitry Andric       llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
226381ad6265SDimitry Andric           CGF, Address(V, CGF.Int8Ty, CGF.getPointerAlign()),
22640b57cec5SDimitry Andric           -TA.Virtual.Microsoft.VBPtrOffset,
22650b57cec5SDimitry Andric           TA.Virtual.Microsoft.VBOffsetOffset, &VBPtr);
2266fe6060f1SDimitry Andric       V = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, VBPtr, VBaseOffset);
22670b57cec5SDimitry Andric     }
22680b57cec5SDimitry Andric   }
22690b57cec5SDimitry Andric 
22700b57cec5SDimitry Andric   if (TA.NonVirtual) {
22710b57cec5SDimitry Andric     // Non-virtual adjustment might result in a pointer outside the allocated
22720b57cec5SDimitry Andric     // object, e.g. if the final overrider class is laid out after the virtual
22730b57cec5SDimitry Andric     // base that declares a method in the most derived class.
2274fe6060f1SDimitry Andric     V = CGF.Builder.CreateConstGEP1_32(CGF.Int8Ty, V, TA.NonVirtual);
22750b57cec5SDimitry Andric   }
22760b57cec5SDimitry Andric 
22770b57cec5SDimitry Andric   // Don't need to bitcast back, the call CodeGen will handle this.
22780b57cec5SDimitry Andric   return V;
22790b57cec5SDimitry Andric }
22800b57cec5SDimitry Andric 
22810fca6ea1SDimitry Andric llvm::Value *MicrosoftCXXABI::performReturnAdjustment(
22820fca6ea1SDimitry Andric     CodeGenFunction &CGF, Address Ret,
22830fca6ea1SDimitry Andric     const CXXRecordDecl * /*UnadjustedClass*/, const ReturnAdjustment &RA) {
22840fca6ea1SDimitry Andric 
22850b57cec5SDimitry Andric   if (RA.isEmpty())
22860fca6ea1SDimitry Andric     return Ret.emitRawPointer(CGF);
22870b57cec5SDimitry Andric 
228806c3fb27SDimitry Andric   Ret = Ret.withElementType(CGF.Int8Ty);
22890b57cec5SDimitry Andric 
22900fca6ea1SDimitry Andric   llvm::Value *V = Ret.emitRawPointer(CGF);
22910b57cec5SDimitry Andric   if (RA.Virtual.Microsoft.VBIndex) {
22920b57cec5SDimitry Andric     assert(RA.Virtual.Microsoft.VBIndex > 0);
22930b57cec5SDimitry Andric     int32_t IntSize = CGF.getIntSize().getQuantity();
22940b57cec5SDimitry Andric     llvm::Value *VBPtr;
22950b57cec5SDimitry Andric     llvm::Value *VBaseOffset =
22960b57cec5SDimitry Andric         GetVBaseOffsetFromVBPtr(CGF, Ret, RA.Virtual.Microsoft.VBPtrOffset,
22970b57cec5SDimitry Andric                                 IntSize * RA.Virtual.Microsoft.VBIndex, &VBPtr);
2298fe6060f1SDimitry Andric     V = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, VBPtr, VBaseOffset);
22990b57cec5SDimitry Andric   }
23000b57cec5SDimitry Andric 
23010b57cec5SDimitry Andric   if (RA.NonVirtual)
23020b57cec5SDimitry Andric     V = CGF.Builder.CreateConstInBoundsGEP1_32(CGF.Int8Ty, V, RA.NonVirtual);
23030b57cec5SDimitry Andric 
23045f757f3fSDimitry Andric   return V;
23050b57cec5SDimitry Andric }
23060b57cec5SDimitry Andric 
23070b57cec5SDimitry Andric bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
23080b57cec5SDimitry Andric                                    QualType elementType) {
23090b57cec5SDimitry Andric   // Microsoft seems to completely ignore the possibility of a
23100b57cec5SDimitry Andric   // two-argument usual deallocation function.
23110b57cec5SDimitry Andric   return elementType.isDestructedType();
23120b57cec5SDimitry Andric }
23130b57cec5SDimitry Andric 
23140b57cec5SDimitry Andric bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
23150b57cec5SDimitry Andric   // Microsoft seems to completely ignore the possibility of a
23160b57cec5SDimitry Andric   // two-argument usual deallocation function.
23170b57cec5SDimitry Andric   return expr->getAllocatedType().isDestructedType();
23180b57cec5SDimitry Andric }
23190b57cec5SDimitry Andric 
23200b57cec5SDimitry Andric CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
23210b57cec5SDimitry Andric   // The array cookie is always a size_t; we then pad that out to the
23220b57cec5SDimitry Andric   // alignment of the element type.
23230b57cec5SDimitry Andric   ASTContext &Ctx = getContext();
23240b57cec5SDimitry Andric   return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
23250b57cec5SDimitry Andric                   Ctx.getTypeAlignInChars(type));
23260b57cec5SDimitry Andric }
23270b57cec5SDimitry Andric 
23280b57cec5SDimitry Andric llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
23290b57cec5SDimitry Andric                                                   Address allocPtr,
23300b57cec5SDimitry Andric                                                   CharUnits cookieSize) {
233106c3fb27SDimitry Andric   Address numElementsPtr = allocPtr.withElementType(CGF.SizeTy);
23320b57cec5SDimitry Andric   return CGF.Builder.CreateLoad(numElementsPtr);
23330b57cec5SDimitry Andric }
23340b57cec5SDimitry Andric 
23350b57cec5SDimitry Andric Address MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
23360b57cec5SDimitry Andric                                                Address newPtr,
23370b57cec5SDimitry Andric                                                llvm::Value *numElements,
23380b57cec5SDimitry Andric                                                const CXXNewExpr *expr,
23390b57cec5SDimitry Andric                                                QualType elementType) {
23400b57cec5SDimitry Andric   assert(requiresArrayCookie(expr));
23410b57cec5SDimitry Andric 
23420b57cec5SDimitry Andric   // The size of the cookie.
23430b57cec5SDimitry Andric   CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
23440b57cec5SDimitry Andric 
23450b57cec5SDimitry Andric   // Compute an offset to the cookie.
23460b57cec5SDimitry Andric   Address cookiePtr = newPtr;
23470b57cec5SDimitry Andric 
23480b57cec5SDimitry Andric   // Write the number of elements into the appropriate slot.
234906c3fb27SDimitry Andric   Address numElementsPtr = cookiePtr.withElementType(CGF.SizeTy);
23500b57cec5SDimitry Andric   CGF.Builder.CreateStore(numElements, numElementsPtr);
23510b57cec5SDimitry Andric 
23520b57cec5SDimitry Andric   // Finally, compute a pointer to the actual data buffer by skipping
23530b57cec5SDimitry Andric   // over the cookie completely.
23540b57cec5SDimitry Andric   return CGF.Builder.CreateConstInBoundsByteGEP(newPtr, cookieSize);
23550b57cec5SDimitry Andric }
23560b57cec5SDimitry Andric 
23570b57cec5SDimitry Andric static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD,
23580b57cec5SDimitry Andric                                         llvm::FunctionCallee Dtor,
23590b57cec5SDimitry Andric                                         llvm::Constant *Addr) {
23600b57cec5SDimitry Andric   // Create a function which calls the destructor.
23610b57cec5SDimitry Andric   llvm::Constant *DtorStub = CGF.createAtExitStub(VD, Dtor, Addr);
23620b57cec5SDimitry Andric 
23630b57cec5SDimitry Andric   // extern "C" int __tlregdtor(void (*f)(void));
23640b57cec5SDimitry Andric   llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
23650b57cec5SDimitry Andric       CGF.IntTy, DtorStub->getType(), /*isVarArg=*/false);
23660b57cec5SDimitry Andric 
23670b57cec5SDimitry Andric   llvm::FunctionCallee TLRegDtor = CGF.CGM.CreateRuntimeFunction(
23680b57cec5SDimitry Andric       TLRegDtorTy, "__tlregdtor", llvm::AttributeList(), /*Local=*/true);
23690b57cec5SDimitry Andric   if (llvm::Function *TLRegDtorFn =
23700b57cec5SDimitry Andric           dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
23710b57cec5SDimitry Andric     TLRegDtorFn->setDoesNotThrow();
23720b57cec5SDimitry Andric 
23730b57cec5SDimitry Andric   CGF.EmitNounwindRuntimeCall(TLRegDtor, DtorStub);
23740b57cec5SDimitry Andric }
23750b57cec5SDimitry Andric 
23760b57cec5SDimitry Andric void MicrosoftCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
23770b57cec5SDimitry Andric                                          llvm::FunctionCallee Dtor,
23780b57cec5SDimitry Andric                                          llvm::Constant *Addr) {
23790b57cec5SDimitry Andric   if (D.isNoDestroy(CGM.getContext()))
23800b57cec5SDimitry Andric     return;
23810b57cec5SDimitry Andric 
23820b57cec5SDimitry Andric   if (D.getTLSKind())
23830b57cec5SDimitry Andric     return emitGlobalDtorWithTLRegDtor(CGF, D, Dtor, Addr);
23840b57cec5SDimitry Andric 
2385bdd1243dSDimitry Andric   // HLSL doesn't support atexit.
2386bdd1243dSDimitry Andric   if (CGM.getLangOpts().HLSL)
2387bdd1243dSDimitry Andric     return CGM.AddCXXDtorEntry(Dtor, Addr);
2388bdd1243dSDimitry Andric 
23890b57cec5SDimitry Andric   // The default behavior is to use atexit.
23900b57cec5SDimitry Andric   CGF.registerGlobalDtorWithAtExit(D, Dtor, Addr);
23910b57cec5SDimitry Andric }
23920b57cec5SDimitry Andric 
23930b57cec5SDimitry Andric void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
23940b57cec5SDimitry Andric     CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
23950b57cec5SDimitry Andric     ArrayRef<llvm::Function *> CXXThreadLocalInits,
23960b57cec5SDimitry Andric     ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
23970b57cec5SDimitry Andric   if (CXXThreadLocalInits.empty())
23980b57cec5SDimitry Andric     return;
23990b57cec5SDimitry Andric 
24000b57cec5SDimitry Andric   CGM.AppendLinkerOptions(CGM.getTarget().getTriple().getArch() ==
24010b57cec5SDimitry Andric                                   llvm::Triple::x86
24020b57cec5SDimitry Andric                               ? "/include:___dyn_tls_init@12"
24030b57cec5SDimitry Andric                               : "/include:__dyn_tls_init");
24040b57cec5SDimitry Andric 
24050b57cec5SDimitry Andric   // This will create a GV in the .CRT$XDU section.  It will point to our
24060b57cec5SDimitry Andric   // initialization function.  The CRT will call all of these function
24070b57cec5SDimitry Andric   // pointers at start-up time and, eventually, at thread-creation time.
24080b57cec5SDimitry Andric   auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
24090b57cec5SDimitry Andric     llvm::GlobalVariable *InitFuncPtr = new llvm::GlobalVariable(
24100b57cec5SDimitry Andric         CGM.getModule(), InitFunc->getType(), /*isConstant=*/true,
24110b57cec5SDimitry Andric         llvm::GlobalVariable::InternalLinkage, InitFunc,
24120b57cec5SDimitry Andric         Twine(InitFunc->getName(), "$initializer$"));
24130b57cec5SDimitry Andric     InitFuncPtr->setSection(".CRT$XDU");
24140b57cec5SDimitry Andric     // This variable has discardable linkage, we have to add it to @llvm.used to
24150b57cec5SDimitry Andric     // ensure it won't get discarded.
24160b57cec5SDimitry Andric     CGM.addUsedGlobal(InitFuncPtr);
24170b57cec5SDimitry Andric     return InitFuncPtr;
24180b57cec5SDimitry Andric   };
24190b57cec5SDimitry Andric 
24200b57cec5SDimitry Andric   std::vector<llvm::Function *> NonComdatInits;
24210b57cec5SDimitry Andric   for (size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
24220b57cec5SDimitry Andric     llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
24230b57cec5SDimitry Andric         CGM.GetGlobalValue(CGM.getMangledName(CXXThreadLocalInitVars[I])));
24240b57cec5SDimitry Andric     llvm::Function *F = CXXThreadLocalInits[I];
24250b57cec5SDimitry Andric 
24260b57cec5SDimitry Andric     // If the GV is already in a comdat group, then we have to join it.
24270b57cec5SDimitry Andric     if (llvm::Comdat *C = GV->getComdat())
24280b57cec5SDimitry Andric       AddToXDU(F)->setComdat(C);
24290b57cec5SDimitry Andric     else
24300b57cec5SDimitry Andric       NonComdatInits.push_back(F);
24310b57cec5SDimitry Andric   }
24320b57cec5SDimitry Andric 
24330b57cec5SDimitry Andric   if (!NonComdatInits.empty()) {
24340b57cec5SDimitry Andric     llvm::FunctionType *FTy =
24350b57cec5SDimitry Andric         llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
24365ffd83dbSDimitry Andric     llvm::Function *InitFunc = CGM.CreateGlobalInitOrCleanUpFunction(
24370b57cec5SDimitry Andric         FTy, "__tls_init", CGM.getTypes().arrangeNullaryFunction(),
24380b57cec5SDimitry Andric         SourceLocation(), /*TLS=*/true);
24390b57cec5SDimitry Andric     CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(InitFunc, NonComdatInits);
24400b57cec5SDimitry Andric 
24410b57cec5SDimitry Andric     AddToXDU(InitFunc);
24420b57cec5SDimitry Andric   }
24430b57cec5SDimitry Andric }
24440b57cec5SDimitry Andric 
244504eeddc0SDimitry Andric static llvm::GlobalValue *getTlsGuardVar(CodeGenModule &CGM) {
244604eeddc0SDimitry Andric   // __tls_guard comes from the MSVC runtime and reflects
244704eeddc0SDimitry Andric   // whether TLS has been initialized for a particular thread.
244804eeddc0SDimitry Andric   // It is set from within __dyn_tls_init by the runtime.
244904eeddc0SDimitry Andric   // Every library and executable has its own variable.
245004eeddc0SDimitry Andric   llvm::Type *VTy = llvm::Type::getInt8Ty(CGM.getLLVMContext());
245104eeddc0SDimitry Andric   llvm::Constant *TlsGuardConstant =
245204eeddc0SDimitry Andric       CGM.CreateRuntimeVariable(VTy, "__tls_guard");
245304eeddc0SDimitry Andric   llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant);
245404eeddc0SDimitry Andric 
245504eeddc0SDimitry Andric   TlsGuard->setThreadLocal(true);
245604eeddc0SDimitry Andric 
245704eeddc0SDimitry Andric   return TlsGuard;
245804eeddc0SDimitry Andric }
245904eeddc0SDimitry Andric 
246004eeddc0SDimitry Andric static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM) {
246104eeddc0SDimitry Andric   // __dyn_tls_on_demand_init comes from the MSVC runtime and triggers
246204eeddc0SDimitry Andric   // dynamic TLS initialization by calling __dyn_tls_init internally.
246304eeddc0SDimitry Andric   llvm::FunctionType *FTy =
246404eeddc0SDimitry Andric       llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()), {},
246504eeddc0SDimitry Andric                               /*isVarArg=*/false);
246604eeddc0SDimitry Andric   return CGM.CreateRuntimeFunction(
246704eeddc0SDimitry Andric       FTy, "__dyn_tls_on_demand_init",
246804eeddc0SDimitry Andric       llvm::AttributeList::get(CGM.getLLVMContext(),
246904eeddc0SDimitry Andric                                llvm::AttributeList::FunctionIndex,
247004eeddc0SDimitry Andric                                llvm::Attribute::NoUnwind),
247104eeddc0SDimitry Andric       /*Local=*/true);
247204eeddc0SDimitry Andric }
247304eeddc0SDimitry Andric 
247404eeddc0SDimitry Andric static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard,
247504eeddc0SDimitry Andric                               llvm::BasicBlock *DynInitBB,
247604eeddc0SDimitry Andric                               llvm::BasicBlock *ContinueBB) {
247704eeddc0SDimitry Andric   llvm::LoadInst *TlsGuardValue =
247881ad6265SDimitry Andric       CGF.Builder.CreateLoad(Address(TlsGuard, CGF.Int8Ty, CharUnits::One()));
247904eeddc0SDimitry Andric   llvm::Value *CmpResult =
248004eeddc0SDimitry Andric       CGF.Builder.CreateICmpEQ(TlsGuardValue, CGF.Builder.getInt8(0));
248104eeddc0SDimitry Andric   CGF.Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
248204eeddc0SDimitry Andric }
248304eeddc0SDimitry Andric 
248404eeddc0SDimitry Andric static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF,
248504eeddc0SDimitry Andric                                              llvm::GlobalValue *TlsGuard,
248604eeddc0SDimitry Andric                                              llvm::BasicBlock *ContinueBB) {
248704eeddc0SDimitry Andric   llvm::FunctionCallee Initializer = getDynTlsOnDemandInitFn(CGF.CGM);
248804eeddc0SDimitry Andric   llvm::Function *InitializerFunction =
248904eeddc0SDimitry Andric       cast<llvm::Function>(Initializer.getCallee());
249004eeddc0SDimitry Andric   llvm::CallInst *CallVal = CGF.Builder.CreateCall(InitializerFunction);
249104eeddc0SDimitry Andric   CallVal->setCallingConv(InitializerFunction->getCallingConv());
249204eeddc0SDimitry Andric 
249304eeddc0SDimitry Andric   CGF.Builder.CreateBr(ContinueBB);
249404eeddc0SDimitry Andric }
249504eeddc0SDimitry Andric 
249604eeddc0SDimitry Andric static void emitDynamicTlsInitialization(CodeGenFunction &CGF) {
249704eeddc0SDimitry Andric   llvm::BasicBlock *DynInitBB =
249804eeddc0SDimitry Andric       CGF.createBasicBlock("dyntls.dyn_init", CGF.CurFn);
249904eeddc0SDimitry Andric   llvm::BasicBlock *ContinueBB =
250004eeddc0SDimitry Andric       CGF.createBasicBlock("dyntls.continue", CGF.CurFn);
250104eeddc0SDimitry Andric 
250204eeddc0SDimitry Andric   llvm::GlobalValue *TlsGuard = getTlsGuardVar(CGF.CGM);
250304eeddc0SDimitry Andric 
250404eeddc0SDimitry Andric   emitTlsGuardCheck(CGF, TlsGuard, DynInitBB, ContinueBB);
250504eeddc0SDimitry Andric   CGF.Builder.SetInsertPoint(DynInitBB);
250604eeddc0SDimitry Andric   emitDynamicTlsInitializationCall(CGF, TlsGuard, ContinueBB);
250704eeddc0SDimitry Andric   CGF.Builder.SetInsertPoint(ContinueBB);
250804eeddc0SDimitry Andric }
250904eeddc0SDimitry Andric 
25100b57cec5SDimitry Andric LValue MicrosoftCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
25110b57cec5SDimitry Andric                                                      const VarDecl *VD,
25120b57cec5SDimitry Andric                                                      QualType LValType) {
251304eeddc0SDimitry Andric   // Dynamic TLS initialization works by checking the state of a
251404eeddc0SDimitry Andric   // guard variable (__tls_guard) to see whether TLS initialization
251504eeddc0SDimitry Andric   // for a thread has happend yet.
251604eeddc0SDimitry Andric   // If not, the initialization is triggered on-demand
251704eeddc0SDimitry Andric   // by calling __dyn_tls_on_demand_init.
251804eeddc0SDimitry Andric   emitDynamicTlsInitialization(CGF);
251904eeddc0SDimitry Andric 
252004eeddc0SDimitry Andric   // Emit the variable just like any regular global variable.
252104eeddc0SDimitry Andric 
252204eeddc0SDimitry Andric   llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
252304eeddc0SDimitry Andric   llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType());
252404eeddc0SDimitry Andric 
252504eeddc0SDimitry Andric   CharUnits Alignment = CGF.getContext().getDeclAlign(VD);
252681ad6265SDimitry Andric   Address Addr(V, RealVarTy, Alignment);
252704eeddc0SDimitry Andric 
252804eeddc0SDimitry Andric   LValue LV = VD->getType()->isReferenceType()
252904eeddc0SDimitry Andric                   ? CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
253004eeddc0SDimitry Andric                                                   AlignmentSource::Decl)
253104eeddc0SDimitry Andric                   : CGF.MakeAddrLValue(Addr, LValType, AlignmentSource::Decl);
253204eeddc0SDimitry Andric   return LV;
25330b57cec5SDimitry Andric }
25340b57cec5SDimitry Andric 
25350b57cec5SDimitry Andric static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM) {
25360b57cec5SDimitry Andric   StringRef VarName("_Init_thread_epoch");
25370b57cec5SDimitry Andric   CharUnits Align = CGM.getIntAlign();
25380b57cec5SDimitry Andric   if (auto *GV = CGM.getModule().getNamedGlobal(VarName))
25390eae32dcSDimitry Andric     return ConstantAddress(GV, GV->getValueType(), Align);
25400b57cec5SDimitry Andric   auto *GV = new llvm::GlobalVariable(
25410b57cec5SDimitry Andric       CGM.getModule(), CGM.IntTy,
25420b57cec5SDimitry Andric       /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage,
25430b57cec5SDimitry Andric       /*Initializer=*/nullptr, VarName,
25440b57cec5SDimitry Andric       /*InsertBefore=*/nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2545a7dea167SDimitry Andric   GV->setAlignment(Align.getAsAlign());
25460eae32dcSDimitry Andric   return ConstantAddress(GV, GV->getValueType(), Align);
25470b57cec5SDimitry Andric }
25480b57cec5SDimitry Andric 
25490b57cec5SDimitry Andric static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM) {
25500b57cec5SDimitry Andric   llvm::FunctionType *FTy =
25510b57cec5SDimitry Andric       llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
25520b57cec5SDimitry Andric                               CGM.IntTy->getPointerTo(), /*isVarArg=*/false);
25530b57cec5SDimitry Andric   return CGM.CreateRuntimeFunction(
25540b57cec5SDimitry Andric       FTy, "_Init_thread_header",
25550b57cec5SDimitry Andric       llvm::AttributeList::get(CGM.getLLVMContext(),
25560b57cec5SDimitry Andric                                llvm::AttributeList::FunctionIndex,
25570b57cec5SDimitry Andric                                llvm::Attribute::NoUnwind),
25580b57cec5SDimitry Andric       /*Local=*/true);
25590b57cec5SDimitry Andric }
25600b57cec5SDimitry Andric 
25610b57cec5SDimitry Andric static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM) {
25620b57cec5SDimitry Andric   llvm::FunctionType *FTy =
25630b57cec5SDimitry Andric       llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
25640b57cec5SDimitry Andric                               CGM.IntTy->getPointerTo(), /*isVarArg=*/false);
25650b57cec5SDimitry Andric   return CGM.CreateRuntimeFunction(
25660b57cec5SDimitry Andric       FTy, "_Init_thread_footer",
25670b57cec5SDimitry Andric       llvm::AttributeList::get(CGM.getLLVMContext(),
25680b57cec5SDimitry Andric                                llvm::AttributeList::FunctionIndex,
25690b57cec5SDimitry Andric                                llvm::Attribute::NoUnwind),
25700b57cec5SDimitry Andric       /*Local=*/true);
25710b57cec5SDimitry Andric }
25720b57cec5SDimitry Andric 
25730b57cec5SDimitry Andric static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM) {
25740b57cec5SDimitry Andric   llvm::FunctionType *FTy =
25750b57cec5SDimitry Andric       llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
25760b57cec5SDimitry Andric                               CGM.IntTy->getPointerTo(), /*isVarArg=*/false);
25770b57cec5SDimitry Andric   return CGM.CreateRuntimeFunction(
25780b57cec5SDimitry Andric       FTy, "_Init_thread_abort",
25790b57cec5SDimitry Andric       llvm::AttributeList::get(CGM.getLLVMContext(),
25800b57cec5SDimitry Andric                                llvm::AttributeList::FunctionIndex,
25810b57cec5SDimitry Andric                                llvm::Attribute::NoUnwind),
25820b57cec5SDimitry Andric       /*Local=*/true);
25830b57cec5SDimitry Andric }
25840b57cec5SDimitry Andric 
25850b57cec5SDimitry Andric namespace {
25860b57cec5SDimitry Andric struct ResetGuardBit final : EHScopeStack::Cleanup {
25870b57cec5SDimitry Andric   Address Guard;
25880b57cec5SDimitry Andric   unsigned GuardNum;
25890b57cec5SDimitry Andric   ResetGuardBit(Address Guard, unsigned GuardNum)
25900b57cec5SDimitry Andric       : Guard(Guard), GuardNum(GuardNum) {}
25910b57cec5SDimitry Andric 
25920b57cec5SDimitry Andric   void Emit(CodeGenFunction &CGF, Flags flags) override {
25930b57cec5SDimitry Andric     // Reset the bit in the mask so that the static variable may be
25940b57cec5SDimitry Andric     // reinitialized.
25950b57cec5SDimitry Andric     CGBuilderTy &Builder = CGF.Builder;
25960b57cec5SDimitry Andric     llvm::LoadInst *LI = Builder.CreateLoad(Guard);
25970b57cec5SDimitry Andric     llvm::ConstantInt *Mask =
25980b57cec5SDimitry Andric         llvm::ConstantInt::get(CGF.IntTy, ~(1ULL << GuardNum));
25990b57cec5SDimitry Andric     Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
26000b57cec5SDimitry Andric   }
26010b57cec5SDimitry Andric };
26020b57cec5SDimitry Andric 
26030b57cec5SDimitry Andric struct CallInitThreadAbort final : EHScopeStack::Cleanup {
26040b57cec5SDimitry Andric   llvm::Value *Guard;
26050fca6ea1SDimitry Andric   CallInitThreadAbort(RawAddress Guard) : Guard(Guard.getPointer()) {}
26060b57cec5SDimitry Andric 
26070b57cec5SDimitry Andric   void Emit(CodeGenFunction &CGF, Flags flags) override {
26080b57cec5SDimitry Andric     // Calling _Init_thread_abort will reset the guard's state.
26090b57cec5SDimitry Andric     CGF.EmitNounwindRuntimeCall(getInitThreadAbortFn(CGF.CGM), Guard);
26100b57cec5SDimitry Andric   }
26110b57cec5SDimitry Andric };
26120b57cec5SDimitry Andric }
26130b57cec5SDimitry Andric 
26140b57cec5SDimitry Andric void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
26150b57cec5SDimitry Andric                                       llvm::GlobalVariable *GV,
26160b57cec5SDimitry Andric                                       bool PerformInit) {
26170b57cec5SDimitry Andric   // MSVC only uses guards for static locals.
26180b57cec5SDimitry Andric   if (!D.isStaticLocal()) {
26190b57cec5SDimitry Andric     assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
26200b57cec5SDimitry Andric     // GlobalOpt is allowed to discard the initializer, so use linkonce_odr.
26210b57cec5SDimitry Andric     llvm::Function *F = CGF.CurFn;
26220b57cec5SDimitry Andric     F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
26230b57cec5SDimitry Andric     F->setComdat(CGM.getModule().getOrInsertComdat(F->getName()));
26240b57cec5SDimitry Andric     CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
26250b57cec5SDimitry Andric     return;
26260b57cec5SDimitry Andric   }
26270b57cec5SDimitry Andric 
26280b57cec5SDimitry Andric   bool ThreadlocalStatic = D.getTLSKind();
26290b57cec5SDimitry Andric   bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
26300b57cec5SDimitry Andric 
26310b57cec5SDimitry Andric   // Thread-safe static variables which aren't thread-specific have a
26320b57cec5SDimitry Andric   // per-variable guard.
26330b57cec5SDimitry Andric   bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
26340b57cec5SDimitry Andric 
26350b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
26360b57cec5SDimitry Andric   llvm::IntegerType *GuardTy = CGF.Int32Ty;
26370b57cec5SDimitry Andric   llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
26380b57cec5SDimitry Andric   CharUnits GuardAlign = CharUnits::fromQuantity(4);
26390b57cec5SDimitry Andric 
26400b57cec5SDimitry Andric   // Get the guard variable for this function if we have one already.
26410b57cec5SDimitry Andric   GuardInfo *GI = nullptr;
26420b57cec5SDimitry Andric   if (ThreadlocalStatic)
26430b57cec5SDimitry Andric     GI = &ThreadLocalGuardVariableMap[D.getDeclContext()];
26440b57cec5SDimitry Andric   else if (!ThreadsafeStatic)
26450b57cec5SDimitry Andric     GI = &GuardVariableMap[D.getDeclContext()];
26460b57cec5SDimitry Andric 
26470b57cec5SDimitry Andric   llvm::GlobalVariable *GuardVar = GI ? GI->Guard : nullptr;
26480b57cec5SDimitry Andric   unsigned GuardNum;
26490b57cec5SDimitry Andric   if (D.isExternallyVisible()) {
26500b57cec5SDimitry Andric     // Externally visible variables have to be numbered in Sema to properly
26510b57cec5SDimitry Andric     // handle unreachable VarDecls.
26520b57cec5SDimitry Andric     GuardNum = getContext().getStaticLocalNumber(&D);
26530b57cec5SDimitry Andric     assert(GuardNum > 0);
26540b57cec5SDimitry Andric     GuardNum--;
26550b57cec5SDimitry Andric   } else if (HasPerVariableGuard) {
26560b57cec5SDimitry Andric     GuardNum = ThreadSafeGuardNumMap[D.getDeclContext()]++;
26570b57cec5SDimitry Andric   } else {
26580b57cec5SDimitry Andric     // Non-externally visible variables are numbered here in CodeGen.
26590b57cec5SDimitry Andric     GuardNum = GI->BitIndex++;
26600b57cec5SDimitry Andric   }
26610b57cec5SDimitry Andric 
26620b57cec5SDimitry Andric   if (!HasPerVariableGuard && GuardNum >= 32) {
26630b57cec5SDimitry Andric     if (D.isExternallyVisible())
26640b57cec5SDimitry Andric       ErrorUnsupportedABI(CGF, "more than 32 guarded initializations");
26650b57cec5SDimitry Andric     GuardNum %= 32;
26660b57cec5SDimitry Andric     GuardVar = nullptr;
26670b57cec5SDimitry Andric   }
26680b57cec5SDimitry Andric 
26690b57cec5SDimitry Andric   if (!GuardVar) {
26700b57cec5SDimitry Andric     // Mangle the name for the guard.
26710b57cec5SDimitry Andric     SmallString<256> GuardName;
26720b57cec5SDimitry Andric     {
26730b57cec5SDimitry Andric       llvm::raw_svector_ostream Out(GuardName);
26740b57cec5SDimitry Andric       if (HasPerVariableGuard)
26750b57cec5SDimitry Andric         getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
26760b57cec5SDimitry Andric                                                                Out);
26770b57cec5SDimitry Andric       else
26780b57cec5SDimitry Andric         getMangleContext().mangleStaticGuardVariable(&D, Out);
26790b57cec5SDimitry Andric     }
26800b57cec5SDimitry Andric 
26810b57cec5SDimitry Andric     // Create the guard variable with a zero-initializer. Just absorb linkage,
26820b57cec5SDimitry Andric     // visibility and dll storage class from the guarded variable.
26830b57cec5SDimitry Andric     GuardVar =
26840b57cec5SDimitry Andric         new llvm::GlobalVariable(CGM.getModule(), GuardTy, /*isConstant=*/false,
26850b57cec5SDimitry Andric                                  GV->getLinkage(), Zero, GuardName.str());
26860b57cec5SDimitry Andric     GuardVar->setVisibility(GV->getVisibility());
26870b57cec5SDimitry Andric     GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2688a7dea167SDimitry Andric     GuardVar->setAlignment(GuardAlign.getAsAlign());
26890b57cec5SDimitry Andric     if (GuardVar->isWeakForLinker())
26900b57cec5SDimitry Andric       GuardVar->setComdat(
26910b57cec5SDimitry Andric           CGM.getModule().getOrInsertComdat(GuardVar->getName()));
26920b57cec5SDimitry Andric     if (D.getTLSKind())
26935ffd83dbSDimitry Andric       CGM.setTLSMode(GuardVar, D);
26940b57cec5SDimitry Andric     if (GI && !HasPerVariableGuard)
26950b57cec5SDimitry Andric       GI->Guard = GuardVar;
26960b57cec5SDimitry Andric   }
26970b57cec5SDimitry Andric 
26980eae32dcSDimitry Andric   ConstantAddress GuardAddr(GuardVar, GuardTy, GuardAlign);
26990b57cec5SDimitry Andric 
27000b57cec5SDimitry Andric   assert(GuardVar->getLinkage() == GV->getLinkage() &&
27010b57cec5SDimitry Andric          "static local from the same function had different linkage");
27020b57cec5SDimitry Andric 
27030b57cec5SDimitry Andric   if (!HasPerVariableGuard) {
27040b57cec5SDimitry Andric     // Pseudo code for the test:
27050b57cec5SDimitry Andric     // if (!(GuardVar & MyGuardBit)) {
27060b57cec5SDimitry Andric     //   GuardVar |= MyGuardBit;
27070b57cec5SDimitry Andric     //   ... initialize the object ...;
27080b57cec5SDimitry Andric     // }
27090b57cec5SDimitry Andric 
27100b57cec5SDimitry Andric     // Test our bit from the guard variable.
27110b57cec5SDimitry Andric     llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
27120b57cec5SDimitry Andric     llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
27130b57cec5SDimitry Andric     llvm::Value *NeedsInit =
27140b57cec5SDimitry Andric         Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
27150b57cec5SDimitry Andric     llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
27160b57cec5SDimitry Andric     llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
27170b57cec5SDimitry Andric     CGF.EmitCXXGuardedInitBranch(NeedsInit, InitBlock, EndBlock,
27180b57cec5SDimitry Andric                                  CodeGenFunction::GuardKind::VariableGuard, &D);
27190b57cec5SDimitry Andric 
27200b57cec5SDimitry Andric     // Set our bit in the guard variable and emit the initializer and add a global
27210b57cec5SDimitry Andric     // destructor if appropriate.
27220b57cec5SDimitry Andric     CGF.EmitBlock(InitBlock);
27230b57cec5SDimitry Andric     Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
27240b57cec5SDimitry Andric     CGF.EHStack.pushCleanup<ResetGuardBit>(EHCleanup, GuardAddr, GuardNum);
27250b57cec5SDimitry Andric     CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
27260b57cec5SDimitry Andric     CGF.PopCleanupBlock();
27270b57cec5SDimitry Andric     Builder.CreateBr(EndBlock);
27280b57cec5SDimitry Andric 
27290b57cec5SDimitry Andric     // Continue.
27300b57cec5SDimitry Andric     CGF.EmitBlock(EndBlock);
27310b57cec5SDimitry Andric   } else {
27320b57cec5SDimitry Andric     // Pseudo code for the test:
27330b57cec5SDimitry Andric     // if (TSS > _Init_thread_epoch) {
27340b57cec5SDimitry Andric     //   _Init_thread_header(&TSS);
27350b57cec5SDimitry Andric     //   if (TSS == -1) {
27360b57cec5SDimitry Andric     //     ... initialize the object ...;
27370b57cec5SDimitry Andric     //     _Init_thread_footer(&TSS);
27380b57cec5SDimitry Andric     //   }
27390b57cec5SDimitry Andric     // }
27400b57cec5SDimitry Andric     //
27410b57cec5SDimitry Andric     // The algorithm is almost identical to what can be found in the appendix
27420b57cec5SDimitry Andric     // found in N2325.
27430b57cec5SDimitry Andric 
27440b57cec5SDimitry Andric     // This BasicBLock determines whether or not we have any work to do.
27450b57cec5SDimitry Andric     llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
27460b57cec5SDimitry Andric     FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
27470b57cec5SDimitry Andric     llvm::LoadInst *InitThreadEpoch =
27480b57cec5SDimitry Andric         Builder.CreateLoad(getInitThreadEpochPtr(CGM));
27490b57cec5SDimitry Andric     llvm::Value *IsUninitialized =
27500b57cec5SDimitry Andric         Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
27510b57cec5SDimitry Andric     llvm::BasicBlock *AttemptInitBlock = CGF.createBasicBlock("init.attempt");
27520b57cec5SDimitry Andric     llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
27530b57cec5SDimitry Andric     CGF.EmitCXXGuardedInitBranch(IsUninitialized, AttemptInitBlock, EndBlock,
27540b57cec5SDimitry Andric                                  CodeGenFunction::GuardKind::VariableGuard, &D);
27550b57cec5SDimitry Andric 
27560b57cec5SDimitry Andric     // This BasicBlock attempts to determine whether or not this thread is
27570b57cec5SDimitry Andric     // responsible for doing the initialization.
27580b57cec5SDimitry Andric     CGF.EmitBlock(AttemptInitBlock);
27590b57cec5SDimitry Andric     CGF.EmitNounwindRuntimeCall(getInitThreadHeaderFn(CGM),
27600b57cec5SDimitry Andric                                 GuardAddr.getPointer());
27610b57cec5SDimitry Andric     llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
27620b57cec5SDimitry Andric     SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
27630b57cec5SDimitry Andric     llvm::Value *ShouldDoInit =
27640b57cec5SDimitry Andric         Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
27650b57cec5SDimitry Andric     llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
27660b57cec5SDimitry Andric     Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
27670b57cec5SDimitry Andric 
27680b57cec5SDimitry Andric     // Ok, we ended up getting selected as the initializing thread.
27690b57cec5SDimitry Andric     CGF.EmitBlock(InitBlock);
27700b57cec5SDimitry Andric     CGF.EHStack.pushCleanup<CallInitThreadAbort>(EHCleanup, GuardAddr);
27710b57cec5SDimitry Andric     CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
27720b57cec5SDimitry Andric     CGF.PopCleanupBlock();
27730b57cec5SDimitry Andric     CGF.EmitNounwindRuntimeCall(getInitThreadFooterFn(CGM),
27740b57cec5SDimitry Andric                                 GuardAddr.getPointer());
27750b57cec5SDimitry Andric     Builder.CreateBr(EndBlock);
27760b57cec5SDimitry Andric 
27770b57cec5SDimitry Andric     CGF.EmitBlock(EndBlock);
27780b57cec5SDimitry Andric   }
27790b57cec5SDimitry Andric }
27800b57cec5SDimitry Andric 
27810b57cec5SDimitry Andric bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
27820b57cec5SDimitry Andric   // Null-ness for function memptrs only depends on the first field, which is
27830b57cec5SDimitry Andric   // the function pointer.  The rest don't matter, so we can zero initialize.
27840b57cec5SDimitry Andric   if (MPT->isMemberFunctionPointer())
27850b57cec5SDimitry Andric     return true;
27860b57cec5SDimitry Andric 
27870b57cec5SDimitry Andric   // The virtual base adjustment field is always -1 for null, so if we have one
27880b57cec5SDimitry Andric   // we can't zero initialize.  The field offset is sometimes also -1 if 0 is a
27890b57cec5SDimitry Andric   // valid field offset.
27900b57cec5SDimitry Andric   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
2791480093f4SDimitry Andric   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2792480093f4SDimitry Andric   return (!inheritanceModelHasVBTableOffsetField(Inheritance) &&
27930b57cec5SDimitry Andric           RD->nullFieldOffsetIsZero());
27940b57cec5SDimitry Andric }
27950b57cec5SDimitry Andric 
27960b57cec5SDimitry Andric llvm::Type *
27970b57cec5SDimitry Andric MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
27980b57cec5SDimitry Andric   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
2799480093f4SDimitry Andric   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
28000b57cec5SDimitry Andric   llvm::SmallVector<llvm::Type *, 4> fields;
28010b57cec5SDimitry Andric   if (MPT->isMemberFunctionPointer())
28020b57cec5SDimitry Andric     fields.push_back(CGM.VoidPtrTy);  // FunctionPointerOrVirtualThunk
28030b57cec5SDimitry Andric   else
28040b57cec5SDimitry Andric     fields.push_back(CGM.IntTy);  // FieldOffset
28050b57cec5SDimitry Andric 
2806480093f4SDimitry Andric   if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
28070b57cec5SDimitry Andric                                        Inheritance))
28080b57cec5SDimitry Andric     fields.push_back(CGM.IntTy);
2809480093f4SDimitry Andric   if (inheritanceModelHasVBPtrOffsetField(Inheritance))
28100b57cec5SDimitry Andric     fields.push_back(CGM.IntTy);
2811480093f4SDimitry Andric   if (inheritanceModelHasVBTableOffsetField(Inheritance))
28120b57cec5SDimitry Andric     fields.push_back(CGM.IntTy);  // VirtualBaseAdjustmentOffset
28130b57cec5SDimitry Andric 
28140b57cec5SDimitry Andric   if (fields.size() == 1)
28150b57cec5SDimitry Andric     return fields[0];
28160b57cec5SDimitry Andric   return llvm::StructType::get(CGM.getLLVMContext(), fields);
28170b57cec5SDimitry Andric }
28180b57cec5SDimitry Andric 
28190b57cec5SDimitry Andric void MicrosoftCXXABI::
28200b57cec5SDimitry Andric GetNullMemberPointerFields(const MemberPointerType *MPT,
28210b57cec5SDimitry Andric                            llvm::SmallVectorImpl<llvm::Constant *> &fields) {
28220b57cec5SDimitry Andric   assert(fields.empty());
28230b57cec5SDimitry Andric   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
2824480093f4SDimitry Andric   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
28250b57cec5SDimitry Andric   if (MPT->isMemberFunctionPointer()) {
28260b57cec5SDimitry Andric     // FunctionPointerOrVirtualThunk
28270b57cec5SDimitry Andric     fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
28280b57cec5SDimitry Andric   } else {
28290b57cec5SDimitry Andric     if (RD->nullFieldOffsetIsZero())
28300b57cec5SDimitry Andric       fields.push_back(getZeroInt());  // FieldOffset
28310b57cec5SDimitry Andric     else
28320b57cec5SDimitry Andric       fields.push_back(getAllOnesInt());  // FieldOffset
28330b57cec5SDimitry Andric   }
28340b57cec5SDimitry Andric 
2835480093f4SDimitry Andric   if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
28360b57cec5SDimitry Andric                                        Inheritance))
28370b57cec5SDimitry Andric     fields.push_back(getZeroInt());
2838480093f4SDimitry Andric   if (inheritanceModelHasVBPtrOffsetField(Inheritance))
28390b57cec5SDimitry Andric     fields.push_back(getZeroInt());
2840480093f4SDimitry Andric   if (inheritanceModelHasVBTableOffsetField(Inheritance))
28410b57cec5SDimitry Andric     fields.push_back(getAllOnesInt());
28420b57cec5SDimitry Andric }
28430b57cec5SDimitry Andric 
28440b57cec5SDimitry Andric llvm::Constant *
28450b57cec5SDimitry Andric MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
28460b57cec5SDimitry Andric   llvm::SmallVector<llvm::Constant *, 4> fields;
28470b57cec5SDimitry Andric   GetNullMemberPointerFields(MPT, fields);
28480b57cec5SDimitry Andric   if (fields.size() == 1)
28490b57cec5SDimitry Andric     return fields[0];
28500b57cec5SDimitry Andric   llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
28510b57cec5SDimitry Andric   assert(Res->getType() == ConvertMemberPointerType(MPT));
28520b57cec5SDimitry Andric   return Res;
28530b57cec5SDimitry Andric }
28540b57cec5SDimitry Andric 
28550b57cec5SDimitry Andric llvm::Constant *
28560b57cec5SDimitry Andric MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
28570b57cec5SDimitry Andric                                        bool IsMemberFunction,
28580b57cec5SDimitry Andric                                        const CXXRecordDecl *RD,
28590b57cec5SDimitry Andric                                        CharUnits NonVirtualBaseAdjustment,
28600b57cec5SDimitry Andric                                        unsigned VBTableIndex) {
2861480093f4SDimitry Andric   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
28620b57cec5SDimitry Andric 
28630b57cec5SDimitry Andric   // Single inheritance class member pointer are represented as scalars instead
28640b57cec5SDimitry Andric   // of aggregates.
2865480093f4SDimitry Andric   if (inheritanceModelHasOnlyOneField(IsMemberFunction, Inheritance))
28660b57cec5SDimitry Andric     return FirstField;
28670b57cec5SDimitry Andric 
28680b57cec5SDimitry Andric   llvm::SmallVector<llvm::Constant *, 4> fields;
28690b57cec5SDimitry Andric   fields.push_back(FirstField);
28700b57cec5SDimitry Andric 
2871480093f4SDimitry Andric   if (inheritanceModelHasNVOffsetField(IsMemberFunction, Inheritance))
28720b57cec5SDimitry Andric     fields.push_back(llvm::ConstantInt::get(
28730b57cec5SDimitry Andric       CGM.IntTy, NonVirtualBaseAdjustment.getQuantity()));
28740b57cec5SDimitry Andric 
2875480093f4SDimitry Andric   if (inheritanceModelHasVBPtrOffsetField(Inheritance)) {
28760b57cec5SDimitry Andric     CharUnits Offs = CharUnits::Zero();
28770b57cec5SDimitry Andric     if (VBTableIndex)
28780b57cec5SDimitry Andric       Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
28790b57cec5SDimitry Andric     fields.push_back(llvm::ConstantInt::get(CGM.IntTy, Offs.getQuantity()));
28800b57cec5SDimitry Andric   }
28810b57cec5SDimitry Andric 
28820b57cec5SDimitry Andric   // The rest of the fields are adjusted by conversions to a more derived class.
2883480093f4SDimitry Andric   if (inheritanceModelHasVBTableOffsetField(Inheritance))
28840b57cec5SDimitry Andric     fields.push_back(llvm::ConstantInt::get(CGM.IntTy, VBTableIndex));
28850b57cec5SDimitry Andric 
28860b57cec5SDimitry Andric   return llvm::ConstantStruct::getAnon(fields);
28870b57cec5SDimitry Andric }
28880b57cec5SDimitry Andric 
28890b57cec5SDimitry Andric llvm::Constant *
28900b57cec5SDimitry Andric MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
28910b57cec5SDimitry Andric                                        CharUnits offset) {
2892c14a5a88SDimitry Andric   return EmitMemberDataPointer(MPT->getMostRecentCXXRecordDecl(), offset);
2893c14a5a88SDimitry Andric }
2894c14a5a88SDimitry Andric 
2895c14a5a88SDimitry Andric llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(const CXXRecordDecl *RD,
2896c14a5a88SDimitry Andric                                                        CharUnits offset) {
28970b57cec5SDimitry Andric   if (RD->getMSInheritanceModel() ==
2898480093f4SDimitry Andric       MSInheritanceModel::Virtual)
28990b57cec5SDimitry Andric     offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
29000b57cec5SDimitry Andric   llvm::Constant *FirstField =
29010b57cec5SDimitry Andric     llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity());
29020b57cec5SDimitry Andric   return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD,
29030b57cec5SDimitry Andric                                CharUnits::Zero(), /*VBTableIndex=*/0);
29040b57cec5SDimitry Andric }
29050b57cec5SDimitry Andric 
29060b57cec5SDimitry Andric llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP,
29070b57cec5SDimitry Andric                                                    QualType MPType) {
29080b57cec5SDimitry Andric   const MemberPointerType *DstTy = MPType->castAs<MemberPointerType>();
29090b57cec5SDimitry Andric   const ValueDecl *MPD = MP.getMemberPointerDecl();
29100b57cec5SDimitry Andric   if (!MPD)
29110b57cec5SDimitry Andric     return EmitNullMemberPointer(DstTy);
29120b57cec5SDimitry Andric 
29130b57cec5SDimitry Andric   ASTContext &Ctx = getContext();
29140b57cec5SDimitry Andric   ArrayRef<const CXXRecordDecl *> MemberPointerPath = MP.getMemberPointerPath();
29150b57cec5SDimitry Andric 
29160b57cec5SDimitry Andric   llvm::Constant *C;
29170b57cec5SDimitry Andric   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
29180b57cec5SDimitry Andric     C = EmitMemberFunctionPointer(MD);
29190b57cec5SDimitry Andric   } else {
2920c14a5a88SDimitry Andric     // For a pointer to data member, start off with the offset of the field in
2921c14a5a88SDimitry Andric     // the class in which it was declared, and convert from there if necessary.
2922c14a5a88SDimitry Andric     // For indirect field decls, get the outermost anonymous field and use the
2923c14a5a88SDimitry Andric     // parent class.
29240b57cec5SDimitry Andric     CharUnits FieldOffset = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(MPD));
2925c14a5a88SDimitry Andric     const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2926c14a5a88SDimitry Andric     if (!FD)
2927c14a5a88SDimitry Andric       FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
2928c14a5a88SDimitry Andric     const CXXRecordDecl *RD = cast<CXXRecordDecl>(FD->getParent());
2929c14a5a88SDimitry Andric     RD = RD->getMostRecentNonInjectedDecl();
2930c14a5a88SDimitry Andric     C = EmitMemberDataPointer(RD, FieldOffset);
29310b57cec5SDimitry Andric   }
29320b57cec5SDimitry Andric 
29330b57cec5SDimitry Andric   if (!MemberPointerPath.empty()) {
29340b57cec5SDimitry Andric     const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
29350b57cec5SDimitry Andric     const Type *SrcRecTy = Ctx.getTypeDeclType(SrcRD).getTypePtr();
29360b57cec5SDimitry Andric     const MemberPointerType *SrcTy =
29370b57cec5SDimitry Andric         Ctx.getMemberPointerType(DstTy->getPointeeType(), SrcRecTy)
29380b57cec5SDimitry Andric             ->castAs<MemberPointerType>();
29390b57cec5SDimitry Andric 
29400b57cec5SDimitry Andric     bool DerivedMember = MP.isMemberPointerToDerivedMember();
29410b57cec5SDimitry Andric     SmallVector<const CXXBaseSpecifier *, 4> DerivedToBasePath;
29420b57cec5SDimitry Andric     const CXXRecordDecl *PrevRD = SrcRD;
29430b57cec5SDimitry Andric     for (const CXXRecordDecl *PathElem : MemberPointerPath) {
29440b57cec5SDimitry Andric       const CXXRecordDecl *Base = nullptr;
29450b57cec5SDimitry Andric       const CXXRecordDecl *Derived = nullptr;
29460b57cec5SDimitry Andric       if (DerivedMember) {
29470b57cec5SDimitry Andric         Base = PathElem;
29480b57cec5SDimitry Andric         Derived = PrevRD;
29490b57cec5SDimitry Andric       } else {
29500b57cec5SDimitry Andric         Base = PrevRD;
29510b57cec5SDimitry Andric         Derived = PathElem;
29520b57cec5SDimitry Andric       }
29530b57cec5SDimitry Andric       for (const CXXBaseSpecifier &BS : Derived->bases())
29540b57cec5SDimitry Andric         if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
29550b57cec5SDimitry Andric             Base->getCanonicalDecl())
29560b57cec5SDimitry Andric           DerivedToBasePath.push_back(&BS);
29570b57cec5SDimitry Andric       PrevRD = PathElem;
29580b57cec5SDimitry Andric     }
29590b57cec5SDimitry Andric     assert(DerivedToBasePath.size() == MemberPointerPath.size());
29600b57cec5SDimitry Andric 
29610b57cec5SDimitry Andric     CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
29620b57cec5SDimitry Andric                                 : CK_BaseToDerivedMemberPointer;
29630b57cec5SDimitry Andric     C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
29640b57cec5SDimitry Andric                                     DerivedToBasePath.end(), C);
29650b57cec5SDimitry Andric   }
29660b57cec5SDimitry Andric   return C;
29670b57cec5SDimitry Andric }
29680b57cec5SDimitry Andric 
29690b57cec5SDimitry Andric llvm::Constant *
29700b57cec5SDimitry Andric MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
29710b57cec5SDimitry Andric   assert(MD->isInstance() && "Member function must not be static!");
29720b57cec5SDimitry Andric 
29730b57cec5SDimitry Andric   CharUnits NonVirtualBaseAdjustment = CharUnits::Zero();
29740b57cec5SDimitry Andric   const CXXRecordDecl *RD = MD->getParent()->getMostRecentNonInjectedDecl();
29750b57cec5SDimitry Andric   CodeGenTypes &Types = CGM.getTypes();
29760b57cec5SDimitry Andric 
29770b57cec5SDimitry Andric   unsigned VBTableIndex = 0;
29780b57cec5SDimitry Andric   llvm::Constant *FirstField;
29790b57cec5SDimitry Andric   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
29800b57cec5SDimitry Andric   if (!MD->isVirtual()) {
29810b57cec5SDimitry Andric     llvm::Type *Ty;
29820b57cec5SDimitry Andric     // Check whether the function has a computable LLVM signature.
29830b57cec5SDimitry Andric     if (Types.isFuncTypeConvertible(FPT)) {
29840b57cec5SDimitry Andric       // The function has a computable LLVM signature; use the correct type.
29850b57cec5SDimitry Andric       Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
29860b57cec5SDimitry Andric     } else {
29870b57cec5SDimitry Andric       // Use an arbitrary non-function type to tell GetAddrOfFunction that the
29880b57cec5SDimitry Andric       // function type is incomplete.
29890b57cec5SDimitry Andric       Ty = CGM.PtrDiffTy;
29900b57cec5SDimitry Andric     }
29910b57cec5SDimitry Andric     FirstField = CGM.GetAddrOfFunction(MD, Ty);
29920b57cec5SDimitry Andric   } else {
29930b57cec5SDimitry Andric     auto &VTableContext = CGM.getMicrosoftVTableContext();
29940b57cec5SDimitry Andric     MethodVFTableLocation ML = VTableContext.getMethodVFTableLocation(MD);
29950b57cec5SDimitry Andric     FirstField = EmitVirtualMemPtrThunk(MD, ML);
29960b57cec5SDimitry Andric     // Include the vfptr adjustment if the method is in a non-primary vftable.
29970b57cec5SDimitry Andric     NonVirtualBaseAdjustment += ML.VFPtrOffset;
29980b57cec5SDimitry Andric     if (ML.VBase)
29990b57cec5SDimitry Andric       VBTableIndex = VTableContext.getVBTableIndex(RD, ML.VBase) * 4;
30000b57cec5SDimitry Andric   }
30010b57cec5SDimitry Andric 
30020b57cec5SDimitry Andric   if (VBTableIndex == 0 &&
30030b57cec5SDimitry Andric       RD->getMSInheritanceModel() ==
3004480093f4SDimitry Andric           MSInheritanceModel::Virtual)
30050b57cec5SDimitry Andric     NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
30060b57cec5SDimitry Andric 
30070b57cec5SDimitry Andric   // The rest of the fields are common with data member pointers.
30080b57cec5SDimitry Andric   return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD,
30090b57cec5SDimitry Andric                                NonVirtualBaseAdjustment, VBTableIndex);
30100b57cec5SDimitry Andric }
30110b57cec5SDimitry Andric 
30120b57cec5SDimitry Andric /// Member pointers are the same if they're either bitwise identical *or* both
30130b57cec5SDimitry Andric /// null.  Null-ness for function members is determined by the first field,
30140b57cec5SDimitry Andric /// while for data member pointers we must compare all fields.
30150b57cec5SDimitry Andric llvm::Value *
30160b57cec5SDimitry Andric MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
30170b57cec5SDimitry Andric                                              llvm::Value *L,
30180b57cec5SDimitry Andric                                              llvm::Value *R,
30190b57cec5SDimitry Andric                                              const MemberPointerType *MPT,
30200b57cec5SDimitry Andric                                              bool Inequality) {
30210b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
30220b57cec5SDimitry Andric 
30230b57cec5SDimitry Andric   // Handle != comparisons by switching the sense of all boolean operations.
30240b57cec5SDimitry Andric   llvm::ICmpInst::Predicate Eq;
30250b57cec5SDimitry Andric   llvm::Instruction::BinaryOps And, Or;
30260b57cec5SDimitry Andric   if (Inequality) {
30270b57cec5SDimitry Andric     Eq = llvm::ICmpInst::ICMP_NE;
30280b57cec5SDimitry Andric     And = llvm::Instruction::Or;
30290b57cec5SDimitry Andric     Or = llvm::Instruction::And;
30300b57cec5SDimitry Andric   } else {
30310b57cec5SDimitry Andric     Eq = llvm::ICmpInst::ICMP_EQ;
30320b57cec5SDimitry Andric     And = llvm::Instruction::And;
30330b57cec5SDimitry Andric     Or = llvm::Instruction::Or;
30340b57cec5SDimitry Andric   }
30350b57cec5SDimitry Andric 
30360b57cec5SDimitry Andric   // If this is a single field member pointer (single inheritance), this is a
30370b57cec5SDimitry Andric   // single icmp.
30380b57cec5SDimitry Andric   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
3039480093f4SDimitry Andric   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
3040480093f4SDimitry Andric   if (inheritanceModelHasOnlyOneField(MPT->isMemberFunctionPointer(),
30410b57cec5SDimitry Andric                                       Inheritance))
30420b57cec5SDimitry Andric     return Builder.CreateICmp(Eq, L, R);
30430b57cec5SDimitry Andric 
30440b57cec5SDimitry Andric   // Compare the first field.
30450b57cec5SDimitry Andric   llvm::Value *L0 = Builder.CreateExtractValue(L, 0, "lhs.0");
30460b57cec5SDimitry Andric   llvm::Value *R0 = Builder.CreateExtractValue(R, 0, "rhs.0");
30470b57cec5SDimitry Andric   llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0, "memptr.cmp.first");
30480b57cec5SDimitry Andric 
30490b57cec5SDimitry Andric   // Compare everything other than the first field.
30500b57cec5SDimitry Andric   llvm::Value *Res = nullptr;
30510b57cec5SDimitry Andric   llvm::StructType *LType = cast<llvm::StructType>(L->getType());
30520b57cec5SDimitry Andric   for (unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
30530b57cec5SDimitry Andric     llvm::Value *LF = Builder.CreateExtractValue(L, I);
30540b57cec5SDimitry Andric     llvm::Value *RF = Builder.CreateExtractValue(R, I);
30550b57cec5SDimitry Andric     llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF, "memptr.cmp.rest");
30560b57cec5SDimitry Andric     if (Res)
30570b57cec5SDimitry Andric       Res = Builder.CreateBinOp(And, Res, Cmp);
30580b57cec5SDimitry Andric     else
30590b57cec5SDimitry Andric       Res = Cmp;
30600b57cec5SDimitry Andric   }
30610b57cec5SDimitry Andric 
30620b57cec5SDimitry Andric   // Check if the first field is 0 if this is a function pointer.
30630b57cec5SDimitry Andric   if (MPT->isMemberFunctionPointer()) {
30640b57cec5SDimitry Andric     // (l1 == r1 && ...) || l0 == 0
30650b57cec5SDimitry Andric     llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
30660b57cec5SDimitry Andric     llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero, "memptr.cmp.iszero");
30670b57cec5SDimitry Andric     Res = Builder.CreateBinOp(Or, Res, IsZero);
30680b57cec5SDimitry Andric   }
30690b57cec5SDimitry Andric 
30700b57cec5SDimitry Andric   // Combine the comparison of the first field, which must always be true for
30710b57cec5SDimitry Andric   // this comparison to succeeed.
30720b57cec5SDimitry Andric   return Builder.CreateBinOp(And, Res, Cmp0, "memptr.cmp");
30730b57cec5SDimitry Andric }
30740b57cec5SDimitry Andric 
30750b57cec5SDimitry Andric llvm::Value *
30760b57cec5SDimitry Andric MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
30770b57cec5SDimitry Andric                                             llvm::Value *MemPtr,
30780b57cec5SDimitry Andric                                             const MemberPointerType *MPT) {
30790b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
30800b57cec5SDimitry Andric   llvm::SmallVector<llvm::Constant *, 4> fields;
30810b57cec5SDimitry Andric   // We only need one field for member functions.
30820b57cec5SDimitry Andric   if (MPT->isMemberFunctionPointer())
30830b57cec5SDimitry Andric     fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
30840b57cec5SDimitry Andric   else
30850b57cec5SDimitry Andric     GetNullMemberPointerFields(MPT, fields);
30860b57cec5SDimitry Andric   assert(!fields.empty());
30870b57cec5SDimitry Andric   llvm::Value *FirstField = MemPtr;
30880b57cec5SDimitry Andric   if (MemPtr->getType()->isStructTy())
30890b57cec5SDimitry Andric     FirstField = Builder.CreateExtractValue(MemPtr, 0);
30900b57cec5SDimitry Andric   llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0], "memptr.cmp0");
30910b57cec5SDimitry Andric 
30920b57cec5SDimitry Andric   // For function member pointers, we only need to test the function pointer
30930b57cec5SDimitry Andric   // field.  The other fields if any can be garbage.
30940b57cec5SDimitry Andric   if (MPT->isMemberFunctionPointer())
30950b57cec5SDimitry Andric     return Res;
30960b57cec5SDimitry Andric 
30970b57cec5SDimitry Andric   // Otherwise, emit a series of compares and combine the results.
30980b57cec5SDimitry Andric   for (int I = 1, E = fields.size(); I < E; ++I) {
30990b57cec5SDimitry Andric     llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
31000b57cec5SDimitry Andric     llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I], "memptr.cmp");
31010b57cec5SDimitry Andric     Res = Builder.CreateOr(Res, Next, "memptr.tobool");
31020b57cec5SDimitry Andric   }
31030b57cec5SDimitry Andric   return Res;
31040b57cec5SDimitry Andric }
31050b57cec5SDimitry Andric 
31060b57cec5SDimitry Andric bool MicrosoftCXXABI::MemberPointerConstantIsNull(const MemberPointerType *MPT,
31070b57cec5SDimitry Andric                                                   llvm::Constant *Val) {
31080b57cec5SDimitry Andric   // Function pointers are null if the pointer in the first field is null.
31090b57cec5SDimitry Andric   if (MPT->isMemberFunctionPointer()) {
31100b57cec5SDimitry Andric     llvm::Constant *FirstField = Val->getType()->isStructTy() ?
31110b57cec5SDimitry Andric       Val->getAggregateElement(0U) : Val;
31120b57cec5SDimitry Andric     return FirstField->isNullValue();
31130b57cec5SDimitry Andric   }
31140b57cec5SDimitry Andric 
31150b57cec5SDimitry Andric   // If it's not a function pointer and it's zero initializable, we can easily
31160b57cec5SDimitry Andric   // check zero.
31170b57cec5SDimitry Andric   if (isZeroInitializable(MPT) && Val->isNullValue())
31180b57cec5SDimitry Andric     return true;
31190b57cec5SDimitry Andric 
31200b57cec5SDimitry Andric   // Otherwise, break down all the fields for comparison.  Hopefully these
31210b57cec5SDimitry Andric   // little Constants are reused, while a big null struct might not be.
31220b57cec5SDimitry Andric   llvm::SmallVector<llvm::Constant *, 4> Fields;
31230b57cec5SDimitry Andric   GetNullMemberPointerFields(MPT, Fields);
31240b57cec5SDimitry Andric   if (Fields.size() == 1) {
31250b57cec5SDimitry Andric     assert(Val->getType()->isIntegerTy());
31260b57cec5SDimitry Andric     return Val == Fields[0];
31270b57cec5SDimitry Andric   }
31280b57cec5SDimitry Andric 
31290b57cec5SDimitry Andric   unsigned I, E;
31300b57cec5SDimitry Andric   for (I = 0, E = Fields.size(); I != E; ++I) {
31310b57cec5SDimitry Andric     if (Val->getAggregateElement(I) != Fields[I])
31320b57cec5SDimitry Andric       break;
31330b57cec5SDimitry Andric   }
31340b57cec5SDimitry Andric   return I == E;
31350b57cec5SDimitry Andric }
31360b57cec5SDimitry Andric 
31370b57cec5SDimitry Andric llvm::Value *
31380b57cec5SDimitry Andric MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
31390b57cec5SDimitry Andric                                          Address This,
31400b57cec5SDimitry Andric                                          llvm::Value *VBPtrOffset,
31410b57cec5SDimitry Andric                                          llvm::Value *VBTableOffset,
31420b57cec5SDimitry Andric                                          llvm::Value **VBPtrOut) {
31430b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
31440b57cec5SDimitry Andric   // Load the vbtable pointer from the vbptr in the instance.
31450fca6ea1SDimitry Andric   llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
31460fca6ea1SDimitry Andric       CGM.Int8Ty, This.emitRawPointer(CGF), VBPtrOffset, "vbptr");
314706c3fb27SDimitry Andric   if (VBPtrOut)
314806c3fb27SDimitry Andric     *VBPtrOut = VBPtr;
31490b57cec5SDimitry Andric 
31500b57cec5SDimitry Andric   CharUnits VBPtrAlign;
31510b57cec5SDimitry Andric   if (auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
31520b57cec5SDimitry Andric     VBPtrAlign = This.getAlignment().alignmentAtOffset(
31530b57cec5SDimitry Andric                                    CharUnits::fromQuantity(CI->getSExtValue()));
31540b57cec5SDimitry Andric   } else {
31550b57cec5SDimitry Andric     VBPtrAlign = CGF.getPointerAlign();
31560b57cec5SDimitry Andric   }
31570b57cec5SDimitry Andric 
3158fe6060f1SDimitry Andric   llvm::Value *VBTable = Builder.CreateAlignedLoad(
3159fe6060f1SDimitry Andric       CGM.Int32Ty->getPointerTo(0), VBPtr, VBPtrAlign, "vbtable");
31600b57cec5SDimitry Andric 
31610b57cec5SDimitry Andric   // Translate from byte offset to table index. It improves analyzability.
31620b57cec5SDimitry Andric   llvm::Value *VBTableIndex = Builder.CreateAShr(
31630b57cec5SDimitry Andric       VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
31640b57cec5SDimitry Andric       "vbtindex", /*isExact=*/true);
31650b57cec5SDimitry Andric 
31660b57cec5SDimitry Andric   // Load an i32 offset from the vb-table.
3167fe6060f1SDimitry Andric   llvm::Value *VBaseOffs =
3168fe6060f1SDimitry Andric       Builder.CreateInBoundsGEP(CGM.Int32Ty, VBTable, VBTableIndex);
3169fe6060f1SDimitry Andric   return Builder.CreateAlignedLoad(CGM.Int32Ty, VBaseOffs,
3170fe6060f1SDimitry Andric                                    CharUnits::fromQuantity(4), "vbase_offs");
31710b57cec5SDimitry Andric }
31720b57cec5SDimitry Andric 
31730b57cec5SDimitry Andric // Returns an adjusted base cast to i8*, since we do more address arithmetic on
31740b57cec5SDimitry Andric // it.
31750b57cec5SDimitry Andric llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
31760b57cec5SDimitry Andric     CodeGenFunction &CGF, const Expr *E, const CXXRecordDecl *RD,
31770b57cec5SDimitry Andric     Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
31780b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
317906c3fb27SDimitry Andric   Base = Base.withElementType(CGM.Int8Ty);
31800b57cec5SDimitry Andric   llvm::BasicBlock *OriginalBB = nullptr;
31810b57cec5SDimitry Andric   llvm::BasicBlock *SkipAdjustBB = nullptr;
31820b57cec5SDimitry Andric   llvm::BasicBlock *VBaseAdjustBB = nullptr;
31830b57cec5SDimitry Andric 
31840b57cec5SDimitry Andric   // In the unspecified inheritance model, there might not be a vbtable at all,
31850b57cec5SDimitry Andric   // in which case we need to skip the virtual base lookup.  If there is a
31860b57cec5SDimitry Andric   // vbtable, the first entry is a no-op entry that gives back the original
31870b57cec5SDimitry Andric   // base, so look for a virtual base adjustment offset of zero.
31880b57cec5SDimitry Andric   if (VBPtrOffset) {
31890b57cec5SDimitry Andric     OriginalBB = Builder.GetInsertBlock();
31900b57cec5SDimitry Andric     VBaseAdjustBB = CGF.createBasicBlock("memptr.vadjust");
31910b57cec5SDimitry Andric     SkipAdjustBB = CGF.createBasicBlock("memptr.skip_vadjust");
31920b57cec5SDimitry Andric     llvm::Value *IsVirtual =
31930b57cec5SDimitry Andric       Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
31940b57cec5SDimitry Andric                            "memptr.is_vbase");
31950b57cec5SDimitry Andric     Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
31960b57cec5SDimitry Andric     CGF.EmitBlock(VBaseAdjustBB);
31970b57cec5SDimitry Andric   }
31980b57cec5SDimitry Andric 
31990b57cec5SDimitry Andric   // If we weren't given a dynamic vbptr offset, RD should be complete and we'll
32000b57cec5SDimitry Andric   // know the vbptr offset.
32010b57cec5SDimitry Andric   if (!VBPtrOffset) {
32020b57cec5SDimitry Andric     CharUnits offs = CharUnits::Zero();
32030b57cec5SDimitry Andric     if (!RD->hasDefinition()) {
32040b57cec5SDimitry Andric       DiagnosticsEngine &Diags = CGF.CGM.getDiags();
32050b57cec5SDimitry Andric       unsigned DiagID = Diags.getCustomDiagID(
32060b57cec5SDimitry Andric           DiagnosticsEngine::Error,
32070b57cec5SDimitry Andric           "member pointer representation requires a "
32080b57cec5SDimitry Andric           "complete class type for %0 to perform this expression");
32090b57cec5SDimitry Andric       Diags.Report(E->getExprLoc(), DiagID) << RD << E->getSourceRange();
32100b57cec5SDimitry Andric     } else if (RD->getNumVBases())
32110b57cec5SDimitry Andric       offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
32120b57cec5SDimitry Andric     VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity());
32130b57cec5SDimitry Andric   }
32140b57cec5SDimitry Andric   llvm::Value *VBPtr = nullptr;
32150b57cec5SDimitry Andric   llvm::Value *VBaseOffs =
32160b57cec5SDimitry Andric     GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
3217fe6060f1SDimitry Andric   llvm::Value *AdjustedBase =
3218fe6060f1SDimitry Andric     Builder.CreateInBoundsGEP(CGM.Int8Ty, VBPtr, VBaseOffs);
32190b57cec5SDimitry Andric 
32200b57cec5SDimitry Andric   // Merge control flow with the case where we didn't have to adjust.
32210b57cec5SDimitry Andric   if (VBaseAdjustBB) {
32220b57cec5SDimitry Andric     Builder.CreateBr(SkipAdjustBB);
32230b57cec5SDimitry Andric     CGF.EmitBlock(SkipAdjustBB);
32240b57cec5SDimitry Andric     llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base");
32250fca6ea1SDimitry Andric     Phi->addIncoming(Base.emitRawPointer(CGF), OriginalBB);
32260b57cec5SDimitry Andric     Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
32270b57cec5SDimitry Andric     return Phi;
32280b57cec5SDimitry Andric   }
32290b57cec5SDimitry Andric   return AdjustedBase;
32300b57cec5SDimitry Andric }
32310b57cec5SDimitry Andric 
32320b57cec5SDimitry Andric llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
32330b57cec5SDimitry Andric     CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr,
32340b57cec5SDimitry Andric     const MemberPointerType *MPT) {
32350b57cec5SDimitry Andric   assert(MPT->isMemberDataPointer());
32360b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
32370b57cec5SDimitry Andric   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
3238480093f4SDimitry Andric   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
32390b57cec5SDimitry Andric 
32400b57cec5SDimitry Andric   // Extract the fields we need, regardless of model.  We'll apply them if we
32410b57cec5SDimitry Andric   // have them.
32420b57cec5SDimitry Andric   llvm::Value *FieldOffset = MemPtr;
32430b57cec5SDimitry Andric   llvm::Value *VirtualBaseAdjustmentOffset = nullptr;
32440b57cec5SDimitry Andric   llvm::Value *VBPtrOffset = nullptr;
32450b57cec5SDimitry Andric   if (MemPtr->getType()->isStructTy()) {
32460b57cec5SDimitry Andric     // We need to extract values.
32470b57cec5SDimitry Andric     unsigned I = 0;
32480b57cec5SDimitry Andric     FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3249480093f4SDimitry Andric     if (inheritanceModelHasVBPtrOffsetField(Inheritance))
32500b57cec5SDimitry Andric       VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3251480093f4SDimitry Andric     if (inheritanceModelHasVBTableOffsetField(Inheritance))
32520b57cec5SDimitry Andric       VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
32530b57cec5SDimitry Andric   }
32540b57cec5SDimitry Andric 
32550b57cec5SDimitry Andric   llvm::Value *Addr;
32560b57cec5SDimitry Andric   if (VirtualBaseAdjustmentOffset) {
32570b57cec5SDimitry Andric     Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
32580b57cec5SDimitry Andric                              VBPtrOffset);
32590b57cec5SDimitry Andric   } else {
32600fca6ea1SDimitry Andric     Addr = Base.emitRawPointer(CGF);
32610b57cec5SDimitry Andric   }
32620b57cec5SDimitry Andric 
32630b57cec5SDimitry Andric   // Apply the offset, which we assume is non-null.
32645f757f3fSDimitry Andric   return Builder.CreateInBoundsGEP(CGF.Int8Ty, Addr, FieldOffset,
3265fe6060f1SDimitry Andric                                    "memptr.offset");
32660b57cec5SDimitry Andric }
32670b57cec5SDimitry Andric 
32680b57cec5SDimitry Andric llvm::Value *
32690b57cec5SDimitry Andric MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
32700b57cec5SDimitry Andric                                              const CastExpr *E,
32710b57cec5SDimitry Andric                                              llvm::Value *Src) {
32720b57cec5SDimitry Andric   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
32730b57cec5SDimitry Andric          E->getCastKind() == CK_BaseToDerivedMemberPointer ||
32740b57cec5SDimitry Andric          E->getCastKind() == CK_ReinterpretMemberPointer);
32750b57cec5SDimitry Andric 
32760b57cec5SDimitry Andric   // Use constant emission if we can.
32770b57cec5SDimitry Andric   if (isa<llvm::Constant>(Src))
32780b57cec5SDimitry Andric     return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
32790b57cec5SDimitry Andric 
32800b57cec5SDimitry Andric   // We may be adding or dropping fields from the member pointer, so we need
32810b57cec5SDimitry Andric   // both types and the inheritance models of both records.
32820b57cec5SDimitry Andric   const MemberPointerType *SrcTy =
32830b57cec5SDimitry Andric     E->getSubExpr()->getType()->castAs<MemberPointerType>();
32840b57cec5SDimitry Andric   const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>();
32850b57cec5SDimitry Andric   bool IsFunc = SrcTy->isMemberFunctionPointer();
32860b57cec5SDimitry Andric 
32870b57cec5SDimitry Andric   // If the classes use the same null representation, reinterpret_cast is a nop.
32880b57cec5SDimitry Andric   bool IsReinterpret = E->getCastKind() == CK_ReinterpretMemberPointer;
32890b57cec5SDimitry Andric   if (IsReinterpret && IsFunc)
32900b57cec5SDimitry Andric     return Src;
32910b57cec5SDimitry Andric 
32920b57cec5SDimitry Andric   CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl();
32930b57cec5SDimitry Andric   CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
32940b57cec5SDimitry Andric   if (IsReinterpret &&
32950b57cec5SDimitry Andric       SrcRD->nullFieldOffsetIsZero() == DstRD->nullFieldOffsetIsZero())
32960b57cec5SDimitry Andric     return Src;
32970b57cec5SDimitry Andric 
32980b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
32990b57cec5SDimitry Andric 
33000b57cec5SDimitry Andric   // Branch past the conversion if Src is null.
33010b57cec5SDimitry Andric   llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
33020b57cec5SDimitry Andric   llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
33030b57cec5SDimitry Andric 
33040b57cec5SDimitry Andric   // C++ 5.2.10p9: The null member pointer value is converted to the null member
33050b57cec5SDimitry Andric   //   pointer value of the destination type.
33060b57cec5SDimitry Andric   if (IsReinterpret) {
33070b57cec5SDimitry Andric     // For reinterpret casts, sema ensures that src and dst are both functions
33080b57cec5SDimitry Andric     // or data and have the same size, which means the LLVM types should match.
33090b57cec5SDimitry Andric     assert(Src->getType() == DstNull->getType());
33100b57cec5SDimitry Andric     return Builder.CreateSelect(IsNotNull, Src, DstNull);
33110b57cec5SDimitry Andric   }
33120b57cec5SDimitry Andric 
33130b57cec5SDimitry Andric   llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
33140b57cec5SDimitry Andric   llvm::BasicBlock *ConvertBB = CGF.createBasicBlock("memptr.convert");
33150b57cec5SDimitry Andric   llvm::BasicBlock *ContinueBB = CGF.createBasicBlock("memptr.converted");
33160b57cec5SDimitry Andric   Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
33170b57cec5SDimitry Andric   CGF.EmitBlock(ConvertBB);
33180b57cec5SDimitry Andric 
33190b57cec5SDimitry Andric   llvm::Value *Dst = EmitNonNullMemberPointerConversion(
33200b57cec5SDimitry Andric       SrcTy, DstTy, E->getCastKind(), E->path_begin(), E->path_end(), Src,
33210b57cec5SDimitry Andric       Builder);
33220b57cec5SDimitry Andric 
33230b57cec5SDimitry Andric   Builder.CreateBr(ContinueBB);
33240b57cec5SDimitry Andric 
33250b57cec5SDimitry Andric   // In the continuation, choose between DstNull and Dst.
33260b57cec5SDimitry Andric   CGF.EmitBlock(ContinueBB);
33270b57cec5SDimitry Andric   llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2, "memptr.converted");
33280b57cec5SDimitry Andric   Phi->addIncoming(DstNull, OriginalBB);
33290b57cec5SDimitry Andric   Phi->addIncoming(Dst, ConvertBB);
33300b57cec5SDimitry Andric   return Phi;
33310b57cec5SDimitry Andric }
33320b57cec5SDimitry Andric 
33330b57cec5SDimitry Andric llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
33340b57cec5SDimitry Andric     const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK,
33350b57cec5SDimitry Andric     CastExpr::path_const_iterator PathBegin,
33360b57cec5SDimitry Andric     CastExpr::path_const_iterator PathEnd, llvm::Value *Src,
33370b57cec5SDimitry Andric     CGBuilderTy &Builder) {
33380b57cec5SDimitry Andric   const CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl();
33390b57cec5SDimitry Andric   const CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
3340480093f4SDimitry Andric   MSInheritanceModel SrcInheritance = SrcRD->getMSInheritanceModel();
3341480093f4SDimitry Andric   MSInheritanceModel DstInheritance = DstRD->getMSInheritanceModel();
33420b57cec5SDimitry Andric   bool IsFunc = SrcTy->isMemberFunctionPointer();
33430b57cec5SDimitry Andric   bool IsConstant = isa<llvm::Constant>(Src);
33440b57cec5SDimitry Andric 
33450b57cec5SDimitry Andric   // Decompose src.
33460b57cec5SDimitry Andric   llvm::Value *FirstField = Src;
33470b57cec5SDimitry Andric   llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
33480b57cec5SDimitry Andric   llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
33490b57cec5SDimitry Andric   llvm::Value *VBPtrOffset = getZeroInt();
3350480093f4SDimitry Andric   if (!inheritanceModelHasOnlyOneField(IsFunc, SrcInheritance)) {
33510b57cec5SDimitry Andric     // We need to extract values.
33520b57cec5SDimitry Andric     unsigned I = 0;
33530b57cec5SDimitry Andric     FirstField = Builder.CreateExtractValue(Src, I++);
3354480093f4SDimitry Andric     if (inheritanceModelHasNVOffsetField(IsFunc, SrcInheritance))
33550b57cec5SDimitry Andric       NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3356480093f4SDimitry Andric     if (inheritanceModelHasVBPtrOffsetField(SrcInheritance))
33570b57cec5SDimitry Andric       VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3358480093f4SDimitry Andric     if (inheritanceModelHasVBTableOffsetField(SrcInheritance))
33590b57cec5SDimitry Andric       VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
33600b57cec5SDimitry Andric   }
33610b57cec5SDimitry Andric 
33620b57cec5SDimitry Andric   bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
33630b57cec5SDimitry Andric   const MemberPointerType *DerivedTy = IsDerivedToBase ? SrcTy : DstTy;
33640b57cec5SDimitry Andric   const CXXRecordDecl *DerivedClass = DerivedTy->getMostRecentCXXRecordDecl();
33650b57cec5SDimitry Andric 
33660b57cec5SDimitry Andric   // For data pointers, we adjust the field offset directly.  For functions, we
33670b57cec5SDimitry Andric   // have a separate field.
33680b57cec5SDimitry Andric   llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
33690b57cec5SDimitry Andric 
33700b57cec5SDimitry Andric   // The virtual inheritance model has a quirk: the virtual base table is always
33710b57cec5SDimitry Andric   // referenced when dereferencing a member pointer even if the member pointer
33720b57cec5SDimitry Andric   // is non-virtual.  This is accounted for by adjusting the non-virtual offset
33730b57cec5SDimitry Andric   // to point backwards to the top of the MDC from the first VBase.  Undo this
33740b57cec5SDimitry Andric   // adjustment to normalize the member pointer.
33750b57cec5SDimitry Andric   llvm::Value *SrcVBIndexEqZero =
33760b57cec5SDimitry Andric       Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3377480093f4SDimitry Andric   if (SrcInheritance == MSInheritanceModel::Virtual) {
33780b57cec5SDimitry Andric     if (int64_t SrcOffsetToFirstVBase =
33790b57cec5SDimitry Andric             getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
33800b57cec5SDimitry Andric       llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
33810b57cec5SDimitry Andric           SrcVBIndexEqZero,
33820b57cec5SDimitry Andric           llvm::ConstantInt::get(CGM.IntTy, SrcOffsetToFirstVBase),
33830b57cec5SDimitry Andric           getZeroInt());
33840b57cec5SDimitry Andric       NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
33850b57cec5SDimitry Andric     }
33860b57cec5SDimitry Andric   }
33870b57cec5SDimitry Andric 
33880b57cec5SDimitry Andric   // A non-zero vbindex implies that we are dealing with a source member in a
33890b57cec5SDimitry Andric   // floating virtual base in addition to some non-virtual offset.  If the
33900b57cec5SDimitry Andric   // vbindex is zero, we are dealing with a source that exists in a non-virtual,
33910b57cec5SDimitry Andric   // fixed, base.  The difference between these two cases is that the vbindex +
33920b57cec5SDimitry Andric   // nvoffset *always* point to the member regardless of what context they are
33930b57cec5SDimitry Andric   // evaluated in so long as the vbindex is adjusted.  A member inside a fixed
33940b57cec5SDimitry Andric   // base requires explicit nv adjustment.
33950b57cec5SDimitry Andric   llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
33960b57cec5SDimitry Andric       CGM.IntTy,
33970b57cec5SDimitry Andric       CGM.computeNonVirtualBaseClassOffset(DerivedClass, PathBegin, PathEnd)
33980b57cec5SDimitry Andric           .getQuantity());
33990b57cec5SDimitry Andric 
34000b57cec5SDimitry Andric   llvm::Value *NVDisp;
34010b57cec5SDimitry Andric   if (IsDerivedToBase)
34020b57cec5SDimitry Andric     NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset, "adj");
34030b57cec5SDimitry Andric   else
34040b57cec5SDimitry Andric     NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset, "adj");
34050b57cec5SDimitry Andric 
34060b57cec5SDimitry Andric   NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
34070b57cec5SDimitry Andric 
34080b57cec5SDimitry Andric   // Update the vbindex to an appropriate value in the destination because
34090b57cec5SDimitry Andric   // SrcRD's vbtable might not be a strict prefix of the one in DstRD.
34100b57cec5SDimitry Andric   llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3411480093f4SDimitry Andric   if (inheritanceModelHasVBTableOffsetField(DstInheritance) &&
3412480093f4SDimitry Andric       inheritanceModelHasVBTableOffsetField(SrcInheritance)) {
34130b57cec5SDimitry Andric     if (llvm::GlobalVariable *VDispMap =
34140b57cec5SDimitry Andric             getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
34150b57cec5SDimitry Andric       llvm::Value *VBIndex = Builder.CreateExactUDiv(
34160b57cec5SDimitry Andric           VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.IntTy, 4));
34170b57cec5SDimitry Andric       if (IsConstant) {
34180b57cec5SDimitry Andric         llvm::Constant *Mapping = VDispMap->getInitializer();
34190b57cec5SDimitry Andric         VirtualBaseAdjustmentOffset =
34200b57cec5SDimitry Andric             Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
34210b57cec5SDimitry Andric       } else {
34220b57cec5SDimitry Andric         llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3423fe6060f1SDimitry Andric         VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3424fe6060f1SDimitry Andric             CGM.IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3425fe6060f1SDimitry Andric                                                  VDispMap, Idxs),
34260b57cec5SDimitry Andric             CharUnits::fromQuantity(4));
34270b57cec5SDimitry Andric       }
34280b57cec5SDimitry Andric 
34290b57cec5SDimitry Andric       DstVBIndexEqZero =
34300b57cec5SDimitry Andric           Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
34310b57cec5SDimitry Andric     }
34320b57cec5SDimitry Andric   }
34330b57cec5SDimitry Andric 
34340b57cec5SDimitry Andric   // Set the VBPtrOffset to zero if the vbindex is zero.  Otherwise, initialize
34350b57cec5SDimitry Andric   // it to the offset of the vbptr.
3436480093f4SDimitry Andric   if (inheritanceModelHasVBPtrOffsetField(DstInheritance)) {
34370b57cec5SDimitry Andric     llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
34380b57cec5SDimitry Andric         CGM.IntTy,
34390b57cec5SDimitry Andric         getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
34400b57cec5SDimitry Andric     VBPtrOffset =
34410b57cec5SDimitry Andric         Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
34420b57cec5SDimitry Andric   }
34430b57cec5SDimitry Andric 
34440b57cec5SDimitry Andric   // Likewise, apply a similar adjustment so that dereferencing the member
34450b57cec5SDimitry Andric   // pointer correctly accounts for the distance between the start of the first
34460b57cec5SDimitry Andric   // virtual base and the top of the MDC.
3447480093f4SDimitry Andric   if (DstInheritance == MSInheritanceModel::Virtual) {
34480b57cec5SDimitry Andric     if (int64_t DstOffsetToFirstVBase =
34490b57cec5SDimitry Andric             getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
34500b57cec5SDimitry Andric       llvm::Value *DoDstAdjustment = Builder.CreateSelect(
34510b57cec5SDimitry Andric           DstVBIndexEqZero,
34520b57cec5SDimitry Andric           llvm::ConstantInt::get(CGM.IntTy, DstOffsetToFirstVBase),
34530b57cec5SDimitry Andric           getZeroInt());
34540b57cec5SDimitry Andric       NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
34550b57cec5SDimitry Andric     }
34560b57cec5SDimitry Andric   }
34570b57cec5SDimitry Andric 
34580b57cec5SDimitry Andric   // Recompose dst from the null struct and the adjusted fields from src.
34590b57cec5SDimitry Andric   llvm::Value *Dst;
3460480093f4SDimitry Andric   if (inheritanceModelHasOnlyOneField(IsFunc, DstInheritance)) {
34610b57cec5SDimitry Andric     Dst = FirstField;
34620b57cec5SDimitry Andric   } else {
34630b57cec5SDimitry Andric     Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
34640b57cec5SDimitry Andric     unsigned Idx = 0;
34650b57cec5SDimitry Andric     Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3466480093f4SDimitry Andric     if (inheritanceModelHasNVOffsetField(IsFunc, DstInheritance))
34670b57cec5SDimitry Andric       Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3468480093f4SDimitry Andric     if (inheritanceModelHasVBPtrOffsetField(DstInheritance))
34690b57cec5SDimitry Andric       Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3470480093f4SDimitry Andric     if (inheritanceModelHasVBTableOffsetField(DstInheritance))
34710b57cec5SDimitry Andric       Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
34720b57cec5SDimitry Andric   }
34730b57cec5SDimitry Andric   return Dst;
34740b57cec5SDimitry Andric }
34750b57cec5SDimitry Andric 
34760b57cec5SDimitry Andric llvm::Constant *
34770b57cec5SDimitry Andric MicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E,
34780b57cec5SDimitry Andric                                              llvm::Constant *Src) {
34790b57cec5SDimitry Andric   const MemberPointerType *SrcTy =
34800b57cec5SDimitry Andric       E->getSubExpr()->getType()->castAs<MemberPointerType>();
34810b57cec5SDimitry Andric   const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>();
34820b57cec5SDimitry Andric 
34830b57cec5SDimitry Andric   CastKind CK = E->getCastKind();
34840b57cec5SDimitry Andric 
34850b57cec5SDimitry Andric   return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->path_begin(),
34860b57cec5SDimitry Andric                                      E->path_end(), Src);
34870b57cec5SDimitry Andric }
34880b57cec5SDimitry Andric 
34890b57cec5SDimitry Andric llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
34900b57cec5SDimitry Andric     const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK,
34910b57cec5SDimitry Andric     CastExpr::path_const_iterator PathBegin,
34920b57cec5SDimitry Andric     CastExpr::path_const_iterator PathEnd, llvm::Constant *Src) {
34930b57cec5SDimitry Andric   assert(CK == CK_DerivedToBaseMemberPointer ||
34940b57cec5SDimitry Andric          CK == CK_BaseToDerivedMemberPointer ||
34950b57cec5SDimitry Andric          CK == CK_ReinterpretMemberPointer);
34960b57cec5SDimitry Andric   // If src is null, emit a new null for dst.  We can't return src because dst
34970b57cec5SDimitry Andric   // might have a new representation.
34980b57cec5SDimitry Andric   if (MemberPointerConstantIsNull(SrcTy, Src))
34990b57cec5SDimitry Andric     return EmitNullMemberPointer(DstTy);
35000b57cec5SDimitry Andric 
35010b57cec5SDimitry Andric   // We don't need to do anything for reinterpret_casts of non-null member
35020b57cec5SDimitry Andric   // pointers.  We should only get here when the two type representations have
35030b57cec5SDimitry Andric   // the same size.
35040b57cec5SDimitry Andric   if (CK == CK_ReinterpretMemberPointer)
35050b57cec5SDimitry Andric     return Src;
35060b57cec5SDimitry Andric 
35070b57cec5SDimitry Andric   CGBuilderTy Builder(CGM, CGM.getLLVMContext());
35080b57cec5SDimitry Andric   auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
35090b57cec5SDimitry Andric       SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
35100b57cec5SDimitry Andric 
35110b57cec5SDimitry Andric   return Dst;
35120b57cec5SDimitry Andric }
35130b57cec5SDimitry Andric 
35140b57cec5SDimitry Andric CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
35150b57cec5SDimitry Andric     CodeGenFunction &CGF, const Expr *E, Address This,
35160b57cec5SDimitry Andric     llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
35170b57cec5SDimitry Andric     const MemberPointerType *MPT) {
35180b57cec5SDimitry Andric   assert(MPT->isMemberFunctionPointer());
35190b57cec5SDimitry Andric   const FunctionProtoType *FPT =
35200b57cec5SDimitry Andric     MPT->getPointeeType()->castAs<FunctionProtoType>();
35210b57cec5SDimitry Andric   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
35220b57cec5SDimitry Andric   CGBuilderTy &Builder = CGF.Builder;
35230b57cec5SDimitry Andric 
3524480093f4SDimitry Andric   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
35250b57cec5SDimitry Andric 
35260b57cec5SDimitry Andric   // Extract the fields we need, regardless of model.  We'll apply them if we
35270b57cec5SDimitry Andric   // have them.
35280b57cec5SDimitry Andric   llvm::Value *FunctionPointer = MemPtr;
35290b57cec5SDimitry Andric   llvm::Value *NonVirtualBaseAdjustment = nullptr;
35300b57cec5SDimitry Andric   llvm::Value *VirtualBaseAdjustmentOffset = nullptr;
35310b57cec5SDimitry Andric   llvm::Value *VBPtrOffset = nullptr;
35320b57cec5SDimitry Andric   if (MemPtr->getType()->isStructTy()) {
35330b57cec5SDimitry Andric     // We need to extract values.
35340b57cec5SDimitry Andric     unsigned I = 0;
35350b57cec5SDimitry Andric     FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3536480093f4SDimitry Andric     if (inheritanceModelHasNVOffsetField(MPT, Inheritance))
35370b57cec5SDimitry Andric       NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3538480093f4SDimitry Andric     if (inheritanceModelHasVBPtrOffsetField(Inheritance))
35390b57cec5SDimitry Andric       VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3540480093f4SDimitry Andric     if (inheritanceModelHasVBTableOffsetField(Inheritance))
35410b57cec5SDimitry Andric       VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
35420b57cec5SDimitry Andric   }
35430b57cec5SDimitry Andric 
35440b57cec5SDimitry Andric   if (VirtualBaseAdjustmentOffset) {
35450b57cec5SDimitry Andric     ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
35460b57cec5SDimitry Andric                                    VirtualBaseAdjustmentOffset, VBPtrOffset);
35470b57cec5SDimitry Andric   } else {
35480fca6ea1SDimitry Andric     ThisPtrForCall = This.emitRawPointer(CGF);
35490b57cec5SDimitry Andric   }
35500b57cec5SDimitry Andric 
35515f757f3fSDimitry Andric   if (NonVirtualBaseAdjustment)
35525f757f3fSDimitry Andric     ThisPtrForCall = Builder.CreateInBoundsGEP(CGF.Int8Ty, ThisPtrForCall,
35535f757f3fSDimitry Andric                                                NonVirtualBaseAdjustment);
35540b57cec5SDimitry Andric 
35550b57cec5SDimitry Andric   CGCallee Callee(FPT, FunctionPointer);
35560b57cec5SDimitry Andric   return Callee;
35570b57cec5SDimitry Andric }
35580b57cec5SDimitry Andric 
35590b57cec5SDimitry Andric CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
35600b57cec5SDimitry Andric   return new MicrosoftCXXABI(CGM);
35610b57cec5SDimitry Andric }
35620b57cec5SDimitry Andric 
35630b57cec5SDimitry Andric // MS RTTI Overview:
35640b57cec5SDimitry Andric // The run time type information emitted by cl.exe contains 5 distinct types of
35650b57cec5SDimitry Andric // structures.  Many of them reference each other.
35660b57cec5SDimitry Andric //
35670b57cec5SDimitry Andric // TypeInfo:  Static classes that are returned by typeid.
35680b57cec5SDimitry Andric //
35690b57cec5SDimitry Andric // CompleteObjectLocator:  Referenced by vftables.  They contain information
35700b57cec5SDimitry Andric //   required for dynamic casting, including OffsetFromTop.  They also contain
35710b57cec5SDimitry Andric //   a reference to the TypeInfo for the type and a reference to the
35720b57cec5SDimitry Andric //   CompleteHierarchyDescriptor for the type.
35730b57cec5SDimitry Andric //
35740b57cec5SDimitry Andric // ClassHierarchyDescriptor: Contains information about a class hierarchy.
35750b57cec5SDimitry Andric //   Used during dynamic_cast to walk a class hierarchy.  References a base
35760b57cec5SDimitry Andric //   class array and the size of said array.
35770b57cec5SDimitry Andric //
35780b57cec5SDimitry Andric // BaseClassArray: Contains a list of classes in a hierarchy.  BaseClassArray is
35790b57cec5SDimitry Andric //   somewhat of a misnomer because the most derived class is also in the list
35800b57cec5SDimitry Andric //   as well as multiple copies of virtual bases (if they occur multiple times
35810b57cec5SDimitry Andric //   in the hierarchy.)  The BaseClassArray contains one BaseClassDescriptor for
35820b57cec5SDimitry Andric //   every path in the hierarchy, in pre-order depth first order.  Note, we do
35830b57cec5SDimitry Andric //   not declare a specific llvm type for BaseClassArray, it's merely an array
35840b57cec5SDimitry Andric //   of BaseClassDescriptor pointers.
35850b57cec5SDimitry Andric //
35860b57cec5SDimitry Andric // BaseClassDescriptor: Contains information about a class in a class hierarchy.
35870b57cec5SDimitry Andric //   BaseClassDescriptor is also somewhat of a misnomer for the same reason that
35880b57cec5SDimitry Andric //   BaseClassArray is.  It contains information about a class within a
35890b57cec5SDimitry Andric //   hierarchy such as: is this base is ambiguous and what is its offset in the
35900b57cec5SDimitry Andric //   vbtable.  The names of the BaseClassDescriptors have all of their fields
35910b57cec5SDimitry Andric //   mangled into them so they can be aggressively deduplicated by the linker.
35920b57cec5SDimitry Andric 
35930b57cec5SDimitry Andric static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) {
35940b57cec5SDimitry Andric   StringRef MangledName("??_7type_info@@6B@");
35950b57cec5SDimitry Andric   if (auto VTable = CGM.getModule().getNamedGlobal(MangledName))
35960b57cec5SDimitry Andric     return VTable;
35970b57cec5SDimitry Andric   return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
35980b57cec5SDimitry Andric                                   /*isConstant=*/true,
35990b57cec5SDimitry Andric                                   llvm::GlobalVariable::ExternalLinkage,
36000b57cec5SDimitry Andric                                   /*Initializer=*/nullptr, MangledName);
36010b57cec5SDimitry Andric }
36020b57cec5SDimitry Andric 
36030b57cec5SDimitry Andric namespace {
36040b57cec5SDimitry Andric 
36050b57cec5SDimitry Andric /// A Helper struct that stores information about a class in a class
36060b57cec5SDimitry Andric /// hierarchy.  The information stored in these structs struct is used during
36070b57cec5SDimitry Andric /// the generation of ClassHierarchyDescriptors and BaseClassDescriptors.
36080b57cec5SDimitry Andric // During RTTI creation, MSRTTIClasses are stored in a contiguous array with
36090b57cec5SDimitry Andric // implicit depth first pre-order tree connectivity.  getFirstChild and
36100b57cec5SDimitry Andric // getNextSibling allow us to walk the tree efficiently.
36110b57cec5SDimitry Andric struct MSRTTIClass {
36120b57cec5SDimitry Andric   enum {
36130b57cec5SDimitry Andric     IsPrivateOnPath = 1 | 8,
36140b57cec5SDimitry Andric     IsAmbiguous = 2,
36150b57cec5SDimitry Andric     IsPrivate = 4,
36160b57cec5SDimitry Andric     IsVirtual = 16,
36170b57cec5SDimitry Andric     HasHierarchyDescriptor = 64
36180b57cec5SDimitry Andric   };
36190b57cec5SDimitry Andric   MSRTTIClass(const CXXRecordDecl *RD) : RD(RD) {}
36200b57cec5SDimitry Andric   uint32_t initialize(const MSRTTIClass *Parent,
36210b57cec5SDimitry Andric                       const CXXBaseSpecifier *Specifier);
36220b57cec5SDimitry Andric 
36230b57cec5SDimitry Andric   MSRTTIClass *getFirstChild() { return this + 1; }
36240b57cec5SDimitry Andric   static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
36250b57cec5SDimitry Andric     return Child + 1 + Child->NumBases;
36260b57cec5SDimitry Andric   }
36270b57cec5SDimitry Andric 
36280b57cec5SDimitry Andric   const CXXRecordDecl *RD, *VirtualRoot;
36290b57cec5SDimitry Andric   uint32_t Flags, NumBases, OffsetInVBase;
36300b57cec5SDimitry Andric };
36310b57cec5SDimitry Andric 
36320b57cec5SDimitry Andric /// Recursively initialize the base class array.
36330b57cec5SDimitry Andric uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
36340b57cec5SDimitry Andric                                  const CXXBaseSpecifier *Specifier) {
36350b57cec5SDimitry Andric   Flags = HasHierarchyDescriptor;
36360b57cec5SDimitry Andric   if (!Parent) {
36370b57cec5SDimitry Andric     VirtualRoot = nullptr;
36380b57cec5SDimitry Andric     OffsetInVBase = 0;
36390b57cec5SDimitry Andric   } else {
36400b57cec5SDimitry Andric     if (Specifier->getAccessSpecifier() != AS_public)
36410b57cec5SDimitry Andric       Flags |= IsPrivate | IsPrivateOnPath;
36420b57cec5SDimitry Andric     if (Specifier->isVirtual()) {
36430b57cec5SDimitry Andric       Flags |= IsVirtual;
36440b57cec5SDimitry Andric       VirtualRoot = RD;
36450b57cec5SDimitry Andric       OffsetInVBase = 0;
36460b57cec5SDimitry Andric     } else {
36470b57cec5SDimitry Andric       if (Parent->Flags & IsPrivateOnPath)
36480b57cec5SDimitry Andric         Flags |= IsPrivateOnPath;
36490b57cec5SDimitry Andric       VirtualRoot = Parent->VirtualRoot;
36500b57cec5SDimitry Andric       OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
36510b57cec5SDimitry Andric           .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
36520b57cec5SDimitry Andric     }
36530b57cec5SDimitry Andric   }
36540b57cec5SDimitry Andric   NumBases = 0;
36550b57cec5SDimitry Andric   MSRTTIClass *Child = getFirstChild();
36560b57cec5SDimitry Andric   for (const CXXBaseSpecifier &Base : RD->bases()) {
36570b57cec5SDimitry Andric     NumBases += Child->initialize(this, &Base) + 1;
36580b57cec5SDimitry Andric     Child = getNextChild(Child);
36590b57cec5SDimitry Andric   }
36600b57cec5SDimitry Andric   return NumBases;
36610b57cec5SDimitry Andric }
36620b57cec5SDimitry Andric 
36630b57cec5SDimitry Andric static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
36640b57cec5SDimitry Andric   switch (Ty->getLinkage()) {
36655f757f3fSDimitry Andric   case Linkage::Invalid:
36665f757f3fSDimitry Andric     llvm_unreachable("Linkage hasn't been computed!");
36675f757f3fSDimitry Andric 
36685f757f3fSDimitry Andric   case Linkage::None:
36695f757f3fSDimitry Andric   case Linkage::Internal:
36705f757f3fSDimitry Andric   case Linkage::UniqueExternal:
36710b57cec5SDimitry Andric     return llvm::GlobalValue::InternalLinkage;
36720b57cec5SDimitry Andric 
36735f757f3fSDimitry Andric   case Linkage::VisibleNone:
36745f757f3fSDimitry Andric   case Linkage::Module:
36755f757f3fSDimitry Andric   case Linkage::External:
36760b57cec5SDimitry Andric     return llvm::GlobalValue::LinkOnceODRLinkage;
36770b57cec5SDimitry Andric   }
36780b57cec5SDimitry Andric   llvm_unreachable("Invalid linkage!");
36790b57cec5SDimitry Andric }
36800b57cec5SDimitry Andric 
36810b57cec5SDimitry Andric /// An ephemeral helper class for building MS RTTI types.  It caches some
36820b57cec5SDimitry Andric /// calls to the module and information about the most derived class in a
36830b57cec5SDimitry Andric /// hierarchy.
36840b57cec5SDimitry Andric struct MSRTTIBuilder {
36850b57cec5SDimitry Andric   enum {
36860b57cec5SDimitry Andric     HasBranchingHierarchy = 1,
36870b57cec5SDimitry Andric     HasVirtualBranchingHierarchy = 2,
36880b57cec5SDimitry Andric     HasAmbiguousBases = 4
36890b57cec5SDimitry Andric   };
36900b57cec5SDimitry Andric 
36910b57cec5SDimitry Andric   MSRTTIBuilder(MicrosoftCXXABI &ABI, const CXXRecordDecl *RD)
36920b57cec5SDimitry Andric       : CGM(ABI.CGM), Context(CGM.getContext()),
36930b57cec5SDimitry Andric         VMContext(CGM.getLLVMContext()), Module(CGM.getModule()), RD(RD),
36940b57cec5SDimitry Andric         Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
36950b57cec5SDimitry Andric         ABI(ABI) {}
36960b57cec5SDimitry Andric 
36970b57cec5SDimitry Andric   llvm::GlobalVariable *getBaseClassDescriptor(const MSRTTIClass &Classes);
36980b57cec5SDimitry Andric   llvm::GlobalVariable *
36990b57cec5SDimitry Andric   getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
37000b57cec5SDimitry Andric   llvm::GlobalVariable *getClassHierarchyDescriptor();
37010b57cec5SDimitry Andric   llvm::GlobalVariable *getCompleteObjectLocator(const VPtrInfo &Info);
37020b57cec5SDimitry Andric 
37030b57cec5SDimitry Andric   CodeGenModule &CGM;
37040b57cec5SDimitry Andric   ASTContext &Context;
37050b57cec5SDimitry Andric   llvm::LLVMContext &VMContext;
37060b57cec5SDimitry Andric   llvm::Module &Module;
37070b57cec5SDimitry Andric   const CXXRecordDecl *RD;
37080b57cec5SDimitry Andric   llvm::GlobalVariable::LinkageTypes Linkage;
37090b57cec5SDimitry Andric   MicrosoftCXXABI &ABI;
37100b57cec5SDimitry Andric };
37110b57cec5SDimitry Andric 
37120b57cec5SDimitry Andric } // namespace
37130b57cec5SDimitry Andric 
37140b57cec5SDimitry Andric /// Recursively serializes a class hierarchy in pre-order depth first
37150b57cec5SDimitry Andric /// order.
37160b57cec5SDimitry Andric static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes,
37170b57cec5SDimitry Andric                                     const CXXRecordDecl *RD) {
37180b57cec5SDimitry Andric   Classes.push_back(MSRTTIClass(RD));
37190b57cec5SDimitry Andric   for (const CXXBaseSpecifier &Base : RD->bases())
37200b57cec5SDimitry Andric     serializeClassHierarchy(Classes, Base.getType()->getAsCXXRecordDecl());
37210b57cec5SDimitry Andric }
37220b57cec5SDimitry Andric 
37230b57cec5SDimitry Andric /// Find ambiguity among base classes.
37240b57cec5SDimitry Andric static void
37250b57cec5SDimitry Andric detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) {
37260b57cec5SDimitry Andric   llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
37270b57cec5SDimitry Andric   llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
37280b57cec5SDimitry Andric   llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
37290b57cec5SDimitry Andric   for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
37300b57cec5SDimitry Andric     if ((Class->Flags & MSRTTIClass::IsVirtual) &&
37310b57cec5SDimitry Andric         !VirtualBases.insert(Class->RD).second) {
37320b57cec5SDimitry Andric       Class = MSRTTIClass::getNextChild(Class);
37330b57cec5SDimitry Andric       continue;
37340b57cec5SDimitry Andric     }
37350b57cec5SDimitry Andric     if (!UniqueBases.insert(Class->RD).second)
37360b57cec5SDimitry Andric       AmbiguousBases.insert(Class->RD);
37370b57cec5SDimitry Andric     Class++;
37380b57cec5SDimitry Andric   }
37390b57cec5SDimitry Andric   if (AmbiguousBases.empty())
37400b57cec5SDimitry Andric     return;
37410b57cec5SDimitry Andric   for (MSRTTIClass &Class : Classes)
37420b57cec5SDimitry Andric     if (AmbiguousBases.count(Class.RD))
37430b57cec5SDimitry Andric       Class.Flags |= MSRTTIClass::IsAmbiguous;
37440b57cec5SDimitry Andric }
37450b57cec5SDimitry Andric 
37460b57cec5SDimitry Andric llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
37470b57cec5SDimitry Andric   SmallString<256> MangledName;
37480b57cec5SDimitry Andric   {
37490b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(MangledName);
37500b57cec5SDimitry Andric     ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
37510b57cec5SDimitry Andric   }
37520b57cec5SDimitry Andric 
37530b57cec5SDimitry Andric   // Check to see if we've already declared this ClassHierarchyDescriptor.
37540b57cec5SDimitry Andric   if (auto CHD = Module.getNamedGlobal(MangledName))
37550b57cec5SDimitry Andric     return CHD;
37560b57cec5SDimitry Andric 
37570b57cec5SDimitry Andric   // Serialize the class hierarchy and initialize the CHD Fields.
37580b57cec5SDimitry Andric   SmallVector<MSRTTIClass, 8> Classes;
37590b57cec5SDimitry Andric   serializeClassHierarchy(Classes, RD);
37600b57cec5SDimitry Andric   Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
37610b57cec5SDimitry Andric   detectAmbiguousBases(Classes);
37620b57cec5SDimitry Andric   int Flags = 0;
376306c3fb27SDimitry Andric   for (const MSRTTIClass &Class : Classes) {
37640b57cec5SDimitry Andric     if (Class.RD->getNumBases() > 1)
37650b57cec5SDimitry Andric       Flags |= HasBranchingHierarchy;
37660b57cec5SDimitry Andric     // Note: cl.exe does not calculate "HasAmbiguousBases" correctly.  We
37670b57cec5SDimitry Andric     // believe the field isn't actually used.
37680b57cec5SDimitry Andric     if (Class.Flags & MSRTTIClass::IsAmbiguous)
37690b57cec5SDimitry Andric       Flags |= HasAmbiguousBases;
37700b57cec5SDimitry Andric   }
37710b57cec5SDimitry Andric   if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
37720b57cec5SDimitry Andric     Flags |= HasVirtualBranchingHierarchy;
37730b57cec5SDimitry Andric   // These gep indices are used to get the address of the first element of the
37740b57cec5SDimitry Andric   // base class array.
37750b57cec5SDimitry Andric   llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
37760b57cec5SDimitry Andric                                llvm::ConstantInt::get(CGM.IntTy, 0)};
37770b57cec5SDimitry Andric 
37780b57cec5SDimitry Andric   // Forward-declare the class hierarchy descriptor
37790b57cec5SDimitry Andric   auto Type = ABI.getClassHierarchyDescriptorType();
37800b57cec5SDimitry Andric   auto CHD = new llvm::GlobalVariable(Module, Type, /*isConstant=*/true, Linkage,
37810b57cec5SDimitry Andric                                       /*Initializer=*/nullptr,
37820b57cec5SDimitry Andric                                       MangledName);
37830b57cec5SDimitry Andric   if (CHD->isWeakForLinker())
37840b57cec5SDimitry Andric     CHD->setComdat(CGM.getModule().getOrInsertComdat(CHD->getName()));
37850b57cec5SDimitry Andric 
37860b57cec5SDimitry Andric   auto *Bases = getBaseClassArray(Classes);
37870b57cec5SDimitry Andric 
37880b57cec5SDimitry Andric   // Initialize the base class ClassHierarchyDescriptor.
37890b57cec5SDimitry Andric   llvm::Constant *Fields[] = {
37900b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, 0), // reserved by the runtime
37910b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, Flags),
37920b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, Classes.size()),
37930b57cec5SDimitry Andric       ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
37940b57cec5SDimitry Andric           Bases->getValueType(), Bases,
37950b57cec5SDimitry Andric           llvm::ArrayRef<llvm::Value *>(GEPIndices))),
37960b57cec5SDimitry Andric   };
37970b57cec5SDimitry Andric   CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
37980b57cec5SDimitry Andric   return CHD;
37990b57cec5SDimitry Andric }
38000b57cec5SDimitry Andric 
38010b57cec5SDimitry Andric llvm::GlobalVariable *
38020b57cec5SDimitry Andric MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
38030b57cec5SDimitry Andric   SmallString<256> MangledName;
38040b57cec5SDimitry Andric   {
38050b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(MangledName);
38060b57cec5SDimitry Andric     ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
38070b57cec5SDimitry Andric   }
38080b57cec5SDimitry Andric 
38090b57cec5SDimitry Andric   // Forward-declare the base class array.
38100b57cec5SDimitry Andric   // cl.exe pads the base class array with 1 (in 32 bit mode) or 4 (in 64 bit
38110b57cec5SDimitry Andric   // mode) bytes of padding.  We provide a pointer sized amount of padding by
38120b57cec5SDimitry Andric   // adding +1 to Classes.size().  The sections have pointer alignment and are
38130b57cec5SDimitry Andric   // marked pick-any so it shouldn't matter.
38140b57cec5SDimitry Andric   llvm::Type *PtrType = ABI.getImageRelativeType(
38150b57cec5SDimitry Andric       ABI.getBaseClassDescriptorType()->getPointerTo());
38160b57cec5SDimitry Andric   auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
38170b57cec5SDimitry Andric   auto *BCA =
38180b57cec5SDimitry Andric       new llvm::GlobalVariable(Module, ArrType,
38190b57cec5SDimitry Andric                                /*isConstant=*/true, Linkage,
38200b57cec5SDimitry Andric                                /*Initializer=*/nullptr, MangledName);
38210b57cec5SDimitry Andric   if (BCA->isWeakForLinker())
38220b57cec5SDimitry Andric     BCA->setComdat(CGM.getModule().getOrInsertComdat(BCA->getName()));
38230b57cec5SDimitry Andric 
38240b57cec5SDimitry Andric   // Initialize the BaseClassArray.
38250b57cec5SDimitry Andric   SmallVector<llvm::Constant *, 8> BaseClassArrayData;
38260b57cec5SDimitry Andric   for (MSRTTIClass &Class : Classes)
38270b57cec5SDimitry Andric     BaseClassArrayData.push_back(
38280b57cec5SDimitry Andric         ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
38290b57cec5SDimitry Andric   BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
38300b57cec5SDimitry Andric   BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
38310b57cec5SDimitry Andric   return BCA;
38320b57cec5SDimitry Andric }
38330b57cec5SDimitry Andric 
38340b57cec5SDimitry Andric llvm::GlobalVariable *
38350b57cec5SDimitry Andric MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {
38360b57cec5SDimitry Andric   // Compute the fields for the BaseClassDescriptor.  They are computed up front
38370b57cec5SDimitry Andric   // because they are mangled into the name of the object.
38380b57cec5SDimitry Andric   uint32_t OffsetInVBTable = 0;
38390b57cec5SDimitry Andric   int32_t VBPtrOffset = -1;
38400b57cec5SDimitry Andric   if (Class.VirtualRoot) {
38410b57cec5SDimitry Andric     auto &VTableContext = CGM.getMicrosoftVTableContext();
38420b57cec5SDimitry Andric     OffsetInVBTable = VTableContext.getVBTableIndex(RD, Class.VirtualRoot) * 4;
38430b57cec5SDimitry Andric     VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
38440b57cec5SDimitry Andric   }
38450b57cec5SDimitry Andric 
38460b57cec5SDimitry Andric   SmallString<256> MangledName;
38470b57cec5SDimitry Andric   {
38480b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(MangledName);
38490b57cec5SDimitry Andric     ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
38500b57cec5SDimitry Andric         Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
38510b57cec5SDimitry Andric         Class.Flags, Out);
38520b57cec5SDimitry Andric   }
38530b57cec5SDimitry Andric 
38540b57cec5SDimitry Andric   // Check to see if we've already declared this object.
38550b57cec5SDimitry Andric   if (auto BCD = Module.getNamedGlobal(MangledName))
38560b57cec5SDimitry Andric     return BCD;
38570b57cec5SDimitry Andric 
38580b57cec5SDimitry Andric   // Forward-declare the base class descriptor.
38590b57cec5SDimitry Andric   auto Type = ABI.getBaseClassDescriptorType();
38600b57cec5SDimitry Andric   auto BCD =
38610b57cec5SDimitry Andric       new llvm::GlobalVariable(Module, Type, /*isConstant=*/true, Linkage,
38620b57cec5SDimitry Andric                                /*Initializer=*/nullptr, MangledName);
38630b57cec5SDimitry Andric   if (BCD->isWeakForLinker())
38640b57cec5SDimitry Andric     BCD->setComdat(CGM.getModule().getOrInsertComdat(BCD->getName()));
38650b57cec5SDimitry Andric 
38660b57cec5SDimitry Andric   // Initialize the BaseClassDescriptor.
38670b57cec5SDimitry Andric   llvm::Constant *Fields[] = {
38680b57cec5SDimitry Andric       ABI.getImageRelativeConstant(
38690b57cec5SDimitry Andric           ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))),
38700b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, Class.NumBases),
38710b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, Class.OffsetInVBase),
38720b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
38730b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, OffsetInVBTable),
38740b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, Class.Flags),
38750b57cec5SDimitry Andric       ABI.getImageRelativeConstant(
38760b57cec5SDimitry Andric           MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
38770b57cec5SDimitry Andric   };
38780b57cec5SDimitry Andric   BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
38790b57cec5SDimitry Andric   return BCD;
38800b57cec5SDimitry Andric }
38810b57cec5SDimitry Andric 
38820b57cec5SDimitry Andric llvm::GlobalVariable *
38830b57cec5SDimitry Andric MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo &Info) {
38840b57cec5SDimitry Andric   SmallString<256> MangledName;
38850b57cec5SDimitry Andric   {
38860b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(MangledName);
38870b57cec5SDimitry Andric     ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.MangledPath, Out);
38880b57cec5SDimitry Andric   }
38890b57cec5SDimitry Andric 
38900b57cec5SDimitry Andric   // Check to see if we've already computed this complete object locator.
38910b57cec5SDimitry Andric   if (auto COL = Module.getNamedGlobal(MangledName))
38920b57cec5SDimitry Andric     return COL;
38930b57cec5SDimitry Andric 
38940b57cec5SDimitry Andric   // Compute the fields of the complete object locator.
38950b57cec5SDimitry Andric   int OffsetToTop = Info.FullOffsetInMDC.getQuantity();
38960b57cec5SDimitry Andric   int VFPtrOffset = 0;
38970b57cec5SDimitry Andric   // The offset includes the vtordisp if one exists.
38980b57cec5SDimitry Andric   if (const CXXRecordDecl *VBase = Info.getVBaseWithVPtr())
38990b57cec5SDimitry Andric     if (Context.getASTRecordLayout(RD)
39000b57cec5SDimitry Andric       .getVBaseOffsetsMap()
39010b57cec5SDimitry Andric       .find(VBase)
39020b57cec5SDimitry Andric       ->second.hasVtorDisp())
39030b57cec5SDimitry Andric       VFPtrOffset = Info.NonVirtualOffset.getQuantity() + 4;
39040b57cec5SDimitry Andric 
39050b57cec5SDimitry Andric   // Forward-declare the complete object locator.
39060b57cec5SDimitry Andric   llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
39070b57cec5SDimitry Andric   auto COL = new llvm::GlobalVariable(Module, Type, /*isConstant=*/true, Linkage,
39080b57cec5SDimitry Andric     /*Initializer=*/nullptr, MangledName);
39090b57cec5SDimitry Andric 
39100b57cec5SDimitry Andric   // Initialize the CompleteObjectLocator.
39110b57cec5SDimitry Andric   llvm::Constant *Fields[] = {
39120b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, ABI.isImageRelative()),
39130b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, OffsetToTop),
39140b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, VFPtrOffset),
39150b57cec5SDimitry Andric       ABI.getImageRelativeConstant(
39160b57cec5SDimitry Andric           CGM.GetAddrOfRTTIDescriptor(Context.getTypeDeclType(RD))),
39170b57cec5SDimitry Andric       ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
39180b57cec5SDimitry Andric       ABI.getImageRelativeConstant(COL),
39190b57cec5SDimitry Andric   };
39200b57cec5SDimitry Andric   llvm::ArrayRef<llvm::Constant *> FieldsRef(Fields);
39210b57cec5SDimitry Andric   if (!ABI.isImageRelative())
39220b57cec5SDimitry Andric     FieldsRef = FieldsRef.drop_back();
39230b57cec5SDimitry Andric   COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
39240b57cec5SDimitry Andric   if (COL->isWeakForLinker())
39250b57cec5SDimitry Andric     COL->setComdat(CGM.getModule().getOrInsertComdat(COL->getName()));
39260b57cec5SDimitry Andric   return COL;
39270b57cec5SDimitry Andric }
39280b57cec5SDimitry Andric 
39290b57cec5SDimitry Andric static QualType decomposeTypeForEH(ASTContext &Context, QualType T,
39300b57cec5SDimitry Andric                                    bool &IsConst, bool &IsVolatile,
39310b57cec5SDimitry Andric                                    bool &IsUnaligned) {
39320b57cec5SDimitry Andric   T = Context.getExceptionObjectType(T);
39330b57cec5SDimitry Andric 
39340b57cec5SDimitry Andric   // C++14 [except.handle]p3:
39350b57cec5SDimitry Andric   //   A handler is a match for an exception object of type E if [...]
39360b57cec5SDimitry Andric   //     - the handler is of type cv T or const T& where T is a pointer type and
39370b57cec5SDimitry Andric   //       E is a pointer type that can be converted to T by [...]
39380b57cec5SDimitry Andric   //         - a qualification conversion
39390b57cec5SDimitry Andric   IsConst = false;
39400b57cec5SDimitry Andric   IsVolatile = false;
39410b57cec5SDimitry Andric   IsUnaligned = false;
39420b57cec5SDimitry Andric   QualType PointeeType = T->getPointeeType();
39430b57cec5SDimitry Andric   if (!PointeeType.isNull()) {
39440b57cec5SDimitry Andric     IsConst = PointeeType.isConstQualified();
39450b57cec5SDimitry Andric     IsVolatile = PointeeType.isVolatileQualified();
39460b57cec5SDimitry Andric     IsUnaligned = PointeeType.getQualifiers().hasUnaligned();
39470b57cec5SDimitry Andric   }
39480b57cec5SDimitry Andric 
39490b57cec5SDimitry Andric   // Member pointer types like "const int A::*" are represented by having RTTI
39500b57cec5SDimitry Andric   // for "int A::*" and separately storing the const qualifier.
39510b57cec5SDimitry Andric   if (const auto *MPTy = T->getAs<MemberPointerType>())
39520b57cec5SDimitry Andric     T = Context.getMemberPointerType(PointeeType.getUnqualifiedType(),
39530b57cec5SDimitry Andric                                      MPTy->getClass());
39540b57cec5SDimitry Andric 
39550b57cec5SDimitry Andric   // Pointer types like "const int * const *" are represented by having RTTI
39560b57cec5SDimitry Andric   // for "const int **" and separately storing the const qualifier.
39570b57cec5SDimitry Andric   if (T->isPointerType())
39580b57cec5SDimitry Andric     T = Context.getPointerType(PointeeType.getUnqualifiedType());
39590b57cec5SDimitry Andric 
39600b57cec5SDimitry Andric   return T;
39610b57cec5SDimitry Andric }
39620b57cec5SDimitry Andric 
39630b57cec5SDimitry Andric CatchTypeInfo
39640b57cec5SDimitry Andric MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType Type,
39650b57cec5SDimitry Andric                                               QualType CatchHandlerType) {
39660b57cec5SDimitry Andric   // TypeDescriptors for exceptions never have qualified pointer types,
39670b57cec5SDimitry Andric   // qualifiers are stored separately in order to support qualification
39680b57cec5SDimitry Andric   // conversions.
39690b57cec5SDimitry Andric   bool IsConst, IsVolatile, IsUnaligned;
39700b57cec5SDimitry Andric   Type =
39710b57cec5SDimitry Andric       decomposeTypeForEH(getContext(), Type, IsConst, IsVolatile, IsUnaligned);
39720b57cec5SDimitry Andric 
39730b57cec5SDimitry Andric   bool IsReference = CatchHandlerType->isReferenceType();
39740b57cec5SDimitry Andric 
39750b57cec5SDimitry Andric   uint32_t Flags = 0;
39760b57cec5SDimitry Andric   if (IsConst)
39770b57cec5SDimitry Andric     Flags |= 1;
39780b57cec5SDimitry Andric   if (IsVolatile)
39790b57cec5SDimitry Andric     Flags |= 2;
39800b57cec5SDimitry Andric   if (IsUnaligned)
39810b57cec5SDimitry Andric     Flags |= 4;
39820b57cec5SDimitry Andric   if (IsReference)
39830b57cec5SDimitry Andric     Flags |= 8;
39840b57cec5SDimitry Andric 
39850b57cec5SDimitry Andric   return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(),
39860b57cec5SDimitry Andric                        Flags};
39870b57cec5SDimitry Andric }
39880b57cec5SDimitry Andric 
39890b57cec5SDimitry Andric /// Gets a TypeDescriptor.  Returns a llvm::Constant * rather than a
39900b57cec5SDimitry Andric /// llvm::GlobalVariable * because different type descriptors have different
39910b57cec5SDimitry Andric /// types, and need to be abstracted.  They are abstracting by casting the
39920b57cec5SDimitry Andric /// address to an Int8PtrTy.
39930b57cec5SDimitry Andric llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) {
39940b57cec5SDimitry Andric   SmallString<256> MangledName;
39950b57cec5SDimitry Andric   {
39960b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(MangledName);
39970b57cec5SDimitry Andric     getMangleContext().mangleCXXRTTI(Type, Out);
39980b57cec5SDimitry Andric   }
39990b57cec5SDimitry Andric 
40000b57cec5SDimitry Andric   // Check to see if we've already declared this TypeDescriptor.
40010b57cec5SDimitry Andric   if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
40025f757f3fSDimitry Andric     return GV;
40030b57cec5SDimitry Andric 
40040b57cec5SDimitry Andric   // Note for the future: If we would ever like to do deferred emission of
40050b57cec5SDimitry Andric   // RTTI, check if emitting vtables opportunistically need any adjustment.
40060b57cec5SDimitry Andric 
40070b57cec5SDimitry Andric   // Compute the fields for the TypeDescriptor.
40080b57cec5SDimitry Andric   SmallString<256> TypeInfoString;
40090b57cec5SDimitry Andric   {
40100b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(TypeInfoString);
40110b57cec5SDimitry Andric     getMangleContext().mangleCXXRTTIName(Type, Out);
40120b57cec5SDimitry Andric   }
40130b57cec5SDimitry Andric 
40140b57cec5SDimitry Andric   // Declare and initialize the TypeDescriptor.
40150b57cec5SDimitry Andric   llvm::Constant *Fields[] = {
40160b57cec5SDimitry Andric     getTypeInfoVTable(CGM),                        // VFPtr
40170b57cec5SDimitry Andric     llvm::ConstantPointerNull::get(CGM.Int8PtrTy), // Runtime data
40180b57cec5SDimitry Andric     llvm::ConstantDataArray::getString(CGM.getLLVMContext(), TypeInfoString)};
40190b57cec5SDimitry Andric   llvm::StructType *TypeDescriptorType =
40200b57cec5SDimitry Andric       getTypeDescriptorType(TypeInfoString);
40210b57cec5SDimitry Andric   auto *Var = new llvm::GlobalVariable(
40220b57cec5SDimitry Andric       CGM.getModule(), TypeDescriptorType, /*isConstant=*/false,
40230b57cec5SDimitry Andric       getLinkageForRTTI(Type),
40240b57cec5SDimitry Andric       llvm::ConstantStruct::get(TypeDescriptorType, Fields),
40250b57cec5SDimitry Andric       MangledName);
40260b57cec5SDimitry Andric   if (Var->isWeakForLinker())
40270b57cec5SDimitry Andric     Var->setComdat(CGM.getModule().getOrInsertComdat(Var->getName()));
40285f757f3fSDimitry Andric   return Var;
40290b57cec5SDimitry Andric }
40300b57cec5SDimitry Andric 
40310b57cec5SDimitry Andric /// Gets or a creates a Microsoft CompleteObjectLocator.
40320b57cec5SDimitry Andric llvm::GlobalVariable *
40330b57cec5SDimitry Andric MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
40340b57cec5SDimitry Andric                                             const VPtrInfo &Info) {
40350b57cec5SDimitry Andric   return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
40360b57cec5SDimitry Andric }
40370b57cec5SDimitry Andric 
40380b57cec5SDimitry Andric void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {
40390b57cec5SDimitry Andric   if (auto *ctor = dyn_cast<CXXConstructorDecl>(GD.getDecl())) {
40400b57cec5SDimitry Andric     // There are no constructor variants, always emit the complete destructor.
40410b57cec5SDimitry Andric     llvm::Function *Fn =
40420b57cec5SDimitry Andric         CGM.codegenCXXStructor(GD.getWithCtorType(Ctor_Complete));
40430b57cec5SDimitry Andric     CGM.maybeSetTrivialComdat(*ctor, *Fn);
40440b57cec5SDimitry Andric     return;
40450b57cec5SDimitry Andric   }
40460b57cec5SDimitry Andric 
40470b57cec5SDimitry Andric   auto *dtor = cast<CXXDestructorDecl>(GD.getDecl());
40480b57cec5SDimitry Andric 
40490b57cec5SDimitry Andric   // Emit the base destructor if the base and complete (vbase) destructors are
40500b57cec5SDimitry Andric   // equivalent. This effectively implements -mconstructor-aliases as part of
40510b57cec5SDimitry Andric   // the ABI.
40520b57cec5SDimitry Andric   if (GD.getDtorType() == Dtor_Complete &&
40530b57cec5SDimitry Andric       dtor->getParent()->getNumVBases() == 0)
40540b57cec5SDimitry Andric     GD = GD.getWithDtorType(Dtor_Base);
40550b57cec5SDimitry Andric 
40560b57cec5SDimitry Andric   // The base destructor is equivalent to the base destructor of its
40570b57cec5SDimitry Andric   // base class if there is exactly one non-virtual base class with a
40580b57cec5SDimitry Andric   // non-trivial destructor, there are no fields with a non-trivial
40590b57cec5SDimitry Andric   // destructor, and the body of the destructor is trivial.
40600b57cec5SDimitry Andric   if (GD.getDtorType() == Dtor_Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
40610b57cec5SDimitry Andric     return;
40620b57cec5SDimitry Andric 
40630b57cec5SDimitry Andric   llvm::Function *Fn = CGM.codegenCXXStructor(GD);
40640b57cec5SDimitry Andric   if (Fn->isWeakForLinker())
40650b57cec5SDimitry Andric     Fn->setComdat(CGM.getModule().getOrInsertComdat(Fn->getName()));
40660b57cec5SDimitry Andric }
40670b57cec5SDimitry Andric 
40680b57cec5SDimitry Andric llvm::Function *
40690b57cec5SDimitry Andric MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
40700b57cec5SDimitry Andric                                          CXXCtorType CT) {
40710b57cec5SDimitry Andric   assert(CT == Ctor_CopyingClosure || CT == Ctor_DefaultClosure);
40720b57cec5SDimitry Andric 
40730b57cec5SDimitry Andric   // Calculate the mangled name.
40740b57cec5SDimitry Andric   SmallString<256> ThunkName;
40750b57cec5SDimitry Andric   llvm::raw_svector_ostream Out(ThunkName);
40765ffd83dbSDimitry Andric   getMangleContext().mangleName(GlobalDecl(CD, CT), Out);
40770b57cec5SDimitry Andric 
40780b57cec5SDimitry Andric   // If the thunk has been generated previously, just return it.
40790b57cec5SDimitry Andric   if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
40800b57cec5SDimitry Andric     return cast<llvm::Function>(GV);
40810b57cec5SDimitry Andric 
40820b57cec5SDimitry Andric   // Create the llvm::Function.
40830b57cec5SDimitry Andric   const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSCtorClosure(CD, CT);
40840b57cec5SDimitry Andric   llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
40850b57cec5SDimitry Andric   const CXXRecordDecl *RD = CD->getParent();
40860b57cec5SDimitry Andric   QualType RecordTy = getContext().getRecordType(RD);
40870b57cec5SDimitry Andric   llvm::Function *ThunkFn = llvm::Function::Create(
40880b57cec5SDimitry Andric       ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.getModule());
40890b57cec5SDimitry Andric   ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
40900b57cec5SDimitry Andric       FnInfo.getEffectiveCallingConvention()));
40910b57cec5SDimitry Andric   if (ThunkFn->isWeakForLinker())
40920b57cec5SDimitry Andric     ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
40930b57cec5SDimitry Andric   bool IsCopy = CT == Ctor_CopyingClosure;
40940b57cec5SDimitry Andric 
40950b57cec5SDimitry Andric   // Start codegen.
40960b57cec5SDimitry Andric   CodeGenFunction CGF(CGM);
40970b57cec5SDimitry Andric   CGF.CurGD = GlobalDecl(CD, Ctor_Complete);
40980b57cec5SDimitry Andric 
40990b57cec5SDimitry Andric   // Build FunctionArgs.
41000b57cec5SDimitry Andric   FunctionArgList FunctionArgs;
41010b57cec5SDimitry Andric 
41020b57cec5SDimitry Andric   // A constructor always starts with a 'this' pointer as its first argument.
41030b57cec5SDimitry Andric   buildThisParam(CGF, FunctionArgs);
41040b57cec5SDimitry Andric 
41050b57cec5SDimitry Andric   // Following the 'this' pointer is a reference to the source object that we
41060b57cec5SDimitry Andric   // are copying from.
41070b57cec5SDimitry Andric   ImplicitParamDecl SrcParam(
41080b57cec5SDimitry Andric       getContext(), /*DC=*/nullptr, SourceLocation(),
41090b57cec5SDimitry Andric       &getContext().Idents.get("src"),
41100b57cec5SDimitry Andric       getContext().getLValueReferenceType(RecordTy,
41110b57cec5SDimitry Andric                                           /*SpelledAsLValue=*/true),
41125f757f3fSDimitry Andric       ImplicitParamKind::Other);
41130b57cec5SDimitry Andric   if (IsCopy)
41140b57cec5SDimitry Andric     FunctionArgs.push_back(&SrcParam);
41150b57cec5SDimitry Andric 
41160b57cec5SDimitry Andric   // Constructors for classes which utilize virtual bases have an additional
41170b57cec5SDimitry Andric   // parameter which indicates whether or not it is being delegated to by a more
41180b57cec5SDimitry Andric   // derived constructor.
41190b57cec5SDimitry Andric   ImplicitParamDecl IsMostDerived(getContext(), /*DC=*/nullptr,
41200b57cec5SDimitry Andric                                   SourceLocation(),
41210b57cec5SDimitry Andric                                   &getContext().Idents.get("is_most_derived"),
41225f757f3fSDimitry Andric                                   getContext().IntTy, ImplicitParamKind::Other);
41230b57cec5SDimitry Andric   // Only add the parameter to the list if the class has virtual bases.
41240b57cec5SDimitry Andric   if (RD->getNumVBases() > 0)
41250b57cec5SDimitry Andric     FunctionArgs.push_back(&IsMostDerived);
41260b57cec5SDimitry Andric 
41270b57cec5SDimitry Andric   // Start defining the function.
41280b57cec5SDimitry Andric   auto NL = ApplyDebugLocation::CreateEmpty(CGF);
41290b57cec5SDimitry Andric   CGF.StartFunction(GlobalDecl(), FnInfo.getReturnType(), ThunkFn, FnInfo,
41300b57cec5SDimitry Andric                     FunctionArgs, CD->getLocation(), SourceLocation());
41310b57cec5SDimitry Andric   // Create a scope with an artificial location for the body of this function.
41320b57cec5SDimitry Andric   auto AL = ApplyDebugLocation::CreateArtificial(CGF);
41330b57cec5SDimitry Andric   setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
41340b57cec5SDimitry Andric   llvm::Value *This = getThisValue(CGF);
41350b57cec5SDimitry Andric 
41360b57cec5SDimitry Andric   llvm::Value *SrcVal =
41370b57cec5SDimitry Andric       IsCopy ? CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&SrcParam), "src")
41380b57cec5SDimitry Andric              : nullptr;
41390b57cec5SDimitry Andric 
41400b57cec5SDimitry Andric   CallArgList Args;
41410b57cec5SDimitry Andric 
41420b57cec5SDimitry Andric   // Push the this ptr.
41430b57cec5SDimitry Andric   Args.add(RValue::get(This), CD->getThisType());
41440b57cec5SDimitry Andric 
41450b57cec5SDimitry Andric   // Push the src ptr.
41460b57cec5SDimitry Andric   if (SrcVal)
41470b57cec5SDimitry Andric     Args.add(RValue::get(SrcVal), SrcParam.getType());
41480b57cec5SDimitry Andric 
41490b57cec5SDimitry Andric   // Add the rest of the default arguments.
41500b57cec5SDimitry Andric   SmallVector<const Stmt *, 4> ArgVec;
41510b57cec5SDimitry Andric   ArrayRef<ParmVarDecl *> params = CD->parameters().drop_front(IsCopy ? 1 : 0);
41520b57cec5SDimitry Andric   for (const ParmVarDecl *PD : params) {
41530b57cec5SDimitry Andric     assert(PD->hasDefaultArg() && "ctor closure lacks default args");
41540b57cec5SDimitry Andric     ArgVec.push_back(PD->getDefaultArg());
41550b57cec5SDimitry Andric   }
41560b57cec5SDimitry Andric 
41570b57cec5SDimitry Andric   CodeGenFunction::RunCleanupsScope Cleanups(CGF);
41580b57cec5SDimitry Andric 
41590b57cec5SDimitry Andric   const auto *FPT = CD->getType()->castAs<FunctionProtoType>();
4160bdd1243dSDimitry Andric   CGF.EmitCallArgs(Args, FPT, llvm::ArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
41610b57cec5SDimitry Andric 
41620b57cec5SDimitry Andric   // Insert any ABI-specific implicit constructor arguments.
41635ffd83dbSDimitry Andric   AddedStructorArgCounts ExtraArgs =
41640b57cec5SDimitry Andric       addImplicitConstructorArgs(CGF, CD, Ctor_Complete,
41650b57cec5SDimitry Andric                                  /*ForVirtualBase=*/false,
41660b57cec5SDimitry Andric                                  /*Delegating=*/false, Args);
41670b57cec5SDimitry Andric   // Call the destructor with our arguments.
41680b57cec5SDimitry Andric   llvm::Constant *CalleePtr =
41690b57cec5SDimitry Andric       CGM.getAddrOfCXXStructor(GlobalDecl(CD, Ctor_Complete));
41700b57cec5SDimitry Andric   CGCallee Callee =
41710b57cec5SDimitry Andric       CGCallee::forDirect(CalleePtr, GlobalDecl(CD, Ctor_Complete));
41720b57cec5SDimitry Andric   const CGFunctionInfo &CalleeInfo = CGM.getTypes().arrangeCXXConstructorCall(
41730b57cec5SDimitry Andric       Args, CD, Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
41740b57cec5SDimitry Andric   CGF.EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args);
41750b57cec5SDimitry Andric 
41760b57cec5SDimitry Andric   Cleanups.ForceCleanup();
41770b57cec5SDimitry Andric 
41780b57cec5SDimitry Andric   // Emit the ret instruction, remove any temporary instructions created for the
41790b57cec5SDimitry Andric   // aid of CodeGen.
41800b57cec5SDimitry Andric   CGF.FinishFunction(SourceLocation());
41810b57cec5SDimitry Andric 
41820b57cec5SDimitry Andric   return ThunkFn;
41830b57cec5SDimitry Andric }
41840b57cec5SDimitry Andric 
41850b57cec5SDimitry Andric llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType T,
41860b57cec5SDimitry Andric                                                   uint32_t NVOffset,
41870b57cec5SDimitry Andric                                                   int32_t VBPtrOffset,
41880b57cec5SDimitry Andric                                                   uint32_t VBIndex) {
41890b57cec5SDimitry Andric   assert(!T->isReferenceType());
41900b57cec5SDimitry Andric 
41910b57cec5SDimitry Andric   CXXRecordDecl *RD = T->getAsCXXRecordDecl();
41920b57cec5SDimitry Andric   const CXXConstructorDecl *CD =
41930b57cec5SDimitry Andric       RD ? CGM.getContext().getCopyConstructorForExceptionObject(RD) : nullptr;
41940b57cec5SDimitry Andric   CXXCtorType CT = Ctor_Complete;
41950b57cec5SDimitry Andric   if (CD)
41960b57cec5SDimitry Andric     if (!hasDefaultCXXMethodCC(getContext(), CD) || CD->getNumParams() != 1)
41970b57cec5SDimitry Andric       CT = Ctor_CopyingClosure;
41980b57cec5SDimitry Andric 
41990b57cec5SDimitry Andric   uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
42000b57cec5SDimitry Andric   SmallString<256> MangledName;
42010b57cec5SDimitry Andric   {
42020b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(MangledName);
42030b57cec5SDimitry Andric     getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
42040b57cec5SDimitry Andric                                               VBPtrOffset, VBIndex, Out);
42050b57cec5SDimitry Andric   }
42060b57cec5SDimitry Andric   if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
42070b57cec5SDimitry Andric     return getImageRelativeConstant(GV);
42080b57cec5SDimitry Andric 
42090b57cec5SDimitry Andric   // The TypeDescriptor is used by the runtime to determine if a catch handler
42100b57cec5SDimitry Andric   // is appropriate for the exception object.
42110b57cec5SDimitry Andric   llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
42120b57cec5SDimitry Andric 
42130b57cec5SDimitry Andric   // The runtime is responsible for calling the copy constructor if the
42140b57cec5SDimitry Andric   // exception is caught by value.
42150b57cec5SDimitry Andric   llvm::Constant *CopyCtor;
42160b57cec5SDimitry Andric   if (CD) {
42170b57cec5SDimitry Andric     if (CT == Ctor_CopyingClosure)
42180b57cec5SDimitry Andric       CopyCtor = getAddrOfCXXCtorClosure(CD, Ctor_CopyingClosure);
42190b57cec5SDimitry Andric     else
42200b57cec5SDimitry Andric       CopyCtor = CGM.getAddrOfCXXStructor(GlobalDecl(CD, Ctor_Complete));
42210b57cec5SDimitry Andric   } else {
42220b57cec5SDimitry Andric     CopyCtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
42230b57cec5SDimitry Andric   }
42240b57cec5SDimitry Andric   CopyCtor = getImageRelativeConstant(CopyCtor);
42250b57cec5SDimitry Andric 
42260b57cec5SDimitry Andric   bool IsScalar = !RD;
42270b57cec5SDimitry Andric   bool HasVirtualBases = false;
42280b57cec5SDimitry Andric   bool IsStdBadAlloc = false; // std::bad_alloc is special for some reason.
42290b57cec5SDimitry Andric   QualType PointeeType = T;
42300b57cec5SDimitry Andric   if (T->isPointerType())
42310b57cec5SDimitry Andric     PointeeType = T->getPointeeType();
42320b57cec5SDimitry Andric   if (const CXXRecordDecl *RD = PointeeType->getAsCXXRecordDecl()) {
42330b57cec5SDimitry Andric     HasVirtualBases = RD->getNumVBases() > 0;
42340b57cec5SDimitry Andric     if (IdentifierInfo *II = RD->getIdentifier())
42350b57cec5SDimitry Andric       IsStdBadAlloc = II->isStr("bad_alloc") && RD->isInStdNamespace();
42360b57cec5SDimitry Andric   }
42370b57cec5SDimitry Andric 
42380b57cec5SDimitry Andric   // Encode the relevant CatchableType properties into the Flags bitfield.
42390b57cec5SDimitry Andric   // FIXME: Figure out how bits 2 or 8 can get set.
42400b57cec5SDimitry Andric   uint32_t Flags = 0;
42410b57cec5SDimitry Andric   if (IsScalar)
42420b57cec5SDimitry Andric     Flags |= 1;
42430b57cec5SDimitry Andric   if (HasVirtualBases)
42440b57cec5SDimitry Andric     Flags |= 4;
42450b57cec5SDimitry Andric   if (IsStdBadAlloc)
42460b57cec5SDimitry Andric     Flags |= 16;
42470b57cec5SDimitry Andric 
42480b57cec5SDimitry Andric   llvm::Constant *Fields[] = {
42490b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, Flags),       // Flags
42500b57cec5SDimitry Andric       TD,                                             // TypeDescriptor
42510b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, NVOffset),    // NonVirtualAdjustment
42520b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset), // OffsetToVBPtr
42530b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, VBIndex),     // VBTableIndex
42540b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, Size),        // Size
42550b57cec5SDimitry Andric       CopyCtor                                        // CopyCtor
42560b57cec5SDimitry Andric   };
42570b57cec5SDimitry Andric   llvm::StructType *CTType = getCatchableTypeType();
42580b57cec5SDimitry Andric   auto *GV = new llvm::GlobalVariable(
42590b57cec5SDimitry Andric       CGM.getModule(), CTType, /*isConstant=*/true, getLinkageForRTTI(T),
42600b57cec5SDimitry Andric       llvm::ConstantStruct::get(CTType, Fields), MangledName);
42610b57cec5SDimitry Andric   GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
42620b57cec5SDimitry Andric   GV->setSection(".xdata");
42630b57cec5SDimitry Andric   if (GV->isWeakForLinker())
42640b57cec5SDimitry Andric     GV->setComdat(CGM.getModule().getOrInsertComdat(GV->getName()));
42650b57cec5SDimitry Andric   return getImageRelativeConstant(GV);
42660b57cec5SDimitry Andric }
42670b57cec5SDimitry Andric 
42680b57cec5SDimitry Andric llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) {
42690b57cec5SDimitry Andric   assert(!T->isReferenceType());
42700b57cec5SDimitry Andric 
42710b57cec5SDimitry Andric   // See if we've already generated a CatchableTypeArray for this type before.
42720b57cec5SDimitry Andric   llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
42730b57cec5SDimitry Andric   if (CTA)
42740b57cec5SDimitry Andric     return CTA;
42750b57cec5SDimitry Andric 
42760b57cec5SDimitry Andric   // Ensure that we don't have duplicate entries in our CatchableTypeArray by
42770b57cec5SDimitry Andric   // using a SmallSetVector.  Duplicates may arise due to virtual bases
42780b57cec5SDimitry Andric   // occurring more than once in the hierarchy.
42790b57cec5SDimitry Andric   llvm::SmallSetVector<llvm::Constant *, 2> CatchableTypes;
42800b57cec5SDimitry Andric 
42810b57cec5SDimitry Andric   // C++14 [except.handle]p3:
42820b57cec5SDimitry Andric   //   A handler is a match for an exception object of type E if [...]
42830b57cec5SDimitry Andric   //     - the handler is of type cv T or cv T& and T is an unambiguous public
42840b57cec5SDimitry Andric   //       base class of E, or
42850b57cec5SDimitry Andric   //     - the handler is of type cv T or const T& where T is a pointer type and
42860b57cec5SDimitry Andric   //       E is a pointer type that can be converted to T by [...]
42870b57cec5SDimitry Andric   //         - a standard pointer conversion (4.10) not involving conversions to
42880b57cec5SDimitry Andric   //           pointers to private or protected or ambiguous classes
42890b57cec5SDimitry Andric   const CXXRecordDecl *MostDerivedClass = nullptr;
42900b57cec5SDimitry Andric   bool IsPointer = T->isPointerType();
42910b57cec5SDimitry Andric   if (IsPointer)
42920b57cec5SDimitry Andric     MostDerivedClass = T->getPointeeType()->getAsCXXRecordDecl();
42930b57cec5SDimitry Andric   else
42940b57cec5SDimitry Andric     MostDerivedClass = T->getAsCXXRecordDecl();
42950b57cec5SDimitry Andric 
42960b57cec5SDimitry Andric   // Collect all the unambiguous public bases of the MostDerivedClass.
42970b57cec5SDimitry Andric   if (MostDerivedClass) {
42980b57cec5SDimitry Andric     const ASTContext &Context = getContext();
42990b57cec5SDimitry Andric     const ASTRecordLayout &MostDerivedLayout =
43000b57cec5SDimitry Andric         Context.getASTRecordLayout(MostDerivedClass);
43010b57cec5SDimitry Andric     MicrosoftVTableContext &VTableContext = CGM.getMicrosoftVTableContext();
43020b57cec5SDimitry Andric     SmallVector<MSRTTIClass, 8> Classes;
43030b57cec5SDimitry Andric     serializeClassHierarchy(Classes, MostDerivedClass);
43040b57cec5SDimitry Andric     Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
43050b57cec5SDimitry Andric     detectAmbiguousBases(Classes);
43060b57cec5SDimitry Andric     for (const MSRTTIClass &Class : Classes) {
43070b57cec5SDimitry Andric       // Skip any ambiguous or private bases.
43080b57cec5SDimitry Andric       if (Class.Flags &
43090b57cec5SDimitry Andric           (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
43100b57cec5SDimitry Andric         continue;
43110b57cec5SDimitry Andric       // Write down how to convert from a derived pointer to a base pointer.
43120b57cec5SDimitry Andric       uint32_t OffsetInVBTable = 0;
43130b57cec5SDimitry Andric       int32_t VBPtrOffset = -1;
43140b57cec5SDimitry Andric       if (Class.VirtualRoot) {
43150b57cec5SDimitry Andric         OffsetInVBTable =
43160b57cec5SDimitry Andric           VTableContext.getVBTableIndex(MostDerivedClass, Class.VirtualRoot)*4;
43170b57cec5SDimitry Andric         VBPtrOffset = MostDerivedLayout.getVBPtrOffset().getQuantity();
43180b57cec5SDimitry Andric       }
43190b57cec5SDimitry Andric 
43200b57cec5SDimitry Andric       // Turn our record back into a pointer if the exception object is a
43210b57cec5SDimitry Andric       // pointer.
43220b57cec5SDimitry Andric       QualType RTTITy = QualType(Class.RD->getTypeForDecl(), 0);
43230b57cec5SDimitry Andric       if (IsPointer)
43240b57cec5SDimitry Andric         RTTITy = Context.getPointerType(RTTITy);
43250b57cec5SDimitry Andric       CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
43260b57cec5SDimitry Andric                                              VBPtrOffset, OffsetInVBTable));
43270b57cec5SDimitry Andric     }
43280b57cec5SDimitry Andric   }
43290b57cec5SDimitry Andric 
43300b57cec5SDimitry Andric   // C++14 [except.handle]p3:
43310b57cec5SDimitry Andric   //   A handler is a match for an exception object of type E if
43320b57cec5SDimitry Andric   //     - The handler is of type cv T or cv T& and E and T are the same type
43330b57cec5SDimitry Andric   //       (ignoring the top-level cv-qualifiers)
43340b57cec5SDimitry Andric   CatchableTypes.insert(getCatchableType(T));
43350b57cec5SDimitry Andric 
43360b57cec5SDimitry Andric   // C++14 [except.handle]p3:
43370b57cec5SDimitry Andric   //   A handler is a match for an exception object of type E if
43380b57cec5SDimitry Andric   //     - the handler is of type cv T or const T& where T is a pointer type and
43390b57cec5SDimitry Andric   //       E is a pointer type that can be converted to T by [...]
43400b57cec5SDimitry Andric   //         - a standard pointer conversion (4.10) not involving conversions to
43410b57cec5SDimitry Andric   //           pointers to private or protected or ambiguous classes
43420b57cec5SDimitry Andric   //
43430b57cec5SDimitry Andric   // C++14 [conv.ptr]p2:
43440b57cec5SDimitry Andric   //   A prvalue of type "pointer to cv T," where T is an object type, can be
43450b57cec5SDimitry Andric   //   converted to a prvalue of type "pointer to cv void".
43460b57cec5SDimitry Andric   if (IsPointer && T->getPointeeType()->isObjectType())
43470b57cec5SDimitry Andric     CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
43480b57cec5SDimitry Andric 
43490b57cec5SDimitry Andric   // C++14 [except.handle]p3:
43500b57cec5SDimitry Andric   //   A handler is a match for an exception object of type E if [...]
43510b57cec5SDimitry Andric   //     - the handler is of type cv T or const T& where T is a pointer or
43520b57cec5SDimitry Andric   //       pointer to member type and E is std::nullptr_t.
43530b57cec5SDimitry Andric   //
43540b57cec5SDimitry Andric   // We cannot possibly list all possible pointer types here, making this
43550b57cec5SDimitry Andric   // implementation incompatible with the standard.  However, MSVC includes an
43560b57cec5SDimitry Andric   // entry for pointer-to-void in this case.  Let's do the same.
43570b57cec5SDimitry Andric   if (T->isNullPtrType())
43580b57cec5SDimitry Andric     CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
43590b57cec5SDimitry Andric 
43600b57cec5SDimitry Andric   uint32_t NumEntries = CatchableTypes.size();
43610b57cec5SDimitry Andric   llvm::Type *CTType =
43620b57cec5SDimitry Andric       getImageRelativeType(getCatchableTypeType()->getPointerTo());
43630b57cec5SDimitry Andric   llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
43640b57cec5SDimitry Andric   llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
43650b57cec5SDimitry Andric   llvm::Constant *Fields[] = {
43660b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, NumEntries), // NumEntries
43670b57cec5SDimitry Andric       llvm::ConstantArray::get(
4368bdd1243dSDimitry Andric           AT, llvm::ArrayRef(CatchableTypes.begin(),
43690b57cec5SDimitry Andric                              CatchableTypes.end())) // CatchableTypes
43700b57cec5SDimitry Andric   };
43710b57cec5SDimitry Andric   SmallString<256> MangledName;
43720b57cec5SDimitry Andric   {
43730b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(MangledName);
43740b57cec5SDimitry Andric     getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
43750b57cec5SDimitry Andric   }
43760b57cec5SDimitry Andric   CTA = new llvm::GlobalVariable(
43770b57cec5SDimitry Andric       CGM.getModule(), CTAType, /*isConstant=*/true, getLinkageForRTTI(T),
43780b57cec5SDimitry Andric       llvm::ConstantStruct::get(CTAType, Fields), MangledName);
43790b57cec5SDimitry Andric   CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
43800b57cec5SDimitry Andric   CTA->setSection(".xdata");
43810b57cec5SDimitry Andric   if (CTA->isWeakForLinker())
43820b57cec5SDimitry Andric     CTA->setComdat(CGM.getModule().getOrInsertComdat(CTA->getName()));
43830b57cec5SDimitry Andric   return CTA;
43840b57cec5SDimitry Andric }
43850b57cec5SDimitry Andric 
43860b57cec5SDimitry Andric llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) {
43870b57cec5SDimitry Andric   bool IsConst, IsVolatile, IsUnaligned;
43880b57cec5SDimitry Andric   T = decomposeTypeForEH(getContext(), T, IsConst, IsVolatile, IsUnaligned);
43890b57cec5SDimitry Andric 
43900b57cec5SDimitry Andric   // The CatchableTypeArray enumerates the various (CV-unqualified) types that
43910b57cec5SDimitry Andric   // the exception object may be caught as.
43920b57cec5SDimitry Andric   llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
43930b57cec5SDimitry Andric   // The first field in a CatchableTypeArray is the number of CatchableTypes.
43940b57cec5SDimitry Andric   // This is used as a component of the mangled name which means that we need to
43950b57cec5SDimitry Andric   // know what it is in order to see if we have previously generated the
43960b57cec5SDimitry Andric   // ThrowInfo.
43970b57cec5SDimitry Andric   uint32_t NumEntries =
43980b57cec5SDimitry Andric       cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
43990b57cec5SDimitry Andric           ->getLimitedValue();
44000b57cec5SDimitry Andric 
44010b57cec5SDimitry Andric   SmallString<256> MangledName;
44020b57cec5SDimitry Andric   {
44030b57cec5SDimitry Andric     llvm::raw_svector_ostream Out(MangledName);
44040b57cec5SDimitry Andric     getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
44050b57cec5SDimitry Andric                                           NumEntries, Out);
44060b57cec5SDimitry Andric   }
44070b57cec5SDimitry Andric 
44080b57cec5SDimitry Andric   // Reuse a previously generated ThrowInfo if we have generated an appropriate
44090b57cec5SDimitry Andric   // one before.
44100b57cec5SDimitry Andric   if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
44110b57cec5SDimitry Andric     return GV;
44120b57cec5SDimitry Andric 
44130b57cec5SDimitry Andric   // The RTTI TypeDescriptor uses an unqualified type but catch clauses must
44140b57cec5SDimitry Andric   // be at least as CV qualified.  Encode this requirement into the Flags
44150b57cec5SDimitry Andric   // bitfield.
44160b57cec5SDimitry Andric   uint32_t Flags = 0;
44170b57cec5SDimitry Andric   if (IsConst)
44180b57cec5SDimitry Andric     Flags |= 1;
44190b57cec5SDimitry Andric   if (IsVolatile)
44200b57cec5SDimitry Andric     Flags |= 2;
44210b57cec5SDimitry Andric   if (IsUnaligned)
44220b57cec5SDimitry Andric     Flags |= 4;
44230b57cec5SDimitry Andric 
44240b57cec5SDimitry Andric   // The cleanup-function (a destructor) must be called when the exception
44250b57cec5SDimitry Andric   // object's lifetime ends.
44260b57cec5SDimitry Andric   llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.Int8PtrTy);
44270b57cec5SDimitry Andric   if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
44280b57cec5SDimitry Andric     if (CXXDestructorDecl *DtorD = RD->getDestructor())
44290b57cec5SDimitry Andric       if (!DtorD->isTrivial())
44305f757f3fSDimitry Andric         CleanupFn = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete));
44310b57cec5SDimitry Andric   // This is unused as far as we can tell, initialize it to null.
44320b57cec5SDimitry Andric   llvm::Constant *ForwardCompat =
44330b57cec5SDimitry Andric       getImageRelativeConstant(llvm::Constant::getNullValue(CGM.Int8PtrTy));
44345f757f3fSDimitry Andric   llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(CTA);
44350b57cec5SDimitry Andric   llvm::StructType *TIType = getThrowInfoType();
44360b57cec5SDimitry Andric   llvm::Constant *Fields[] = {
44370b57cec5SDimitry Andric       llvm::ConstantInt::get(CGM.IntTy, Flags), // Flags
44380b57cec5SDimitry Andric       getImageRelativeConstant(CleanupFn),      // CleanupFn
44390b57cec5SDimitry Andric       ForwardCompat,                            // ForwardCompat
44400b57cec5SDimitry Andric       PointerToCatchableTypes                   // CatchableTypeArray
44410b57cec5SDimitry Andric   };
44420b57cec5SDimitry Andric   auto *GV = new llvm::GlobalVariable(
44430b57cec5SDimitry Andric       CGM.getModule(), TIType, /*isConstant=*/true, getLinkageForRTTI(T),
4444fe6060f1SDimitry Andric       llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
44450b57cec5SDimitry Andric   GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
44460b57cec5SDimitry Andric   GV->setSection(".xdata");
44470b57cec5SDimitry Andric   if (GV->isWeakForLinker())
44480b57cec5SDimitry Andric     GV->setComdat(CGM.getModule().getOrInsertComdat(GV->getName()));
44490b57cec5SDimitry Andric   return GV;
44500b57cec5SDimitry Andric }
44510b57cec5SDimitry Andric 
44520b57cec5SDimitry Andric void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
44530b57cec5SDimitry Andric   const Expr *SubExpr = E->getSubExpr();
4454349cc55cSDimitry Andric   assert(SubExpr && "SubExpr cannot be null");
44550b57cec5SDimitry Andric   QualType ThrowType = SubExpr->getType();
44560b57cec5SDimitry Andric   // The exception object lives on the stack and it's address is passed to the
44570b57cec5SDimitry Andric   // runtime function.
44580b57cec5SDimitry Andric   Address AI = CGF.CreateMemTemp(ThrowType);
44590b57cec5SDimitry Andric   CGF.EmitAnyExprToMem(SubExpr, AI, ThrowType.getQualifiers(),
44600b57cec5SDimitry Andric                        /*IsInit=*/true);
44610b57cec5SDimitry Andric 
44620b57cec5SDimitry Andric   // The so-called ThrowInfo is used to describe how the exception object may be
44630b57cec5SDimitry Andric   // caught.
44640b57cec5SDimitry Andric   llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
44650b57cec5SDimitry Andric 
44660b57cec5SDimitry Andric   // Call into the runtime to throw the exception.
44670fca6ea1SDimitry Andric   llvm::Value *Args[] = {AI.emitRawPointer(CGF), TI};
44680b57cec5SDimitry Andric   CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(), Args);
44690b57cec5SDimitry Andric }
44700b57cec5SDimitry Andric 
44710b57cec5SDimitry Andric std::pair<llvm::Value *, const CXXRecordDecl *>
44720b57cec5SDimitry Andric MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
44730b57cec5SDimitry Andric                                const CXXRecordDecl *RD) {
44740b57cec5SDimitry Andric   std::tie(This, std::ignore, RD) =
44750b57cec5SDimitry Andric       performBaseAdjustment(CGF, This, QualType(RD->getTypeForDecl(), 0));
44760b57cec5SDimitry Andric   return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
44770b57cec5SDimitry Andric }
4478e8d8bef9SDimitry Andric 
4479e8d8bef9SDimitry Andric bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4480bdd1243dSDimitry Andric     const CXXRecordDecl *RD) const {
4481bdd1243dSDimitry Andric   // All aggregates are permitted to be HFA on non-ARM platforms, which mostly
4482bdd1243dSDimitry Andric   // affects vectorcall on x64/x86.
4483bdd1243dSDimitry Andric   if (!CGM.getTarget().getTriple().isAArch64())
4484bdd1243dSDimitry Andric     return true;
4485bdd1243dSDimitry Andric   // MSVC Windows on Arm64 has its own rules for determining if a type is HFA
4486bdd1243dSDimitry Andric   // that are inconsistent with the AAPCS64 ABI. The following are our best
4487bdd1243dSDimitry Andric   // determination of those rules so far, based on observation of MSVC's
4488bdd1243dSDimitry Andric   // behavior.
4489bdd1243dSDimitry Andric   if (RD->isEmpty())
4490bdd1243dSDimitry Andric     return false;
4491bdd1243dSDimitry Andric   if (RD->isPolymorphic())
4492bdd1243dSDimitry Andric     return false;
4493bdd1243dSDimitry Andric   if (RD->hasNonTrivialCopyAssignment())
4494bdd1243dSDimitry Andric     return false;
4495bdd1243dSDimitry Andric   if (RD->hasNonTrivialDestructor())
4496bdd1243dSDimitry Andric     return false;
4497bdd1243dSDimitry Andric   if (RD->hasNonTrivialDefaultConstructor())
4498bdd1243dSDimitry Andric     return false;
4499bdd1243dSDimitry Andric   // These two are somewhat redundant given the caller
4500bdd1243dSDimitry Andric   // (ABIInfo::isHomogeneousAggregate) checks the bases and fields, but that
4501bdd1243dSDimitry Andric   // caller doesn't consider empty bases/fields to be non-homogenous, but it
4502bdd1243dSDimitry Andric   // looks like Microsoft's AArch64 ABI does care about these empty types &
4503bdd1243dSDimitry Andric   // anything containing/derived from one is non-homogeneous.
4504bdd1243dSDimitry Andric   // Instead we could add another CXXABI entry point to query this property and
4505bdd1243dSDimitry Andric   // have ABIInfo::isHomogeneousAggregate use that property.
4506bdd1243dSDimitry Andric   // I don't think any other of the features listed above could be true of a
4507bdd1243dSDimitry Andric   // base/field while not true of the outer struct. For example, if you have a
4508bdd1243dSDimitry Andric   // base/field that has an non-trivial copy assignment/dtor/default ctor, then
4509bdd1243dSDimitry Andric   // the outer struct's corresponding operation must be non-trivial.
4510bdd1243dSDimitry Andric   for (const CXXBaseSpecifier &B : RD->bases()) {
4511bdd1243dSDimitry Andric     if (const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4512bdd1243dSDimitry Andric       if (!isPermittedToBeHomogeneousAggregate(FRD))
4513bdd1243dSDimitry Andric         return false;
4514bdd1243dSDimitry Andric     }
4515bdd1243dSDimitry Andric   }
4516bdd1243dSDimitry Andric   // empty fields seem to be caught by the ABIInfo::isHomogeneousAggregate
4517bdd1243dSDimitry Andric   // checking for padding - but maybe there are ways to end up with an empty
4518bdd1243dSDimitry Andric   // field without padding? Not that I know of, so don't check fields here &
4519bdd1243dSDimitry Andric   // rely on the padding check.
4520bdd1243dSDimitry Andric   return true;
4521e8d8bef9SDimitry Andric }
4522