xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/MicrosoftCXXABI.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- MicrosoftCXXABI.cpp - Emit LLVM Code from ASTs for a Module ------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This provides C++ code generation targeting the Microsoft Visual C++ ABI.
10e5dd7070Spatrick // The class in this file generates structures that follow the Microsoft
11e5dd7070Spatrick // Visual C++ ABI, which is actually not very well documented at all outside
12e5dd7070Spatrick // of Microsoft.
13e5dd7070Spatrick //
14e5dd7070Spatrick //===----------------------------------------------------------------------===//
15e5dd7070Spatrick 
16e5dd7070Spatrick #include "CGCXXABI.h"
17e5dd7070Spatrick #include "CGCleanup.h"
18e5dd7070Spatrick #include "CGVTables.h"
19e5dd7070Spatrick #include "CodeGenModule.h"
20e5dd7070Spatrick #include "CodeGenTypes.h"
21e5dd7070Spatrick #include "TargetInfo.h"
22e5dd7070Spatrick #include "clang/AST/Attr.h"
23e5dd7070Spatrick #include "clang/AST/CXXInheritance.h"
24e5dd7070Spatrick #include "clang/AST/Decl.h"
25e5dd7070Spatrick #include "clang/AST/DeclCXX.h"
26e5dd7070Spatrick #include "clang/AST/StmtCXX.h"
27e5dd7070Spatrick #include "clang/AST/VTableBuilder.h"
28e5dd7070Spatrick #include "clang/CodeGen/ConstantInitBuilder.h"
29e5dd7070Spatrick #include "llvm/ADT/StringExtras.h"
30e5dd7070Spatrick #include "llvm/ADT/StringSet.h"
31e5dd7070Spatrick #include "llvm/IR/Intrinsics.h"
32e5dd7070Spatrick 
33e5dd7070Spatrick using namespace clang;
34e5dd7070Spatrick using namespace CodeGen;
35e5dd7070Spatrick 
36e5dd7070Spatrick namespace {
37e5dd7070Spatrick 
38e5dd7070Spatrick /// Holds all the vbtable globals for a given class.
39e5dd7070Spatrick struct VBTableGlobals {
40e5dd7070Spatrick   const VPtrInfoVector *VBTables;
41e5dd7070Spatrick   SmallVector<llvm::GlobalVariable *, 2> Globals;
42e5dd7070Spatrick };
43e5dd7070Spatrick 
44e5dd7070Spatrick class MicrosoftCXXABI : public CGCXXABI {
45e5dd7070Spatrick public:
MicrosoftCXXABI(CodeGenModule & CGM)46e5dd7070Spatrick   MicrosoftCXXABI(CodeGenModule &CGM)
47e5dd7070Spatrick       : CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
48e5dd7070Spatrick         ClassHierarchyDescriptorType(nullptr),
49e5dd7070Spatrick         CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
50*12c85518Srobert         ThrowInfoType(nullptr) {
51*12c85518Srobert     assert(!(CGM.getLangOpts().isExplicitDefaultVisibilityExportMapping() ||
52*12c85518Srobert              CGM.getLangOpts().isAllDefaultVisibilityExportMapping()) &&
53*12c85518Srobert            "visibility export mapping option unimplemented in this ABI");
54*12c85518Srobert   }
55e5dd7070Spatrick 
56e5dd7070Spatrick   bool HasThisReturn(GlobalDecl GD) const override;
57e5dd7070Spatrick   bool hasMostDerivedReturn(GlobalDecl GD) const override;
58e5dd7070Spatrick 
59e5dd7070Spatrick   bool classifyReturnType(CGFunctionInfo &FI) const override;
60e5dd7070Spatrick 
61e5dd7070Spatrick   RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override;
62e5dd7070Spatrick 
isSRetParameterAfterThis() const63e5dd7070Spatrick   bool isSRetParameterAfterThis() const override { return true; }
64e5dd7070Spatrick 
isThisCompleteObject(GlobalDecl GD) const65e5dd7070Spatrick   bool isThisCompleteObject(GlobalDecl GD) const override {
66e5dd7070Spatrick     // The Microsoft ABI doesn't use separate complete-object vs.
67e5dd7070Spatrick     // base-object variants of constructors, but it does of destructors.
68e5dd7070Spatrick     if (isa<CXXDestructorDecl>(GD.getDecl())) {
69e5dd7070Spatrick       switch (GD.getDtorType()) {
70e5dd7070Spatrick       case Dtor_Complete:
71e5dd7070Spatrick       case Dtor_Deleting:
72e5dd7070Spatrick         return true;
73e5dd7070Spatrick 
74e5dd7070Spatrick       case Dtor_Base:
75e5dd7070Spatrick         return false;
76e5dd7070Spatrick 
77e5dd7070Spatrick       case Dtor_Comdat: llvm_unreachable("emitting dtor comdat as function?");
78e5dd7070Spatrick       }
79e5dd7070Spatrick       llvm_unreachable("bad dtor kind");
80e5dd7070Spatrick     }
81e5dd7070Spatrick 
82e5dd7070Spatrick     // No other kinds.
83e5dd7070Spatrick     return false;
84e5dd7070Spatrick   }
85e5dd7070Spatrick 
getSrcArgforCopyCtor(const CXXConstructorDecl * CD,FunctionArgList & Args) const86e5dd7070Spatrick   size_t getSrcArgforCopyCtor(const CXXConstructorDecl *CD,
87e5dd7070Spatrick                               FunctionArgList &Args) const override {
88e5dd7070Spatrick     assert(Args.size() >= 2 &&
89e5dd7070Spatrick            "expected the arglist to have at least two args!");
90e5dd7070Spatrick     // The 'most_derived' parameter goes second if the ctor is variadic and
91e5dd7070Spatrick     // has v-bases.
92e5dd7070Spatrick     if (CD->getParent()->getNumVBases() > 0 &&
93e5dd7070Spatrick         CD->getType()->castAs<FunctionProtoType>()->isVariadic())
94e5dd7070Spatrick       return 2;
95e5dd7070Spatrick     return 1;
96e5dd7070Spatrick   }
97e5dd7070Spatrick 
getVBPtrOffsets(const CXXRecordDecl * RD)98e5dd7070Spatrick   std::vector<CharUnits> getVBPtrOffsets(const CXXRecordDecl *RD) override {
99e5dd7070Spatrick     std::vector<CharUnits> VBPtrOffsets;
100e5dd7070Spatrick     const ASTContext &Context = getContext();
101e5dd7070Spatrick     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
102e5dd7070Spatrick 
103e5dd7070Spatrick     const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
104e5dd7070Spatrick     for (const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
105e5dd7070Spatrick       const ASTRecordLayout &SubobjectLayout =
106e5dd7070Spatrick           Context.getASTRecordLayout(VBT->IntroducingObject);
107e5dd7070Spatrick       CharUnits Offs = VBT->NonVirtualOffset;
108e5dd7070Spatrick       Offs += SubobjectLayout.getVBPtrOffset();
109e5dd7070Spatrick       if (VBT->getVBaseWithVPtr())
110e5dd7070Spatrick         Offs += Layout.getVBaseClassOffset(VBT->getVBaseWithVPtr());
111e5dd7070Spatrick       VBPtrOffsets.push_back(Offs);
112e5dd7070Spatrick     }
113e5dd7070Spatrick     llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
114e5dd7070Spatrick     return VBPtrOffsets;
115e5dd7070Spatrick   }
116e5dd7070Spatrick 
GetPureVirtualCallName()117e5dd7070Spatrick   StringRef GetPureVirtualCallName() override { return "_purecall"; }
GetDeletedVirtualCallName()118e5dd7070Spatrick   StringRef GetDeletedVirtualCallName() override { return "_purecall"; }
119e5dd7070Spatrick 
120e5dd7070Spatrick   void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE,
121e5dd7070Spatrick                                Address Ptr, QualType ElementType,
122e5dd7070Spatrick                                const CXXDestructorDecl *Dtor) override;
123e5dd7070Spatrick 
124e5dd7070Spatrick   void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
125e5dd7070Spatrick   void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) override;
126e5dd7070Spatrick 
127e5dd7070Spatrick   void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override;
128e5dd7070Spatrick 
129e5dd7070Spatrick   llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
130e5dd7070Spatrick                                                    const VPtrInfo &Info);
131e5dd7070Spatrick 
132e5dd7070Spatrick   llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
133e5dd7070Spatrick   CatchTypeInfo
134e5dd7070Spatrick   getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) override;
135e5dd7070Spatrick 
136e5dd7070Spatrick   /// MSVC needs an extra flag to indicate a catchall.
getCatchAllTypeInfo()137e5dd7070Spatrick   CatchTypeInfo getCatchAllTypeInfo() override {
138a9ac8606Spatrick     // For -EHa catch(...) must handle HW exception
139a9ac8606Spatrick     // Adjective = HT_IsStdDotDot (0x40), only catch C++ exceptions
140a9ac8606Spatrick     if (getContext().getLangOpts().EHAsynch)
141a9ac8606Spatrick       return CatchTypeInfo{nullptr, 0};
142a9ac8606Spatrick     else
143e5dd7070Spatrick       return CatchTypeInfo{nullptr, 0x40};
144e5dd7070Spatrick   }
145e5dd7070Spatrick 
146e5dd7070Spatrick   bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override;
147e5dd7070Spatrick   void EmitBadTypeidCall(CodeGenFunction &CGF) override;
148e5dd7070Spatrick   llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
149e5dd7070Spatrick                           Address ThisPtr,
150e5dd7070Spatrick                           llvm::Type *StdTypeInfoPtrTy) override;
151e5dd7070Spatrick 
152e5dd7070Spatrick   bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
153e5dd7070Spatrick                                           QualType SrcRecordTy) override;
154e5dd7070Spatrick 
155e5dd7070Spatrick   llvm::Value *EmitDynamicCastCall(CodeGenFunction &CGF, Address Value,
156e5dd7070Spatrick                                    QualType SrcRecordTy, QualType DestTy,
157e5dd7070Spatrick                                    QualType DestRecordTy,
158e5dd7070Spatrick                                    llvm::BasicBlock *CastEnd) override;
159e5dd7070Spatrick 
160e5dd7070Spatrick   llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,
161e5dd7070Spatrick                                      QualType SrcRecordTy,
162e5dd7070Spatrick                                      QualType DestTy) override;
163e5dd7070Spatrick 
164e5dd7070Spatrick   bool EmitBadCastCall(CodeGenFunction &CGF) override;
canSpeculativelyEmitVTable(const CXXRecordDecl * RD) const165e5dd7070Spatrick   bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const override {
166e5dd7070Spatrick     return false;
167e5dd7070Spatrick   }
168e5dd7070Spatrick 
169e5dd7070Spatrick   llvm::Value *
170e5dd7070Spatrick   GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
171e5dd7070Spatrick                             const CXXRecordDecl *ClassDecl,
172e5dd7070Spatrick                             const CXXRecordDecl *BaseClassDecl) override;
173e5dd7070Spatrick 
174e5dd7070Spatrick   llvm::BasicBlock *
175e5dd7070Spatrick   EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
176e5dd7070Spatrick                                 const CXXRecordDecl *RD) override;
177e5dd7070Spatrick 
178e5dd7070Spatrick   llvm::BasicBlock *
179e5dd7070Spatrick   EmitDtorCompleteObjectHandler(CodeGenFunction &CGF);
180e5dd7070Spatrick 
181e5dd7070Spatrick   void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF,
182e5dd7070Spatrick                                               const CXXRecordDecl *RD) override;
183e5dd7070Spatrick 
184e5dd7070Spatrick   void EmitCXXConstructors(const CXXConstructorDecl *D) override;
185e5dd7070Spatrick 
186e5dd7070Spatrick   // Background on MSVC destructors
187e5dd7070Spatrick   // ==============================
188e5dd7070Spatrick   //
189e5dd7070Spatrick   // Both Itanium and MSVC ABIs have destructor variants.  The variant names
190e5dd7070Spatrick   // roughly correspond in the following way:
191e5dd7070Spatrick   //   Itanium       Microsoft
192e5dd7070Spatrick   //   Base       -> no name, just ~Class
193e5dd7070Spatrick   //   Complete   -> vbase destructor
194e5dd7070Spatrick   //   Deleting   -> scalar deleting destructor
195e5dd7070Spatrick   //                 vector deleting destructor
196e5dd7070Spatrick   //
197e5dd7070Spatrick   // The base and complete destructors are the same as in Itanium, although the
198e5dd7070Spatrick   // complete destructor does not accept a VTT parameter when there are virtual
199e5dd7070Spatrick   // bases.  A separate mechanism involving vtordisps is used to ensure that
200e5dd7070Spatrick   // virtual methods of destroyed subobjects are not called.
201e5dd7070Spatrick   //
202e5dd7070Spatrick   // The deleting destructors accept an i32 bitfield as a second parameter.  Bit
203e5dd7070Spatrick   // 1 indicates if the memory should be deleted.  Bit 2 indicates if the this
204e5dd7070Spatrick   // pointer points to an array.  The scalar deleting destructor assumes that
205e5dd7070Spatrick   // bit 2 is zero, and therefore does not contain a loop.
206e5dd7070Spatrick   //
207e5dd7070Spatrick   // For virtual destructors, only one entry is reserved in the vftable, and it
208e5dd7070Spatrick   // always points to the vector deleting destructor.  The vector deleting
209e5dd7070Spatrick   // destructor is the most general, so it can be used to destroy objects in
210e5dd7070Spatrick   // place, delete single heap objects, or delete arrays.
211e5dd7070Spatrick   //
212e5dd7070Spatrick   // A TU defining a non-inline destructor is only guaranteed to emit a base
213e5dd7070Spatrick   // destructor, and all of the other variants are emitted on an as-needed basis
214e5dd7070Spatrick   // in COMDATs.  Because a non-base destructor can be emitted in a TU that
215e5dd7070Spatrick   // lacks a definition for the destructor, non-base destructors must always
216e5dd7070Spatrick   // delegate to or alias the base destructor.
217e5dd7070Spatrick 
218ec727ea7Spatrick   AddedStructorArgCounts
219e5dd7070Spatrick   buildStructorSignature(GlobalDecl GD,
220e5dd7070Spatrick                          SmallVectorImpl<CanQualType> &ArgTys) override;
221e5dd7070Spatrick 
222e5dd7070Spatrick   /// Non-base dtors should be emitted as delegating thunks in this ABI.
useThunkForDtorVariant(const CXXDestructorDecl * Dtor,CXXDtorType DT) const223e5dd7070Spatrick   bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
224e5dd7070Spatrick                               CXXDtorType DT) const override {
225e5dd7070Spatrick     return DT != Dtor_Base;
226e5dd7070Spatrick   }
227e5dd7070Spatrick 
228e5dd7070Spatrick   void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
229e5dd7070Spatrick                                   const CXXDestructorDecl *Dtor,
230e5dd7070Spatrick                                   CXXDtorType DT) const override;
231e5dd7070Spatrick 
232e5dd7070Spatrick   llvm::GlobalValue::LinkageTypes
233e5dd7070Spatrick   getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor,
234e5dd7070Spatrick                           CXXDtorType DT) const override;
235e5dd7070Spatrick 
236e5dd7070Spatrick   void EmitCXXDestructors(const CXXDestructorDecl *D) override;
237e5dd7070Spatrick 
getThisArgumentTypeForMethod(GlobalDecl GD)238*12c85518Srobert   const CXXRecordDecl *getThisArgumentTypeForMethod(GlobalDecl GD) override {
239*12c85518Srobert     auto *MD = cast<CXXMethodDecl>(GD.getDecl());
240*12c85518Srobert 
241*12c85518Srobert     if (MD->isVirtual()) {
242*12c85518Srobert       GlobalDecl LookupGD = GD;
243*12c85518Srobert       if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
244*12c85518Srobert         // Complete dtors take a pointer to the complete object,
245*12c85518Srobert         // thus don't need adjustment.
246*12c85518Srobert         if (GD.getDtorType() == Dtor_Complete)
247*12c85518Srobert           return MD->getParent();
248*12c85518Srobert 
249*12c85518Srobert         // There's only Dtor_Deleting in vftable but it shares the this
250*12c85518Srobert         // adjustment with the base one, so look up the deleting one instead.
251*12c85518Srobert         LookupGD = GlobalDecl(DD, Dtor_Deleting);
252*12c85518Srobert       }
253e5dd7070Spatrick       MethodVFTableLocation ML =
254*12c85518Srobert           CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
255*12c85518Srobert 
256e5dd7070Spatrick       // The vbases might be ordered differently in the final overrider object
257e5dd7070Spatrick       // and the complete object, so the "this" argument may sometimes point to
258e5dd7070Spatrick       // memory that has no particular type (e.g. past the complete object).
259e5dd7070Spatrick       // In this case, we just use a generic pointer type.
260e5dd7070Spatrick       // FIXME: might want to have a more precise type in the non-virtual
261e5dd7070Spatrick       // multiple inheritance case.
262e5dd7070Spatrick       if (ML.VBase || !ML.VFPtrOffset.isZero())
263e5dd7070Spatrick         return nullptr;
264e5dd7070Spatrick     }
265e5dd7070Spatrick     return MD->getParent();
266e5dd7070Spatrick   }
267e5dd7070Spatrick 
268e5dd7070Spatrick   Address
269e5dd7070Spatrick   adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD,
270e5dd7070Spatrick                                            Address This,
271e5dd7070Spatrick                                            bool VirtualCall) override;
272e5dd7070Spatrick 
273e5dd7070Spatrick   void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
274e5dd7070Spatrick                                  FunctionArgList &Params) override;
275e5dd7070Spatrick 
276e5dd7070Spatrick   void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
277e5dd7070Spatrick 
278ec727ea7Spatrick   AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
279ec727ea7Spatrick                                                const CXXConstructorDecl *D,
280ec727ea7Spatrick                                                CXXCtorType Type,
281ec727ea7Spatrick                                                bool ForVirtualBase,
282ec727ea7Spatrick                                                bool Delegating) override;
283ec727ea7Spatrick 
284ec727ea7Spatrick   llvm::Value *getCXXDestructorImplicitParam(CodeGenFunction &CGF,
285ec727ea7Spatrick                                              const CXXDestructorDecl *DD,
286ec727ea7Spatrick                                              CXXDtorType Type,
287ec727ea7Spatrick                                              bool ForVirtualBase,
288ec727ea7Spatrick                                              bool Delegating) override;
289e5dd7070Spatrick 
290e5dd7070Spatrick   void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
291e5dd7070Spatrick                           CXXDtorType Type, bool ForVirtualBase,
292e5dd7070Spatrick                           bool Delegating, Address This,
293e5dd7070Spatrick                           QualType ThisTy) override;
294e5dd7070Spatrick 
295e5dd7070Spatrick   void emitVTableTypeMetadata(const VPtrInfo &Info, const CXXRecordDecl *RD,
296e5dd7070Spatrick                               llvm::GlobalVariable *VTable);
297e5dd7070Spatrick 
298e5dd7070Spatrick   void emitVTableDefinitions(CodeGenVTables &CGVT,
299e5dd7070Spatrick                              const CXXRecordDecl *RD) override;
300e5dd7070Spatrick 
301e5dd7070Spatrick   bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
302e5dd7070Spatrick                                            CodeGenFunction::VPtr Vptr) override;
303e5dd7070Spatrick 
304e5dd7070Spatrick   /// Don't initialize vptrs if dynamic class
305*12c85518Srobert   /// is marked with the 'novtable' attribute.
doStructorsInitializeVPtrs(const CXXRecordDecl * VTableClass)306e5dd7070Spatrick   bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) override {
307e5dd7070Spatrick     return !VTableClass->hasAttr<MSNoVTableAttr>();
308e5dd7070Spatrick   }
309e5dd7070Spatrick 
310e5dd7070Spatrick   llvm::Constant *
311e5dd7070Spatrick   getVTableAddressPoint(BaseSubobject Base,
312e5dd7070Spatrick                         const CXXRecordDecl *VTableClass) override;
313e5dd7070Spatrick 
314e5dd7070Spatrick   llvm::Value *getVTableAddressPointInStructor(
315e5dd7070Spatrick       CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
316e5dd7070Spatrick       BaseSubobject Base, const CXXRecordDecl *NearestVBase) override;
317e5dd7070Spatrick 
318e5dd7070Spatrick   llvm::Constant *
319e5dd7070Spatrick   getVTableAddressPointForConstExpr(BaseSubobject Base,
320e5dd7070Spatrick                                     const CXXRecordDecl *VTableClass) override;
321e5dd7070Spatrick 
322e5dd7070Spatrick   llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
323e5dd7070Spatrick                                         CharUnits VPtrOffset) override;
324e5dd7070Spatrick 
325e5dd7070Spatrick   CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
326e5dd7070Spatrick                                      Address This, llvm::Type *Ty,
327e5dd7070Spatrick                                      SourceLocation Loc) override;
328e5dd7070Spatrick 
329e5dd7070Spatrick   llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
330e5dd7070Spatrick                                          const CXXDestructorDecl *Dtor,
331e5dd7070Spatrick                                          CXXDtorType DtorType, Address This,
332e5dd7070Spatrick                                          DeleteOrMemberCallExpr E) override;
333e5dd7070Spatrick 
adjustCallArgsForDestructorThunk(CodeGenFunction & CGF,GlobalDecl GD,CallArgList & CallArgs)334e5dd7070Spatrick   void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
335e5dd7070Spatrick                                         CallArgList &CallArgs) override {
336e5dd7070Spatrick     assert(GD.getDtorType() == Dtor_Deleting &&
337e5dd7070Spatrick            "Only deleting destructor thunks are available in this ABI");
338e5dd7070Spatrick     CallArgs.add(RValue::get(getStructorImplicitParamValue(CGF)),
339e5dd7070Spatrick                  getContext().IntTy);
340e5dd7070Spatrick   }
341e5dd7070Spatrick 
342e5dd7070Spatrick   void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
343e5dd7070Spatrick 
344e5dd7070Spatrick   llvm::GlobalVariable *
345e5dd7070Spatrick   getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
346e5dd7070Spatrick                    llvm::GlobalVariable::LinkageTypes Linkage);
347e5dd7070Spatrick 
348e5dd7070Spatrick   llvm::GlobalVariable *
getAddrOfVirtualDisplacementMap(const CXXRecordDecl * SrcRD,const CXXRecordDecl * DstRD)349e5dd7070Spatrick   getAddrOfVirtualDisplacementMap(const CXXRecordDecl *SrcRD,
350e5dd7070Spatrick                                   const CXXRecordDecl *DstRD) {
351e5dd7070Spatrick     SmallString<256> OutName;
352e5dd7070Spatrick     llvm::raw_svector_ostream Out(OutName);
353e5dd7070Spatrick     getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
354e5dd7070Spatrick     StringRef MangledName = OutName.str();
355e5dd7070Spatrick 
356e5dd7070Spatrick     if (auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
357e5dd7070Spatrick       return VDispMap;
358e5dd7070Spatrick 
359e5dd7070Spatrick     MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
360e5dd7070Spatrick     unsigned NumEntries = 1 + SrcRD->getNumVBases();
361e5dd7070Spatrick     SmallVector<llvm::Constant *, 4> Map(NumEntries,
362e5dd7070Spatrick                                          llvm::UndefValue::get(CGM.IntTy));
363e5dd7070Spatrick     Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
364e5dd7070Spatrick     bool AnyDifferent = false;
365e5dd7070Spatrick     for (const auto &I : SrcRD->vbases()) {
366e5dd7070Spatrick       const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
367e5dd7070Spatrick       if (!DstRD->isVirtuallyDerivedFrom(VBase))
368e5dd7070Spatrick         continue;
369e5dd7070Spatrick 
370e5dd7070Spatrick       unsigned SrcVBIndex = VTContext.getVBTableIndex(SrcRD, VBase);
371e5dd7070Spatrick       unsigned DstVBIndex = VTContext.getVBTableIndex(DstRD, VBase);
372e5dd7070Spatrick       Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
373e5dd7070Spatrick       AnyDifferent |= SrcVBIndex != DstVBIndex;
374e5dd7070Spatrick     }
375e5dd7070Spatrick     // This map would be useless, don't use it.
376e5dd7070Spatrick     if (!AnyDifferent)
377e5dd7070Spatrick       return nullptr;
378e5dd7070Spatrick 
379e5dd7070Spatrick     llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy, Map.size());
380e5dd7070Spatrick     llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy, Map);
381e5dd7070Spatrick     llvm::GlobalValue::LinkageTypes Linkage =
382e5dd7070Spatrick         SrcRD->isExternallyVisible() && DstRD->isExternallyVisible()
383e5dd7070Spatrick             ? llvm::GlobalValue::LinkOnceODRLinkage
384e5dd7070Spatrick             : llvm::GlobalValue::InternalLinkage;
385e5dd7070Spatrick     auto *VDispMap = new llvm::GlobalVariable(
386e5dd7070Spatrick         CGM.getModule(), VDispMapTy, /*isConstant=*/true, Linkage,
387e5dd7070Spatrick         /*Initializer=*/Init, MangledName);
388e5dd7070Spatrick     return VDispMap;
389e5dd7070Spatrick   }
390e5dd7070Spatrick 
391e5dd7070Spatrick   void emitVBTableDefinition(const VPtrInfo &VBT, const CXXRecordDecl *RD,
392e5dd7070Spatrick                              llvm::GlobalVariable *GV) const;
393e5dd7070Spatrick 
setThunkLinkage(llvm::Function * Thunk,bool ForVTable,GlobalDecl GD,bool ReturnAdjustment)394e5dd7070Spatrick   void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
395e5dd7070Spatrick                        GlobalDecl GD, bool ReturnAdjustment) override {
396e5dd7070Spatrick     GVALinkage Linkage =
397e5dd7070Spatrick         getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.getDecl()));
398e5dd7070Spatrick 
399e5dd7070Spatrick     if (Linkage == GVA_Internal)
400e5dd7070Spatrick       Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
401e5dd7070Spatrick     else if (ReturnAdjustment)
402e5dd7070Spatrick       Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
403e5dd7070Spatrick     else
404e5dd7070Spatrick       Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
405e5dd7070Spatrick   }
406e5dd7070Spatrick 
exportThunk()407e5dd7070Spatrick   bool exportThunk() override { return false; }
408e5dd7070Spatrick 
409e5dd7070Spatrick   llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
410e5dd7070Spatrick                                      const ThisAdjustment &TA) override;
411e5dd7070Spatrick 
412e5dd7070Spatrick   llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
413e5dd7070Spatrick                                        const ReturnAdjustment &RA) override;
414e5dd7070Spatrick 
415e5dd7070Spatrick   void EmitThreadLocalInitFuncs(
416e5dd7070Spatrick       CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
417e5dd7070Spatrick       ArrayRef<llvm::Function *> CXXThreadLocalInits,
418e5dd7070Spatrick       ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override;
419e5dd7070Spatrick 
usesThreadWrapperFunction(const VarDecl * VD) const420e5dd7070Spatrick   bool usesThreadWrapperFunction(const VarDecl *VD) const override {
421*12c85518Srobert     return getContext().getLangOpts().isCompatibleWithMSVC(
422*12c85518Srobert                LangOptions::MSVC2019_5) &&
423*12c85518Srobert            (!isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD));
424e5dd7070Spatrick   }
425e5dd7070Spatrick   LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,
426e5dd7070Spatrick                                       QualType LValType) override;
427e5dd7070Spatrick 
428e5dd7070Spatrick   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
429e5dd7070Spatrick                        llvm::GlobalVariable *DeclPtr,
430e5dd7070Spatrick                        bool PerformInit) override;
431e5dd7070Spatrick   void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
432e5dd7070Spatrick                           llvm::FunctionCallee Dtor,
433e5dd7070Spatrick                           llvm::Constant *Addr) override;
434e5dd7070Spatrick 
435e5dd7070Spatrick   // ==== Notes on array cookies =========
436e5dd7070Spatrick   //
437e5dd7070Spatrick   // MSVC seems to only use cookies when the class has a destructor; a
438e5dd7070Spatrick   // two-argument usual array deallocation function isn't sufficient.
439e5dd7070Spatrick   //
440e5dd7070Spatrick   // For example, this code prints "100" and "1":
441e5dd7070Spatrick   //   struct A {
442e5dd7070Spatrick   //     char x;
443e5dd7070Spatrick   //     void *operator new[](size_t sz) {
444e5dd7070Spatrick   //       printf("%u\n", sz);
445e5dd7070Spatrick   //       return malloc(sz);
446e5dd7070Spatrick   //     }
447e5dd7070Spatrick   //     void operator delete[](void *p, size_t sz) {
448e5dd7070Spatrick   //       printf("%u\n", sz);
449e5dd7070Spatrick   //       free(p);
450e5dd7070Spatrick   //     }
451e5dd7070Spatrick   //   };
452e5dd7070Spatrick   //   int main() {
453e5dd7070Spatrick   //     A *p = new A[100];
454e5dd7070Spatrick   //     delete[] p;
455e5dd7070Spatrick   //   }
456e5dd7070Spatrick   // Whereas it prints "104" and "104" if you give A a destructor.
457e5dd7070Spatrick 
458e5dd7070Spatrick   bool requiresArrayCookie(const CXXDeleteExpr *expr,
459e5dd7070Spatrick                            QualType elementType) override;
460e5dd7070Spatrick   bool requiresArrayCookie(const CXXNewExpr *expr) override;
461e5dd7070Spatrick   CharUnits getArrayCookieSizeImpl(QualType type) override;
462e5dd7070Spatrick   Address InitializeArrayCookie(CodeGenFunction &CGF,
463e5dd7070Spatrick                                 Address NewPtr,
464e5dd7070Spatrick                                 llvm::Value *NumElements,
465e5dd7070Spatrick                                 const CXXNewExpr *expr,
466e5dd7070Spatrick                                 QualType ElementType) override;
467e5dd7070Spatrick   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
468e5dd7070Spatrick                                    Address allocPtr,
469e5dd7070Spatrick                                    CharUnits cookieSize) override;
470e5dd7070Spatrick 
471e5dd7070Spatrick   friend struct MSRTTIBuilder;
472e5dd7070Spatrick 
isImageRelative() const473e5dd7070Spatrick   bool isImageRelative() const {
474*12c85518Srobert     return CGM.getTarget().getPointerWidth(LangAS::Default) == 64;
475e5dd7070Spatrick   }
476e5dd7070Spatrick 
477e5dd7070Spatrick   // 5 routines for constructing the llvm types for MS RTTI structs.
getTypeDescriptorType(StringRef TypeInfoString)478e5dd7070Spatrick   llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
479e5dd7070Spatrick     llvm::SmallString<32> TDTypeName("rtti.TypeDescriptor");
480e5dd7070Spatrick     TDTypeName += llvm::utostr(TypeInfoString.size());
481e5dd7070Spatrick     llvm::StructType *&TypeDescriptorType =
482e5dd7070Spatrick         TypeDescriptorTypeMap[TypeInfoString.size()];
483e5dd7070Spatrick     if (TypeDescriptorType)
484e5dd7070Spatrick       return TypeDescriptorType;
485e5dd7070Spatrick     llvm::Type *FieldTypes[] = {
486e5dd7070Spatrick         CGM.Int8PtrPtrTy,
487e5dd7070Spatrick         CGM.Int8PtrTy,
488e5dd7070Spatrick         llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
489e5dd7070Spatrick     TypeDescriptorType =
490e5dd7070Spatrick         llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, TDTypeName);
491e5dd7070Spatrick     return TypeDescriptorType;
492e5dd7070Spatrick   }
493e5dd7070Spatrick 
getImageRelativeType(llvm::Type * PtrType)494e5dd7070Spatrick   llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
495e5dd7070Spatrick     if (!isImageRelative())
496e5dd7070Spatrick       return PtrType;
497e5dd7070Spatrick     return CGM.IntTy;
498e5dd7070Spatrick   }
499e5dd7070Spatrick 
getBaseClassDescriptorType()500e5dd7070Spatrick   llvm::StructType *getBaseClassDescriptorType() {
501e5dd7070Spatrick     if (BaseClassDescriptorType)
502e5dd7070Spatrick       return BaseClassDescriptorType;
503e5dd7070Spatrick     llvm::Type *FieldTypes[] = {
504e5dd7070Spatrick         getImageRelativeType(CGM.Int8PtrTy),
505e5dd7070Spatrick         CGM.IntTy,
506e5dd7070Spatrick         CGM.IntTy,
507e5dd7070Spatrick         CGM.IntTy,
508e5dd7070Spatrick         CGM.IntTy,
509e5dd7070Spatrick         CGM.IntTy,
510e5dd7070Spatrick         getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
511e5dd7070Spatrick     };
512e5dd7070Spatrick     BaseClassDescriptorType = llvm::StructType::create(
513e5dd7070Spatrick         CGM.getLLVMContext(), FieldTypes, "rtti.BaseClassDescriptor");
514e5dd7070Spatrick     return BaseClassDescriptorType;
515e5dd7070Spatrick   }
516e5dd7070Spatrick 
getClassHierarchyDescriptorType()517e5dd7070Spatrick   llvm::StructType *getClassHierarchyDescriptorType() {
518e5dd7070Spatrick     if (ClassHierarchyDescriptorType)
519e5dd7070Spatrick       return ClassHierarchyDescriptorType;
520e5dd7070Spatrick     // Forward-declare RTTIClassHierarchyDescriptor to break a cycle.
521e5dd7070Spatrick     ClassHierarchyDescriptorType = llvm::StructType::create(
522e5dd7070Spatrick         CGM.getLLVMContext(), "rtti.ClassHierarchyDescriptor");
523e5dd7070Spatrick     llvm::Type *FieldTypes[] = {
524e5dd7070Spatrick         CGM.IntTy,
525e5dd7070Spatrick         CGM.IntTy,
526e5dd7070Spatrick         CGM.IntTy,
527e5dd7070Spatrick         getImageRelativeType(
528e5dd7070Spatrick             getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
529e5dd7070Spatrick     };
530e5dd7070Spatrick     ClassHierarchyDescriptorType->setBody(FieldTypes);
531e5dd7070Spatrick     return ClassHierarchyDescriptorType;
532e5dd7070Spatrick   }
533e5dd7070Spatrick 
getCompleteObjectLocatorType()534e5dd7070Spatrick   llvm::StructType *getCompleteObjectLocatorType() {
535e5dd7070Spatrick     if (CompleteObjectLocatorType)
536e5dd7070Spatrick       return CompleteObjectLocatorType;
537e5dd7070Spatrick     CompleteObjectLocatorType = llvm::StructType::create(
538e5dd7070Spatrick         CGM.getLLVMContext(), "rtti.CompleteObjectLocator");
539e5dd7070Spatrick     llvm::Type *FieldTypes[] = {
540e5dd7070Spatrick         CGM.IntTy,
541e5dd7070Spatrick         CGM.IntTy,
542e5dd7070Spatrick         CGM.IntTy,
543e5dd7070Spatrick         getImageRelativeType(CGM.Int8PtrTy),
544e5dd7070Spatrick         getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
545e5dd7070Spatrick         getImageRelativeType(CompleteObjectLocatorType),
546e5dd7070Spatrick     };
547e5dd7070Spatrick     llvm::ArrayRef<llvm::Type *> FieldTypesRef(FieldTypes);
548e5dd7070Spatrick     if (!isImageRelative())
549e5dd7070Spatrick       FieldTypesRef = FieldTypesRef.drop_back();
550e5dd7070Spatrick     CompleteObjectLocatorType->setBody(FieldTypesRef);
551e5dd7070Spatrick     return CompleteObjectLocatorType;
552e5dd7070Spatrick   }
553e5dd7070Spatrick 
getImageBase()554e5dd7070Spatrick   llvm::GlobalVariable *getImageBase() {
555e5dd7070Spatrick     StringRef Name = "__ImageBase";
556e5dd7070Spatrick     if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
557e5dd7070Spatrick       return GV;
558e5dd7070Spatrick 
559e5dd7070Spatrick     auto *GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
560e5dd7070Spatrick                                         /*isConstant=*/true,
561e5dd7070Spatrick                                         llvm::GlobalValue::ExternalLinkage,
562e5dd7070Spatrick                                         /*Initializer=*/nullptr, Name);
563e5dd7070Spatrick     CGM.setDSOLocal(GV);
564e5dd7070Spatrick     return GV;
565e5dd7070Spatrick   }
566e5dd7070Spatrick 
getImageRelativeConstant(llvm::Constant * PtrVal)567e5dd7070Spatrick   llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
568e5dd7070Spatrick     if (!isImageRelative())
569e5dd7070Spatrick       return PtrVal;
570e5dd7070Spatrick 
571e5dd7070Spatrick     if (PtrVal->isNullValue())
572e5dd7070Spatrick       return llvm::Constant::getNullValue(CGM.IntTy);
573e5dd7070Spatrick 
574e5dd7070Spatrick     llvm::Constant *ImageBaseAsInt =
575e5dd7070Spatrick         llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
576e5dd7070Spatrick     llvm::Constant *PtrValAsInt =
577e5dd7070Spatrick         llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
578e5dd7070Spatrick     llvm::Constant *Diff =
579e5dd7070Spatrick         llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
580e5dd7070Spatrick                                    /*HasNUW=*/true, /*HasNSW=*/true);
581e5dd7070Spatrick     return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
582e5dd7070Spatrick   }
583e5dd7070Spatrick 
584e5dd7070Spatrick private:
getMangleContext()585e5dd7070Spatrick   MicrosoftMangleContext &getMangleContext() {
586e5dd7070Spatrick     return cast<MicrosoftMangleContext>(CodeGen::CGCXXABI::getMangleContext());
587e5dd7070Spatrick   }
588e5dd7070Spatrick 
getZeroInt()589e5dd7070Spatrick   llvm::Constant *getZeroInt() {
590e5dd7070Spatrick     return llvm::ConstantInt::get(CGM.IntTy, 0);
591e5dd7070Spatrick   }
592e5dd7070Spatrick 
getAllOnesInt()593e5dd7070Spatrick   llvm::Constant *getAllOnesInt() {
594e5dd7070Spatrick     return  llvm::Constant::getAllOnesValue(CGM.IntTy);
595e5dd7070Spatrick   }
596e5dd7070Spatrick 
597e5dd7070Spatrick   CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) override;
598e5dd7070Spatrick 
599e5dd7070Spatrick   void
600e5dd7070Spatrick   GetNullMemberPointerFields(const MemberPointerType *MPT,
601e5dd7070Spatrick                              llvm::SmallVectorImpl<llvm::Constant *> &fields);
602e5dd7070Spatrick 
603e5dd7070Spatrick   /// Shared code for virtual base adjustment.  Returns the offset from
604e5dd7070Spatrick   /// the vbptr to the virtual base.  Optionally returns the address of the
605e5dd7070Spatrick   /// vbptr itself.
606e5dd7070Spatrick   llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
607e5dd7070Spatrick                                        Address Base,
608e5dd7070Spatrick                                        llvm::Value *VBPtrOffset,
609e5dd7070Spatrick                                        llvm::Value *VBTableOffset,
610e5dd7070Spatrick                                        llvm::Value **VBPtr = nullptr);
611e5dd7070Spatrick 
GetVBaseOffsetFromVBPtr(CodeGenFunction & CGF,Address Base,int32_t VBPtrOffset,int32_t VBTableOffset,llvm::Value ** VBPtr=nullptr)612e5dd7070Spatrick   llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
613e5dd7070Spatrick                                        Address Base,
614e5dd7070Spatrick                                        int32_t VBPtrOffset,
615e5dd7070Spatrick                                        int32_t VBTableOffset,
616e5dd7070Spatrick                                        llvm::Value **VBPtr = nullptr) {
617e5dd7070Spatrick     assert(VBTableOffset % 4 == 0 && "should be byte offset into table of i32s");
618e5dd7070Spatrick     llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
619e5dd7070Spatrick                 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
620e5dd7070Spatrick     return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
621e5dd7070Spatrick   }
622e5dd7070Spatrick 
623e5dd7070Spatrick   std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
624e5dd7070Spatrick   performBaseAdjustment(CodeGenFunction &CGF, Address Value,
625e5dd7070Spatrick                         QualType SrcRecordTy);
626e5dd7070Spatrick 
627e5dd7070Spatrick   /// Performs a full virtual base adjustment.  Used to dereference
628e5dd7070Spatrick   /// pointers to members of virtual bases.
629e5dd7070Spatrick   llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const Expr *E,
630e5dd7070Spatrick                                  const CXXRecordDecl *RD, Address Base,
631e5dd7070Spatrick                                  llvm::Value *VirtualBaseAdjustmentOffset,
632e5dd7070Spatrick                                  llvm::Value *VBPtrOffset /* optional */);
633e5dd7070Spatrick 
634e5dd7070Spatrick   /// Emits a full member pointer with the fields common to data and
635e5dd7070Spatrick   /// function member pointers.
636e5dd7070Spatrick   llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
637e5dd7070Spatrick                                         bool IsMemberFunction,
638e5dd7070Spatrick                                         const CXXRecordDecl *RD,
639e5dd7070Spatrick                                         CharUnits NonVirtualBaseAdjustment,
640e5dd7070Spatrick                                         unsigned VBTableIndex);
641e5dd7070Spatrick 
642e5dd7070Spatrick   bool MemberPointerConstantIsNull(const MemberPointerType *MPT,
643e5dd7070Spatrick                                    llvm::Constant *MP);
644e5dd7070Spatrick 
645e5dd7070Spatrick   /// - Initialize all vbptrs of 'this' with RD as the complete type.
646e5dd7070Spatrick   void EmitVBPtrStores(CodeGenFunction &CGF, const CXXRecordDecl *RD);
647e5dd7070Spatrick 
648e5dd7070Spatrick   /// Caching wrapper around VBTableBuilder::enumerateVBTables().
649e5dd7070Spatrick   const VBTableGlobals &enumerateVBTables(const CXXRecordDecl *RD);
650e5dd7070Spatrick 
651e5dd7070Spatrick   /// Generate a thunk for calling a virtual member function MD.
652e5dd7070Spatrick   llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
653e5dd7070Spatrick                                          const MethodVFTableLocation &ML);
654e5dd7070Spatrick 
655e5dd7070Spatrick   llvm::Constant *EmitMemberDataPointer(const CXXRecordDecl *RD,
656e5dd7070Spatrick                                         CharUnits offset);
657e5dd7070Spatrick 
658e5dd7070Spatrick public:
659e5dd7070Spatrick   llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
660e5dd7070Spatrick 
661e5dd7070Spatrick   bool isZeroInitializable(const MemberPointerType *MPT) override;
662e5dd7070Spatrick 
isMemberPointerConvertible(const MemberPointerType * MPT) const663e5dd7070Spatrick   bool isMemberPointerConvertible(const MemberPointerType *MPT) const override {
664e5dd7070Spatrick     const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
665e5dd7070Spatrick     return RD->hasAttr<MSInheritanceAttr>();
666e5dd7070Spatrick   }
667e5dd7070Spatrick 
668e5dd7070Spatrick   llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override;
669e5dd7070Spatrick 
670e5dd7070Spatrick   llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
671e5dd7070Spatrick                                         CharUnits offset) override;
672e5dd7070Spatrick   llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD) override;
673e5dd7070Spatrick   llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override;
674e5dd7070Spatrick 
675e5dd7070Spatrick   llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
676e5dd7070Spatrick                                            llvm::Value *L,
677e5dd7070Spatrick                                            llvm::Value *R,
678e5dd7070Spatrick                                            const MemberPointerType *MPT,
679e5dd7070Spatrick                                            bool Inequality) override;
680e5dd7070Spatrick 
681e5dd7070Spatrick   llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
682e5dd7070Spatrick                                           llvm::Value *MemPtr,
683e5dd7070Spatrick                                           const MemberPointerType *MPT) override;
684e5dd7070Spatrick 
685e5dd7070Spatrick   llvm::Value *
686e5dd7070Spatrick   EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
687e5dd7070Spatrick                                Address Base, llvm::Value *MemPtr,
688e5dd7070Spatrick                                const MemberPointerType *MPT) override;
689e5dd7070Spatrick 
690e5dd7070Spatrick   llvm::Value *EmitNonNullMemberPointerConversion(
691e5dd7070Spatrick       const MemberPointerType *SrcTy, const MemberPointerType *DstTy,
692e5dd7070Spatrick       CastKind CK, CastExpr::path_const_iterator PathBegin,
693e5dd7070Spatrick       CastExpr::path_const_iterator PathEnd, llvm::Value *Src,
694e5dd7070Spatrick       CGBuilderTy &Builder);
695e5dd7070Spatrick 
696e5dd7070Spatrick   llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
697e5dd7070Spatrick                                            const CastExpr *E,
698e5dd7070Spatrick                                            llvm::Value *Src) override;
699e5dd7070Spatrick 
700e5dd7070Spatrick   llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
701e5dd7070Spatrick                                               llvm::Constant *Src) override;
702e5dd7070Spatrick 
703e5dd7070Spatrick   llvm::Constant *EmitMemberPointerConversion(
704e5dd7070Spatrick       const MemberPointerType *SrcTy, const MemberPointerType *DstTy,
705e5dd7070Spatrick       CastKind CK, CastExpr::path_const_iterator PathBegin,
706e5dd7070Spatrick       CastExpr::path_const_iterator PathEnd, llvm::Constant *Src);
707e5dd7070Spatrick 
708e5dd7070Spatrick   CGCallee
709e5dd7070Spatrick   EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E,
710e5dd7070Spatrick                                   Address This, llvm::Value *&ThisPtrForCall,
711e5dd7070Spatrick                                   llvm::Value *MemPtr,
712e5dd7070Spatrick                                   const MemberPointerType *MPT) override;
713e5dd7070Spatrick 
714e5dd7070Spatrick   void emitCXXStructor(GlobalDecl GD) override;
715e5dd7070Spatrick 
getCatchableTypeType()716e5dd7070Spatrick   llvm::StructType *getCatchableTypeType() {
717e5dd7070Spatrick     if (CatchableTypeType)
718e5dd7070Spatrick       return CatchableTypeType;
719e5dd7070Spatrick     llvm::Type *FieldTypes[] = {
720e5dd7070Spatrick         CGM.IntTy,                           // Flags
721e5dd7070Spatrick         getImageRelativeType(CGM.Int8PtrTy), // TypeDescriptor
722e5dd7070Spatrick         CGM.IntTy,                           // NonVirtualAdjustment
723e5dd7070Spatrick         CGM.IntTy,                           // OffsetToVBPtr
724e5dd7070Spatrick         CGM.IntTy,                           // VBTableIndex
725e5dd7070Spatrick         CGM.IntTy,                           // Size
726e5dd7070Spatrick         getImageRelativeType(CGM.Int8PtrTy)  // CopyCtor
727e5dd7070Spatrick     };
728e5dd7070Spatrick     CatchableTypeType = llvm::StructType::create(
729e5dd7070Spatrick         CGM.getLLVMContext(), FieldTypes, "eh.CatchableType");
730e5dd7070Spatrick     return CatchableTypeType;
731e5dd7070Spatrick   }
732e5dd7070Spatrick 
getCatchableTypeArrayType(uint32_t NumEntries)733e5dd7070Spatrick   llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
734e5dd7070Spatrick     llvm::StructType *&CatchableTypeArrayType =
735e5dd7070Spatrick         CatchableTypeArrayTypeMap[NumEntries];
736e5dd7070Spatrick     if (CatchableTypeArrayType)
737e5dd7070Spatrick       return CatchableTypeArrayType;
738e5dd7070Spatrick 
739e5dd7070Spatrick     llvm::SmallString<23> CTATypeName("eh.CatchableTypeArray.");
740e5dd7070Spatrick     CTATypeName += llvm::utostr(NumEntries);
741e5dd7070Spatrick     llvm::Type *CTType =
742e5dd7070Spatrick         getImageRelativeType(getCatchableTypeType()->getPointerTo());
743e5dd7070Spatrick     llvm::Type *FieldTypes[] = {
744e5dd7070Spatrick         CGM.IntTy,                               // NumEntries
745e5dd7070Spatrick         llvm::ArrayType::get(CTType, NumEntries) // CatchableTypes
746e5dd7070Spatrick     };
747e5dd7070Spatrick     CatchableTypeArrayType =
748e5dd7070Spatrick         llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, CTATypeName);
749e5dd7070Spatrick     return CatchableTypeArrayType;
750e5dd7070Spatrick   }
751e5dd7070Spatrick 
getThrowInfoType()752e5dd7070Spatrick   llvm::StructType *getThrowInfoType() {
753e5dd7070Spatrick     if (ThrowInfoType)
754e5dd7070Spatrick       return ThrowInfoType;
755e5dd7070Spatrick     llvm::Type *FieldTypes[] = {
756e5dd7070Spatrick         CGM.IntTy,                           // Flags
757e5dd7070Spatrick         getImageRelativeType(CGM.Int8PtrTy), // CleanupFn
758e5dd7070Spatrick         getImageRelativeType(CGM.Int8PtrTy), // ForwardCompat
759e5dd7070Spatrick         getImageRelativeType(CGM.Int8PtrTy)  // CatchableTypeArray
760e5dd7070Spatrick     };
761e5dd7070Spatrick     ThrowInfoType = llvm::StructType::create(CGM.getLLVMContext(), FieldTypes,
762e5dd7070Spatrick                                              "eh.ThrowInfo");
763e5dd7070Spatrick     return ThrowInfoType;
764e5dd7070Spatrick   }
765e5dd7070Spatrick 
getThrowFn()766e5dd7070Spatrick   llvm::FunctionCallee getThrowFn() {
767e5dd7070Spatrick     // _CxxThrowException is passed an exception object and a ThrowInfo object
768e5dd7070Spatrick     // which describes the exception.
769e5dd7070Spatrick     llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
770e5dd7070Spatrick     llvm::FunctionType *FTy =
771e5dd7070Spatrick         llvm::FunctionType::get(CGM.VoidTy, Args, /*isVarArg=*/false);
772e5dd7070Spatrick     llvm::FunctionCallee Throw =
773e5dd7070Spatrick         CGM.CreateRuntimeFunction(FTy, "_CxxThrowException");
774e5dd7070Spatrick     // _CxxThrowException is stdcall on 32-bit x86 platforms.
775e5dd7070Spatrick     if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
776e5dd7070Spatrick       if (auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
777e5dd7070Spatrick         Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
778e5dd7070Spatrick     }
779e5dd7070Spatrick     return Throw;
780e5dd7070Spatrick   }
781e5dd7070Spatrick 
782e5dd7070Spatrick   llvm::Function *getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
783e5dd7070Spatrick                                           CXXCtorType CT);
784e5dd7070Spatrick 
785e5dd7070Spatrick   llvm::Constant *getCatchableType(QualType T,
786e5dd7070Spatrick                                    uint32_t NVOffset = 0,
787e5dd7070Spatrick                                    int32_t VBPtrOffset = -1,
788e5dd7070Spatrick                                    uint32_t VBIndex = 0);
789e5dd7070Spatrick 
790e5dd7070Spatrick   llvm::GlobalVariable *getCatchableTypeArray(QualType T);
791e5dd7070Spatrick 
792e5dd7070Spatrick   llvm::GlobalVariable *getThrowInfo(QualType T) override;
793e5dd7070Spatrick 
794e5dd7070Spatrick   std::pair<llvm::Value *, const CXXRecordDecl *>
795e5dd7070Spatrick   LoadVTablePtr(CodeGenFunction &CGF, Address This,
796e5dd7070Spatrick                 const CXXRecordDecl *RD) override;
797e5dd7070Spatrick 
798*12c85518Srobert   bool
799a9ac8606Spatrick   isPermittedToBeHomogeneousAggregate(const CXXRecordDecl *RD) const override;
800a9ac8606Spatrick 
801e5dd7070Spatrick private:
802e5dd7070Spatrick   typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
803e5dd7070Spatrick   typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
804e5dd7070Spatrick   typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
805e5dd7070Spatrick   /// All the vftables that have been referenced.
806e5dd7070Spatrick   VFTablesMapTy VFTablesMap;
807e5dd7070Spatrick   VTablesMapTy VTablesMap;
808e5dd7070Spatrick 
809e5dd7070Spatrick   /// This set holds the record decls we've deferred vtable emission for.
810e5dd7070Spatrick   llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
811e5dd7070Spatrick 
812e5dd7070Spatrick 
813e5dd7070Spatrick   /// All the vbtables which have been referenced.
814e5dd7070Spatrick   llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
815e5dd7070Spatrick 
816e5dd7070Spatrick   /// Info on the global variable used to guard initialization of static locals.
817e5dd7070Spatrick   /// The BitIndex field is only used for externally invisible declarations.
818e5dd7070Spatrick   struct GuardInfo {
GuardInfo__anon063cb12a0111::MicrosoftCXXABI::GuardInfo819e5dd7070Spatrick     GuardInfo() : Guard(nullptr), BitIndex(0) {}
820e5dd7070Spatrick     llvm::GlobalVariable *Guard;
821e5dd7070Spatrick     unsigned BitIndex;
822e5dd7070Spatrick   };
823e5dd7070Spatrick 
824e5dd7070Spatrick   /// Map from DeclContext to the current guard variable.  We assume that the
825e5dd7070Spatrick   /// AST is visited in source code order.
826e5dd7070Spatrick   llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
827e5dd7070Spatrick   llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
828e5dd7070Spatrick   llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
829e5dd7070Spatrick 
830e5dd7070Spatrick   llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
831e5dd7070Spatrick   llvm::StructType *BaseClassDescriptorType;
832e5dd7070Spatrick   llvm::StructType *ClassHierarchyDescriptorType;
833e5dd7070Spatrick   llvm::StructType *CompleteObjectLocatorType;
834e5dd7070Spatrick 
835e5dd7070Spatrick   llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
836e5dd7070Spatrick 
837e5dd7070Spatrick   llvm::StructType *CatchableTypeType;
838e5dd7070Spatrick   llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
839e5dd7070Spatrick   llvm::StructType *ThrowInfoType;
840e5dd7070Spatrick };
841e5dd7070Spatrick 
842e5dd7070Spatrick }
843e5dd7070Spatrick 
844e5dd7070Spatrick CGCXXABI::RecordArgABI
getRecordArgABI(const CXXRecordDecl * RD) const845e5dd7070Spatrick MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
846a9ac8606Spatrick   // Use the default C calling convention rules for things that can be passed in
847a9ac8606Spatrick   // registers, i.e. non-trivially copyable records or records marked with
848a9ac8606Spatrick   // [[trivial_abi]].
849a9ac8606Spatrick   if (RD->canPassInRegisters())
850a9ac8606Spatrick     return RAA_Default;
851a9ac8606Spatrick 
852e5dd7070Spatrick   switch (CGM.getTarget().getTriple().getArch()) {
853e5dd7070Spatrick   default:
854e5dd7070Spatrick     // FIXME: Implement for other architectures.
855a9ac8606Spatrick     return RAA_Indirect;
856e5dd7070Spatrick 
857e5dd7070Spatrick   case llvm::Triple::thumb:
858a9ac8606Spatrick     // Pass things indirectly for now because it is simple.
859e5dd7070Spatrick     // FIXME: This is incompatible with MSVC for arguments with a dtor and no
860e5dd7070Spatrick     // copy ctor.
861a9ac8606Spatrick     return RAA_Indirect;
862e5dd7070Spatrick 
863a9ac8606Spatrick   case llvm::Triple::x86: {
864a9ac8606Spatrick     // If the argument has *required* alignment greater than four bytes, pass
865a9ac8606Spatrick     // it indirectly. Prior to MSVC version 19.14, passing overaligned
866a9ac8606Spatrick     // arguments was not supported and resulted in a compiler error. In 19.14
867a9ac8606Spatrick     // and later versions, such arguments are now passed indirectly.
868a9ac8606Spatrick     TypeInfo Info = getContext().getTypeInfo(RD->getTypeForDecl());
869*12c85518Srobert     if (Info.isAlignRequired() && Info.Align > 4)
870a9ac8606Spatrick       return RAA_Indirect;
871e5dd7070Spatrick 
872e5dd7070Spatrick     // If C++ prohibits us from making a copy, construct the arguments directly
873e5dd7070Spatrick     // into argument memory.
874e5dd7070Spatrick     return RAA_DirectInMemory;
875a9ac8606Spatrick   }
876e5dd7070Spatrick 
877e5dd7070Spatrick   case llvm::Triple::x86_64:
878e5dd7070Spatrick   case llvm::Triple::aarch64:
879a9ac8606Spatrick     return RAA_Indirect;
880e5dd7070Spatrick   }
881e5dd7070Spatrick 
882e5dd7070Spatrick   llvm_unreachable("invalid enum");
883e5dd7070Spatrick }
884e5dd7070Spatrick 
emitVirtualObjectDelete(CodeGenFunction & CGF,const CXXDeleteExpr * DE,Address Ptr,QualType ElementType,const CXXDestructorDecl * Dtor)885e5dd7070Spatrick void MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
886e5dd7070Spatrick                                               const CXXDeleteExpr *DE,
887e5dd7070Spatrick                                               Address Ptr,
888e5dd7070Spatrick                                               QualType ElementType,
889e5dd7070Spatrick                                               const CXXDestructorDecl *Dtor) {
890e5dd7070Spatrick   // FIXME: Provide a source location here even though there's no
891e5dd7070Spatrick   // CXXMemberCallExpr for dtor call.
892e5dd7070Spatrick   bool UseGlobalDelete = DE->isGlobalDelete();
893e5dd7070Spatrick   CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
894e5dd7070Spatrick   llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
895e5dd7070Spatrick   if (UseGlobalDelete)
896e5dd7070Spatrick     CGF.EmitDeleteCall(DE->getOperatorDelete(), MDThis, ElementType);
897e5dd7070Spatrick }
898e5dd7070Spatrick 
emitRethrow(CodeGenFunction & CGF,bool isNoReturn)899e5dd7070Spatrick void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
900e5dd7070Spatrick   llvm::Value *Args[] = {
901e5dd7070Spatrick       llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
902e5dd7070Spatrick       llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
903e5dd7070Spatrick   llvm::FunctionCallee Fn = getThrowFn();
904e5dd7070Spatrick   if (isNoReturn)
905e5dd7070Spatrick     CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, Args);
906e5dd7070Spatrick   else
907e5dd7070Spatrick     CGF.EmitRuntimeCallOrInvoke(Fn, Args);
908e5dd7070Spatrick }
909e5dd7070Spatrick 
emitBeginCatch(CodeGenFunction & CGF,const CXXCatchStmt * S)910e5dd7070Spatrick void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
911e5dd7070Spatrick                                      const CXXCatchStmt *S) {
912e5dd7070Spatrick   // In the MS ABI, the runtime handles the copy, and the catch handler is
913e5dd7070Spatrick   // responsible for destruction.
914e5dd7070Spatrick   VarDecl *CatchParam = S->getExceptionDecl();
915e5dd7070Spatrick   llvm::BasicBlock *CatchPadBB = CGF.Builder.GetInsertBlock();
916e5dd7070Spatrick   llvm::CatchPadInst *CPI =
917e5dd7070Spatrick       cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
918e5dd7070Spatrick   CGF.CurrentFuncletPad = CPI;
919e5dd7070Spatrick 
920e5dd7070Spatrick   // If this is a catch-all or the catch parameter is unnamed, we don't need to
921e5dd7070Spatrick   // emit an alloca to the object.
922e5dd7070Spatrick   if (!CatchParam || !CatchParam->getDeclName()) {
923e5dd7070Spatrick     CGF.EHStack.pushCleanup<CatchRetScope>(NormalCleanup, CPI);
924e5dd7070Spatrick     return;
925e5dd7070Spatrick   }
926e5dd7070Spatrick 
927e5dd7070Spatrick   CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam);
928e5dd7070Spatrick   CPI->setArgOperand(2, var.getObjectAddress(CGF).getPointer());
929e5dd7070Spatrick   CGF.EHStack.pushCleanup<CatchRetScope>(NormalCleanup, CPI);
930e5dd7070Spatrick   CGF.EmitAutoVarCleanups(var);
931e5dd7070Spatrick }
932e5dd7070Spatrick 
933e5dd7070Spatrick /// We need to perform a generic polymorphic operation (like a typeid
934e5dd7070Spatrick /// or a cast), which requires an object with a vfptr.  Adjust the
935e5dd7070Spatrick /// address to point to an object with a vfptr.
936e5dd7070Spatrick std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
performBaseAdjustment(CodeGenFunction & CGF,Address Value,QualType SrcRecordTy)937e5dd7070Spatrick MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address Value,
938e5dd7070Spatrick                                        QualType SrcRecordTy) {
939*12c85518Srobert   Value = CGF.Builder.CreateElementBitCast(Value, CGF.Int8Ty);
940e5dd7070Spatrick   const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
941e5dd7070Spatrick   const ASTContext &Context = getContext();
942e5dd7070Spatrick 
943e5dd7070Spatrick   // If the class itself has a vfptr, great.  This check implicitly
944e5dd7070Spatrick   // covers non-virtual base subobjects: a class with its own virtual
945e5dd7070Spatrick   // functions would be a candidate to be a primary base.
946e5dd7070Spatrick   if (Context.getASTRecordLayout(SrcDecl).hasExtendableVFPtr())
947e5dd7070Spatrick     return std::make_tuple(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0),
948e5dd7070Spatrick                            SrcDecl);
949e5dd7070Spatrick 
950e5dd7070Spatrick   // Okay, one of the vbases must have a vfptr, or else this isn't
951e5dd7070Spatrick   // actually a polymorphic class.
952e5dd7070Spatrick   const CXXRecordDecl *PolymorphicBase = nullptr;
953e5dd7070Spatrick   for (auto &Base : SrcDecl->vbases()) {
954e5dd7070Spatrick     const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
955e5dd7070Spatrick     if (Context.getASTRecordLayout(BaseDecl).hasExtendableVFPtr()) {
956e5dd7070Spatrick       PolymorphicBase = BaseDecl;
957e5dd7070Spatrick       break;
958e5dd7070Spatrick     }
959e5dd7070Spatrick   }
960e5dd7070Spatrick   assert(PolymorphicBase && "polymorphic class has no apparent vfptr?");
961e5dd7070Spatrick 
962e5dd7070Spatrick   llvm::Value *Offset =
963e5dd7070Spatrick     GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase);
964a9ac8606Spatrick   llvm::Value *Ptr = CGF.Builder.CreateInBoundsGEP(
965a9ac8606Spatrick       Value.getElementType(), Value.getPointer(), Offset);
966e5dd7070Spatrick   CharUnits VBaseAlign =
967e5dd7070Spatrick     CGF.CGM.getVBaseAlignment(Value.getAlignment(), SrcDecl, PolymorphicBase);
968*12c85518Srobert   return std::make_tuple(Address(Ptr, CGF.Int8Ty, VBaseAlign), Offset,
969*12c85518Srobert                          PolymorphicBase);
970e5dd7070Spatrick }
971e5dd7070Spatrick 
shouldTypeidBeNullChecked(bool IsDeref,QualType SrcRecordTy)972e5dd7070Spatrick bool MicrosoftCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
973e5dd7070Spatrick                                                 QualType SrcRecordTy) {
974e5dd7070Spatrick   const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
975e5dd7070Spatrick   return IsDeref &&
976e5dd7070Spatrick          !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
977e5dd7070Spatrick }
978e5dd7070Spatrick 
emitRTtypeidCall(CodeGenFunction & CGF,llvm::Value * Argument)979e5dd7070Spatrick static llvm::CallBase *emitRTtypeidCall(CodeGenFunction &CGF,
980e5dd7070Spatrick                                         llvm::Value *Argument) {
981e5dd7070Spatrick   llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
982e5dd7070Spatrick   llvm::FunctionType *FTy =
983e5dd7070Spatrick       llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false);
984e5dd7070Spatrick   llvm::Value *Args[] = {Argument};
985e5dd7070Spatrick   llvm::FunctionCallee Fn = CGF.CGM.CreateRuntimeFunction(FTy, "__RTtypeid");
986e5dd7070Spatrick   return CGF.EmitRuntimeCallOrInvoke(Fn, Args);
987e5dd7070Spatrick }
988e5dd7070Spatrick 
EmitBadTypeidCall(CodeGenFunction & CGF)989e5dd7070Spatrick void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
990e5dd7070Spatrick   llvm::CallBase *Call =
991e5dd7070Spatrick       emitRTtypeidCall(CGF, llvm::Constant::getNullValue(CGM.VoidPtrTy));
992e5dd7070Spatrick   Call->setDoesNotReturn();
993e5dd7070Spatrick   CGF.Builder.CreateUnreachable();
994e5dd7070Spatrick }
995e5dd7070Spatrick 
EmitTypeid(CodeGenFunction & CGF,QualType SrcRecordTy,Address ThisPtr,llvm::Type * StdTypeInfoPtrTy)996e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
997e5dd7070Spatrick                                          QualType SrcRecordTy,
998e5dd7070Spatrick                                          Address ThisPtr,
999e5dd7070Spatrick                                          llvm::Type *StdTypeInfoPtrTy) {
1000e5dd7070Spatrick   std::tie(ThisPtr, std::ignore, std::ignore) =
1001e5dd7070Spatrick       performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
1002e5dd7070Spatrick   llvm::CallBase *Typeid = emitRTtypeidCall(CGF, ThisPtr.getPointer());
1003e5dd7070Spatrick   return CGF.Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
1004e5dd7070Spatrick }
1005e5dd7070Spatrick 
shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,QualType SrcRecordTy)1006e5dd7070Spatrick bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
1007e5dd7070Spatrick                                                          QualType SrcRecordTy) {
1008e5dd7070Spatrick   const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
1009e5dd7070Spatrick   return SrcIsPtr &&
1010e5dd7070Spatrick          !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1011e5dd7070Spatrick }
1012e5dd7070Spatrick 
EmitDynamicCastCall(CodeGenFunction & CGF,Address This,QualType SrcRecordTy,QualType DestTy,QualType DestRecordTy,llvm::BasicBlock * CastEnd)1013e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
1014e5dd7070Spatrick     CodeGenFunction &CGF, Address This, QualType SrcRecordTy,
1015e5dd7070Spatrick     QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1016e5dd7070Spatrick   llvm::Type *DestLTy = CGF.ConvertType(DestTy);
1017e5dd7070Spatrick 
1018e5dd7070Spatrick   llvm::Value *SrcRTTI =
1019e5dd7070Spatrick       CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
1020e5dd7070Spatrick   llvm::Value *DestRTTI =
1021e5dd7070Spatrick       CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
1022e5dd7070Spatrick 
1023e5dd7070Spatrick   llvm::Value *Offset;
1024e5dd7070Spatrick   std::tie(This, Offset, std::ignore) =
1025e5dd7070Spatrick       performBaseAdjustment(CGF, This, SrcRecordTy);
1026e5dd7070Spatrick   llvm::Value *ThisPtr = This.getPointer();
1027e5dd7070Spatrick   Offset = CGF.Builder.CreateTrunc(Offset, CGF.Int32Ty);
1028e5dd7070Spatrick 
1029e5dd7070Spatrick   // PVOID __RTDynamicCast(
1030e5dd7070Spatrick   //   PVOID inptr,
1031e5dd7070Spatrick   //   LONG VfDelta,
1032e5dd7070Spatrick   //   PVOID SrcType,
1033e5dd7070Spatrick   //   PVOID TargetType,
1034e5dd7070Spatrick   //   BOOL isReference)
1035e5dd7070Spatrick   llvm::Type *ArgTypes[] = {CGF.Int8PtrTy, CGF.Int32Ty, CGF.Int8PtrTy,
1036e5dd7070Spatrick                             CGF.Int8PtrTy, CGF.Int32Ty};
1037e5dd7070Spatrick   llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction(
1038e5dd7070Spatrick       llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
1039e5dd7070Spatrick       "__RTDynamicCast");
1040e5dd7070Spatrick   llvm::Value *Args[] = {
1041e5dd7070Spatrick       ThisPtr, Offset, SrcRTTI, DestRTTI,
1042e5dd7070Spatrick       llvm::ConstantInt::get(CGF.Int32Ty, DestTy->isReferenceType())};
1043e5dd7070Spatrick   ThisPtr = CGF.EmitRuntimeCallOrInvoke(Function, Args);
1044e5dd7070Spatrick   return CGF.Builder.CreateBitCast(ThisPtr, DestLTy);
1045e5dd7070Spatrick }
1046e5dd7070Spatrick 
1047e5dd7070Spatrick llvm::Value *
EmitDynamicCastToVoid(CodeGenFunction & CGF,Address Value,QualType SrcRecordTy,QualType DestTy)1048e5dd7070Spatrick MicrosoftCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,
1049e5dd7070Spatrick                                        QualType SrcRecordTy,
1050e5dd7070Spatrick                                        QualType DestTy) {
1051e5dd7070Spatrick   std::tie(Value, std::ignore, std::ignore) =
1052e5dd7070Spatrick       performBaseAdjustment(CGF, Value, SrcRecordTy);
1053e5dd7070Spatrick 
1054e5dd7070Spatrick   // PVOID __RTCastToVoid(
1055e5dd7070Spatrick   //   PVOID inptr)
1056e5dd7070Spatrick   llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
1057e5dd7070Spatrick   llvm::FunctionCallee Function = CGF.CGM.CreateRuntimeFunction(
1058e5dd7070Spatrick       llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
1059e5dd7070Spatrick       "__RTCastToVoid");
1060e5dd7070Spatrick   llvm::Value *Args[] = {Value.getPointer()};
1061e5dd7070Spatrick   return CGF.EmitRuntimeCall(Function, Args);
1062e5dd7070Spatrick }
1063e5dd7070Spatrick 
EmitBadCastCall(CodeGenFunction & CGF)1064e5dd7070Spatrick bool MicrosoftCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1065e5dd7070Spatrick   return false;
1066e5dd7070Spatrick }
1067e5dd7070Spatrick 
GetVirtualBaseClassOffset(CodeGenFunction & CGF,Address This,const CXXRecordDecl * ClassDecl,const CXXRecordDecl * BaseClassDecl)1068e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1069e5dd7070Spatrick     CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl,
1070e5dd7070Spatrick     const CXXRecordDecl *BaseClassDecl) {
1071e5dd7070Spatrick   const ASTContext &Context = getContext();
1072e5dd7070Spatrick   int64_t VBPtrChars =
1073e5dd7070Spatrick       Context.getASTRecordLayout(ClassDecl).getVBPtrOffset().getQuantity();
1074e5dd7070Spatrick   llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
1075e5dd7070Spatrick   CharUnits IntSize = Context.getTypeSizeInChars(Context.IntTy);
1076e5dd7070Spatrick   CharUnits VBTableChars =
1077e5dd7070Spatrick       IntSize *
1078e5dd7070Spatrick       CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
1079e5dd7070Spatrick   llvm::Value *VBTableOffset =
1080e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, VBTableChars.getQuantity());
1081e5dd7070Spatrick 
1082e5dd7070Spatrick   llvm::Value *VBPtrToNewBase =
1083e5dd7070Spatrick       GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1084e5dd7070Spatrick   VBPtrToNewBase =
1085e5dd7070Spatrick       CGF.Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
1086e5dd7070Spatrick   return CGF.Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1087e5dd7070Spatrick }
1088e5dd7070Spatrick 
HasThisReturn(GlobalDecl GD) const1089e5dd7070Spatrick bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD) const {
1090e5dd7070Spatrick   return isa<CXXConstructorDecl>(GD.getDecl());
1091e5dd7070Spatrick }
1092e5dd7070Spatrick 
isDeletingDtor(GlobalDecl GD)1093e5dd7070Spatrick static bool isDeletingDtor(GlobalDecl GD) {
1094e5dd7070Spatrick   return isa<CXXDestructorDecl>(GD.getDecl()) &&
1095e5dd7070Spatrick          GD.getDtorType() == Dtor_Deleting;
1096e5dd7070Spatrick }
1097e5dd7070Spatrick 
hasMostDerivedReturn(GlobalDecl GD) const1098e5dd7070Spatrick bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {
1099e5dd7070Spatrick   return isDeletingDtor(GD);
1100e5dd7070Spatrick }
1101e5dd7070Spatrick 
isTrivialForMSVC(const CXXRecordDecl * RD)1102*12c85518Srobert static bool isTrivialForMSVC(const CXXRecordDecl *RD) {
1103*12c85518Srobert   // We use the C++14 definition of an aggregate, so we also
1104e5dd7070Spatrick   // check for:
1105e5dd7070Spatrick   //   No private or protected non static data members.
1106e5dd7070Spatrick   //   No base classes
1107e5dd7070Spatrick   //   No virtual functions
1108e5dd7070Spatrick   // Additionally, we need to ensure that there is a trivial copy assignment
1109e5dd7070Spatrick   // operator, a trivial destructor and no user-provided constructors.
1110e5dd7070Spatrick   if (RD->hasProtectedFields() || RD->hasPrivateFields())
1111a9ac8606Spatrick     return false;
1112e5dd7070Spatrick   if (RD->getNumBases() > 0)
1113a9ac8606Spatrick     return false;
1114e5dd7070Spatrick   if (RD->isPolymorphic())
1115a9ac8606Spatrick     return false;
1116e5dd7070Spatrick   if (RD->hasNonTrivialCopyAssignment())
1117a9ac8606Spatrick     return false;
1118e5dd7070Spatrick   for (const CXXConstructorDecl *Ctor : RD->ctors())
1119e5dd7070Spatrick     if (Ctor->isUserProvided())
1120e5dd7070Spatrick       return false;
1121a9ac8606Spatrick   if (RD->hasNonTrivialDestructor())
1122a9ac8606Spatrick     return false;
1123a9ac8606Spatrick   return true;
1124e5dd7070Spatrick }
1125e5dd7070Spatrick 
classifyReturnType(CGFunctionInfo & FI) const1126e5dd7070Spatrick bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
1127e5dd7070Spatrick   const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();
1128e5dd7070Spatrick   if (!RD)
1129e5dd7070Spatrick     return false;
1130e5dd7070Spatrick 
1131*12c85518Srobert   bool isTrivialForABI = RD->canPassInRegisters() && isTrivialForMSVC(RD);
1132e5dd7070Spatrick 
1133a9ac8606Spatrick   // MSVC always returns structs indirectly from C++ instance methods.
1134a9ac8606Spatrick   bool isIndirectReturn = !isTrivialForABI || FI.isInstanceMethod();
1135a9ac8606Spatrick 
1136a9ac8606Spatrick   if (isIndirectReturn) {
1137e5dd7070Spatrick     CharUnits Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
1138e5dd7070Spatrick     FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
1139e5dd7070Spatrick 
1140a9ac8606Spatrick     // MSVC always passes `this` before the `sret` parameter.
1141a9ac8606Spatrick     FI.getReturnInfo().setSRetAfterThis(FI.isInstanceMethod());
1142a9ac8606Spatrick 
1143a9ac8606Spatrick     // On AArch64, use the `inreg` attribute if the object is considered to not
1144a9ac8606Spatrick     // be trivially copyable, or if this is an instance method struct return.
1145*12c85518Srobert     FI.getReturnInfo().setInReg(CGM.getTarget().getTriple().isAArch64());
1146e5dd7070Spatrick 
1147e5dd7070Spatrick     return true;
1148e5dd7070Spatrick   }
1149e5dd7070Spatrick 
1150e5dd7070Spatrick   // Otherwise, use the C ABI rules.
1151e5dd7070Spatrick   return false;
1152e5dd7070Spatrick }
1153e5dd7070Spatrick 
1154e5dd7070Spatrick llvm::BasicBlock *
EmitCtorCompleteObjectHandler(CodeGenFunction & CGF,const CXXRecordDecl * RD)1155e5dd7070Spatrick MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
1156e5dd7070Spatrick                                                const CXXRecordDecl *RD) {
1157e5dd7070Spatrick   llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1158e5dd7070Spatrick   assert(IsMostDerivedClass &&
1159e5dd7070Spatrick          "ctor for a class with virtual bases must have an implicit parameter");
1160e5dd7070Spatrick   llvm::Value *IsCompleteObject =
1161e5dd7070Spatrick     CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object");
1162e5dd7070Spatrick 
1163e5dd7070Spatrick   llvm::BasicBlock *CallVbaseCtorsBB = CGF.createBasicBlock("ctor.init_vbases");
1164e5dd7070Spatrick   llvm::BasicBlock *SkipVbaseCtorsBB = CGF.createBasicBlock("ctor.skip_vbases");
1165e5dd7070Spatrick   CGF.Builder.CreateCondBr(IsCompleteObject,
1166e5dd7070Spatrick                            CallVbaseCtorsBB, SkipVbaseCtorsBB);
1167e5dd7070Spatrick 
1168e5dd7070Spatrick   CGF.EmitBlock(CallVbaseCtorsBB);
1169e5dd7070Spatrick 
1170e5dd7070Spatrick   // Fill in the vbtable pointers here.
1171e5dd7070Spatrick   EmitVBPtrStores(CGF, RD);
1172e5dd7070Spatrick 
1173e5dd7070Spatrick   // CGF will put the base ctor calls in this basic block for us later.
1174e5dd7070Spatrick 
1175e5dd7070Spatrick   return SkipVbaseCtorsBB;
1176e5dd7070Spatrick }
1177e5dd7070Spatrick 
1178e5dd7070Spatrick llvm::BasicBlock *
EmitDtorCompleteObjectHandler(CodeGenFunction & CGF)1179e5dd7070Spatrick MicrosoftCXXABI::EmitDtorCompleteObjectHandler(CodeGenFunction &CGF) {
1180e5dd7070Spatrick   llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1181e5dd7070Spatrick   assert(IsMostDerivedClass &&
1182e5dd7070Spatrick          "ctor for a class with virtual bases must have an implicit parameter");
1183e5dd7070Spatrick   llvm::Value *IsCompleteObject =
1184e5dd7070Spatrick       CGF.Builder.CreateIsNotNull(IsMostDerivedClass, "is_complete_object");
1185e5dd7070Spatrick 
1186e5dd7070Spatrick   llvm::BasicBlock *CallVbaseDtorsBB = CGF.createBasicBlock("Dtor.dtor_vbases");
1187e5dd7070Spatrick   llvm::BasicBlock *SkipVbaseDtorsBB = CGF.createBasicBlock("Dtor.skip_vbases");
1188e5dd7070Spatrick   CGF.Builder.CreateCondBr(IsCompleteObject,
1189e5dd7070Spatrick                            CallVbaseDtorsBB, SkipVbaseDtorsBB);
1190e5dd7070Spatrick 
1191e5dd7070Spatrick   CGF.EmitBlock(CallVbaseDtorsBB);
1192e5dd7070Spatrick   // CGF will put the base dtor calls in this basic block for us later.
1193e5dd7070Spatrick 
1194e5dd7070Spatrick   return SkipVbaseDtorsBB;
1195e5dd7070Spatrick }
1196e5dd7070Spatrick 
initializeHiddenVirtualInheritanceMembers(CodeGenFunction & CGF,const CXXRecordDecl * RD)1197e5dd7070Spatrick void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1198e5dd7070Spatrick     CodeGenFunction &CGF, const CXXRecordDecl *RD) {
1199e5dd7070Spatrick   // In most cases, an override for a vbase virtual method can adjust
1200e5dd7070Spatrick   // the "this" parameter by applying a constant offset.
1201e5dd7070Spatrick   // However, this is not enough while a constructor or a destructor of some
1202e5dd7070Spatrick   // class X is being executed if all the following conditions are met:
1203e5dd7070Spatrick   //  - X has virtual bases, (1)
1204e5dd7070Spatrick   //  - X overrides a virtual method M of a vbase Y, (2)
1205e5dd7070Spatrick   //  - X itself is a vbase of the most derived class.
1206e5dd7070Spatrick   //
1207e5dd7070Spatrick   // If (1) and (2) are true, the vtorDisp for vbase Y is a hidden member of X
1208e5dd7070Spatrick   // which holds the extra amount of "this" adjustment we must do when we use
1209e5dd7070Spatrick   // the X vftables (i.e. during X ctor or dtor).
1210e5dd7070Spatrick   // Outside the ctors and dtors, the values of vtorDisps are zero.
1211e5dd7070Spatrick 
1212e5dd7070Spatrick   const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
1213e5dd7070Spatrick   typedef ASTRecordLayout::VBaseOffsetsMapTy VBOffsets;
1214e5dd7070Spatrick   const VBOffsets &VBaseMap = Layout.getVBaseOffsetsMap();
1215e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
1216e5dd7070Spatrick 
1217e5dd7070Spatrick   unsigned AS = getThisAddress(CGF).getAddressSpace();
1218e5dd7070Spatrick   llvm::Value *Int8This = nullptr;  // Initialize lazily.
1219e5dd7070Spatrick 
1220e5dd7070Spatrick   for (const CXXBaseSpecifier &S : RD->vbases()) {
1221e5dd7070Spatrick     const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1222e5dd7070Spatrick     auto I = VBaseMap.find(VBase);
1223e5dd7070Spatrick     assert(I != VBaseMap.end());
1224e5dd7070Spatrick     if (!I->second.hasVtorDisp())
1225e5dd7070Spatrick       continue;
1226e5dd7070Spatrick 
1227e5dd7070Spatrick     llvm::Value *VBaseOffset =
1228e5dd7070Spatrick         GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1229e5dd7070Spatrick     uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1230e5dd7070Spatrick 
1231e5dd7070Spatrick     // vtorDisp_for_vbase = vbptr[vbase_idx] - offsetof(RD, vbase).
1232e5dd7070Spatrick     llvm::Value *VtorDispValue = Builder.CreateSub(
1233e5dd7070Spatrick         VBaseOffset, llvm::ConstantInt::get(CGM.PtrDiffTy, ConstantVBaseOffset),
1234e5dd7070Spatrick         "vtordisp.value");
1235e5dd7070Spatrick     VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.Int32Ty);
1236e5dd7070Spatrick 
1237e5dd7070Spatrick     if (!Int8This)
1238e5dd7070Spatrick       Int8This = Builder.CreateBitCast(getThisValue(CGF),
1239e5dd7070Spatrick                                        CGF.Int8Ty->getPointerTo(AS));
1240a9ac8606Spatrick     llvm::Value *VtorDispPtr =
1241a9ac8606Spatrick         Builder.CreateInBoundsGEP(CGF.Int8Ty, Int8This, VBaseOffset);
1242e5dd7070Spatrick     // vtorDisp is always the 32-bits before the vbase in the class layout.
1243a9ac8606Spatrick     VtorDispPtr = Builder.CreateConstGEP1_32(CGF.Int8Ty, VtorDispPtr, -4);
1244e5dd7070Spatrick     VtorDispPtr = Builder.CreateBitCast(
1245e5dd7070Spatrick         VtorDispPtr, CGF.Int32Ty->getPointerTo(AS), "vtordisp.ptr");
1246e5dd7070Spatrick 
1247e5dd7070Spatrick     Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1248e5dd7070Spatrick                                CharUnits::fromQuantity(4));
1249e5dd7070Spatrick   }
1250e5dd7070Spatrick }
1251e5dd7070Spatrick 
hasDefaultCXXMethodCC(ASTContext & Context,const CXXMethodDecl * MD)1252e5dd7070Spatrick static bool hasDefaultCXXMethodCC(ASTContext &Context,
1253e5dd7070Spatrick                                   const CXXMethodDecl *MD) {
1254e5dd7070Spatrick   CallingConv ExpectedCallingConv = Context.getDefaultCallingConvention(
1255e5dd7070Spatrick       /*IsVariadic=*/false, /*IsCXXMethod=*/true);
1256e5dd7070Spatrick   CallingConv ActualCallingConv =
1257e5dd7070Spatrick       MD->getType()->castAs<FunctionProtoType>()->getCallConv();
1258e5dd7070Spatrick   return ExpectedCallingConv == ActualCallingConv;
1259e5dd7070Spatrick }
1260e5dd7070Spatrick 
EmitCXXConstructors(const CXXConstructorDecl * D)1261e5dd7070Spatrick void MicrosoftCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
1262e5dd7070Spatrick   // There's only one constructor type in this ABI.
1263e5dd7070Spatrick   CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete));
1264e5dd7070Spatrick 
1265e5dd7070Spatrick   // Exported default constructors either have a simple call-site where they use
1266e5dd7070Spatrick   // the typical calling convention and have a single 'this' pointer for an
1267e5dd7070Spatrick   // argument -or- they get a wrapper function which appropriately thunks to the
1268e5dd7070Spatrick   // real default constructor.  This thunk is the default constructor closure.
1269a9ac8606Spatrick   if (D->hasAttr<DLLExportAttr>() && D->isDefaultConstructor() &&
1270a9ac8606Spatrick       D->isDefined()) {
1271e5dd7070Spatrick     if (!hasDefaultCXXMethodCC(getContext(), D) || D->getNumParams() != 0) {
1272e5dd7070Spatrick       llvm::Function *Fn = getAddrOfCXXCtorClosure(D, Ctor_DefaultClosure);
1273e5dd7070Spatrick       Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1274e5dd7070Spatrick       CGM.setGVProperties(Fn, D);
1275e5dd7070Spatrick     }
1276e5dd7070Spatrick   }
1277a9ac8606Spatrick }
1278e5dd7070Spatrick 
EmitVBPtrStores(CodeGenFunction & CGF,const CXXRecordDecl * RD)1279e5dd7070Spatrick void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
1280e5dd7070Spatrick                                       const CXXRecordDecl *RD) {
1281e5dd7070Spatrick   Address This = getThisAddress(CGF);
1282e5dd7070Spatrick   This = CGF.Builder.CreateElementBitCast(This, CGM.Int8Ty, "this.int8");
1283e5dd7070Spatrick   const ASTContext &Context = getContext();
1284e5dd7070Spatrick   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1285e5dd7070Spatrick 
1286e5dd7070Spatrick   const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1287e5dd7070Spatrick   for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1288e5dd7070Spatrick     const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1289e5dd7070Spatrick     llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1290e5dd7070Spatrick     const ASTRecordLayout &SubobjectLayout =
1291e5dd7070Spatrick         Context.getASTRecordLayout(VBT->IntroducingObject);
1292e5dd7070Spatrick     CharUnits Offs = VBT->NonVirtualOffset;
1293e5dd7070Spatrick     Offs += SubobjectLayout.getVBPtrOffset();
1294e5dd7070Spatrick     if (VBT->getVBaseWithVPtr())
1295e5dd7070Spatrick       Offs += Layout.getVBaseClassOffset(VBT->getVBaseWithVPtr());
1296e5dd7070Spatrick     Address VBPtr = CGF.Builder.CreateConstInBoundsByteGEP(This, Offs);
1297e5dd7070Spatrick     llvm::Value *GVPtr =
1298e5dd7070Spatrick         CGF.Builder.CreateConstInBoundsGEP2_32(GV->getValueType(), GV, 0, 0);
1299e5dd7070Spatrick     VBPtr = CGF.Builder.CreateElementBitCast(VBPtr, GVPtr->getType(),
1300e5dd7070Spatrick                                       "vbptr." + VBT->ObjectWithVPtr->getName());
1301e5dd7070Spatrick     CGF.Builder.CreateStore(GVPtr, VBPtr);
1302e5dd7070Spatrick   }
1303e5dd7070Spatrick }
1304e5dd7070Spatrick 
1305ec727ea7Spatrick CGCXXABI::AddedStructorArgCounts
buildStructorSignature(GlobalDecl GD,SmallVectorImpl<CanQualType> & ArgTys)1306e5dd7070Spatrick MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
1307e5dd7070Spatrick                                         SmallVectorImpl<CanQualType> &ArgTys) {
1308ec727ea7Spatrick   AddedStructorArgCounts Added;
1309e5dd7070Spatrick   // TODO: 'for base' flag
1310e5dd7070Spatrick   if (isa<CXXDestructorDecl>(GD.getDecl()) &&
1311e5dd7070Spatrick       GD.getDtorType() == Dtor_Deleting) {
1312e5dd7070Spatrick     // The scalar deleting destructor takes an implicit int parameter.
1313e5dd7070Spatrick     ArgTys.push_back(getContext().IntTy);
1314e5dd7070Spatrick     ++Added.Suffix;
1315e5dd7070Spatrick   }
1316e5dd7070Spatrick   auto *CD = dyn_cast<CXXConstructorDecl>(GD.getDecl());
1317e5dd7070Spatrick   if (!CD)
1318e5dd7070Spatrick     return Added;
1319e5dd7070Spatrick 
1320e5dd7070Spatrick   // All parameters are already in place except is_most_derived, which goes
1321e5dd7070Spatrick   // after 'this' if it's variadic and last if it's not.
1322e5dd7070Spatrick 
1323e5dd7070Spatrick   const CXXRecordDecl *Class = CD->getParent();
1324e5dd7070Spatrick   const FunctionProtoType *FPT = CD->getType()->castAs<FunctionProtoType>();
1325e5dd7070Spatrick   if (Class->getNumVBases()) {
1326e5dd7070Spatrick     if (FPT->isVariadic()) {
1327e5dd7070Spatrick       ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1328e5dd7070Spatrick       ++Added.Prefix;
1329e5dd7070Spatrick     } else {
1330e5dd7070Spatrick       ArgTys.push_back(getContext().IntTy);
1331e5dd7070Spatrick       ++Added.Suffix;
1332e5dd7070Spatrick     }
1333e5dd7070Spatrick   }
1334e5dd7070Spatrick 
1335e5dd7070Spatrick   return Added;
1336e5dd7070Spatrick }
1337e5dd7070Spatrick 
setCXXDestructorDLLStorage(llvm::GlobalValue * GV,const CXXDestructorDecl * Dtor,CXXDtorType DT) const1338e5dd7070Spatrick void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1339e5dd7070Spatrick                                                  const CXXDestructorDecl *Dtor,
1340e5dd7070Spatrick                                                  CXXDtorType DT) const {
1341e5dd7070Spatrick   // Deleting destructor variants are never imported or exported. Give them the
1342e5dd7070Spatrick   // default storage class.
1343e5dd7070Spatrick   if (DT == Dtor_Deleting) {
1344e5dd7070Spatrick     GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1345e5dd7070Spatrick   } else {
1346e5dd7070Spatrick     const NamedDecl *ND = Dtor;
1347e5dd7070Spatrick     CGM.setDLLImportDLLExport(GV, ND);
1348e5dd7070Spatrick   }
1349e5dd7070Spatrick }
1350e5dd7070Spatrick 
getCXXDestructorLinkage(GVALinkage Linkage,const CXXDestructorDecl * Dtor,CXXDtorType DT) const1351e5dd7070Spatrick llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1352e5dd7070Spatrick     GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const {
1353e5dd7070Spatrick   // Internal things are always internal, regardless of attributes. After this,
1354e5dd7070Spatrick   // we know the thunk is externally visible.
1355e5dd7070Spatrick   if (Linkage == GVA_Internal)
1356e5dd7070Spatrick     return llvm::GlobalValue::InternalLinkage;
1357e5dd7070Spatrick 
1358e5dd7070Spatrick   switch (DT) {
1359e5dd7070Spatrick   case Dtor_Base:
1360e5dd7070Spatrick     // The base destructor most closely tracks the user-declared constructor, so
1361e5dd7070Spatrick     // we delegate back to the normal declarator case.
1362e5dd7070Spatrick     return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage,
1363e5dd7070Spatrick                                            /*IsConstantVariable=*/false);
1364e5dd7070Spatrick   case Dtor_Complete:
1365e5dd7070Spatrick     // The complete destructor is like an inline function, but it may be
1366e5dd7070Spatrick     // imported and therefore must be exported as well. This requires changing
1367e5dd7070Spatrick     // the linkage if a DLL attribute is present.
1368e5dd7070Spatrick     if (Dtor->hasAttr<DLLExportAttr>())
1369e5dd7070Spatrick       return llvm::GlobalValue::WeakODRLinkage;
1370e5dd7070Spatrick     if (Dtor->hasAttr<DLLImportAttr>())
1371e5dd7070Spatrick       return llvm::GlobalValue::AvailableExternallyLinkage;
1372e5dd7070Spatrick     return llvm::GlobalValue::LinkOnceODRLinkage;
1373e5dd7070Spatrick   case Dtor_Deleting:
1374e5dd7070Spatrick     // Deleting destructors are like inline functions. They have vague linkage
1375e5dd7070Spatrick     // and are emitted everywhere they are used. They are internal if the class
1376e5dd7070Spatrick     // is internal.
1377e5dd7070Spatrick     return llvm::GlobalValue::LinkOnceODRLinkage;
1378e5dd7070Spatrick   case Dtor_Comdat:
1379e5dd7070Spatrick     llvm_unreachable("MS C++ ABI does not support comdat dtors");
1380e5dd7070Spatrick   }
1381e5dd7070Spatrick   llvm_unreachable("invalid dtor type");
1382e5dd7070Spatrick }
1383e5dd7070Spatrick 
EmitCXXDestructors(const CXXDestructorDecl * D)1384e5dd7070Spatrick void MicrosoftCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
1385e5dd7070Spatrick   // The TU defining a dtor is only guaranteed to emit a base destructor.  All
1386e5dd7070Spatrick   // other destructor variants are delegating thunks.
1387e5dd7070Spatrick   CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));
1388e5dd7070Spatrick 
1389e5dd7070Spatrick   // If the class is dllexported, emit the complete (vbase) destructor wherever
1390e5dd7070Spatrick   // the base dtor is emitted.
1391e5dd7070Spatrick   // FIXME: To match MSVC, this should only be done when the class is exported
1392e5dd7070Spatrick   // with -fdllexport-inlines enabled.
1393e5dd7070Spatrick   if (D->getParent()->getNumVBases() > 0 && D->hasAttr<DLLExportAttr>())
1394e5dd7070Spatrick     CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete));
1395e5dd7070Spatrick }
1396e5dd7070Spatrick 
1397e5dd7070Spatrick CharUnits
getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)1398e5dd7070Spatrick MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
1399e5dd7070Spatrick   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
1400e5dd7070Spatrick 
1401e5dd7070Spatrick   if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1402e5dd7070Spatrick     // Complete destructors take a pointer to the complete object as a
1403e5dd7070Spatrick     // parameter, thus don't need this adjustment.
1404e5dd7070Spatrick     if (GD.getDtorType() == Dtor_Complete)
1405e5dd7070Spatrick       return CharUnits();
1406e5dd7070Spatrick 
1407e5dd7070Spatrick     // There's no Dtor_Base in vftable but it shares the this adjustment with
1408e5dd7070Spatrick     // the deleting one, so look it up instead.
1409e5dd7070Spatrick     GD = GlobalDecl(DD, Dtor_Deleting);
1410e5dd7070Spatrick   }
1411e5dd7070Spatrick 
1412e5dd7070Spatrick   MethodVFTableLocation ML =
1413e5dd7070Spatrick       CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1414e5dd7070Spatrick   CharUnits Adjustment = ML.VFPtrOffset;
1415e5dd7070Spatrick 
1416e5dd7070Spatrick   // Normal virtual instance methods need to adjust from the vfptr that first
1417e5dd7070Spatrick   // defined the virtual method to the virtual base subobject, but destructors
1418e5dd7070Spatrick   // do not.  The vector deleting destructor thunk applies this adjustment for
1419e5dd7070Spatrick   // us if necessary.
1420e5dd7070Spatrick   if (isa<CXXDestructorDecl>(MD))
1421e5dd7070Spatrick     Adjustment = CharUnits::Zero();
1422e5dd7070Spatrick 
1423e5dd7070Spatrick   if (ML.VBase) {
1424e5dd7070Spatrick     const ASTRecordLayout &DerivedLayout =
1425e5dd7070Spatrick         getContext().getASTRecordLayout(MD->getParent());
1426e5dd7070Spatrick     Adjustment += DerivedLayout.getVBaseClassOffset(ML.VBase);
1427e5dd7070Spatrick   }
1428e5dd7070Spatrick 
1429e5dd7070Spatrick   return Adjustment;
1430e5dd7070Spatrick }
1431e5dd7070Spatrick 
adjustThisArgumentForVirtualFunctionCall(CodeGenFunction & CGF,GlobalDecl GD,Address This,bool VirtualCall)1432e5dd7070Spatrick Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1433e5dd7070Spatrick     CodeGenFunction &CGF, GlobalDecl GD, Address This,
1434e5dd7070Spatrick     bool VirtualCall) {
1435e5dd7070Spatrick   if (!VirtualCall) {
1436e5dd7070Spatrick     // If the call of a virtual function is not virtual, we just have to
1437e5dd7070Spatrick     // compensate for the adjustment the virtual function does in its prologue.
1438e5dd7070Spatrick     CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1439e5dd7070Spatrick     if (Adjustment.isZero())
1440e5dd7070Spatrick       return This;
1441e5dd7070Spatrick 
1442e5dd7070Spatrick     This = CGF.Builder.CreateElementBitCast(This, CGF.Int8Ty);
1443e5dd7070Spatrick     assert(Adjustment.isPositive());
1444e5dd7070Spatrick     return CGF.Builder.CreateConstByteGEP(This, Adjustment);
1445e5dd7070Spatrick   }
1446e5dd7070Spatrick 
1447e5dd7070Spatrick   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
1448e5dd7070Spatrick 
1449e5dd7070Spatrick   GlobalDecl LookupGD = GD;
1450e5dd7070Spatrick   if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1451e5dd7070Spatrick     // Complete dtors take a pointer to the complete object,
1452e5dd7070Spatrick     // thus don't need adjustment.
1453e5dd7070Spatrick     if (GD.getDtorType() == Dtor_Complete)
1454e5dd7070Spatrick       return This;
1455e5dd7070Spatrick 
1456e5dd7070Spatrick     // There's only Dtor_Deleting in vftable but it shares the this adjustment
1457e5dd7070Spatrick     // with the base one, so look up the deleting one instead.
1458e5dd7070Spatrick     LookupGD = GlobalDecl(DD, Dtor_Deleting);
1459e5dd7070Spatrick   }
1460e5dd7070Spatrick   MethodVFTableLocation ML =
1461e5dd7070Spatrick       CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1462e5dd7070Spatrick 
1463e5dd7070Spatrick   CharUnits StaticOffset = ML.VFPtrOffset;
1464e5dd7070Spatrick 
1465e5dd7070Spatrick   // Base destructors expect 'this' to point to the beginning of the base
1466e5dd7070Spatrick   // subobject, not the first vfptr that happens to contain the virtual dtor.
1467e5dd7070Spatrick   // However, we still need to apply the virtual base adjustment.
1468e5dd7070Spatrick   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
1469e5dd7070Spatrick     StaticOffset = CharUnits::Zero();
1470e5dd7070Spatrick 
1471e5dd7070Spatrick   Address Result = This;
1472e5dd7070Spatrick   if (ML.VBase) {
1473e5dd7070Spatrick     Result = CGF.Builder.CreateElementBitCast(Result, CGF.Int8Ty);
1474e5dd7070Spatrick 
1475e5dd7070Spatrick     const CXXRecordDecl *Derived = MD->getParent();
1476e5dd7070Spatrick     const CXXRecordDecl *VBase = ML.VBase;
1477e5dd7070Spatrick     llvm::Value *VBaseOffset =
1478e5dd7070Spatrick       GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1479a9ac8606Spatrick     llvm::Value *VBasePtr = CGF.Builder.CreateInBoundsGEP(
1480a9ac8606Spatrick         Result.getElementType(), Result.getPointer(), VBaseOffset);
1481e5dd7070Spatrick     CharUnits VBaseAlign =
1482e5dd7070Spatrick       CGF.CGM.getVBaseAlignment(Result.getAlignment(), Derived, VBase);
1483*12c85518Srobert     Result = Address(VBasePtr, CGF.Int8Ty, VBaseAlign);
1484e5dd7070Spatrick   }
1485e5dd7070Spatrick   if (!StaticOffset.isZero()) {
1486e5dd7070Spatrick     assert(StaticOffset.isPositive());
1487e5dd7070Spatrick     Result = CGF.Builder.CreateElementBitCast(Result, CGF.Int8Ty);
1488e5dd7070Spatrick     if (ML.VBase) {
1489e5dd7070Spatrick       // Non-virtual adjustment might result in a pointer outside the allocated
1490e5dd7070Spatrick       // object, e.g. if the final overrider class is laid out after the virtual
1491e5dd7070Spatrick       // base that declares a method in the most derived class.
1492e5dd7070Spatrick       // FIXME: Update the code that emits this adjustment in thunks prologues.
1493e5dd7070Spatrick       Result = CGF.Builder.CreateConstByteGEP(Result, StaticOffset);
1494e5dd7070Spatrick     } else {
1495e5dd7070Spatrick       Result = CGF.Builder.CreateConstInBoundsByteGEP(Result, StaticOffset);
1496e5dd7070Spatrick     }
1497e5dd7070Spatrick   }
1498e5dd7070Spatrick   return Result;
1499e5dd7070Spatrick }
1500e5dd7070Spatrick 
addImplicitStructorParams(CodeGenFunction & CGF,QualType & ResTy,FunctionArgList & Params)1501e5dd7070Spatrick void MicrosoftCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1502e5dd7070Spatrick                                                 QualType &ResTy,
1503e5dd7070Spatrick                                                 FunctionArgList &Params) {
1504e5dd7070Spatrick   ASTContext &Context = getContext();
1505e5dd7070Spatrick   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
1506e5dd7070Spatrick   assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1507e5dd7070Spatrick   if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
1508e5dd7070Spatrick     auto *IsMostDerived = ImplicitParamDecl::Create(
1509e5dd7070Spatrick         Context, /*DC=*/nullptr, CGF.CurGD.getDecl()->getLocation(),
1510e5dd7070Spatrick         &Context.Idents.get("is_most_derived"), Context.IntTy,
1511e5dd7070Spatrick         ImplicitParamDecl::Other);
1512e5dd7070Spatrick     // The 'most_derived' parameter goes second if the ctor is variadic and last
1513e5dd7070Spatrick     // if it's not.  Dtors can't be variadic.
1514e5dd7070Spatrick     const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
1515e5dd7070Spatrick     if (FPT->isVariadic())
1516e5dd7070Spatrick       Params.insert(Params.begin() + 1, IsMostDerived);
1517e5dd7070Spatrick     else
1518e5dd7070Spatrick       Params.push_back(IsMostDerived);
1519e5dd7070Spatrick     getStructorImplicitParamDecl(CGF) = IsMostDerived;
1520e5dd7070Spatrick   } else if (isDeletingDtor(CGF.CurGD)) {
1521e5dd7070Spatrick     auto *ShouldDelete = ImplicitParamDecl::Create(
1522e5dd7070Spatrick         Context, /*DC=*/nullptr, CGF.CurGD.getDecl()->getLocation(),
1523e5dd7070Spatrick         &Context.Idents.get("should_call_delete"), Context.IntTy,
1524e5dd7070Spatrick         ImplicitParamDecl::Other);
1525e5dd7070Spatrick     Params.push_back(ShouldDelete);
1526e5dd7070Spatrick     getStructorImplicitParamDecl(CGF) = ShouldDelete;
1527e5dd7070Spatrick   }
1528e5dd7070Spatrick }
1529e5dd7070Spatrick 
EmitInstanceFunctionProlog(CodeGenFunction & CGF)1530e5dd7070Spatrick void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1531e5dd7070Spatrick   // Naked functions have no prolog.
1532e5dd7070Spatrick   if (CGF.CurFuncDecl && CGF.CurFuncDecl->hasAttr<NakedAttr>())
1533e5dd7070Spatrick     return;
1534e5dd7070Spatrick 
1535e5dd7070Spatrick   // Overridden virtual methods of non-primary bases need to adjust the incoming
1536e5dd7070Spatrick   // 'this' pointer in the prologue. In this hierarchy, C::b will subtract
1537e5dd7070Spatrick   // sizeof(void*) to adjust from B* to C*:
1538e5dd7070Spatrick   //   struct A { virtual void a(); };
1539e5dd7070Spatrick   //   struct B { virtual void b(); };
1540e5dd7070Spatrick   //   struct C : A, B { virtual void b(); };
1541e5dd7070Spatrick   //
1542e5dd7070Spatrick   // Leave the value stored in the 'this' alloca unadjusted, so that the
1543e5dd7070Spatrick   // debugger sees the unadjusted value. Microsoft debuggers require this, and
1544e5dd7070Spatrick   // will apply the ThisAdjustment in the method type information.
1545e5dd7070Spatrick   // FIXME: Do something better for DWARF debuggers, which won't expect this,
1546e5dd7070Spatrick   // without making our codegen depend on debug info settings.
1547e5dd7070Spatrick   llvm::Value *This = loadIncomingCXXThis(CGF);
1548e5dd7070Spatrick   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
1549e5dd7070Spatrick   if (!CGF.CurFuncIsThunk && MD->isVirtual()) {
1550e5dd7070Spatrick     CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.CurGD);
1551e5dd7070Spatrick     if (!Adjustment.isZero()) {
1552e5dd7070Spatrick       unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1553e5dd7070Spatrick       llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS),
1554e5dd7070Spatrick                  *thisTy = This->getType();
1555e5dd7070Spatrick       This = CGF.Builder.CreateBitCast(This, charPtrTy);
1556e5dd7070Spatrick       assert(Adjustment.isPositive());
1557e5dd7070Spatrick       This = CGF.Builder.CreateConstInBoundsGEP1_32(CGF.Int8Ty, This,
1558e5dd7070Spatrick                                                     -Adjustment.getQuantity());
1559e5dd7070Spatrick       This = CGF.Builder.CreateBitCast(This, thisTy, "this.adjusted");
1560e5dd7070Spatrick     }
1561e5dd7070Spatrick   }
1562e5dd7070Spatrick   setCXXABIThisValue(CGF, This);
1563e5dd7070Spatrick 
1564e5dd7070Spatrick   // If this is a function that the ABI specifies returns 'this', initialize
1565e5dd7070Spatrick   // the return slot to 'this' at the start of the function.
1566e5dd7070Spatrick   //
1567e5dd7070Spatrick   // Unlike the setting of return types, this is done within the ABI
1568e5dd7070Spatrick   // implementation instead of by clients of CGCXXABI because:
1569e5dd7070Spatrick   // 1) getThisValue is currently protected
1570e5dd7070Spatrick   // 2) in theory, an ABI could implement 'this' returns some other way;
1571e5dd7070Spatrick   //    HasThisReturn only specifies a contract, not the implementation
1572e5dd7070Spatrick   if (HasThisReturn(CGF.CurGD))
1573e5dd7070Spatrick     CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
1574e5dd7070Spatrick   else if (hasMostDerivedReturn(CGF.CurGD))
1575e5dd7070Spatrick     CGF.Builder.CreateStore(CGF.EmitCastToVoidPtr(getThisValue(CGF)),
1576e5dd7070Spatrick                             CGF.ReturnValue);
1577e5dd7070Spatrick 
1578e5dd7070Spatrick   if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
1579e5dd7070Spatrick     assert(getStructorImplicitParamDecl(CGF) &&
1580e5dd7070Spatrick            "no implicit parameter for a constructor with virtual bases?");
1581e5dd7070Spatrick     getStructorImplicitParamValue(CGF)
1582e5dd7070Spatrick       = CGF.Builder.CreateLoad(
1583e5dd7070Spatrick           CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
1584e5dd7070Spatrick           "is_most_derived");
1585e5dd7070Spatrick   }
1586e5dd7070Spatrick 
1587e5dd7070Spatrick   if (isDeletingDtor(CGF.CurGD)) {
1588e5dd7070Spatrick     assert(getStructorImplicitParamDecl(CGF) &&
1589e5dd7070Spatrick            "no implicit parameter for a deleting destructor?");
1590e5dd7070Spatrick     getStructorImplicitParamValue(CGF)
1591e5dd7070Spatrick       = CGF.Builder.CreateLoad(
1592e5dd7070Spatrick           CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)),
1593e5dd7070Spatrick           "should_call_delete");
1594e5dd7070Spatrick   }
1595e5dd7070Spatrick }
1596e5dd7070Spatrick 
getImplicitConstructorArgs(CodeGenFunction & CGF,const CXXConstructorDecl * D,CXXCtorType Type,bool ForVirtualBase,bool Delegating)1597ec727ea7Spatrick CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs(
1598e5dd7070Spatrick     CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
1599ec727ea7Spatrick     bool ForVirtualBase, bool Delegating) {
1600e5dd7070Spatrick   assert(Type == Ctor_Complete || Type == Ctor_Base);
1601e5dd7070Spatrick 
1602e5dd7070Spatrick   // Check if we need a 'most_derived' parameter.
1603e5dd7070Spatrick   if (!D->getParent()->getNumVBases())
1604e5dd7070Spatrick     return AddedStructorArgs{};
1605e5dd7070Spatrick 
1606e5dd7070Spatrick   // Add the 'most_derived' argument second if we are variadic or last if not.
1607e5dd7070Spatrick   const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
1608e5dd7070Spatrick   llvm::Value *MostDerivedArg;
1609e5dd7070Spatrick   if (Delegating) {
1610e5dd7070Spatrick     MostDerivedArg = getStructorImplicitParamValue(CGF);
1611e5dd7070Spatrick   } else {
1612e5dd7070Spatrick     MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
1613e5dd7070Spatrick   }
1614e5dd7070Spatrick   if (FPT->isVariadic()) {
1615ec727ea7Spatrick     return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1616e5dd7070Spatrick   }
1617ec727ea7Spatrick   return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1618ec727ea7Spatrick }
1619ec727ea7Spatrick 
getCXXDestructorImplicitParam(CodeGenFunction & CGF,const CXXDestructorDecl * DD,CXXDtorType Type,bool ForVirtualBase,bool Delegating)1620ec727ea7Spatrick llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
1621ec727ea7Spatrick     CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type,
1622ec727ea7Spatrick     bool ForVirtualBase, bool Delegating) {
1623ec727ea7Spatrick   return nullptr;
1624e5dd7070Spatrick }
1625e5dd7070Spatrick 
EmitDestructorCall(CodeGenFunction & CGF,const CXXDestructorDecl * DD,CXXDtorType Type,bool ForVirtualBase,bool Delegating,Address This,QualType ThisTy)1626e5dd7070Spatrick void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
1627e5dd7070Spatrick                                          const CXXDestructorDecl *DD,
1628e5dd7070Spatrick                                          CXXDtorType Type, bool ForVirtualBase,
1629e5dd7070Spatrick                                          bool Delegating, Address This,
1630e5dd7070Spatrick                                          QualType ThisTy) {
1631e5dd7070Spatrick   // Use the base destructor variant in place of the complete destructor variant
1632e5dd7070Spatrick   // if the class has no virtual bases. This effectively implements some of the
1633e5dd7070Spatrick   // -mconstructor-aliases optimization, but as part of the MS C++ ABI.
1634e5dd7070Spatrick   if (Type == Dtor_Complete && DD->getParent()->getNumVBases() == 0)
1635e5dd7070Spatrick     Type = Dtor_Base;
1636e5dd7070Spatrick 
1637e5dd7070Spatrick   GlobalDecl GD(DD, Type);
1638e5dd7070Spatrick   CGCallee Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD);
1639e5dd7070Spatrick 
1640e5dd7070Spatrick   if (DD->isVirtual()) {
1641e5dd7070Spatrick     assert(Type != CXXDtorType::Dtor_Deleting &&
1642e5dd7070Spatrick            "The deleting destructor should only be called via a virtual call");
1643e5dd7070Spatrick     This = adjustThisArgumentForVirtualFunctionCall(CGF, GlobalDecl(DD, Type),
1644e5dd7070Spatrick                                                     This, false);
1645e5dd7070Spatrick   }
1646e5dd7070Spatrick 
1647e5dd7070Spatrick   llvm::BasicBlock *BaseDtorEndBB = nullptr;
1648e5dd7070Spatrick   if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.CurCodeDecl)) {
1649e5dd7070Spatrick     BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1650e5dd7070Spatrick   }
1651e5dd7070Spatrick 
1652ec727ea7Spatrick   llvm::Value *Implicit =
1653ec727ea7Spatrick       getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase,
1654ec727ea7Spatrick                                     Delegating); // = nullptr
1655e5dd7070Spatrick   CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy,
1656ec727ea7Spatrick                             /*ImplicitParam=*/Implicit,
1657e5dd7070Spatrick                             /*ImplicitParamTy=*/QualType(), nullptr);
1658e5dd7070Spatrick   if (BaseDtorEndBB) {
1659e5dd7070Spatrick     // Complete object handler should continue to be the remaining
1660e5dd7070Spatrick     CGF.Builder.CreateBr(BaseDtorEndBB);
1661e5dd7070Spatrick     CGF.EmitBlock(BaseDtorEndBB);
1662e5dd7070Spatrick   }
1663e5dd7070Spatrick }
1664e5dd7070Spatrick 
emitVTableTypeMetadata(const VPtrInfo & Info,const CXXRecordDecl * RD,llvm::GlobalVariable * VTable)1665e5dd7070Spatrick void MicrosoftCXXABI::emitVTableTypeMetadata(const VPtrInfo &Info,
1666e5dd7070Spatrick                                              const CXXRecordDecl *RD,
1667e5dd7070Spatrick                                              llvm::GlobalVariable *VTable) {
1668e5dd7070Spatrick   if (!CGM.getCodeGenOpts().LTOUnit)
1669e5dd7070Spatrick     return;
1670e5dd7070Spatrick 
1671ec727ea7Spatrick   // TODO: Should VirtualFunctionElimination also be supported here?
1672ec727ea7Spatrick   // See similar handling in CodeGenModule::EmitVTableTypeMetadata.
1673ec727ea7Spatrick   if (CGM.getCodeGenOpts().WholeProgramVTables) {
1674a9ac8606Spatrick     llvm::DenseSet<const CXXRecordDecl *> Visited;
1675ec727ea7Spatrick     llvm::GlobalObject::VCallVisibility TypeVis =
1676a9ac8606Spatrick         CGM.GetVCallVisibilityLevel(RD, Visited);
1677ec727ea7Spatrick     if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1678ec727ea7Spatrick       VTable->setVCallVisibilityMetadata(TypeVis);
1679ec727ea7Spatrick   }
1680ec727ea7Spatrick 
1681e5dd7070Spatrick   // The location of the first virtual function pointer in the virtual table,
1682e5dd7070Spatrick   // aka the "address point" on Itanium. This is at offset 0 if RTTI is
1683e5dd7070Spatrick   // disabled, or sizeof(void*) if RTTI is enabled.
1684e5dd7070Spatrick   CharUnits AddressPoint =
1685e5dd7070Spatrick       getContext().getLangOpts().RTTIData
1686e5dd7070Spatrick           ? getContext().toCharUnitsFromBits(
1687*12c85518Srobert                 getContext().getTargetInfo().getPointerWidth(LangAS::Default))
1688e5dd7070Spatrick           : CharUnits::Zero();
1689e5dd7070Spatrick 
1690e5dd7070Spatrick   if (Info.PathToIntroducingObject.empty()) {
1691e5dd7070Spatrick     CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1692e5dd7070Spatrick     return;
1693e5dd7070Spatrick   }
1694e5dd7070Spatrick 
1695e5dd7070Spatrick   // Add a bitset entry for the least derived base belonging to this vftable.
1696e5dd7070Spatrick   CGM.AddVTableTypeMetadata(VTable, AddressPoint,
1697e5dd7070Spatrick                             Info.PathToIntroducingObject.back());
1698e5dd7070Spatrick 
1699e5dd7070Spatrick   // Add a bitset entry for each derived class that is laid out at the same
1700e5dd7070Spatrick   // offset as the least derived base.
1701e5dd7070Spatrick   for (unsigned I = Info.PathToIntroducingObject.size() - 1; I != 0; --I) {
1702e5dd7070Spatrick     const CXXRecordDecl *DerivedRD = Info.PathToIntroducingObject[I - 1];
1703e5dd7070Spatrick     const CXXRecordDecl *BaseRD = Info.PathToIntroducingObject[I];
1704e5dd7070Spatrick 
1705e5dd7070Spatrick     const ASTRecordLayout &Layout =
1706e5dd7070Spatrick         getContext().getASTRecordLayout(DerivedRD);
1707e5dd7070Spatrick     CharUnits Offset;
1708e5dd7070Spatrick     auto VBI = Layout.getVBaseOffsetsMap().find(BaseRD);
1709e5dd7070Spatrick     if (VBI == Layout.getVBaseOffsetsMap().end())
1710e5dd7070Spatrick       Offset = Layout.getBaseClassOffset(BaseRD);
1711e5dd7070Spatrick     else
1712e5dd7070Spatrick       Offset = VBI->second.VBaseOffset;
1713e5dd7070Spatrick     if (!Offset.isZero())
1714e5dd7070Spatrick       return;
1715e5dd7070Spatrick     CGM.AddVTableTypeMetadata(VTable, AddressPoint, DerivedRD);
1716e5dd7070Spatrick   }
1717e5dd7070Spatrick 
1718e5dd7070Spatrick   // Finally do the same for the most derived class.
1719e5dd7070Spatrick   if (Info.FullOffsetInMDC.isZero())
1720e5dd7070Spatrick     CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1721e5dd7070Spatrick }
1722e5dd7070Spatrick 
emitVTableDefinitions(CodeGenVTables & CGVT,const CXXRecordDecl * RD)1723e5dd7070Spatrick void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
1724e5dd7070Spatrick                                             const CXXRecordDecl *RD) {
1725e5dd7070Spatrick   MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
1726e5dd7070Spatrick   const VPtrInfoVector &VFPtrs = VFTContext.getVFPtrOffsets(RD);
1727e5dd7070Spatrick 
1728e5dd7070Spatrick   for (const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1729e5dd7070Spatrick     llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->FullOffsetInMDC);
1730e5dd7070Spatrick     if (VTable->hasInitializer())
1731e5dd7070Spatrick       continue;
1732e5dd7070Spatrick 
1733e5dd7070Spatrick     const VTableLayout &VTLayout =
1734e5dd7070Spatrick       VFTContext.getVFTableLayout(RD, Info->FullOffsetInMDC);
1735e5dd7070Spatrick 
1736e5dd7070Spatrick     llvm::Constant *RTTI = nullptr;
1737e5dd7070Spatrick     if (any_of(VTLayout.vtable_components(),
1738e5dd7070Spatrick                [](const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
1739e5dd7070Spatrick       RTTI = getMSCompleteObjectLocator(RD, *Info);
1740e5dd7070Spatrick 
1741ec727ea7Spatrick     ConstantInitBuilder builder(CGM);
1742ec727ea7Spatrick     auto components = builder.beginStruct();
1743ec727ea7Spatrick     CGVT.createVTableInitializer(components, VTLayout, RTTI,
1744ec727ea7Spatrick                                  VTable->hasLocalLinkage());
1745ec727ea7Spatrick     components.finishAndSetAsInitializer(VTable);
1746e5dd7070Spatrick 
1747e5dd7070Spatrick     emitVTableTypeMetadata(*Info, RD, VTable);
1748e5dd7070Spatrick   }
1749e5dd7070Spatrick }
1750e5dd7070Spatrick 
isVirtualOffsetNeededForVTableField(CodeGenFunction & CGF,CodeGenFunction::VPtr Vptr)1751e5dd7070Spatrick bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1752e5dd7070Spatrick     CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
1753e5dd7070Spatrick   return Vptr.NearestVBase != nullptr;
1754e5dd7070Spatrick }
1755e5dd7070Spatrick 
getVTableAddressPointInStructor(CodeGenFunction & CGF,const CXXRecordDecl * VTableClass,BaseSubobject Base,const CXXRecordDecl * NearestVBase)1756e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1757e5dd7070Spatrick     CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
1758e5dd7070Spatrick     const CXXRecordDecl *NearestVBase) {
1759e5dd7070Spatrick   llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1760e5dd7070Spatrick   if (!VTableAddressPoint) {
1761e5dd7070Spatrick     assert(Base.getBase()->getNumVBases() &&
1762e5dd7070Spatrick            !getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr());
1763e5dd7070Spatrick   }
1764e5dd7070Spatrick   return VTableAddressPoint;
1765e5dd7070Spatrick }
1766e5dd7070Spatrick 
mangleVFTableName(MicrosoftMangleContext & MangleContext,const CXXRecordDecl * RD,const VPtrInfo & VFPtr,SmallString<256> & Name)1767e5dd7070Spatrick static void mangleVFTableName(MicrosoftMangleContext &MangleContext,
1768e5dd7070Spatrick                               const CXXRecordDecl *RD, const VPtrInfo &VFPtr,
1769e5dd7070Spatrick                               SmallString<256> &Name) {
1770e5dd7070Spatrick   llvm::raw_svector_ostream Out(Name);
1771e5dd7070Spatrick   MangleContext.mangleCXXVFTable(RD, VFPtr.MangledPath, Out);
1772e5dd7070Spatrick }
1773e5dd7070Spatrick 
1774e5dd7070Spatrick llvm::Constant *
getVTableAddressPoint(BaseSubobject Base,const CXXRecordDecl * VTableClass)1775e5dd7070Spatrick MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base,
1776e5dd7070Spatrick                                        const CXXRecordDecl *VTableClass) {
1777e5dd7070Spatrick   (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
1778e5dd7070Spatrick   VFTableIdTy ID(VTableClass, Base.getBaseOffset());
1779e5dd7070Spatrick   return VFTablesMap[ID];
1780e5dd7070Spatrick }
1781e5dd7070Spatrick 
getVTableAddressPointForConstExpr(BaseSubobject Base,const CXXRecordDecl * VTableClass)1782e5dd7070Spatrick llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1783e5dd7070Spatrick     BaseSubobject Base, const CXXRecordDecl *VTableClass) {
1784e5dd7070Spatrick   llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass);
1785e5dd7070Spatrick   assert(VFTable && "Couldn't find a vftable for the given base?");
1786e5dd7070Spatrick   return VFTable;
1787e5dd7070Spatrick }
1788e5dd7070Spatrick 
getAddrOfVTable(const CXXRecordDecl * RD,CharUnits VPtrOffset)1789e5dd7070Spatrick llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
1790e5dd7070Spatrick                                                        CharUnits VPtrOffset) {
1791e5dd7070Spatrick   // getAddrOfVTable may return 0 if asked to get an address of a vtable which
1792e5dd7070Spatrick   // shouldn't be used in the given record type. We want to cache this result in
1793e5dd7070Spatrick   // VFTablesMap, thus a simple zero check is not sufficient.
1794e5dd7070Spatrick 
1795e5dd7070Spatrick   VFTableIdTy ID(RD, VPtrOffset);
1796e5dd7070Spatrick   VTablesMapTy::iterator I;
1797e5dd7070Spatrick   bool Inserted;
1798e5dd7070Spatrick   std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID, nullptr));
1799e5dd7070Spatrick   if (!Inserted)
1800e5dd7070Spatrick     return I->second;
1801e5dd7070Spatrick 
1802e5dd7070Spatrick   llvm::GlobalVariable *&VTable = I->second;
1803e5dd7070Spatrick 
1804e5dd7070Spatrick   MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
1805e5dd7070Spatrick   const VPtrInfoVector &VFPtrs = VTContext.getVFPtrOffsets(RD);
1806e5dd7070Spatrick 
1807e5dd7070Spatrick   if (DeferredVFTables.insert(RD).second) {
1808e5dd7070Spatrick     // We haven't processed this record type before.
1809e5dd7070Spatrick     // Queue up this vtable for possible deferred emission.
1810e5dd7070Spatrick     CGM.addDeferredVTable(RD);
1811e5dd7070Spatrick 
1812e5dd7070Spatrick #ifndef NDEBUG
1813e5dd7070Spatrick     // Create all the vftables at once in order to make sure each vftable has
1814e5dd7070Spatrick     // a unique mangled name.
1815e5dd7070Spatrick     llvm::StringSet<> ObservedMangledNames;
1816e5dd7070Spatrick     for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1817e5dd7070Spatrick       SmallString<256> Name;
1818e5dd7070Spatrick       mangleVFTableName(getMangleContext(), RD, *VFPtrs[J], Name);
1819e5dd7070Spatrick       if (!ObservedMangledNames.insert(Name.str()).second)
1820e5dd7070Spatrick         llvm_unreachable("Already saw this mangling before?");
1821e5dd7070Spatrick     }
1822e5dd7070Spatrick #endif
1823e5dd7070Spatrick   }
1824e5dd7070Spatrick 
1825*12c85518Srobert   const std::unique_ptr<VPtrInfo> *VFPtrI =
1826*12c85518Srobert       llvm::find_if(VFPtrs, [&](const std::unique_ptr<VPtrInfo> &VPI) {
1827e5dd7070Spatrick         return VPI->FullOffsetInMDC == VPtrOffset;
1828e5dd7070Spatrick       });
1829e5dd7070Spatrick   if (VFPtrI == VFPtrs.end()) {
1830e5dd7070Spatrick     VFTablesMap[ID] = nullptr;
1831e5dd7070Spatrick     return nullptr;
1832e5dd7070Spatrick   }
1833e5dd7070Spatrick   const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1834e5dd7070Spatrick 
1835e5dd7070Spatrick   SmallString<256> VFTableName;
1836e5dd7070Spatrick   mangleVFTableName(getMangleContext(), RD, *VFPtr, VFTableName);
1837e5dd7070Spatrick 
1838e5dd7070Spatrick   // Classes marked __declspec(dllimport) need vftables generated on the
1839e5dd7070Spatrick   // import-side in order to support features like constexpr.  No other
1840e5dd7070Spatrick   // translation unit relies on the emission of the local vftable, translation
1841e5dd7070Spatrick   // units are expected to generate them as needed.
1842e5dd7070Spatrick   //
1843e5dd7070Spatrick   // Because of this unique behavior, we maintain this logic here instead of
1844e5dd7070Spatrick   // getVTableLinkage.
1845e5dd7070Spatrick   llvm::GlobalValue::LinkageTypes VFTableLinkage =
1846e5dd7070Spatrick       RD->hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1847e5dd7070Spatrick                                    : CGM.getVTableLinkage(RD);
1848e5dd7070Spatrick   bool VFTableComesFromAnotherTU =
1849e5dd7070Spatrick       llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1850e5dd7070Spatrick       llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1851e5dd7070Spatrick   bool VTableAliasIsRequred =
1852e5dd7070Spatrick       !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1853e5dd7070Spatrick 
1854e5dd7070Spatrick   if (llvm::GlobalValue *VFTable =
1855e5dd7070Spatrick           CGM.getModule().getNamedGlobal(VFTableName)) {
1856e5dd7070Spatrick     VFTablesMap[ID] = VFTable;
1857e5dd7070Spatrick     VTable = VTableAliasIsRequred
1858e5dd7070Spatrick                  ? cast<llvm::GlobalVariable>(
1859*12c85518Srobert                        cast<llvm::GlobalAlias>(VFTable)->getAliaseeObject())
1860e5dd7070Spatrick                  : cast<llvm::GlobalVariable>(VFTable);
1861e5dd7070Spatrick     return VTable;
1862e5dd7070Spatrick   }
1863e5dd7070Spatrick 
1864e5dd7070Spatrick   const VTableLayout &VTLayout =
1865e5dd7070Spatrick       VTContext.getVFTableLayout(RD, VFPtr->FullOffsetInMDC);
1866e5dd7070Spatrick   llvm::GlobalValue::LinkageTypes VTableLinkage =
1867e5dd7070Spatrick       VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1868e5dd7070Spatrick 
1869e5dd7070Spatrick   StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1870e5dd7070Spatrick 
1871e5dd7070Spatrick   llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1872e5dd7070Spatrick 
1873e5dd7070Spatrick   // Create a backing variable for the contents of VTable.  The VTable may
1874e5dd7070Spatrick   // or may not include space for a pointer to RTTI data.
1875e5dd7070Spatrick   llvm::GlobalValue *VFTable;
1876e5dd7070Spatrick   VTable = new llvm::GlobalVariable(CGM.getModule(), VTableType,
1877e5dd7070Spatrick                                     /*isConstant=*/true, VTableLinkage,
1878e5dd7070Spatrick                                     /*Initializer=*/nullptr, VTableName);
1879e5dd7070Spatrick   VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1880e5dd7070Spatrick 
1881e5dd7070Spatrick   llvm::Comdat *C = nullptr;
1882e5dd7070Spatrick   if (!VFTableComesFromAnotherTU &&
1883e5dd7070Spatrick       (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1884e5dd7070Spatrick        (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1885e5dd7070Spatrick         VTableAliasIsRequred)))
1886e5dd7070Spatrick     C = CGM.getModule().getOrInsertComdat(VFTableName.str());
1887e5dd7070Spatrick 
1888e5dd7070Spatrick   // Only insert a pointer into the VFTable for RTTI data if we are not
1889e5dd7070Spatrick   // importing it.  We never reference the RTTI data directly so there is no
1890e5dd7070Spatrick   // need to make room for it.
1891e5dd7070Spatrick   if (VTableAliasIsRequred) {
1892e5dd7070Spatrick     llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.Int32Ty, 0),
1893e5dd7070Spatrick                                  llvm::ConstantInt::get(CGM.Int32Ty, 0),
1894e5dd7070Spatrick                                  llvm::ConstantInt::get(CGM.Int32Ty, 1)};
1895e5dd7070Spatrick     // Create a GEP which points just after the first entry in the VFTable,
1896e5dd7070Spatrick     // this should be the location of the first virtual method.
1897e5dd7070Spatrick     llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1898e5dd7070Spatrick         VTable->getValueType(), VTable, GEPIndices);
1899e5dd7070Spatrick     if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1900e5dd7070Spatrick       VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1901e5dd7070Spatrick       if (C)
1902e5dd7070Spatrick         C->setSelectionKind(llvm::Comdat::Largest);
1903e5dd7070Spatrick     }
1904e5dd7070Spatrick     VFTable = llvm::GlobalAlias::create(CGM.Int8PtrTy,
1905e5dd7070Spatrick                                         /*AddressSpace=*/0, VFTableLinkage,
1906e5dd7070Spatrick                                         VFTableName.str(), VTableGEP,
1907e5dd7070Spatrick                                         &CGM.getModule());
1908e5dd7070Spatrick     VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1909e5dd7070Spatrick   } else {
1910e5dd7070Spatrick     // We don't need a GlobalAlias to be a symbol for the VTable if we won't
1911e5dd7070Spatrick     // be referencing any RTTI data.
1912e5dd7070Spatrick     // The GlobalVariable will end up being an appropriate definition of the
1913e5dd7070Spatrick     // VFTable.
1914e5dd7070Spatrick     VFTable = VTable;
1915e5dd7070Spatrick   }
1916e5dd7070Spatrick   if (C)
1917e5dd7070Spatrick     VTable->setComdat(C);
1918e5dd7070Spatrick 
1919e5dd7070Spatrick   if (RD->hasAttr<DLLExportAttr>())
1920e5dd7070Spatrick     VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1921e5dd7070Spatrick 
1922e5dd7070Spatrick   VFTablesMap[ID] = VFTable;
1923e5dd7070Spatrick   return VTable;
1924e5dd7070Spatrick }
1925e5dd7070Spatrick 
getVirtualFunctionPointer(CodeGenFunction & CGF,GlobalDecl GD,Address This,llvm::Type * Ty,SourceLocation Loc)1926e5dd7070Spatrick CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
1927e5dd7070Spatrick                                                     GlobalDecl GD,
1928e5dd7070Spatrick                                                     Address This,
1929e5dd7070Spatrick                                                     llvm::Type *Ty,
1930e5dd7070Spatrick                                                     SourceLocation Loc) {
1931e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
1932e5dd7070Spatrick 
1933a9ac8606Spatrick   Ty = Ty->getPointerTo();
1934e5dd7070Spatrick   Address VPtr =
1935e5dd7070Spatrick       adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
1936e5dd7070Spatrick 
1937e5dd7070Spatrick   auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl());
1938a9ac8606Spatrick   llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty->getPointerTo(),
1939a9ac8606Spatrick                                          MethodDecl->getParent());
1940e5dd7070Spatrick 
1941e5dd7070Spatrick   MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
1942e5dd7070Spatrick   MethodVFTableLocation ML = VFTContext.getMethodVFTableLocation(GD);
1943e5dd7070Spatrick 
1944e5dd7070Spatrick   // Compute the identity of the most derived class whose virtual table is
1945e5dd7070Spatrick   // located at the MethodVFTableLocation ML.
1946e5dd7070Spatrick   auto getObjectWithVPtr = [&] {
1947e5dd7070Spatrick     return llvm::find_if(VFTContext.getVFPtrOffsets(
1948e5dd7070Spatrick                              ML.VBase ? ML.VBase : MethodDecl->getParent()),
1949e5dd7070Spatrick                          [&](const std::unique_ptr<VPtrInfo> &Info) {
1950e5dd7070Spatrick                            return Info->FullOffsetInMDC == ML.VFPtrOffset;
1951e5dd7070Spatrick                          })
1952e5dd7070Spatrick         ->get()
1953e5dd7070Spatrick         ->ObjectWithVPtr;
1954e5dd7070Spatrick   };
1955e5dd7070Spatrick 
1956e5dd7070Spatrick   llvm::Value *VFunc;
1957e5dd7070Spatrick   if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) {
1958e5dd7070Spatrick     VFunc = CGF.EmitVTableTypeCheckedLoad(
1959*12c85518Srobert         getObjectWithVPtr(), VTable, Ty,
1960*12c85518Srobert         ML.Index *
1961*12c85518Srobert             CGM.getContext().getTargetInfo().getPointerWidth(LangAS::Default) /
1962*12c85518Srobert             8);
1963e5dd7070Spatrick   } else {
1964e5dd7070Spatrick     if (CGM.getCodeGenOpts().PrepareForLTO)
1965e5dd7070Spatrick       CGF.EmitTypeMetadataCodeForVCall(getObjectWithVPtr(), VTable, Loc);
1966e5dd7070Spatrick 
1967e5dd7070Spatrick     llvm::Value *VFuncPtr =
1968a9ac8606Spatrick         Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.Index, "vfn");
1969a9ac8606Spatrick     VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.getPointerAlign());
1970e5dd7070Spatrick   }
1971e5dd7070Spatrick 
1972e5dd7070Spatrick   CGCallee Callee(GD, VFunc);
1973e5dd7070Spatrick   return Callee;
1974e5dd7070Spatrick }
1975e5dd7070Spatrick 
EmitVirtualDestructorCall(CodeGenFunction & CGF,const CXXDestructorDecl * Dtor,CXXDtorType DtorType,Address This,DeleteOrMemberCallExpr E)1976e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1977e5dd7070Spatrick     CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,
1978e5dd7070Spatrick     Address This, DeleteOrMemberCallExpr E) {
1979e5dd7070Spatrick   auto *CE = E.dyn_cast<const CXXMemberCallExpr *>();
1980e5dd7070Spatrick   auto *D = E.dyn_cast<const CXXDeleteExpr *>();
1981e5dd7070Spatrick   assert((CE != nullptr) ^ (D != nullptr));
1982e5dd7070Spatrick   assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
1983e5dd7070Spatrick   assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
1984e5dd7070Spatrick 
1985e5dd7070Spatrick   // We have only one destructor in the vftable but can get both behaviors
1986e5dd7070Spatrick   // by passing an implicit int parameter.
1987e5dd7070Spatrick   GlobalDecl GD(Dtor, Dtor_Deleting);
1988e5dd7070Spatrick   const CGFunctionInfo *FInfo =
1989e5dd7070Spatrick       &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
1990e5dd7070Spatrick   llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
1991e5dd7070Spatrick   CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
1992e5dd7070Spatrick 
1993e5dd7070Spatrick   ASTContext &Context = getContext();
1994e5dd7070Spatrick   llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1995e5dd7070Spatrick       llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()),
1996e5dd7070Spatrick       DtorType == Dtor_Deleting);
1997e5dd7070Spatrick 
1998e5dd7070Spatrick   QualType ThisTy;
1999e5dd7070Spatrick   if (CE) {
2000e5dd7070Spatrick     ThisTy = CE->getObjectType();
2001e5dd7070Spatrick   } else {
2002e5dd7070Spatrick     ThisTy = D->getDestroyedType();
2003e5dd7070Spatrick   }
2004e5dd7070Spatrick 
2005e5dd7070Spatrick   This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
2006e5dd7070Spatrick   RValue RV = CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy,
2007e5dd7070Spatrick                                         ImplicitParam, Context.IntTy, CE);
2008e5dd7070Spatrick   return RV.getScalarVal();
2009e5dd7070Spatrick }
2010e5dd7070Spatrick 
2011e5dd7070Spatrick const VBTableGlobals &
enumerateVBTables(const CXXRecordDecl * RD)2012e5dd7070Spatrick MicrosoftCXXABI::enumerateVBTables(const CXXRecordDecl *RD) {
2013e5dd7070Spatrick   // At this layer, we can key the cache off of a single class, which is much
2014e5dd7070Spatrick   // easier than caching each vbtable individually.
2015e5dd7070Spatrick   llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
2016e5dd7070Spatrick   bool Added;
2017e5dd7070Spatrick   std::tie(Entry, Added) =
2018e5dd7070Spatrick       VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
2019e5dd7070Spatrick   VBTableGlobals &VBGlobals = Entry->second;
2020e5dd7070Spatrick   if (!Added)
2021e5dd7070Spatrick     return VBGlobals;
2022e5dd7070Spatrick 
2023e5dd7070Spatrick   MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
2024e5dd7070Spatrick   VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2025e5dd7070Spatrick 
2026e5dd7070Spatrick   // Cache the globals for all vbtables so we don't have to recompute the
2027e5dd7070Spatrick   // mangled names.
2028e5dd7070Spatrick   llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
2029e5dd7070Spatrick   for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2030e5dd7070Spatrick                                       E = VBGlobals.VBTables->end();
2031e5dd7070Spatrick        I != E; ++I) {
2032e5dd7070Spatrick     VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
2033e5dd7070Spatrick   }
2034e5dd7070Spatrick 
2035e5dd7070Spatrick   return VBGlobals;
2036e5dd7070Spatrick }
2037e5dd7070Spatrick 
2038e5dd7070Spatrick llvm::Function *
EmitVirtualMemPtrThunk(const CXXMethodDecl * MD,const MethodVFTableLocation & ML)2039e5dd7070Spatrick MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
2040e5dd7070Spatrick                                         const MethodVFTableLocation &ML) {
2041e5dd7070Spatrick   assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
2042e5dd7070Spatrick          "can't form pointers to ctors or virtual dtors");
2043e5dd7070Spatrick 
2044e5dd7070Spatrick   // Calculate the mangled name.
2045e5dd7070Spatrick   SmallString<256> ThunkName;
2046e5dd7070Spatrick   llvm::raw_svector_ostream Out(ThunkName);
2047e5dd7070Spatrick   getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2048e5dd7070Spatrick 
2049e5dd7070Spatrick   // If the thunk has been generated previously, just return it.
2050e5dd7070Spatrick   if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
2051e5dd7070Spatrick     return cast<llvm::Function>(GV);
2052e5dd7070Spatrick 
2053e5dd7070Spatrick   // Create the llvm::Function.
2054e5dd7070Spatrick   const CGFunctionInfo &FnInfo =
2055e5dd7070Spatrick       CGM.getTypes().arrangeUnprototypedMustTailThunk(MD);
2056e5dd7070Spatrick   llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
2057e5dd7070Spatrick   llvm::Function *ThunkFn =
2058e5dd7070Spatrick       llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
2059e5dd7070Spatrick                              ThunkName.str(), &CGM.getModule());
2060e5dd7070Spatrick   assert(ThunkFn->getName() == ThunkName && "name was uniqued!");
2061e5dd7070Spatrick 
2062e5dd7070Spatrick   ThunkFn->setLinkage(MD->isExternallyVisible()
2063e5dd7070Spatrick                           ? llvm::GlobalValue::LinkOnceODRLinkage
2064e5dd7070Spatrick                           : llvm::GlobalValue::InternalLinkage);
2065e5dd7070Spatrick   if (MD->isExternallyVisible())
2066e5dd7070Spatrick     ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
2067e5dd7070Spatrick 
2068a9ac8606Spatrick   CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn, /*IsThunk=*/false);
2069e5dd7070Spatrick   CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
2070e5dd7070Spatrick 
2071e5dd7070Spatrick   // Add the "thunk" attribute so that LLVM knows that the return type is
2072e5dd7070Spatrick   // meaningless. These thunks can be used to call functions with differing
2073e5dd7070Spatrick   // return types, and the caller is required to cast the prototype
2074e5dd7070Spatrick   // appropriately to extract the correct value.
2075e5dd7070Spatrick   ThunkFn->addFnAttr("thunk");
2076e5dd7070Spatrick 
2077e5dd7070Spatrick   // These thunks can be compared, so they are not unnamed.
2078e5dd7070Spatrick   ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
2079e5dd7070Spatrick 
2080e5dd7070Spatrick   // Start codegen.
2081e5dd7070Spatrick   CodeGenFunction CGF(CGM);
2082e5dd7070Spatrick   CGF.CurGD = GlobalDecl(MD);
2083e5dd7070Spatrick   CGF.CurFuncIsThunk = true;
2084e5dd7070Spatrick 
2085e5dd7070Spatrick   // Build FunctionArgs, but only include the implicit 'this' parameter
2086e5dd7070Spatrick   // declaration.
2087e5dd7070Spatrick   FunctionArgList FunctionArgs;
2088e5dd7070Spatrick   buildThisParam(CGF, FunctionArgs);
2089e5dd7070Spatrick 
2090e5dd7070Spatrick   // Start defining the function.
2091e5dd7070Spatrick   CGF.StartFunction(GlobalDecl(), FnInfo.getReturnType(), ThunkFn, FnInfo,
2092e5dd7070Spatrick                     FunctionArgs, MD->getLocation(), SourceLocation());
2093*12c85518Srobert 
2094*12c85518Srobert   ApplyDebugLocation AL(CGF, MD->getLocation());
2095e5dd7070Spatrick   setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2096e5dd7070Spatrick 
2097e5dd7070Spatrick   // Load the vfptr and then callee from the vftable.  The callee should have
2098e5dd7070Spatrick   // adjusted 'this' so that the vfptr is at offset zero.
2099a9ac8606Spatrick   llvm::Type *ThunkPtrTy = ThunkTy->getPointerTo();
2100e5dd7070Spatrick   llvm::Value *VTable = CGF.GetVTablePtr(
2101a9ac8606Spatrick       getThisAddress(CGF), ThunkPtrTy->getPointerTo(), MD->getParent());
2102e5dd7070Spatrick 
2103a9ac8606Spatrick   llvm::Value *VFuncPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
2104a9ac8606Spatrick       ThunkPtrTy, VTable, ML.Index, "vfn");
2105e5dd7070Spatrick   llvm::Value *Callee =
2106a9ac8606Spatrick     CGF.Builder.CreateAlignedLoad(ThunkPtrTy, VFuncPtr, CGF.getPointerAlign());
2107e5dd7070Spatrick 
2108e5dd7070Spatrick   CGF.EmitMustTailThunk(MD, getThisValue(CGF), {ThunkTy, Callee});
2109e5dd7070Spatrick 
2110e5dd7070Spatrick   return ThunkFn;
2111e5dd7070Spatrick }
2112e5dd7070Spatrick 
emitVirtualInheritanceTables(const CXXRecordDecl * RD)2113e5dd7070Spatrick void MicrosoftCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {
2114e5dd7070Spatrick   const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2115e5dd7070Spatrick   for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2116e5dd7070Spatrick     const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2117e5dd7070Spatrick     llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2118e5dd7070Spatrick     if (GV->isDeclaration())
2119e5dd7070Spatrick       emitVBTableDefinition(*VBT, RD, GV);
2120e5dd7070Spatrick   }
2121e5dd7070Spatrick }
2122e5dd7070Spatrick 
2123e5dd7070Spatrick llvm::GlobalVariable *
getAddrOfVBTable(const VPtrInfo & VBT,const CXXRecordDecl * RD,llvm::GlobalVariable::LinkageTypes Linkage)2124e5dd7070Spatrick MicrosoftCXXABI::getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
2125e5dd7070Spatrick                                   llvm::GlobalVariable::LinkageTypes Linkage) {
2126e5dd7070Spatrick   SmallString<256> OutName;
2127e5dd7070Spatrick   llvm::raw_svector_ostream Out(OutName);
2128e5dd7070Spatrick   getMangleContext().mangleCXXVBTable(RD, VBT.MangledPath, Out);
2129e5dd7070Spatrick   StringRef Name = OutName.str();
2130e5dd7070Spatrick 
2131e5dd7070Spatrick   llvm::ArrayType *VBTableType =
2132e5dd7070Spatrick       llvm::ArrayType::get(CGM.IntTy, 1 + VBT.ObjectWithVPtr->getNumVBases());
2133e5dd7070Spatrick 
2134e5dd7070Spatrick   assert(!CGM.getModule().getNamedGlobal(Name) &&
2135e5dd7070Spatrick          "vbtable with this name already exists: mangling bug?");
2136e5dd7070Spatrick   CharUnits Alignment =
2137e5dd7070Spatrick       CGM.getContext().getTypeAlignInChars(CGM.getContext().IntTy);
2138e5dd7070Spatrick   llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable(
2139*12c85518Srobert       Name, VBTableType, Linkage, Alignment.getAsAlign());
2140e5dd7070Spatrick   GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2141e5dd7070Spatrick 
2142e5dd7070Spatrick   if (RD->hasAttr<DLLImportAttr>())
2143e5dd7070Spatrick     GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2144e5dd7070Spatrick   else if (RD->hasAttr<DLLExportAttr>())
2145e5dd7070Spatrick     GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2146e5dd7070Spatrick 
2147e5dd7070Spatrick   if (!GV->hasExternalLinkage())
2148e5dd7070Spatrick     emitVBTableDefinition(VBT, RD, GV);
2149e5dd7070Spatrick 
2150e5dd7070Spatrick   return GV;
2151e5dd7070Spatrick }
2152e5dd7070Spatrick 
emitVBTableDefinition(const VPtrInfo & VBT,const CXXRecordDecl * RD,llvm::GlobalVariable * GV) const2153e5dd7070Spatrick void MicrosoftCXXABI::emitVBTableDefinition(const VPtrInfo &VBT,
2154e5dd7070Spatrick                                             const CXXRecordDecl *RD,
2155e5dd7070Spatrick                                             llvm::GlobalVariable *GV) const {
2156e5dd7070Spatrick   const CXXRecordDecl *ObjectWithVPtr = VBT.ObjectWithVPtr;
2157e5dd7070Spatrick 
2158e5dd7070Spatrick   assert(RD->getNumVBases() && ObjectWithVPtr->getNumVBases() &&
2159e5dd7070Spatrick          "should only emit vbtables for classes with vbtables");
2160e5dd7070Spatrick 
2161e5dd7070Spatrick   const ASTRecordLayout &BaseLayout =
2162e5dd7070Spatrick       getContext().getASTRecordLayout(VBT.IntroducingObject);
2163e5dd7070Spatrick   const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2164e5dd7070Spatrick 
2165e5dd7070Spatrick   SmallVector<llvm::Constant *, 4> Offsets(1 + ObjectWithVPtr->getNumVBases(),
2166e5dd7070Spatrick                                            nullptr);
2167e5dd7070Spatrick 
2168e5dd7070Spatrick   // The offset from ObjectWithVPtr's vbptr to itself always leads.
2169e5dd7070Spatrick   CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2170e5dd7070Spatrick   Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
2171e5dd7070Spatrick 
2172e5dd7070Spatrick   MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
2173e5dd7070Spatrick   for (const auto &I : ObjectWithVPtr->vbases()) {
2174e5dd7070Spatrick     const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2175e5dd7070Spatrick     CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase);
2176e5dd7070Spatrick     assert(!Offset.isNegative());
2177e5dd7070Spatrick 
2178e5dd7070Spatrick     // Make it relative to the subobject vbptr.
2179e5dd7070Spatrick     CharUnits CompleteVBPtrOffset = VBT.NonVirtualOffset + VBPtrOffset;
2180e5dd7070Spatrick     if (VBT.getVBaseWithVPtr())
2181e5dd7070Spatrick       CompleteVBPtrOffset +=
2182e5dd7070Spatrick           DerivedLayout.getVBaseClassOffset(VBT.getVBaseWithVPtr());
2183e5dd7070Spatrick     Offset -= CompleteVBPtrOffset;
2184e5dd7070Spatrick 
2185e5dd7070Spatrick     unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2186e5dd7070Spatrick     assert(Offsets[VBIndex] == nullptr && "The same vbindex seen twice?");
2187e5dd7070Spatrick     Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity());
2188e5dd7070Spatrick   }
2189e5dd7070Spatrick 
2190e5dd7070Spatrick   assert(Offsets.size() ==
2191a9ac8606Spatrick          cast<llvm::ArrayType>(GV->getValueType())->getNumElements());
2192e5dd7070Spatrick   llvm::ArrayType *VBTableType =
2193e5dd7070Spatrick     llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2194e5dd7070Spatrick   llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2195e5dd7070Spatrick   GV->setInitializer(Init);
2196e5dd7070Spatrick 
2197e5dd7070Spatrick   if (RD->hasAttr<DLLImportAttr>())
2198e5dd7070Spatrick     GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2199e5dd7070Spatrick }
2200e5dd7070Spatrick 
performThisAdjustment(CodeGenFunction & CGF,Address This,const ThisAdjustment & TA)2201e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::performThisAdjustment(CodeGenFunction &CGF,
2202e5dd7070Spatrick                                                     Address This,
2203e5dd7070Spatrick                                                     const ThisAdjustment &TA) {
2204e5dd7070Spatrick   if (TA.isEmpty())
2205e5dd7070Spatrick     return This.getPointer();
2206e5dd7070Spatrick 
2207e5dd7070Spatrick   This = CGF.Builder.CreateElementBitCast(This, CGF.Int8Ty);
2208e5dd7070Spatrick 
2209e5dd7070Spatrick   llvm::Value *V;
2210e5dd7070Spatrick   if (TA.Virtual.isEmpty()) {
2211e5dd7070Spatrick     V = This.getPointer();
2212e5dd7070Spatrick   } else {
2213e5dd7070Spatrick     assert(TA.Virtual.Microsoft.VtordispOffset < 0);
2214e5dd7070Spatrick     // Adjust the this argument based on the vtordisp value.
2215e5dd7070Spatrick     Address VtorDispPtr =
2216e5dd7070Spatrick         CGF.Builder.CreateConstInBoundsByteGEP(This,
2217e5dd7070Spatrick                  CharUnits::fromQuantity(TA.Virtual.Microsoft.VtordispOffset));
2218e5dd7070Spatrick     VtorDispPtr = CGF.Builder.CreateElementBitCast(VtorDispPtr, CGF.Int32Ty);
2219e5dd7070Spatrick     llvm::Value *VtorDisp = CGF.Builder.CreateLoad(VtorDispPtr, "vtordisp");
2220a9ac8606Spatrick     V = CGF.Builder.CreateGEP(This.getElementType(), This.getPointer(),
2221e5dd7070Spatrick                               CGF.Builder.CreateNeg(VtorDisp));
2222e5dd7070Spatrick 
2223e5dd7070Spatrick     // Unfortunately, having applied the vtordisp means that we no
2224e5dd7070Spatrick     // longer really have a known alignment for the vbptr step.
2225e5dd7070Spatrick     // We'll assume the vbptr is pointer-aligned.
2226e5dd7070Spatrick 
2227e5dd7070Spatrick     if (TA.Virtual.Microsoft.VBPtrOffset) {
2228e5dd7070Spatrick       // If the final overrider is defined in a virtual base other than the one
2229e5dd7070Spatrick       // that holds the vfptr, we have to use a vtordispex thunk which looks up
2230e5dd7070Spatrick       // the vbtable of the derived class.
2231e5dd7070Spatrick       assert(TA.Virtual.Microsoft.VBPtrOffset > 0);
2232e5dd7070Spatrick       assert(TA.Virtual.Microsoft.VBOffsetOffset >= 0);
2233e5dd7070Spatrick       llvm::Value *VBPtr;
2234*12c85518Srobert       llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2235*12c85518Srobert           CGF, Address(V, CGF.Int8Ty, CGF.getPointerAlign()),
2236e5dd7070Spatrick           -TA.Virtual.Microsoft.VBPtrOffset,
2237e5dd7070Spatrick           TA.Virtual.Microsoft.VBOffsetOffset, &VBPtr);
2238a9ac8606Spatrick       V = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, VBPtr, VBaseOffset);
2239e5dd7070Spatrick     }
2240e5dd7070Spatrick   }
2241e5dd7070Spatrick 
2242e5dd7070Spatrick   if (TA.NonVirtual) {
2243e5dd7070Spatrick     // Non-virtual adjustment might result in a pointer outside the allocated
2244e5dd7070Spatrick     // object, e.g. if the final overrider class is laid out after the virtual
2245e5dd7070Spatrick     // base that declares a method in the most derived class.
2246a9ac8606Spatrick     V = CGF.Builder.CreateConstGEP1_32(CGF.Int8Ty, V, TA.NonVirtual);
2247e5dd7070Spatrick   }
2248e5dd7070Spatrick 
2249e5dd7070Spatrick   // Don't need to bitcast back, the call CodeGen will handle this.
2250e5dd7070Spatrick   return V;
2251e5dd7070Spatrick }
2252e5dd7070Spatrick 
2253e5dd7070Spatrick llvm::Value *
performReturnAdjustment(CodeGenFunction & CGF,Address Ret,const ReturnAdjustment & RA)2254e5dd7070Spatrick MicrosoftCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
2255e5dd7070Spatrick                                          const ReturnAdjustment &RA) {
2256e5dd7070Spatrick   if (RA.isEmpty())
2257e5dd7070Spatrick     return Ret.getPointer();
2258e5dd7070Spatrick 
2259e5dd7070Spatrick   auto OrigTy = Ret.getType();
2260e5dd7070Spatrick   Ret = CGF.Builder.CreateElementBitCast(Ret, CGF.Int8Ty);
2261e5dd7070Spatrick 
2262e5dd7070Spatrick   llvm::Value *V = Ret.getPointer();
2263e5dd7070Spatrick   if (RA.Virtual.Microsoft.VBIndex) {
2264e5dd7070Spatrick     assert(RA.Virtual.Microsoft.VBIndex > 0);
2265e5dd7070Spatrick     int32_t IntSize = CGF.getIntSize().getQuantity();
2266e5dd7070Spatrick     llvm::Value *VBPtr;
2267e5dd7070Spatrick     llvm::Value *VBaseOffset =
2268e5dd7070Spatrick         GetVBaseOffsetFromVBPtr(CGF, Ret, RA.Virtual.Microsoft.VBPtrOffset,
2269e5dd7070Spatrick                                 IntSize * RA.Virtual.Microsoft.VBIndex, &VBPtr);
2270a9ac8606Spatrick     V = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, VBPtr, VBaseOffset);
2271e5dd7070Spatrick   }
2272e5dd7070Spatrick 
2273e5dd7070Spatrick   if (RA.NonVirtual)
2274e5dd7070Spatrick     V = CGF.Builder.CreateConstInBoundsGEP1_32(CGF.Int8Ty, V, RA.NonVirtual);
2275e5dd7070Spatrick 
2276e5dd7070Spatrick   // Cast back to the original type.
2277e5dd7070Spatrick   return CGF.Builder.CreateBitCast(V, OrigTy);
2278e5dd7070Spatrick }
2279e5dd7070Spatrick 
requiresArrayCookie(const CXXDeleteExpr * expr,QualType elementType)2280e5dd7070Spatrick bool MicrosoftCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
2281e5dd7070Spatrick                                    QualType elementType) {
2282e5dd7070Spatrick   // Microsoft seems to completely ignore the possibility of a
2283e5dd7070Spatrick   // two-argument usual deallocation function.
2284e5dd7070Spatrick   return elementType.isDestructedType();
2285e5dd7070Spatrick }
2286e5dd7070Spatrick 
requiresArrayCookie(const CXXNewExpr * expr)2287e5dd7070Spatrick bool MicrosoftCXXABI::requiresArrayCookie(const CXXNewExpr *expr) {
2288e5dd7070Spatrick   // Microsoft seems to completely ignore the possibility of a
2289e5dd7070Spatrick   // two-argument usual deallocation function.
2290e5dd7070Spatrick   return expr->getAllocatedType().isDestructedType();
2291e5dd7070Spatrick }
2292e5dd7070Spatrick 
getArrayCookieSizeImpl(QualType type)2293e5dd7070Spatrick CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType type) {
2294e5dd7070Spatrick   // The array cookie is always a size_t; we then pad that out to the
2295e5dd7070Spatrick   // alignment of the element type.
2296e5dd7070Spatrick   ASTContext &Ctx = getContext();
2297e5dd7070Spatrick   return std::max(Ctx.getTypeSizeInChars(Ctx.getSizeType()),
2298e5dd7070Spatrick                   Ctx.getTypeAlignInChars(type));
2299e5dd7070Spatrick }
2300e5dd7070Spatrick 
readArrayCookieImpl(CodeGenFunction & CGF,Address allocPtr,CharUnits cookieSize)2301e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2302e5dd7070Spatrick                                                   Address allocPtr,
2303e5dd7070Spatrick                                                   CharUnits cookieSize) {
2304e5dd7070Spatrick   Address numElementsPtr =
2305e5dd7070Spatrick     CGF.Builder.CreateElementBitCast(allocPtr, CGF.SizeTy);
2306e5dd7070Spatrick   return CGF.Builder.CreateLoad(numElementsPtr);
2307e5dd7070Spatrick }
2308e5dd7070Spatrick 
InitializeArrayCookie(CodeGenFunction & CGF,Address newPtr,llvm::Value * numElements,const CXXNewExpr * expr,QualType elementType)2309e5dd7070Spatrick Address MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2310e5dd7070Spatrick                                                Address newPtr,
2311e5dd7070Spatrick                                                llvm::Value *numElements,
2312e5dd7070Spatrick                                                const CXXNewExpr *expr,
2313e5dd7070Spatrick                                                QualType elementType) {
2314e5dd7070Spatrick   assert(requiresArrayCookie(expr));
2315e5dd7070Spatrick 
2316e5dd7070Spatrick   // The size of the cookie.
2317e5dd7070Spatrick   CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2318e5dd7070Spatrick 
2319e5dd7070Spatrick   // Compute an offset to the cookie.
2320e5dd7070Spatrick   Address cookiePtr = newPtr;
2321e5dd7070Spatrick 
2322e5dd7070Spatrick   // Write the number of elements into the appropriate slot.
2323e5dd7070Spatrick   Address numElementsPtr
2324e5dd7070Spatrick     = CGF.Builder.CreateElementBitCast(cookiePtr, CGF.SizeTy);
2325e5dd7070Spatrick   CGF.Builder.CreateStore(numElements, numElementsPtr);
2326e5dd7070Spatrick 
2327e5dd7070Spatrick   // Finally, compute a pointer to the actual data buffer by skipping
2328e5dd7070Spatrick   // over the cookie completely.
2329e5dd7070Spatrick   return CGF.Builder.CreateConstInBoundsByteGEP(newPtr, cookieSize);
2330e5dd7070Spatrick }
2331e5dd7070Spatrick 
emitGlobalDtorWithTLRegDtor(CodeGenFunction & CGF,const VarDecl & VD,llvm::FunctionCallee Dtor,llvm::Constant * Addr)2332e5dd7070Spatrick static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD,
2333e5dd7070Spatrick                                         llvm::FunctionCallee Dtor,
2334e5dd7070Spatrick                                         llvm::Constant *Addr) {
2335e5dd7070Spatrick   // Create a function which calls the destructor.
2336e5dd7070Spatrick   llvm::Constant *DtorStub = CGF.createAtExitStub(VD, Dtor, Addr);
2337e5dd7070Spatrick 
2338e5dd7070Spatrick   // extern "C" int __tlregdtor(void (*f)(void));
2339e5dd7070Spatrick   llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2340e5dd7070Spatrick       CGF.IntTy, DtorStub->getType(), /*isVarArg=*/false);
2341e5dd7070Spatrick 
2342e5dd7070Spatrick   llvm::FunctionCallee TLRegDtor = CGF.CGM.CreateRuntimeFunction(
2343e5dd7070Spatrick       TLRegDtorTy, "__tlregdtor", llvm::AttributeList(), /*Local=*/true);
2344e5dd7070Spatrick   if (llvm::Function *TLRegDtorFn =
2345e5dd7070Spatrick           dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2346e5dd7070Spatrick     TLRegDtorFn->setDoesNotThrow();
2347e5dd7070Spatrick 
2348e5dd7070Spatrick   CGF.EmitNounwindRuntimeCall(TLRegDtor, DtorStub);
2349e5dd7070Spatrick }
2350e5dd7070Spatrick 
registerGlobalDtor(CodeGenFunction & CGF,const VarDecl & D,llvm::FunctionCallee Dtor,llvm::Constant * Addr)2351e5dd7070Spatrick void MicrosoftCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
2352e5dd7070Spatrick                                          llvm::FunctionCallee Dtor,
2353e5dd7070Spatrick                                          llvm::Constant *Addr) {
2354e5dd7070Spatrick   if (D.isNoDestroy(CGM.getContext()))
2355e5dd7070Spatrick     return;
2356e5dd7070Spatrick 
2357e5dd7070Spatrick   if (D.getTLSKind())
2358e5dd7070Spatrick     return emitGlobalDtorWithTLRegDtor(CGF, D, Dtor, Addr);
2359e5dd7070Spatrick 
2360*12c85518Srobert   // HLSL doesn't support atexit.
2361*12c85518Srobert   if (CGM.getLangOpts().HLSL)
2362*12c85518Srobert     return CGM.AddCXXDtorEntry(Dtor, Addr);
2363*12c85518Srobert 
2364e5dd7070Spatrick   // The default behavior is to use atexit.
2365e5dd7070Spatrick   CGF.registerGlobalDtorWithAtExit(D, Dtor, Addr);
2366e5dd7070Spatrick }
2367e5dd7070Spatrick 
EmitThreadLocalInitFuncs(CodeGenModule & CGM,ArrayRef<const VarDecl * > CXXThreadLocals,ArrayRef<llvm::Function * > CXXThreadLocalInits,ArrayRef<const VarDecl * > CXXThreadLocalInitVars)2368e5dd7070Spatrick void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2369e5dd7070Spatrick     CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
2370e5dd7070Spatrick     ArrayRef<llvm::Function *> CXXThreadLocalInits,
2371e5dd7070Spatrick     ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
2372e5dd7070Spatrick   if (CXXThreadLocalInits.empty())
2373e5dd7070Spatrick     return;
2374e5dd7070Spatrick 
2375e5dd7070Spatrick   CGM.AppendLinkerOptions(CGM.getTarget().getTriple().getArch() ==
2376e5dd7070Spatrick                                   llvm::Triple::x86
2377e5dd7070Spatrick                               ? "/include:___dyn_tls_init@12"
2378e5dd7070Spatrick                               : "/include:__dyn_tls_init");
2379e5dd7070Spatrick 
2380e5dd7070Spatrick   // This will create a GV in the .CRT$XDU section.  It will point to our
2381e5dd7070Spatrick   // initialization function.  The CRT will call all of these function
2382e5dd7070Spatrick   // pointers at start-up time and, eventually, at thread-creation time.
2383e5dd7070Spatrick   auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2384e5dd7070Spatrick     llvm::GlobalVariable *InitFuncPtr = new llvm::GlobalVariable(
2385e5dd7070Spatrick         CGM.getModule(), InitFunc->getType(), /*isConstant=*/true,
2386e5dd7070Spatrick         llvm::GlobalVariable::InternalLinkage, InitFunc,
2387e5dd7070Spatrick         Twine(InitFunc->getName(), "$initializer$"));
2388e5dd7070Spatrick     InitFuncPtr->setSection(".CRT$XDU");
2389e5dd7070Spatrick     // This variable has discardable linkage, we have to add it to @llvm.used to
2390e5dd7070Spatrick     // ensure it won't get discarded.
2391e5dd7070Spatrick     CGM.addUsedGlobal(InitFuncPtr);
2392e5dd7070Spatrick     return InitFuncPtr;
2393e5dd7070Spatrick   };
2394e5dd7070Spatrick 
2395e5dd7070Spatrick   std::vector<llvm::Function *> NonComdatInits;
2396e5dd7070Spatrick   for (size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2397e5dd7070Spatrick     llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2398e5dd7070Spatrick         CGM.GetGlobalValue(CGM.getMangledName(CXXThreadLocalInitVars[I])));
2399e5dd7070Spatrick     llvm::Function *F = CXXThreadLocalInits[I];
2400e5dd7070Spatrick 
2401e5dd7070Spatrick     // If the GV is already in a comdat group, then we have to join it.
2402e5dd7070Spatrick     if (llvm::Comdat *C = GV->getComdat())
2403e5dd7070Spatrick       AddToXDU(F)->setComdat(C);
2404e5dd7070Spatrick     else
2405e5dd7070Spatrick       NonComdatInits.push_back(F);
2406e5dd7070Spatrick   }
2407e5dd7070Spatrick 
2408e5dd7070Spatrick   if (!NonComdatInits.empty()) {
2409e5dd7070Spatrick     llvm::FunctionType *FTy =
2410e5dd7070Spatrick         llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
2411ec727ea7Spatrick     llvm::Function *InitFunc = CGM.CreateGlobalInitOrCleanUpFunction(
2412e5dd7070Spatrick         FTy, "__tls_init", CGM.getTypes().arrangeNullaryFunction(),
2413e5dd7070Spatrick         SourceLocation(), /*TLS=*/true);
2414e5dd7070Spatrick     CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(InitFunc, NonComdatInits);
2415e5dd7070Spatrick 
2416e5dd7070Spatrick     AddToXDU(InitFunc);
2417e5dd7070Spatrick   }
2418e5dd7070Spatrick }
2419e5dd7070Spatrick 
getTlsGuardVar(CodeGenModule & CGM)2420*12c85518Srobert static llvm::GlobalValue *getTlsGuardVar(CodeGenModule &CGM) {
2421*12c85518Srobert   // __tls_guard comes from the MSVC runtime and reflects
2422*12c85518Srobert   // whether TLS has been initialized for a particular thread.
2423*12c85518Srobert   // It is set from within __dyn_tls_init by the runtime.
2424*12c85518Srobert   // Every library and executable has its own variable.
2425*12c85518Srobert   llvm::Type *VTy = llvm::Type::getInt8Ty(CGM.getLLVMContext());
2426*12c85518Srobert   llvm::Constant *TlsGuardConstant =
2427*12c85518Srobert       CGM.CreateRuntimeVariable(VTy, "__tls_guard");
2428*12c85518Srobert   llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant);
2429*12c85518Srobert 
2430*12c85518Srobert   TlsGuard->setThreadLocal(true);
2431*12c85518Srobert 
2432*12c85518Srobert   return TlsGuard;
2433*12c85518Srobert }
2434*12c85518Srobert 
getDynTlsOnDemandInitFn(CodeGenModule & CGM)2435*12c85518Srobert static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM) {
2436*12c85518Srobert   // __dyn_tls_on_demand_init comes from the MSVC runtime and triggers
2437*12c85518Srobert   // dynamic TLS initialization by calling __dyn_tls_init internally.
2438*12c85518Srobert   llvm::FunctionType *FTy =
2439*12c85518Srobert       llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()), {},
2440*12c85518Srobert                               /*isVarArg=*/false);
2441*12c85518Srobert   return CGM.CreateRuntimeFunction(
2442*12c85518Srobert       FTy, "__dyn_tls_on_demand_init",
2443*12c85518Srobert       llvm::AttributeList::get(CGM.getLLVMContext(),
2444*12c85518Srobert                                llvm::AttributeList::FunctionIndex,
2445*12c85518Srobert                                llvm::Attribute::NoUnwind),
2446*12c85518Srobert       /*Local=*/true);
2447*12c85518Srobert }
2448*12c85518Srobert 
emitTlsGuardCheck(CodeGenFunction & CGF,llvm::GlobalValue * TlsGuard,llvm::BasicBlock * DynInitBB,llvm::BasicBlock * ContinueBB)2449*12c85518Srobert static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard,
2450*12c85518Srobert                               llvm::BasicBlock *DynInitBB,
2451*12c85518Srobert                               llvm::BasicBlock *ContinueBB) {
2452*12c85518Srobert   llvm::LoadInst *TlsGuardValue =
2453*12c85518Srobert       CGF.Builder.CreateLoad(Address(TlsGuard, CGF.Int8Ty, CharUnits::One()));
2454*12c85518Srobert   llvm::Value *CmpResult =
2455*12c85518Srobert       CGF.Builder.CreateICmpEQ(TlsGuardValue, CGF.Builder.getInt8(0));
2456*12c85518Srobert   CGF.Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2457*12c85518Srobert }
2458*12c85518Srobert 
emitDynamicTlsInitializationCall(CodeGenFunction & CGF,llvm::GlobalValue * TlsGuard,llvm::BasicBlock * ContinueBB)2459*12c85518Srobert static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF,
2460*12c85518Srobert                                              llvm::GlobalValue *TlsGuard,
2461*12c85518Srobert                                              llvm::BasicBlock *ContinueBB) {
2462*12c85518Srobert   llvm::FunctionCallee Initializer = getDynTlsOnDemandInitFn(CGF.CGM);
2463*12c85518Srobert   llvm::Function *InitializerFunction =
2464*12c85518Srobert       cast<llvm::Function>(Initializer.getCallee());
2465*12c85518Srobert   llvm::CallInst *CallVal = CGF.Builder.CreateCall(InitializerFunction);
2466*12c85518Srobert   CallVal->setCallingConv(InitializerFunction->getCallingConv());
2467*12c85518Srobert 
2468*12c85518Srobert   CGF.Builder.CreateBr(ContinueBB);
2469*12c85518Srobert }
2470*12c85518Srobert 
emitDynamicTlsInitialization(CodeGenFunction & CGF)2471*12c85518Srobert static void emitDynamicTlsInitialization(CodeGenFunction &CGF) {
2472*12c85518Srobert   llvm::BasicBlock *DynInitBB =
2473*12c85518Srobert       CGF.createBasicBlock("dyntls.dyn_init", CGF.CurFn);
2474*12c85518Srobert   llvm::BasicBlock *ContinueBB =
2475*12c85518Srobert       CGF.createBasicBlock("dyntls.continue", CGF.CurFn);
2476*12c85518Srobert 
2477*12c85518Srobert   llvm::GlobalValue *TlsGuard = getTlsGuardVar(CGF.CGM);
2478*12c85518Srobert 
2479*12c85518Srobert   emitTlsGuardCheck(CGF, TlsGuard, DynInitBB, ContinueBB);
2480*12c85518Srobert   CGF.Builder.SetInsertPoint(DynInitBB);
2481*12c85518Srobert   emitDynamicTlsInitializationCall(CGF, TlsGuard, ContinueBB);
2482*12c85518Srobert   CGF.Builder.SetInsertPoint(ContinueBB);
2483*12c85518Srobert }
2484*12c85518Srobert 
EmitThreadLocalVarDeclLValue(CodeGenFunction & CGF,const VarDecl * VD,QualType LValType)2485e5dd7070Spatrick LValue MicrosoftCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
2486e5dd7070Spatrick                                                      const VarDecl *VD,
2487e5dd7070Spatrick                                                      QualType LValType) {
2488*12c85518Srobert   // Dynamic TLS initialization works by checking the state of a
2489*12c85518Srobert   // guard variable (__tls_guard) to see whether TLS initialization
2490*12c85518Srobert   // for a thread has happend yet.
2491*12c85518Srobert   // If not, the initialization is triggered on-demand
2492*12c85518Srobert   // by calling __dyn_tls_on_demand_init.
2493*12c85518Srobert   emitDynamicTlsInitialization(CGF);
2494*12c85518Srobert 
2495*12c85518Srobert   // Emit the variable just like any regular global variable.
2496*12c85518Srobert 
2497*12c85518Srobert   llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
2498*12c85518Srobert   llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType());
2499*12c85518Srobert 
2500*12c85518Srobert   unsigned AS = cast<llvm::PointerType>(V->getType())->getAddressSpace();
2501*12c85518Srobert   V = CGF.Builder.CreateBitCast(V, RealVarTy->getPointerTo(AS));
2502*12c85518Srobert 
2503*12c85518Srobert   CharUnits Alignment = CGF.getContext().getDeclAlign(VD);
2504*12c85518Srobert   Address Addr(V, RealVarTy, Alignment);
2505*12c85518Srobert 
2506*12c85518Srobert   LValue LV = VD->getType()->isReferenceType()
2507*12c85518Srobert                   ? CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
2508*12c85518Srobert                                                   AlignmentSource::Decl)
2509*12c85518Srobert                   : CGF.MakeAddrLValue(Addr, LValType, AlignmentSource::Decl);
2510*12c85518Srobert   return LV;
2511e5dd7070Spatrick }
2512e5dd7070Spatrick 
getInitThreadEpochPtr(CodeGenModule & CGM)2513e5dd7070Spatrick static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM) {
2514e5dd7070Spatrick   StringRef VarName("_Init_thread_epoch");
2515e5dd7070Spatrick   CharUnits Align = CGM.getIntAlign();
2516e5dd7070Spatrick   if (auto *GV = CGM.getModule().getNamedGlobal(VarName))
2517*12c85518Srobert     return ConstantAddress(GV, GV->getValueType(), Align);
2518e5dd7070Spatrick   auto *GV = new llvm::GlobalVariable(
2519e5dd7070Spatrick       CGM.getModule(), CGM.IntTy,
2520e5dd7070Spatrick       /*isConstant=*/false, llvm::GlobalVariable::ExternalLinkage,
2521e5dd7070Spatrick       /*Initializer=*/nullptr, VarName,
2522e5dd7070Spatrick       /*InsertBefore=*/nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2523e5dd7070Spatrick   GV->setAlignment(Align.getAsAlign());
2524*12c85518Srobert   return ConstantAddress(GV, GV->getValueType(), Align);
2525e5dd7070Spatrick }
2526e5dd7070Spatrick 
getInitThreadHeaderFn(CodeGenModule & CGM)2527e5dd7070Spatrick static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM) {
2528e5dd7070Spatrick   llvm::FunctionType *FTy =
2529e5dd7070Spatrick       llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
2530e5dd7070Spatrick                               CGM.IntTy->getPointerTo(), /*isVarArg=*/false);
2531e5dd7070Spatrick   return CGM.CreateRuntimeFunction(
2532e5dd7070Spatrick       FTy, "_Init_thread_header",
2533e5dd7070Spatrick       llvm::AttributeList::get(CGM.getLLVMContext(),
2534e5dd7070Spatrick                                llvm::AttributeList::FunctionIndex,
2535e5dd7070Spatrick                                llvm::Attribute::NoUnwind),
2536e5dd7070Spatrick       /*Local=*/true);
2537e5dd7070Spatrick }
2538e5dd7070Spatrick 
getInitThreadFooterFn(CodeGenModule & CGM)2539e5dd7070Spatrick static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM) {
2540e5dd7070Spatrick   llvm::FunctionType *FTy =
2541e5dd7070Spatrick       llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
2542e5dd7070Spatrick                               CGM.IntTy->getPointerTo(), /*isVarArg=*/false);
2543e5dd7070Spatrick   return CGM.CreateRuntimeFunction(
2544e5dd7070Spatrick       FTy, "_Init_thread_footer",
2545e5dd7070Spatrick       llvm::AttributeList::get(CGM.getLLVMContext(),
2546e5dd7070Spatrick                                llvm::AttributeList::FunctionIndex,
2547e5dd7070Spatrick                                llvm::Attribute::NoUnwind),
2548e5dd7070Spatrick       /*Local=*/true);
2549e5dd7070Spatrick }
2550e5dd7070Spatrick 
getInitThreadAbortFn(CodeGenModule & CGM)2551e5dd7070Spatrick static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM) {
2552e5dd7070Spatrick   llvm::FunctionType *FTy =
2553e5dd7070Spatrick       llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.getLLVMContext()),
2554e5dd7070Spatrick                               CGM.IntTy->getPointerTo(), /*isVarArg=*/false);
2555e5dd7070Spatrick   return CGM.CreateRuntimeFunction(
2556e5dd7070Spatrick       FTy, "_Init_thread_abort",
2557e5dd7070Spatrick       llvm::AttributeList::get(CGM.getLLVMContext(),
2558e5dd7070Spatrick                                llvm::AttributeList::FunctionIndex,
2559e5dd7070Spatrick                                llvm::Attribute::NoUnwind),
2560e5dd7070Spatrick       /*Local=*/true);
2561e5dd7070Spatrick }
2562e5dd7070Spatrick 
2563e5dd7070Spatrick namespace {
2564e5dd7070Spatrick struct ResetGuardBit final : EHScopeStack::Cleanup {
2565e5dd7070Spatrick   Address Guard;
2566e5dd7070Spatrick   unsigned GuardNum;
ResetGuardBit__anon063cb12a0711::ResetGuardBit2567e5dd7070Spatrick   ResetGuardBit(Address Guard, unsigned GuardNum)
2568e5dd7070Spatrick       : Guard(Guard), GuardNum(GuardNum) {}
2569e5dd7070Spatrick 
Emit__anon063cb12a0711::ResetGuardBit2570e5dd7070Spatrick   void Emit(CodeGenFunction &CGF, Flags flags) override {
2571e5dd7070Spatrick     // Reset the bit in the mask so that the static variable may be
2572e5dd7070Spatrick     // reinitialized.
2573e5dd7070Spatrick     CGBuilderTy &Builder = CGF.Builder;
2574e5dd7070Spatrick     llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2575e5dd7070Spatrick     llvm::ConstantInt *Mask =
2576e5dd7070Spatrick         llvm::ConstantInt::get(CGF.IntTy, ~(1ULL << GuardNum));
2577e5dd7070Spatrick     Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2578e5dd7070Spatrick   }
2579e5dd7070Spatrick };
2580e5dd7070Spatrick 
2581e5dd7070Spatrick struct CallInitThreadAbort final : EHScopeStack::Cleanup {
2582e5dd7070Spatrick   llvm::Value *Guard;
CallInitThreadAbort__anon063cb12a0711::CallInitThreadAbort2583e5dd7070Spatrick   CallInitThreadAbort(Address Guard) : Guard(Guard.getPointer()) {}
2584e5dd7070Spatrick 
Emit__anon063cb12a0711::CallInitThreadAbort2585e5dd7070Spatrick   void Emit(CodeGenFunction &CGF, Flags flags) override {
2586e5dd7070Spatrick     // Calling _Init_thread_abort will reset the guard's state.
2587e5dd7070Spatrick     CGF.EmitNounwindRuntimeCall(getInitThreadAbortFn(CGF.CGM), Guard);
2588e5dd7070Spatrick   }
2589e5dd7070Spatrick };
2590e5dd7070Spatrick }
2591e5dd7070Spatrick 
EmitGuardedInit(CodeGenFunction & CGF,const VarDecl & D,llvm::GlobalVariable * GV,bool PerformInit)2592e5dd7070Spatrick void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
2593e5dd7070Spatrick                                       llvm::GlobalVariable *GV,
2594e5dd7070Spatrick                                       bool PerformInit) {
2595e5dd7070Spatrick   // MSVC only uses guards for static locals.
2596e5dd7070Spatrick   if (!D.isStaticLocal()) {
2597e5dd7070Spatrick     assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2598e5dd7070Spatrick     // GlobalOpt is allowed to discard the initializer, so use linkonce_odr.
2599e5dd7070Spatrick     llvm::Function *F = CGF.CurFn;
2600e5dd7070Spatrick     F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2601e5dd7070Spatrick     F->setComdat(CGM.getModule().getOrInsertComdat(F->getName()));
2602e5dd7070Spatrick     CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
2603e5dd7070Spatrick     return;
2604e5dd7070Spatrick   }
2605e5dd7070Spatrick 
2606e5dd7070Spatrick   bool ThreadlocalStatic = D.getTLSKind();
2607e5dd7070Spatrick   bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2608e5dd7070Spatrick 
2609e5dd7070Spatrick   // Thread-safe static variables which aren't thread-specific have a
2610e5dd7070Spatrick   // per-variable guard.
2611e5dd7070Spatrick   bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2612e5dd7070Spatrick 
2613e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
2614e5dd7070Spatrick   llvm::IntegerType *GuardTy = CGF.Int32Ty;
2615e5dd7070Spatrick   llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
2616e5dd7070Spatrick   CharUnits GuardAlign = CharUnits::fromQuantity(4);
2617e5dd7070Spatrick 
2618e5dd7070Spatrick   // Get the guard variable for this function if we have one already.
2619e5dd7070Spatrick   GuardInfo *GI = nullptr;
2620e5dd7070Spatrick   if (ThreadlocalStatic)
2621e5dd7070Spatrick     GI = &ThreadLocalGuardVariableMap[D.getDeclContext()];
2622e5dd7070Spatrick   else if (!ThreadsafeStatic)
2623e5dd7070Spatrick     GI = &GuardVariableMap[D.getDeclContext()];
2624e5dd7070Spatrick 
2625e5dd7070Spatrick   llvm::GlobalVariable *GuardVar = GI ? GI->Guard : nullptr;
2626e5dd7070Spatrick   unsigned GuardNum;
2627e5dd7070Spatrick   if (D.isExternallyVisible()) {
2628e5dd7070Spatrick     // Externally visible variables have to be numbered in Sema to properly
2629e5dd7070Spatrick     // handle unreachable VarDecls.
2630e5dd7070Spatrick     GuardNum = getContext().getStaticLocalNumber(&D);
2631e5dd7070Spatrick     assert(GuardNum > 0);
2632e5dd7070Spatrick     GuardNum--;
2633e5dd7070Spatrick   } else if (HasPerVariableGuard) {
2634e5dd7070Spatrick     GuardNum = ThreadSafeGuardNumMap[D.getDeclContext()]++;
2635e5dd7070Spatrick   } else {
2636e5dd7070Spatrick     // Non-externally visible variables are numbered here in CodeGen.
2637e5dd7070Spatrick     GuardNum = GI->BitIndex++;
2638e5dd7070Spatrick   }
2639e5dd7070Spatrick 
2640e5dd7070Spatrick   if (!HasPerVariableGuard && GuardNum >= 32) {
2641e5dd7070Spatrick     if (D.isExternallyVisible())
2642e5dd7070Spatrick       ErrorUnsupportedABI(CGF, "more than 32 guarded initializations");
2643e5dd7070Spatrick     GuardNum %= 32;
2644e5dd7070Spatrick     GuardVar = nullptr;
2645e5dd7070Spatrick   }
2646e5dd7070Spatrick 
2647e5dd7070Spatrick   if (!GuardVar) {
2648e5dd7070Spatrick     // Mangle the name for the guard.
2649e5dd7070Spatrick     SmallString<256> GuardName;
2650e5dd7070Spatrick     {
2651e5dd7070Spatrick       llvm::raw_svector_ostream Out(GuardName);
2652e5dd7070Spatrick       if (HasPerVariableGuard)
2653e5dd7070Spatrick         getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2654e5dd7070Spatrick                                                                Out);
2655e5dd7070Spatrick       else
2656e5dd7070Spatrick         getMangleContext().mangleStaticGuardVariable(&D, Out);
2657e5dd7070Spatrick     }
2658e5dd7070Spatrick 
2659e5dd7070Spatrick     // Create the guard variable with a zero-initializer. Just absorb linkage,
2660e5dd7070Spatrick     // visibility and dll storage class from the guarded variable.
2661e5dd7070Spatrick     GuardVar =
2662e5dd7070Spatrick         new llvm::GlobalVariable(CGM.getModule(), GuardTy, /*isConstant=*/false,
2663e5dd7070Spatrick                                  GV->getLinkage(), Zero, GuardName.str());
2664e5dd7070Spatrick     GuardVar->setVisibility(GV->getVisibility());
2665e5dd7070Spatrick     GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2666e5dd7070Spatrick     GuardVar->setAlignment(GuardAlign.getAsAlign());
2667e5dd7070Spatrick     if (GuardVar->isWeakForLinker())
2668e5dd7070Spatrick       GuardVar->setComdat(
2669e5dd7070Spatrick           CGM.getModule().getOrInsertComdat(GuardVar->getName()));
2670e5dd7070Spatrick     if (D.getTLSKind())
2671ec727ea7Spatrick       CGM.setTLSMode(GuardVar, D);
2672e5dd7070Spatrick     if (GI && !HasPerVariableGuard)
2673e5dd7070Spatrick       GI->Guard = GuardVar;
2674e5dd7070Spatrick   }
2675e5dd7070Spatrick 
2676*12c85518Srobert   ConstantAddress GuardAddr(GuardVar, GuardTy, GuardAlign);
2677e5dd7070Spatrick 
2678e5dd7070Spatrick   assert(GuardVar->getLinkage() == GV->getLinkage() &&
2679e5dd7070Spatrick          "static local from the same function had different linkage");
2680e5dd7070Spatrick 
2681e5dd7070Spatrick   if (!HasPerVariableGuard) {
2682e5dd7070Spatrick     // Pseudo code for the test:
2683e5dd7070Spatrick     // if (!(GuardVar & MyGuardBit)) {
2684e5dd7070Spatrick     //   GuardVar |= MyGuardBit;
2685e5dd7070Spatrick     //   ... initialize the object ...;
2686e5dd7070Spatrick     // }
2687e5dd7070Spatrick 
2688e5dd7070Spatrick     // Test our bit from the guard variable.
2689e5dd7070Spatrick     llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2690e5dd7070Spatrick     llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2691e5dd7070Spatrick     llvm::Value *NeedsInit =
2692e5dd7070Spatrick         Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
2693e5dd7070Spatrick     llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
2694e5dd7070Spatrick     llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
2695e5dd7070Spatrick     CGF.EmitCXXGuardedInitBranch(NeedsInit, InitBlock, EndBlock,
2696e5dd7070Spatrick                                  CodeGenFunction::GuardKind::VariableGuard, &D);
2697e5dd7070Spatrick 
2698e5dd7070Spatrick     // Set our bit in the guard variable and emit the initializer and add a global
2699e5dd7070Spatrick     // destructor if appropriate.
2700e5dd7070Spatrick     CGF.EmitBlock(InitBlock);
2701e5dd7070Spatrick     Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2702e5dd7070Spatrick     CGF.EHStack.pushCleanup<ResetGuardBit>(EHCleanup, GuardAddr, GuardNum);
2703e5dd7070Spatrick     CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
2704e5dd7070Spatrick     CGF.PopCleanupBlock();
2705e5dd7070Spatrick     Builder.CreateBr(EndBlock);
2706e5dd7070Spatrick 
2707e5dd7070Spatrick     // Continue.
2708e5dd7070Spatrick     CGF.EmitBlock(EndBlock);
2709e5dd7070Spatrick   } else {
2710e5dd7070Spatrick     // Pseudo code for the test:
2711e5dd7070Spatrick     // if (TSS > _Init_thread_epoch) {
2712e5dd7070Spatrick     //   _Init_thread_header(&TSS);
2713e5dd7070Spatrick     //   if (TSS == -1) {
2714e5dd7070Spatrick     //     ... initialize the object ...;
2715e5dd7070Spatrick     //     _Init_thread_footer(&TSS);
2716e5dd7070Spatrick     //   }
2717e5dd7070Spatrick     // }
2718e5dd7070Spatrick     //
2719e5dd7070Spatrick     // The algorithm is almost identical to what can be found in the appendix
2720e5dd7070Spatrick     // found in N2325.
2721e5dd7070Spatrick 
2722e5dd7070Spatrick     // This BasicBLock determines whether or not we have any work to do.
2723e5dd7070Spatrick     llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2724e5dd7070Spatrick     FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2725e5dd7070Spatrick     llvm::LoadInst *InitThreadEpoch =
2726e5dd7070Spatrick         Builder.CreateLoad(getInitThreadEpochPtr(CGM));
2727e5dd7070Spatrick     llvm::Value *IsUninitialized =
2728e5dd7070Spatrick         Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2729e5dd7070Spatrick     llvm::BasicBlock *AttemptInitBlock = CGF.createBasicBlock("init.attempt");
2730e5dd7070Spatrick     llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
2731e5dd7070Spatrick     CGF.EmitCXXGuardedInitBranch(IsUninitialized, AttemptInitBlock, EndBlock,
2732e5dd7070Spatrick                                  CodeGenFunction::GuardKind::VariableGuard, &D);
2733e5dd7070Spatrick 
2734e5dd7070Spatrick     // This BasicBlock attempts to determine whether or not this thread is
2735e5dd7070Spatrick     // responsible for doing the initialization.
2736e5dd7070Spatrick     CGF.EmitBlock(AttemptInitBlock);
2737e5dd7070Spatrick     CGF.EmitNounwindRuntimeCall(getInitThreadHeaderFn(CGM),
2738e5dd7070Spatrick                                 GuardAddr.getPointer());
2739e5dd7070Spatrick     llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2740e5dd7070Spatrick     SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2741e5dd7070Spatrick     llvm::Value *ShouldDoInit =
2742e5dd7070Spatrick         Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2743e5dd7070Spatrick     llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
2744e5dd7070Spatrick     Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2745e5dd7070Spatrick 
2746e5dd7070Spatrick     // Ok, we ended up getting selected as the initializing thread.
2747e5dd7070Spatrick     CGF.EmitBlock(InitBlock);
2748e5dd7070Spatrick     CGF.EHStack.pushCleanup<CallInitThreadAbort>(EHCleanup, GuardAddr);
2749e5dd7070Spatrick     CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
2750e5dd7070Spatrick     CGF.PopCleanupBlock();
2751e5dd7070Spatrick     CGF.EmitNounwindRuntimeCall(getInitThreadFooterFn(CGM),
2752e5dd7070Spatrick                                 GuardAddr.getPointer());
2753e5dd7070Spatrick     Builder.CreateBr(EndBlock);
2754e5dd7070Spatrick 
2755e5dd7070Spatrick     CGF.EmitBlock(EndBlock);
2756e5dd7070Spatrick   }
2757e5dd7070Spatrick }
2758e5dd7070Spatrick 
isZeroInitializable(const MemberPointerType * MPT)2759e5dd7070Spatrick bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
2760e5dd7070Spatrick   // Null-ness for function memptrs only depends on the first field, which is
2761e5dd7070Spatrick   // the function pointer.  The rest don't matter, so we can zero initialize.
2762e5dd7070Spatrick   if (MPT->isMemberFunctionPointer())
2763e5dd7070Spatrick     return true;
2764e5dd7070Spatrick 
2765e5dd7070Spatrick   // The virtual base adjustment field is always -1 for null, so if we have one
2766e5dd7070Spatrick   // we can't zero initialize.  The field offset is sometimes also -1 if 0 is a
2767e5dd7070Spatrick   // valid field offset.
2768e5dd7070Spatrick   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
2769e5dd7070Spatrick   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2770e5dd7070Spatrick   return (!inheritanceModelHasVBTableOffsetField(Inheritance) &&
2771e5dd7070Spatrick           RD->nullFieldOffsetIsZero());
2772e5dd7070Spatrick }
2773e5dd7070Spatrick 
2774e5dd7070Spatrick llvm::Type *
ConvertMemberPointerType(const MemberPointerType * MPT)2775e5dd7070Spatrick MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
2776e5dd7070Spatrick   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
2777e5dd7070Spatrick   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2778e5dd7070Spatrick   llvm::SmallVector<llvm::Type *, 4> fields;
2779e5dd7070Spatrick   if (MPT->isMemberFunctionPointer())
2780e5dd7070Spatrick     fields.push_back(CGM.VoidPtrTy);  // FunctionPointerOrVirtualThunk
2781e5dd7070Spatrick   else
2782e5dd7070Spatrick     fields.push_back(CGM.IntTy);  // FieldOffset
2783e5dd7070Spatrick 
2784e5dd7070Spatrick   if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
2785e5dd7070Spatrick                                        Inheritance))
2786e5dd7070Spatrick     fields.push_back(CGM.IntTy);
2787e5dd7070Spatrick   if (inheritanceModelHasVBPtrOffsetField(Inheritance))
2788e5dd7070Spatrick     fields.push_back(CGM.IntTy);
2789e5dd7070Spatrick   if (inheritanceModelHasVBTableOffsetField(Inheritance))
2790e5dd7070Spatrick     fields.push_back(CGM.IntTy);  // VirtualBaseAdjustmentOffset
2791e5dd7070Spatrick 
2792e5dd7070Spatrick   if (fields.size() == 1)
2793e5dd7070Spatrick     return fields[0];
2794e5dd7070Spatrick   return llvm::StructType::get(CGM.getLLVMContext(), fields);
2795e5dd7070Spatrick }
2796e5dd7070Spatrick 
2797e5dd7070Spatrick void MicrosoftCXXABI::
GetNullMemberPointerFields(const MemberPointerType * MPT,llvm::SmallVectorImpl<llvm::Constant * > & fields)2798e5dd7070Spatrick GetNullMemberPointerFields(const MemberPointerType *MPT,
2799e5dd7070Spatrick                            llvm::SmallVectorImpl<llvm::Constant *> &fields) {
2800e5dd7070Spatrick   assert(fields.empty());
2801e5dd7070Spatrick   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
2802e5dd7070Spatrick   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2803e5dd7070Spatrick   if (MPT->isMemberFunctionPointer()) {
2804e5dd7070Spatrick     // FunctionPointerOrVirtualThunk
2805e5dd7070Spatrick     fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
2806e5dd7070Spatrick   } else {
2807e5dd7070Spatrick     if (RD->nullFieldOffsetIsZero())
2808e5dd7070Spatrick       fields.push_back(getZeroInt());  // FieldOffset
2809e5dd7070Spatrick     else
2810e5dd7070Spatrick       fields.push_back(getAllOnesInt());  // FieldOffset
2811e5dd7070Spatrick   }
2812e5dd7070Spatrick 
2813e5dd7070Spatrick   if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(),
2814e5dd7070Spatrick                                        Inheritance))
2815e5dd7070Spatrick     fields.push_back(getZeroInt());
2816e5dd7070Spatrick   if (inheritanceModelHasVBPtrOffsetField(Inheritance))
2817e5dd7070Spatrick     fields.push_back(getZeroInt());
2818e5dd7070Spatrick   if (inheritanceModelHasVBTableOffsetField(Inheritance))
2819e5dd7070Spatrick     fields.push_back(getAllOnesInt());
2820e5dd7070Spatrick }
2821e5dd7070Spatrick 
2822e5dd7070Spatrick llvm::Constant *
EmitNullMemberPointer(const MemberPointerType * MPT)2823e5dd7070Spatrick MicrosoftCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
2824e5dd7070Spatrick   llvm::SmallVector<llvm::Constant *, 4> fields;
2825e5dd7070Spatrick   GetNullMemberPointerFields(MPT, fields);
2826e5dd7070Spatrick   if (fields.size() == 1)
2827e5dd7070Spatrick     return fields[0];
2828e5dd7070Spatrick   llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2829e5dd7070Spatrick   assert(Res->getType() == ConvertMemberPointerType(MPT));
2830e5dd7070Spatrick   return Res;
2831e5dd7070Spatrick }
2832e5dd7070Spatrick 
2833e5dd7070Spatrick llvm::Constant *
EmitFullMemberPointer(llvm::Constant * FirstField,bool IsMemberFunction,const CXXRecordDecl * RD,CharUnits NonVirtualBaseAdjustment,unsigned VBTableIndex)2834e5dd7070Spatrick MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2835e5dd7070Spatrick                                        bool IsMemberFunction,
2836e5dd7070Spatrick                                        const CXXRecordDecl *RD,
2837e5dd7070Spatrick                                        CharUnits NonVirtualBaseAdjustment,
2838e5dd7070Spatrick                                        unsigned VBTableIndex) {
2839e5dd7070Spatrick   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
2840e5dd7070Spatrick 
2841e5dd7070Spatrick   // Single inheritance class member pointer are represented as scalars instead
2842e5dd7070Spatrick   // of aggregates.
2843e5dd7070Spatrick   if (inheritanceModelHasOnlyOneField(IsMemberFunction, Inheritance))
2844e5dd7070Spatrick     return FirstField;
2845e5dd7070Spatrick 
2846e5dd7070Spatrick   llvm::SmallVector<llvm::Constant *, 4> fields;
2847e5dd7070Spatrick   fields.push_back(FirstField);
2848e5dd7070Spatrick 
2849e5dd7070Spatrick   if (inheritanceModelHasNVOffsetField(IsMemberFunction, Inheritance))
2850e5dd7070Spatrick     fields.push_back(llvm::ConstantInt::get(
2851e5dd7070Spatrick       CGM.IntTy, NonVirtualBaseAdjustment.getQuantity()));
2852e5dd7070Spatrick 
2853e5dd7070Spatrick   if (inheritanceModelHasVBPtrOffsetField(Inheritance)) {
2854e5dd7070Spatrick     CharUnits Offs = CharUnits::Zero();
2855e5dd7070Spatrick     if (VBTableIndex)
2856e5dd7070Spatrick       Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2857e5dd7070Spatrick     fields.push_back(llvm::ConstantInt::get(CGM.IntTy, Offs.getQuantity()));
2858e5dd7070Spatrick   }
2859e5dd7070Spatrick 
2860e5dd7070Spatrick   // The rest of the fields are adjusted by conversions to a more derived class.
2861e5dd7070Spatrick   if (inheritanceModelHasVBTableOffsetField(Inheritance))
2862e5dd7070Spatrick     fields.push_back(llvm::ConstantInt::get(CGM.IntTy, VBTableIndex));
2863e5dd7070Spatrick 
2864e5dd7070Spatrick   return llvm::ConstantStruct::getAnon(fields);
2865e5dd7070Spatrick }
2866e5dd7070Spatrick 
2867e5dd7070Spatrick llvm::Constant *
EmitMemberDataPointer(const MemberPointerType * MPT,CharUnits offset)2868e5dd7070Spatrick MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
2869e5dd7070Spatrick                                        CharUnits offset) {
2870e5dd7070Spatrick   return EmitMemberDataPointer(MPT->getMostRecentCXXRecordDecl(), offset);
2871e5dd7070Spatrick }
2872e5dd7070Spatrick 
EmitMemberDataPointer(const CXXRecordDecl * RD,CharUnits offset)2873e5dd7070Spatrick llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(const CXXRecordDecl *RD,
2874e5dd7070Spatrick                                                        CharUnits offset) {
2875e5dd7070Spatrick   if (RD->getMSInheritanceModel() ==
2876e5dd7070Spatrick       MSInheritanceModel::Virtual)
2877e5dd7070Spatrick     offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2878e5dd7070Spatrick   llvm::Constant *FirstField =
2879e5dd7070Spatrick     llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity());
2880e5dd7070Spatrick   return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD,
2881e5dd7070Spatrick                                CharUnits::Zero(), /*VBTableIndex=*/0);
2882e5dd7070Spatrick }
2883e5dd7070Spatrick 
EmitMemberPointer(const APValue & MP,QualType MPType)2884e5dd7070Spatrick llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP,
2885e5dd7070Spatrick                                                    QualType MPType) {
2886e5dd7070Spatrick   const MemberPointerType *DstTy = MPType->castAs<MemberPointerType>();
2887e5dd7070Spatrick   const ValueDecl *MPD = MP.getMemberPointerDecl();
2888e5dd7070Spatrick   if (!MPD)
2889e5dd7070Spatrick     return EmitNullMemberPointer(DstTy);
2890e5dd7070Spatrick 
2891e5dd7070Spatrick   ASTContext &Ctx = getContext();
2892e5dd7070Spatrick   ArrayRef<const CXXRecordDecl *> MemberPointerPath = MP.getMemberPointerPath();
2893e5dd7070Spatrick 
2894e5dd7070Spatrick   llvm::Constant *C;
2895e5dd7070Spatrick   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2896e5dd7070Spatrick     C = EmitMemberFunctionPointer(MD);
2897e5dd7070Spatrick   } else {
2898e5dd7070Spatrick     // For a pointer to data member, start off with the offset of the field in
2899e5dd7070Spatrick     // the class in which it was declared, and convert from there if necessary.
2900e5dd7070Spatrick     // For indirect field decls, get the outermost anonymous field and use the
2901e5dd7070Spatrick     // parent class.
2902e5dd7070Spatrick     CharUnits FieldOffset = Ctx.toCharUnitsFromBits(Ctx.getFieldOffset(MPD));
2903e5dd7070Spatrick     const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2904e5dd7070Spatrick     if (!FD)
2905e5dd7070Spatrick       FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
2906e5dd7070Spatrick     const CXXRecordDecl *RD = cast<CXXRecordDecl>(FD->getParent());
2907e5dd7070Spatrick     RD = RD->getMostRecentNonInjectedDecl();
2908e5dd7070Spatrick     C = EmitMemberDataPointer(RD, FieldOffset);
2909e5dd7070Spatrick   }
2910e5dd7070Spatrick 
2911e5dd7070Spatrick   if (!MemberPointerPath.empty()) {
2912e5dd7070Spatrick     const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2913e5dd7070Spatrick     const Type *SrcRecTy = Ctx.getTypeDeclType(SrcRD).getTypePtr();
2914e5dd7070Spatrick     const MemberPointerType *SrcTy =
2915e5dd7070Spatrick         Ctx.getMemberPointerType(DstTy->getPointeeType(), SrcRecTy)
2916e5dd7070Spatrick             ->castAs<MemberPointerType>();
2917e5dd7070Spatrick 
2918e5dd7070Spatrick     bool DerivedMember = MP.isMemberPointerToDerivedMember();
2919e5dd7070Spatrick     SmallVector<const CXXBaseSpecifier *, 4> DerivedToBasePath;
2920e5dd7070Spatrick     const CXXRecordDecl *PrevRD = SrcRD;
2921e5dd7070Spatrick     for (const CXXRecordDecl *PathElem : MemberPointerPath) {
2922e5dd7070Spatrick       const CXXRecordDecl *Base = nullptr;
2923e5dd7070Spatrick       const CXXRecordDecl *Derived = nullptr;
2924e5dd7070Spatrick       if (DerivedMember) {
2925e5dd7070Spatrick         Base = PathElem;
2926e5dd7070Spatrick         Derived = PrevRD;
2927e5dd7070Spatrick       } else {
2928e5dd7070Spatrick         Base = PrevRD;
2929e5dd7070Spatrick         Derived = PathElem;
2930e5dd7070Spatrick       }
2931e5dd7070Spatrick       for (const CXXBaseSpecifier &BS : Derived->bases())
2932e5dd7070Spatrick         if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2933e5dd7070Spatrick             Base->getCanonicalDecl())
2934e5dd7070Spatrick           DerivedToBasePath.push_back(&BS);
2935e5dd7070Spatrick       PrevRD = PathElem;
2936e5dd7070Spatrick     }
2937e5dd7070Spatrick     assert(DerivedToBasePath.size() == MemberPointerPath.size());
2938e5dd7070Spatrick 
2939e5dd7070Spatrick     CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2940e5dd7070Spatrick                                 : CK_BaseToDerivedMemberPointer;
2941e5dd7070Spatrick     C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2942e5dd7070Spatrick                                     DerivedToBasePath.end(), C);
2943e5dd7070Spatrick   }
2944e5dd7070Spatrick   return C;
2945e5dd7070Spatrick }
2946e5dd7070Spatrick 
2947e5dd7070Spatrick llvm::Constant *
EmitMemberFunctionPointer(const CXXMethodDecl * MD)2948e5dd7070Spatrick MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
2949e5dd7070Spatrick   assert(MD->isInstance() && "Member function must not be static!");
2950e5dd7070Spatrick 
2951e5dd7070Spatrick   CharUnits NonVirtualBaseAdjustment = CharUnits::Zero();
2952e5dd7070Spatrick   const CXXRecordDecl *RD = MD->getParent()->getMostRecentNonInjectedDecl();
2953e5dd7070Spatrick   CodeGenTypes &Types = CGM.getTypes();
2954e5dd7070Spatrick 
2955e5dd7070Spatrick   unsigned VBTableIndex = 0;
2956e5dd7070Spatrick   llvm::Constant *FirstField;
2957e5dd7070Spatrick   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
2958e5dd7070Spatrick   if (!MD->isVirtual()) {
2959e5dd7070Spatrick     llvm::Type *Ty;
2960e5dd7070Spatrick     // Check whether the function has a computable LLVM signature.
2961e5dd7070Spatrick     if (Types.isFuncTypeConvertible(FPT)) {
2962e5dd7070Spatrick       // The function has a computable LLVM signature; use the correct type.
2963e5dd7070Spatrick       Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
2964e5dd7070Spatrick     } else {
2965e5dd7070Spatrick       // Use an arbitrary non-function type to tell GetAddrOfFunction that the
2966e5dd7070Spatrick       // function type is incomplete.
2967e5dd7070Spatrick       Ty = CGM.PtrDiffTy;
2968e5dd7070Spatrick     }
2969e5dd7070Spatrick     FirstField = CGM.GetAddrOfFunction(MD, Ty);
2970e5dd7070Spatrick   } else {
2971e5dd7070Spatrick     auto &VTableContext = CGM.getMicrosoftVTableContext();
2972e5dd7070Spatrick     MethodVFTableLocation ML = VTableContext.getMethodVFTableLocation(MD);
2973e5dd7070Spatrick     FirstField = EmitVirtualMemPtrThunk(MD, ML);
2974e5dd7070Spatrick     // Include the vfptr adjustment if the method is in a non-primary vftable.
2975e5dd7070Spatrick     NonVirtualBaseAdjustment += ML.VFPtrOffset;
2976e5dd7070Spatrick     if (ML.VBase)
2977e5dd7070Spatrick       VBTableIndex = VTableContext.getVBTableIndex(RD, ML.VBase) * 4;
2978e5dd7070Spatrick   }
2979e5dd7070Spatrick 
2980e5dd7070Spatrick   if (VBTableIndex == 0 &&
2981e5dd7070Spatrick       RD->getMSInheritanceModel() ==
2982e5dd7070Spatrick           MSInheritanceModel::Virtual)
2983e5dd7070Spatrick     NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2984e5dd7070Spatrick 
2985e5dd7070Spatrick   // The rest of the fields are common with data member pointers.
2986e5dd7070Spatrick   FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.VoidPtrTy);
2987e5dd7070Spatrick   return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/true, RD,
2988e5dd7070Spatrick                                NonVirtualBaseAdjustment, VBTableIndex);
2989e5dd7070Spatrick }
2990e5dd7070Spatrick 
2991e5dd7070Spatrick /// Member pointers are the same if they're either bitwise identical *or* both
2992e5dd7070Spatrick /// null.  Null-ness for function members is determined by the first field,
2993e5dd7070Spatrick /// while for data member pointers we must compare all fields.
2994e5dd7070Spatrick llvm::Value *
EmitMemberPointerComparison(CodeGenFunction & CGF,llvm::Value * L,llvm::Value * R,const MemberPointerType * MPT,bool Inequality)2995e5dd7070Spatrick MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
2996e5dd7070Spatrick                                              llvm::Value *L,
2997e5dd7070Spatrick                                              llvm::Value *R,
2998e5dd7070Spatrick                                              const MemberPointerType *MPT,
2999e5dd7070Spatrick                                              bool Inequality) {
3000e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
3001e5dd7070Spatrick 
3002e5dd7070Spatrick   // Handle != comparisons by switching the sense of all boolean operations.
3003e5dd7070Spatrick   llvm::ICmpInst::Predicate Eq;
3004e5dd7070Spatrick   llvm::Instruction::BinaryOps And, Or;
3005e5dd7070Spatrick   if (Inequality) {
3006e5dd7070Spatrick     Eq = llvm::ICmpInst::ICMP_NE;
3007e5dd7070Spatrick     And = llvm::Instruction::Or;
3008e5dd7070Spatrick     Or = llvm::Instruction::And;
3009e5dd7070Spatrick   } else {
3010e5dd7070Spatrick     Eq = llvm::ICmpInst::ICMP_EQ;
3011e5dd7070Spatrick     And = llvm::Instruction::And;
3012e5dd7070Spatrick     Or = llvm::Instruction::Or;
3013e5dd7070Spatrick   }
3014e5dd7070Spatrick 
3015e5dd7070Spatrick   // If this is a single field member pointer (single inheritance), this is a
3016e5dd7070Spatrick   // single icmp.
3017e5dd7070Spatrick   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
3018e5dd7070Spatrick   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
3019e5dd7070Spatrick   if (inheritanceModelHasOnlyOneField(MPT->isMemberFunctionPointer(),
3020e5dd7070Spatrick                                       Inheritance))
3021e5dd7070Spatrick     return Builder.CreateICmp(Eq, L, R);
3022e5dd7070Spatrick 
3023e5dd7070Spatrick   // Compare the first field.
3024e5dd7070Spatrick   llvm::Value *L0 = Builder.CreateExtractValue(L, 0, "lhs.0");
3025e5dd7070Spatrick   llvm::Value *R0 = Builder.CreateExtractValue(R, 0, "rhs.0");
3026e5dd7070Spatrick   llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0, "memptr.cmp.first");
3027e5dd7070Spatrick 
3028e5dd7070Spatrick   // Compare everything other than the first field.
3029e5dd7070Spatrick   llvm::Value *Res = nullptr;
3030e5dd7070Spatrick   llvm::StructType *LType = cast<llvm::StructType>(L->getType());
3031e5dd7070Spatrick   for (unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3032e5dd7070Spatrick     llvm::Value *LF = Builder.CreateExtractValue(L, I);
3033e5dd7070Spatrick     llvm::Value *RF = Builder.CreateExtractValue(R, I);
3034e5dd7070Spatrick     llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF, "memptr.cmp.rest");
3035e5dd7070Spatrick     if (Res)
3036e5dd7070Spatrick       Res = Builder.CreateBinOp(And, Res, Cmp);
3037e5dd7070Spatrick     else
3038e5dd7070Spatrick       Res = Cmp;
3039e5dd7070Spatrick   }
3040e5dd7070Spatrick 
3041e5dd7070Spatrick   // Check if the first field is 0 if this is a function pointer.
3042e5dd7070Spatrick   if (MPT->isMemberFunctionPointer()) {
3043e5dd7070Spatrick     // (l1 == r1 && ...) || l0 == 0
3044e5dd7070Spatrick     llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
3045e5dd7070Spatrick     llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero, "memptr.cmp.iszero");
3046e5dd7070Spatrick     Res = Builder.CreateBinOp(Or, Res, IsZero);
3047e5dd7070Spatrick   }
3048e5dd7070Spatrick 
3049e5dd7070Spatrick   // Combine the comparison of the first field, which must always be true for
3050e5dd7070Spatrick   // this comparison to succeeed.
3051e5dd7070Spatrick   return Builder.CreateBinOp(And, Res, Cmp0, "memptr.cmp");
3052e5dd7070Spatrick }
3053e5dd7070Spatrick 
3054e5dd7070Spatrick llvm::Value *
EmitMemberPointerIsNotNull(CodeGenFunction & CGF,llvm::Value * MemPtr,const MemberPointerType * MPT)3055e5dd7070Spatrick MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
3056e5dd7070Spatrick                                             llvm::Value *MemPtr,
3057e5dd7070Spatrick                                             const MemberPointerType *MPT) {
3058e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
3059e5dd7070Spatrick   llvm::SmallVector<llvm::Constant *, 4> fields;
3060e5dd7070Spatrick   // We only need one field for member functions.
3061e5dd7070Spatrick   if (MPT->isMemberFunctionPointer())
3062e5dd7070Spatrick     fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
3063e5dd7070Spatrick   else
3064e5dd7070Spatrick     GetNullMemberPointerFields(MPT, fields);
3065e5dd7070Spatrick   assert(!fields.empty());
3066e5dd7070Spatrick   llvm::Value *FirstField = MemPtr;
3067e5dd7070Spatrick   if (MemPtr->getType()->isStructTy())
3068e5dd7070Spatrick     FirstField = Builder.CreateExtractValue(MemPtr, 0);
3069e5dd7070Spatrick   llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0], "memptr.cmp0");
3070e5dd7070Spatrick 
3071e5dd7070Spatrick   // For function member pointers, we only need to test the function pointer
3072e5dd7070Spatrick   // field.  The other fields if any can be garbage.
3073e5dd7070Spatrick   if (MPT->isMemberFunctionPointer())
3074e5dd7070Spatrick     return Res;
3075e5dd7070Spatrick 
3076e5dd7070Spatrick   // Otherwise, emit a series of compares and combine the results.
3077e5dd7070Spatrick   for (int I = 1, E = fields.size(); I < E; ++I) {
3078e5dd7070Spatrick     llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
3079e5dd7070Spatrick     llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I], "memptr.cmp");
3080e5dd7070Spatrick     Res = Builder.CreateOr(Res, Next, "memptr.tobool");
3081e5dd7070Spatrick   }
3082e5dd7070Spatrick   return Res;
3083e5dd7070Spatrick }
3084e5dd7070Spatrick 
MemberPointerConstantIsNull(const MemberPointerType * MPT,llvm::Constant * Val)3085e5dd7070Spatrick bool MicrosoftCXXABI::MemberPointerConstantIsNull(const MemberPointerType *MPT,
3086e5dd7070Spatrick                                                   llvm::Constant *Val) {
3087e5dd7070Spatrick   // Function pointers are null if the pointer in the first field is null.
3088e5dd7070Spatrick   if (MPT->isMemberFunctionPointer()) {
3089e5dd7070Spatrick     llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3090e5dd7070Spatrick       Val->getAggregateElement(0U) : Val;
3091e5dd7070Spatrick     return FirstField->isNullValue();
3092e5dd7070Spatrick   }
3093e5dd7070Spatrick 
3094e5dd7070Spatrick   // If it's not a function pointer and it's zero initializable, we can easily
3095e5dd7070Spatrick   // check zero.
3096e5dd7070Spatrick   if (isZeroInitializable(MPT) && Val->isNullValue())
3097e5dd7070Spatrick     return true;
3098e5dd7070Spatrick 
3099e5dd7070Spatrick   // Otherwise, break down all the fields for comparison.  Hopefully these
3100e5dd7070Spatrick   // little Constants are reused, while a big null struct might not be.
3101e5dd7070Spatrick   llvm::SmallVector<llvm::Constant *, 4> Fields;
3102e5dd7070Spatrick   GetNullMemberPointerFields(MPT, Fields);
3103e5dd7070Spatrick   if (Fields.size() == 1) {
3104e5dd7070Spatrick     assert(Val->getType()->isIntegerTy());
3105e5dd7070Spatrick     return Val == Fields[0];
3106e5dd7070Spatrick   }
3107e5dd7070Spatrick 
3108e5dd7070Spatrick   unsigned I, E;
3109e5dd7070Spatrick   for (I = 0, E = Fields.size(); I != E; ++I) {
3110e5dd7070Spatrick     if (Val->getAggregateElement(I) != Fields[I])
3111e5dd7070Spatrick       break;
3112e5dd7070Spatrick   }
3113e5dd7070Spatrick   return I == E;
3114e5dd7070Spatrick }
3115e5dd7070Spatrick 
3116e5dd7070Spatrick llvm::Value *
GetVBaseOffsetFromVBPtr(CodeGenFunction & CGF,Address This,llvm::Value * VBPtrOffset,llvm::Value * VBTableOffset,llvm::Value ** VBPtrOut)3117e5dd7070Spatrick MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
3118e5dd7070Spatrick                                          Address This,
3119e5dd7070Spatrick                                          llvm::Value *VBPtrOffset,
3120e5dd7070Spatrick                                          llvm::Value *VBTableOffset,
3121e5dd7070Spatrick                                          llvm::Value **VBPtrOut) {
3122e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
3123e5dd7070Spatrick   // Load the vbtable pointer from the vbptr in the instance.
3124e5dd7070Spatrick   This = Builder.CreateElementBitCast(This, CGM.Int8Ty);
3125a9ac8606Spatrick   llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3126a9ac8606Spatrick       This.getElementType(), This.getPointer(), VBPtrOffset, "vbptr");
3127e5dd7070Spatrick   if (VBPtrOut) *VBPtrOut = VBPtr;
3128e5dd7070Spatrick   VBPtr = Builder.CreateBitCast(VBPtr,
3129e5dd7070Spatrick             CGM.Int32Ty->getPointerTo(0)->getPointerTo(This.getAddressSpace()));
3130e5dd7070Spatrick 
3131e5dd7070Spatrick   CharUnits VBPtrAlign;
3132e5dd7070Spatrick   if (auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3133e5dd7070Spatrick     VBPtrAlign = This.getAlignment().alignmentAtOffset(
3134e5dd7070Spatrick                                    CharUnits::fromQuantity(CI->getSExtValue()));
3135e5dd7070Spatrick   } else {
3136e5dd7070Spatrick     VBPtrAlign = CGF.getPointerAlign();
3137e5dd7070Spatrick   }
3138e5dd7070Spatrick 
3139a9ac8606Spatrick   llvm::Value *VBTable = Builder.CreateAlignedLoad(
3140a9ac8606Spatrick       CGM.Int32Ty->getPointerTo(0), VBPtr, VBPtrAlign, "vbtable");
3141e5dd7070Spatrick 
3142e5dd7070Spatrick   // Translate from byte offset to table index. It improves analyzability.
3143e5dd7070Spatrick   llvm::Value *VBTableIndex = Builder.CreateAShr(
3144e5dd7070Spatrick       VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3145e5dd7070Spatrick       "vbtindex", /*isExact=*/true);
3146e5dd7070Spatrick 
3147e5dd7070Spatrick   // Load an i32 offset from the vb-table.
3148a9ac8606Spatrick   llvm::Value *VBaseOffs =
3149a9ac8606Spatrick       Builder.CreateInBoundsGEP(CGM.Int32Ty, VBTable, VBTableIndex);
3150e5dd7070Spatrick   VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.Int32Ty->getPointerTo(0));
3151a9ac8606Spatrick   return Builder.CreateAlignedLoad(CGM.Int32Ty, VBaseOffs,
3152a9ac8606Spatrick                                    CharUnits::fromQuantity(4), "vbase_offs");
3153e5dd7070Spatrick }
3154e5dd7070Spatrick 
3155e5dd7070Spatrick // Returns an adjusted base cast to i8*, since we do more address arithmetic on
3156e5dd7070Spatrick // it.
AdjustVirtualBase(CodeGenFunction & CGF,const Expr * E,const CXXRecordDecl * RD,Address Base,llvm::Value * VBTableOffset,llvm::Value * VBPtrOffset)3157e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3158e5dd7070Spatrick     CodeGenFunction &CGF, const Expr *E, const CXXRecordDecl *RD,
3159e5dd7070Spatrick     Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3160e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
3161e5dd7070Spatrick   Base = Builder.CreateElementBitCast(Base, CGM.Int8Ty);
3162e5dd7070Spatrick   llvm::BasicBlock *OriginalBB = nullptr;
3163e5dd7070Spatrick   llvm::BasicBlock *SkipAdjustBB = nullptr;
3164e5dd7070Spatrick   llvm::BasicBlock *VBaseAdjustBB = nullptr;
3165e5dd7070Spatrick 
3166e5dd7070Spatrick   // In the unspecified inheritance model, there might not be a vbtable at all,
3167e5dd7070Spatrick   // in which case we need to skip the virtual base lookup.  If there is a
3168e5dd7070Spatrick   // vbtable, the first entry is a no-op entry that gives back the original
3169e5dd7070Spatrick   // base, so look for a virtual base adjustment offset of zero.
3170e5dd7070Spatrick   if (VBPtrOffset) {
3171e5dd7070Spatrick     OriginalBB = Builder.GetInsertBlock();
3172e5dd7070Spatrick     VBaseAdjustBB = CGF.createBasicBlock("memptr.vadjust");
3173e5dd7070Spatrick     SkipAdjustBB = CGF.createBasicBlock("memptr.skip_vadjust");
3174e5dd7070Spatrick     llvm::Value *IsVirtual =
3175e5dd7070Spatrick       Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3176e5dd7070Spatrick                            "memptr.is_vbase");
3177e5dd7070Spatrick     Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3178e5dd7070Spatrick     CGF.EmitBlock(VBaseAdjustBB);
3179e5dd7070Spatrick   }
3180e5dd7070Spatrick 
3181e5dd7070Spatrick   // If we weren't given a dynamic vbptr offset, RD should be complete and we'll
3182e5dd7070Spatrick   // know the vbptr offset.
3183e5dd7070Spatrick   if (!VBPtrOffset) {
3184e5dd7070Spatrick     CharUnits offs = CharUnits::Zero();
3185e5dd7070Spatrick     if (!RD->hasDefinition()) {
3186e5dd7070Spatrick       DiagnosticsEngine &Diags = CGF.CGM.getDiags();
3187e5dd7070Spatrick       unsigned DiagID = Diags.getCustomDiagID(
3188e5dd7070Spatrick           DiagnosticsEngine::Error,
3189e5dd7070Spatrick           "member pointer representation requires a "
3190e5dd7070Spatrick           "complete class type for %0 to perform this expression");
3191e5dd7070Spatrick       Diags.Report(E->getExprLoc(), DiagID) << RD << E->getSourceRange();
3192e5dd7070Spatrick     } else if (RD->getNumVBases())
3193e5dd7070Spatrick       offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3194e5dd7070Spatrick     VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity());
3195e5dd7070Spatrick   }
3196e5dd7070Spatrick   llvm::Value *VBPtr = nullptr;
3197e5dd7070Spatrick   llvm::Value *VBaseOffs =
3198e5dd7070Spatrick     GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
3199a9ac8606Spatrick   llvm::Value *AdjustedBase =
3200a9ac8606Spatrick     Builder.CreateInBoundsGEP(CGM.Int8Ty, VBPtr, VBaseOffs);
3201e5dd7070Spatrick 
3202e5dd7070Spatrick   // Merge control flow with the case where we didn't have to adjust.
3203e5dd7070Spatrick   if (VBaseAdjustBB) {
3204e5dd7070Spatrick     Builder.CreateBr(SkipAdjustBB);
3205e5dd7070Spatrick     CGF.EmitBlock(SkipAdjustBB);
3206e5dd7070Spatrick     llvm::PHINode *Phi = Builder.CreatePHI(CGM.Int8PtrTy, 2, "memptr.base");
3207e5dd7070Spatrick     Phi->addIncoming(Base.getPointer(), OriginalBB);
3208e5dd7070Spatrick     Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3209e5dd7070Spatrick     return Phi;
3210e5dd7070Spatrick   }
3211e5dd7070Spatrick   return AdjustedBase;
3212e5dd7070Spatrick }
3213e5dd7070Spatrick 
EmitMemberDataPointerAddress(CodeGenFunction & CGF,const Expr * E,Address Base,llvm::Value * MemPtr,const MemberPointerType * MPT)3214e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3215e5dd7070Spatrick     CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr,
3216e5dd7070Spatrick     const MemberPointerType *MPT) {
3217e5dd7070Spatrick   assert(MPT->isMemberDataPointer());
3218e5dd7070Spatrick   unsigned AS = Base.getAddressSpace();
3219e5dd7070Spatrick   llvm::Type *PType =
3220e5dd7070Spatrick       CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
3221e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
3222e5dd7070Spatrick   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
3223e5dd7070Spatrick   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
3224e5dd7070Spatrick 
3225e5dd7070Spatrick   // Extract the fields we need, regardless of model.  We'll apply them if we
3226e5dd7070Spatrick   // have them.
3227e5dd7070Spatrick   llvm::Value *FieldOffset = MemPtr;
3228e5dd7070Spatrick   llvm::Value *VirtualBaseAdjustmentOffset = nullptr;
3229e5dd7070Spatrick   llvm::Value *VBPtrOffset = nullptr;
3230e5dd7070Spatrick   if (MemPtr->getType()->isStructTy()) {
3231e5dd7070Spatrick     // We need to extract values.
3232e5dd7070Spatrick     unsigned I = 0;
3233e5dd7070Spatrick     FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3234e5dd7070Spatrick     if (inheritanceModelHasVBPtrOffsetField(Inheritance))
3235e5dd7070Spatrick       VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3236e5dd7070Spatrick     if (inheritanceModelHasVBTableOffsetField(Inheritance))
3237e5dd7070Spatrick       VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3238e5dd7070Spatrick   }
3239e5dd7070Spatrick 
3240e5dd7070Spatrick   llvm::Value *Addr;
3241e5dd7070Spatrick   if (VirtualBaseAdjustmentOffset) {
3242e5dd7070Spatrick     Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
3243e5dd7070Spatrick                              VBPtrOffset);
3244e5dd7070Spatrick   } else {
3245e5dd7070Spatrick     Addr = Base.getPointer();
3246e5dd7070Spatrick   }
3247e5dd7070Spatrick 
3248e5dd7070Spatrick   // Cast to char*.
3249e5dd7070Spatrick   Addr = Builder.CreateBitCast(Addr, CGF.Int8Ty->getPointerTo(AS));
3250e5dd7070Spatrick 
3251e5dd7070Spatrick   // Apply the offset, which we assume is non-null.
3252a9ac8606Spatrick   Addr = Builder.CreateInBoundsGEP(CGF.Int8Ty, Addr, FieldOffset,
3253a9ac8606Spatrick                                    "memptr.offset");
3254e5dd7070Spatrick 
3255e5dd7070Spatrick   // Cast the address to the appropriate pointer type, adopting the address
3256e5dd7070Spatrick   // space of the base pointer.
3257e5dd7070Spatrick   return Builder.CreateBitCast(Addr, PType);
3258e5dd7070Spatrick }
3259e5dd7070Spatrick 
3260e5dd7070Spatrick llvm::Value *
EmitMemberPointerConversion(CodeGenFunction & CGF,const CastExpr * E,llvm::Value * Src)3261e5dd7070Spatrick MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
3262e5dd7070Spatrick                                              const CastExpr *E,
3263e5dd7070Spatrick                                              llvm::Value *Src) {
3264e5dd7070Spatrick   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
3265e5dd7070Spatrick          E->getCastKind() == CK_BaseToDerivedMemberPointer ||
3266e5dd7070Spatrick          E->getCastKind() == CK_ReinterpretMemberPointer);
3267e5dd7070Spatrick 
3268e5dd7070Spatrick   // Use constant emission if we can.
3269e5dd7070Spatrick   if (isa<llvm::Constant>(Src))
3270e5dd7070Spatrick     return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3271e5dd7070Spatrick 
3272e5dd7070Spatrick   // We may be adding or dropping fields from the member pointer, so we need
3273e5dd7070Spatrick   // both types and the inheritance models of both records.
3274e5dd7070Spatrick   const MemberPointerType *SrcTy =
3275e5dd7070Spatrick     E->getSubExpr()->getType()->castAs<MemberPointerType>();
3276e5dd7070Spatrick   const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>();
3277e5dd7070Spatrick   bool IsFunc = SrcTy->isMemberFunctionPointer();
3278e5dd7070Spatrick 
3279e5dd7070Spatrick   // If the classes use the same null representation, reinterpret_cast is a nop.
3280e5dd7070Spatrick   bool IsReinterpret = E->getCastKind() == CK_ReinterpretMemberPointer;
3281e5dd7070Spatrick   if (IsReinterpret && IsFunc)
3282e5dd7070Spatrick     return Src;
3283e5dd7070Spatrick 
3284e5dd7070Spatrick   CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl();
3285e5dd7070Spatrick   CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
3286e5dd7070Spatrick   if (IsReinterpret &&
3287e5dd7070Spatrick       SrcRD->nullFieldOffsetIsZero() == DstRD->nullFieldOffsetIsZero())
3288e5dd7070Spatrick     return Src;
3289e5dd7070Spatrick 
3290e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
3291e5dd7070Spatrick 
3292e5dd7070Spatrick   // Branch past the conversion if Src is null.
3293e5dd7070Spatrick   llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3294e5dd7070Spatrick   llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3295e5dd7070Spatrick 
3296e5dd7070Spatrick   // C++ 5.2.10p9: The null member pointer value is converted to the null member
3297e5dd7070Spatrick   //   pointer value of the destination type.
3298e5dd7070Spatrick   if (IsReinterpret) {
3299e5dd7070Spatrick     // For reinterpret casts, sema ensures that src and dst are both functions
3300e5dd7070Spatrick     // or data and have the same size, which means the LLVM types should match.
3301e5dd7070Spatrick     assert(Src->getType() == DstNull->getType());
3302e5dd7070Spatrick     return Builder.CreateSelect(IsNotNull, Src, DstNull);
3303e5dd7070Spatrick   }
3304e5dd7070Spatrick 
3305e5dd7070Spatrick   llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3306e5dd7070Spatrick   llvm::BasicBlock *ConvertBB = CGF.createBasicBlock("memptr.convert");
3307e5dd7070Spatrick   llvm::BasicBlock *ContinueBB = CGF.createBasicBlock("memptr.converted");
3308e5dd7070Spatrick   Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3309e5dd7070Spatrick   CGF.EmitBlock(ConvertBB);
3310e5dd7070Spatrick 
3311e5dd7070Spatrick   llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3312e5dd7070Spatrick       SrcTy, DstTy, E->getCastKind(), E->path_begin(), E->path_end(), Src,
3313e5dd7070Spatrick       Builder);
3314e5dd7070Spatrick 
3315e5dd7070Spatrick   Builder.CreateBr(ContinueBB);
3316e5dd7070Spatrick 
3317e5dd7070Spatrick   // In the continuation, choose between DstNull and Dst.
3318e5dd7070Spatrick   CGF.EmitBlock(ContinueBB);
3319e5dd7070Spatrick   llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2, "memptr.converted");
3320e5dd7070Spatrick   Phi->addIncoming(DstNull, OriginalBB);
3321e5dd7070Spatrick   Phi->addIncoming(Dst, ConvertBB);
3322e5dd7070Spatrick   return Phi;
3323e5dd7070Spatrick }
3324e5dd7070Spatrick 
EmitNonNullMemberPointerConversion(const MemberPointerType * SrcTy,const MemberPointerType * DstTy,CastKind CK,CastExpr::path_const_iterator PathBegin,CastExpr::path_const_iterator PathEnd,llvm::Value * Src,CGBuilderTy & Builder)3325e5dd7070Spatrick llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3326e5dd7070Spatrick     const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK,
3327e5dd7070Spatrick     CastExpr::path_const_iterator PathBegin,
3328e5dd7070Spatrick     CastExpr::path_const_iterator PathEnd, llvm::Value *Src,
3329e5dd7070Spatrick     CGBuilderTy &Builder) {
3330e5dd7070Spatrick   const CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl();
3331e5dd7070Spatrick   const CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
3332e5dd7070Spatrick   MSInheritanceModel SrcInheritance = SrcRD->getMSInheritanceModel();
3333e5dd7070Spatrick   MSInheritanceModel DstInheritance = DstRD->getMSInheritanceModel();
3334e5dd7070Spatrick   bool IsFunc = SrcTy->isMemberFunctionPointer();
3335e5dd7070Spatrick   bool IsConstant = isa<llvm::Constant>(Src);
3336e5dd7070Spatrick 
3337e5dd7070Spatrick   // Decompose src.
3338e5dd7070Spatrick   llvm::Value *FirstField = Src;
3339e5dd7070Spatrick   llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3340e5dd7070Spatrick   llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3341e5dd7070Spatrick   llvm::Value *VBPtrOffset = getZeroInt();
3342e5dd7070Spatrick   if (!inheritanceModelHasOnlyOneField(IsFunc, SrcInheritance)) {
3343e5dd7070Spatrick     // We need to extract values.
3344e5dd7070Spatrick     unsigned I = 0;
3345e5dd7070Spatrick     FirstField = Builder.CreateExtractValue(Src, I++);
3346e5dd7070Spatrick     if (inheritanceModelHasNVOffsetField(IsFunc, SrcInheritance))
3347e5dd7070Spatrick       NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3348e5dd7070Spatrick     if (inheritanceModelHasVBPtrOffsetField(SrcInheritance))
3349e5dd7070Spatrick       VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3350e5dd7070Spatrick     if (inheritanceModelHasVBTableOffsetField(SrcInheritance))
3351e5dd7070Spatrick       VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3352e5dd7070Spatrick   }
3353e5dd7070Spatrick 
3354e5dd7070Spatrick   bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3355e5dd7070Spatrick   const MemberPointerType *DerivedTy = IsDerivedToBase ? SrcTy : DstTy;
3356e5dd7070Spatrick   const CXXRecordDecl *DerivedClass = DerivedTy->getMostRecentCXXRecordDecl();
3357e5dd7070Spatrick 
3358e5dd7070Spatrick   // For data pointers, we adjust the field offset directly.  For functions, we
3359e5dd7070Spatrick   // have a separate field.
3360e5dd7070Spatrick   llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3361e5dd7070Spatrick 
3362e5dd7070Spatrick   // The virtual inheritance model has a quirk: the virtual base table is always
3363e5dd7070Spatrick   // referenced when dereferencing a member pointer even if the member pointer
3364e5dd7070Spatrick   // is non-virtual.  This is accounted for by adjusting the non-virtual offset
3365e5dd7070Spatrick   // to point backwards to the top of the MDC from the first VBase.  Undo this
3366e5dd7070Spatrick   // adjustment to normalize the member pointer.
3367e5dd7070Spatrick   llvm::Value *SrcVBIndexEqZero =
3368e5dd7070Spatrick       Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3369e5dd7070Spatrick   if (SrcInheritance == MSInheritanceModel::Virtual) {
3370e5dd7070Spatrick     if (int64_t SrcOffsetToFirstVBase =
3371e5dd7070Spatrick             getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3372e5dd7070Spatrick       llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3373e5dd7070Spatrick           SrcVBIndexEqZero,
3374e5dd7070Spatrick           llvm::ConstantInt::get(CGM.IntTy, SrcOffsetToFirstVBase),
3375e5dd7070Spatrick           getZeroInt());
3376e5dd7070Spatrick       NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3377e5dd7070Spatrick     }
3378e5dd7070Spatrick   }
3379e5dd7070Spatrick 
3380e5dd7070Spatrick   // A non-zero vbindex implies that we are dealing with a source member in a
3381e5dd7070Spatrick   // floating virtual base in addition to some non-virtual offset.  If the
3382e5dd7070Spatrick   // vbindex is zero, we are dealing with a source that exists in a non-virtual,
3383e5dd7070Spatrick   // fixed, base.  The difference between these two cases is that the vbindex +
3384e5dd7070Spatrick   // nvoffset *always* point to the member regardless of what context they are
3385e5dd7070Spatrick   // evaluated in so long as the vbindex is adjusted.  A member inside a fixed
3386e5dd7070Spatrick   // base requires explicit nv adjustment.
3387e5dd7070Spatrick   llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3388e5dd7070Spatrick       CGM.IntTy,
3389e5dd7070Spatrick       CGM.computeNonVirtualBaseClassOffset(DerivedClass, PathBegin, PathEnd)
3390e5dd7070Spatrick           .getQuantity());
3391e5dd7070Spatrick 
3392e5dd7070Spatrick   llvm::Value *NVDisp;
3393e5dd7070Spatrick   if (IsDerivedToBase)
3394e5dd7070Spatrick     NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset, "adj");
3395e5dd7070Spatrick   else
3396e5dd7070Spatrick     NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset, "adj");
3397e5dd7070Spatrick 
3398e5dd7070Spatrick   NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3399e5dd7070Spatrick 
3400e5dd7070Spatrick   // Update the vbindex to an appropriate value in the destination because
3401e5dd7070Spatrick   // SrcRD's vbtable might not be a strict prefix of the one in DstRD.
3402e5dd7070Spatrick   llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3403e5dd7070Spatrick   if (inheritanceModelHasVBTableOffsetField(DstInheritance) &&
3404e5dd7070Spatrick       inheritanceModelHasVBTableOffsetField(SrcInheritance)) {
3405e5dd7070Spatrick     if (llvm::GlobalVariable *VDispMap =
3406e5dd7070Spatrick             getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3407e5dd7070Spatrick       llvm::Value *VBIndex = Builder.CreateExactUDiv(
3408e5dd7070Spatrick           VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.IntTy, 4));
3409e5dd7070Spatrick       if (IsConstant) {
3410e5dd7070Spatrick         llvm::Constant *Mapping = VDispMap->getInitializer();
3411e5dd7070Spatrick         VirtualBaseAdjustmentOffset =
3412e5dd7070Spatrick             Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3413e5dd7070Spatrick       } else {
3414e5dd7070Spatrick         llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3415a9ac8606Spatrick         VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3416a9ac8606Spatrick             CGM.IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3417a9ac8606Spatrick                                                  VDispMap, Idxs),
3418e5dd7070Spatrick             CharUnits::fromQuantity(4));
3419e5dd7070Spatrick       }
3420e5dd7070Spatrick 
3421e5dd7070Spatrick       DstVBIndexEqZero =
3422e5dd7070Spatrick           Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3423e5dd7070Spatrick     }
3424e5dd7070Spatrick   }
3425e5dd7070Spatrick 
3426e5dd7070Spatrick   // Set the VBPtrOffset to zero if the vbindex is zero.  Otherwise, initialize
3427e5dd7070Spatrick   // it to the offset of the vbptr.
3428e5dd7070Spatrick   if (inheritanceModelHasVBPtrOffsetField(DstInheritance)) {
3429e5dd7070Spatrick     llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3430e5dd7070Spatrick         CGM.IntTy,
3431e5dd7070Spatrick         getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3432e5dd7070Spatrick     VBPtrOffset =
3433e5dd7070Spatrick         Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3434e5dd7070Spatrick   }
3435e5dd7070Spatrick 
3436e5dd7070Spatrick   // Likewise, apply a similar adjustment so that dereferencing the member
3437e5dd7070Spatrick   // pointer correctly accounts for the distance between the start of the first
3438e5dd7070Spatrick   // virtual base and the top of the MDC.
3439e5dd7070Spatrick   if (DstInheritance == MSInheritanceModel::Virtual) {
3440e5dd7070Spatrick     if (int64_t DstOffsetToFirstVBase =
3441e5dd7070Spatrick             getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3442e5dd7070Spatrick       llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3443e5dd7070Spatrick           DstVBIndexEqZero,
3444e5dd7070Spatrick           llvm::ConstantInt::get(CGM.IntTy, DstOffsetToFirstVBase),
3445e5dd7070Spatrick           getZeroInt());
3446e5dd7070Spatrick       NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3447e5dd7070Spatrick     }
3448e5dd7070Spatrick   }
3449e5dd7070Spatrick 
3450e5dd7070Spatrick   // Recompose dst from the null struct and the adjusted fields from src.
3451e5dd7070Spatrick   llvm::Value *Dst;
3452e5dd7070Spatrick   if (inheritanceModelHasOnlyOneField(IsFunc, DstInheritance)) {
3453e5dd7070Spatrick     Dst = FirstField;
3454e5dd7070Spatrick   } else {
3455e5dd7070Spatrick     Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3456e5dd7070Spatrick     unsigned Idx = 0;
3457e5dd7070Spatrick     Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3458e5dd7070Spatrick     if (inheritanceModelHasNVOffsetField(IsFunc, DstInheritance))
3459e5dd7070Spatrick       Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3460e5dd7070Spatrick     if (inheritanceModelHasVBPtrOffsetField(DstInheritance))
3461e5dd7070Spatrick       Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3462e5dd7070Spatrick     if (inheritanceModelHasVBTableOffsetField(DstInheritance))
3463e5dd7070Spatrick       Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3464e5dd7070Spatrick   }
3465e5dd7070Spatrick   return Dst;
3466e5dd7070Spatrick }
3467e5dd7070Spatrick 
3468e5dd7070Spatrick llvm::Constant *
EmitMemberPointerConversion(const CastExpr * E,llvm::Constant * Src)3469e5dd7070Spatrick MicrosoftCXXABI::EmitMemberPointerConversion(const CastExpr *E,
3470e5dd7070Spatrick                                              llvm::Constant *Src) {
3471e5dd7070Spatrick   const MemberPointerType *SrcTy =
3472e5dd7070Spatrick       E->getSubExpr()->getType()->castAs<MemberPointerType>();
3473e5dd7070Spatrick   const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>();
3474e5dd7070Spatrick 
3475e5dd7070Spatrick   CastKind CK = E->getCastKind();
3476e5dd7070Spatrick 
3477e5dd7070Spatrick   return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->path_begin(),
3478e5dd7070Spatrick                                      E->path_end(), Src);
3479e5dd7070Spatrick }
3480e5dd7070Spatrick 
EmitMemberPointerConversion(const MemberPointerType * SrcTy,const MemberPointerType * DstTy,CastKind CK,CastExpr::path_const_iterator PathBegin,CastExpr::path_const_iterator PathEnd,llvm::Constant * Src)3481e5dd7070Spatrick llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3482e5dd7070Spatrick     const MemberPointerType *SrcTy, const MemberPointerType *DstTy, CastKind CK,
3483e5dd7070Spatrick     CastExpr::path_const_iterator PathBegin,
3484e5dd7070Spatrick     CastExpr::path_const_iterator PathEnd, llvm::Constant *Src) {
3485e5dd7070Spatrick   assert(CK == CK_DerivedToBaseMemberPointer ||
3486e5dd7070Spatrick          CK == CK_BaseToDerivedMemberPointer ||
3487e5dd7070Spatrick          CK == CK_ReinterpretMemberPointer);
3488e5dd7070Spatrick   // If src is null, emit a new null for dst.  We can't return src because dst
3489e5dd7070Spatrick   // might have a new representation.
3490e5dd7070Spatrick   if (MemberPointerConstantIsNull(SrcTy, Src))
3491e5dd7070Spatrick     return EmitNullMemberPointer(DstTy);
3492e5dd7070Spatrick 
3493e5dd7070Spatrick   // We don't need to do anything for reinterpret_casts of non-null member
3494e5dd7070Spatrick   // pointers.  We should only get here when the two type representations have
3495e5dd7070Spatrick   // the same size.
3496e5dd7070Spatrick   if (CK == CK_ReinterpretMemberPointer)
3497e5dd7070Spatrick     return Src;
3498e5dd7070Spatrick 
3499e5dd7070Spatrick   CGBuilderTy Builder(CGM, CGM.getLLVMContext());
3500e5dd7070Spatrick   auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3501e5dd7070Spatrick       SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3502e5dd7070Spatrick 
3503e5dd7070Spatrick   return Dst;
3504e5dd7070Spatrick }
3505e5dd7070Spatrick 
EmitLoadOfMemberFunctionPointer(CodeGenFunction & CGF,const Expr * E,Address This,llvm::Value * & ThisPtrForCall,llvm::Value * MemPtr,const MemberPointerType * MPT)3506e5dd7070Spatrick CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3507e5dd7070Spatrick     CodeGenFunction &CGF, const Expr *E, Address This,
3508e5dd7070Spatrick     llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3509e5dd7070Spatrick     const MemberPointerType *MPT) {
3510e5dd7070Spatrick   assert(MPT->isMemberFunctionPointer());
3511e5dd7070Spatrick   const FunctionProtoType *FPT =
3512e5dd7070Spatrick     MPT->getPointeeType()->castAs<FunctionProtoType>();
3513e5dd7070Spatrick   const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
3514e5dd7070Spatrick   llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
3515e5dd7070Spatrick       CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr));
3516e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
3517e5dd7070Spatrick 
3518e5dd7070Spatrick   MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
3519e5dd7070Spatrick 
3520e5dd7070Spatrick   // Extract the fields we need, regardless of model.  We'll apply them if we
3521e5dd7070Spatrick   // have them.
3522e5dd7070Spatrick   llvm::Value *FunctionPointer = MemPtr;
3523e5dd7070Spatrick   llvm::Value *NonVirtualBaseAdjustment = nullptr;
3524e5dd7070Spatrick   llvm::Value *VirtualBaseAdjustmentOffset = nullptr;
3525e5dd7070Spatrick   llvm::Value *VBPtrOffset = nullptr;
3526e5dd7070Spatrick   if (MemPtr->getType()->isStructTy()) {
3527e5dd7070Spatrick     // We need to extract values.
3528e5dd7070Spatrick     unsigned I = 0;
3529e5dd7070Spatrick     FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3530e5dd7070Spatrick     if (inheritanceModelHasNVOffsetField(MPT, Inheritance))
3531e5dd7070Spatrick       NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3532e5dd7070Spatrick     if (inheritanceModelHasVBPtrOffsetField(Inheritance))
3533e5dd7070Spatrick       VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3534e5dd7070Spatrick     if (inheritanceModelHasVBTableOffsetField(Inheritance))
3535e5dd7070Spatrick       VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3536e5dd7070Spatrick   }
3537e5dd7070Spatrick 
3538e5dd7070Spatrick   if (VirtualBaseAdjustmentOffset) {
3539e5dd7070Spatrick     ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3540e5dd7070Spatrick                                    VirtualBaseAdjustmentOffset, VBPtrOffset);
3541e5dd7070Spatrick   } else {
3542e5dd7070Spatrick     ThisPtrForCall = This.getPointer();
3543e5dd7070Spatrick   }
3544e5dd7070Spatrick 
3545e5dd7070Spatrick   if (NonVirtualBaseAdjustment) {
3546e5dd7070Spatrick     // Apply the adjustment and cast back to the original struct type.
3547e5dd7070Spatrick     llvm::Value *Ptr = Builder.CreateBitCast(ThisPtrForCall, CGF.Int8PtrTy);
3548a9ac8606Spatrick     Ptr = Builder.CreateInBoundsGEP(CGF.Int8Ty, Ptr, NonVirtualBaseAdjustment);
3549e5dd7070Spatrick     ThisPtrForCall = Builder.CreateBitCast(Ptr, ThisPtrForCall->getType(),
3550e5dd7070Spatrick                                            "this.adjusted");
3551e5dd7070Spatrick   }
3552e5dd7070Spatrick 
3553e5dd7070Spatrick   FunctionPointer =
3554e5dd7070Spatrick     Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo());
3555e5dd7070Spatrick   CGCallee Callee(FPT, FunctionPointer);
3556e5dd7070Spatrick   return Callee;
3557e5dd7070Spatrick }
3558e5dd7070Spatrick 
CreateMicrosoftCXXABI(CodeGenModule & CGM)3559e5dd7070Spatrick CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
3560e5dd7070Spatrick   return new MicrosoftCXXABI(CGM);
3561e5dd7070Spatrick }
3562e5dd7070Spatrick 
3563e5dd7070Spatrick // MS RTTI Overview:
3564e5dd7070Spatrick // The run time type information emitted by cl.exe contains 5 distinct types of
3565e5dd7070Spatrick // structures.  Many of them reference each other.
3566e5dd7070Spatrick //
3567e5dd7070Spatrick // TypeInfo:  Static classes that are returned by typeid.
3568e5dd7070Spatrick //
3569e5dd7070Spatrick // CompleteObjectLocator:  Referenced by vftables.  They contain information
3570e5dd7070Spatrick //   required for dynamic casting, including OffsetFromTop.  They also contain
3571e5dd7070Spatrick //   a reference to the TypeInfo for the type and a reference to the
3572e5dd7070Spatrick //   CompleteHierarchyDescriptor for the type.
3573e5dd7070Spatrick //
3574e5dd7070Spatrick // ClassHierarchyDescriptor: Contains information about a class hierarchy.
3575e5dd7070Spatrick //   Used during dynamic_cast to walk a class hierarchy.  References a base
3576e5dd7070Spatrick //   class array and the size of said array.
3577e5dd7070Spatrick //
3578e5dd7070Spatrick // BaseClassArray: Contains a list of classes in a hierarchy.  BaseClassArray is
3579e5dd7070Spatrick //   somewhat of a misnomer because the most derived class is also in the list
3580e5dd7070Spatrick //   as well as multiple copies of virtual bases (if they occur multiple times
3581e5dd7070Spatrick //   in the hierarchy.)  The BaseClassArray contains one BaseClassDescriptor for
3582e5dd7070Spatrick //   every path in the hierarchy, in pre-order depth first order.  Note, we do
3583e5dd7070Spatrick //   not declare a specific llvm type for BaseClassArray, it's merely an array
3584e5dd7070Spatrick //   of BaseClassDescriptor pointers.
3585e5dd7070Spatrick //
3586e5dd7070Spatrick // BaseClassDescriptor: Contains information about a class in a class hierarchy.
3587e5dd7070Spatrick //   BaseClassDescriptor is also somewhat of a misnomer for the same reason that
3588e5dd7070Spatrick //   BaseClassArray is.  It contains information about a class within a
3589e5dd7070Spatrick //   hierarchy such as: is this base is ambiguous and what is its offset in the
3590e5dd7070Spatrick //   vbtable.  The names of the BaseClassDescriptors have all of their fields
3591e5dd7070Spatrick //   mangled into them so they can be aggressively deduplicated by the linker.
3592e5dd7070Spatrick 
getTypeInfoVTable(CodeGenModule & CGM)3593e5dd7070Spatrick static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) {
3594e5dd7070Spatrick   StringRef MangledName("??_7type_info@@6B@");
3595e5dd7070Spatrick   if (auto VTable = CGM.getModule().getNamedGlobal(MangledName))
3596e5dd7070Spatrick     return VTable;
3597e5dd7070Spatrick   return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
3598e5dd7070Spatrick                                   /*isConstant=*/true,
3599e5dd7070Spatrick                                   llvm::GlobalVariable::ExternalLinkage,
3600e5dd7070Spatrick                                   /*Initializer=*/nullptr, MangledName);
3601e5dd7070Spatrick }
3602e5dd7070Spatrick 
3603e5dd7070Spatrick namespace {
3604e5dd7070Spatrick 
3605e5dd7070Spatrick /// A Helper struct that stores information about a class in a class
3606e5dd7070Spatrick /// hierarchy.  The information stored in these structs struct is used during
3607e5dd7070Spatrick /// the generation of ClassHierarchyDescriptors and BaseClassDescriptors.
3608e5dd7070Spatrick // During RTTI creation, MSRTTIClasses are stored in a contiguous array with
3609e5dd7070Spatrick // implicit depth first pre-order tree connectivity.  getFirstChild and
3610e5dd7070Spatrick // getNextSibling allow us to walk the tree efficiently.
3611e5dd7070Spatrick struct MSRTTIClass {
3612e5dd7070Spatrick   enum {
3613e5dd7070Spatrick     IsPrivateOnPath = 1 | 8,
3614e5dd7070Spatrick     IsAmbiguous = 2,
3615e5dd7070Spatrick     IsPrivate = 4,
3616e5dd7070Spatrick     IsVirtual = 16,
3617e5dd7070Spatrick     HasHierarchyDescriptor = 64
3618e5dd7070Spatrick   };
MSRTTIClass__anon063cb12a0811::MSRTTIClass3619e5dd7070Spatrick   MSRTTIClass(const CXXRecordDecl *RD) : RD(RD) {}
3620e5dd7070Spatrick   uint32_t initialize(const MSRTTIClass *Parent,
3621e5dd7070Spatrick                       const CXXBaseSpecifier *Specifier);
3622e5dd7070Spatrick 
getFirstChild__anon063cb12a0811::MSRTTIClass3623e5dd7070Spatrick   MSRTTIClass *getFirstChild() { return this + 1; }
getNextChild__anon063cb12a0811::MSRTTIClass3624e5dd7070Spatrick   static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3625e5dd7070Spatrick     return Child + 1 + Child->NumBases;
3626e5dd7070Spatrick   }
3627e5dd7070Spatrick 
3628e5dd7070Spatrick   const CXXRecordDecl *RD, *VirtualRoot;
3629e5dd7070Spatrick   uint32_t Flags, NumBases, OffsetInVBase;
3630e5dd7070Spatrick };
3631e5dd7070Spatrick 
3632e5dd7070Spatrick /// Recursively initialize the base class array.
initialize(const MSRTTIClass * Parent,const CXXBaseSpecifier * Specifier)3633e5dd7070Spatrick uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
3634e5dd7070Spatrick                                  const CXXBaseSpecifier *Specifier) {
3635e5dd7070Spatrick   Flags = HasHierarchyDescriptor;
3636e5dd7070Spatrick   if (!Parent) {
3637e5dd7070Spatrick     VirtualRoot = nullptr;
3638e5dd7070Spatrick     OffsetInVBase = 0;
3639e5dd7070Spatrick   } else {
3640e5dd7070Spatrick     if (Specifier->getAccessSpecifier() != AS_public)
3641e5dd7070Spatrick       Flags |= IsPrivate | IsPrivateOnPath;
3642e5dd7070Spatrick     if (Specifier->isVirtual()) {
3643e5dd7070Spatrick       Flags |= IsVirtual;
3644e5dd7070Spatrick       VirtualRoot = RD;
3645e5dd7070Spatrick       OffsetInVBase = 0;
3646e5dd7070Spatrick     } else {
3647e5dd7070Spatrick       if (Parent->Flags & IsPrivateOnPath)
3648e5dd7070Spatrick         Flags |= IsPrivateOnPath;
3649e5dd7070Spatrick       VirtualRoot = Parent->VirtualRoot;
3650e5dd7070Spatrick       OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
3651e5dd7070Spatrick           .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
3652e5dd7070Spatrick     }
3653e5dd7070Spatrick   }
3654e5dd7070Spatrick   NumBases = 0;
3655e5dd7070Spatrick   MSRTTIClass *Child = getFirstChild();
3656e5dd7070Spatrick   for (const CXXBaseSpecifier &Base : RD->bases()) {
3657e5dd7070Spatrick     NumBases += Child->initialize(this, &Base) + 1;
3658e5dd7070Spatrick     Child = getNextChild(Child);
3659e5dd7070Spatrick   }
3660e5dd7070Spatrick   return NumBases;
3661e5dd7070Spatrick }
3662e5dd7070Spatrick 
getLinkageForRTTI(QualType Ty)3663e5dd7070Spatrick static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
3664e5dd7070Spatrick   switch (Ty->getLinkage()) {
3665e5dd7070Spatrick   case NoLinkage:
3666e5dd7070Spatrick   case InternalLinkage:
3667e5dd7070Spatrick   case UniqueExternalLinkage:
3668e5dd7070Spatrick     return llvm::GlobalValue::InternalLinkage;
3669e5dd7070Spatrick 
3670e5dd7070Spatrick   case VisibleNoLinkage:
3671e5dd7070Spatrick   case ModuleInternalLinkage:
3672e5dd7070Spatrick   case ModuleLinkage:
3673e5dd7070Spatrick   case ExternalLinkage:
3674e5dd7070Spatrick     return llvm::GlobalValue::LinkOnceODRLinkage;
3675e5dd7070Spatrick   }
3676e5dd7070Spatrick   llvm_unreachable("Invalid linkage!");
3677e5dd7070Spatrick }
3678e5dd7070Spatrick 
3679e5dd7070Spatrick /// An ephemeral helper class for building MS RTTI types.  It caches some
3680e5dd7070Spatrick /// calls to the module and information about the most derived class in a
3681e5dd7070Spatrick /// hierarchy.
3682e5dd7070Spatrick struct MSRTTIBuilder {
3683e5dd7070Spatrick   enum {
3684e5dd7070Spatrick     HasBranchingHierarchy = 1,
3685e5dd7070Spatrick     HasVirtualBranchingHierarchy = 2,
3686e5dd7070Spatrick     HasAmbiguousBases = 4
3687e5dd7070Spatrick   };
3688e5dd7070Spatrick 
MSRTTIBuilder__anon063cb12a0811::MSRTTIBuilder3689e5dd7070Spatrick   MSRTTIBuilder(MicrosoftCXXABI &ABI, const CXXRecordDecl *RD)
3690e5dd7070Spatrick       : CGM(ABI.CGM), Context(CGM.getContext()),
3691e5dd7070Spatrick         VMContext(CGM.getLLVMContext()), Module(CGM.getModule()), RD(RD),
3692e5dd7070Spatrick         Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3693e5dd7070Spatrick         ABI(ABI) {}
3694e5dd7070Spatrick 
3695e5dd7070Spatrick   llvm::GlobalVariable *getBaseClassDescriptor(const MSRTTIClass &Classes);
3696e5dd7070Spatrick   llvm::GlobalVariable *
3697e5dd7070Spatrick   getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
3698e5dd7070Spatrick   llvm::GlobalVariable *getClassHierarchyDescriptor();
3699e5dd7070Spatrick   llvm::GlobalVariable *getCompleteObjectLocator(const VPtrInfo &Info);
3700e5dd7070Spatrick 
3701e5dd7070Spatrick   CodeGenModule &CGM;
3702e5dd7070Spatrick   ASTContext &Context;
3703e5dd7070Spatrick   llvm::LLVMContext &VMContext;
3704e5dd7070Spatrick   llvm::Module &Module;
3705e5dd7070Spatrick   const CXXRecordDecl *RD;
3706e5dd7070Spatrick   llvm::GlobalVariable::LinkageTypes Linkage;
3707e5dd7070Spatrick   MicrosoftCXXABI &ABI;
3708e5dd7070Spatrick };
3709e5dd7070Spatrick 
3710e5dd7070Spatrick } // namespace
3711e5dd7070Spatrick 
3712e5dd7070Spatrick /// Recursively serializes a class hierarchy in pre-order depth first
3713e5dd7070Spatrick /// order.
serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> & Classes,const CXXRecordDecl * RD)3714e5dd7070Spatrick static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes,
3715e5dd7070Spatrick                                     const CXXRecordDecl *RD) {
3716e5dd7070Spatrick   Classes.push_back(MSRTTIClass(RD));
3717e5dd7070Spatrick   for (const CXXBaseSpecifier &Base : RD->bases())
3718e5dd7070Spatrick     serializeClassHierarchy(Classes, Base.getType()->getAsCXXRecordDecl());
3719e5dd7070Spatrick }
3720e5dd7070Spatrick 
3721e5dd7070Spatrick /// Find ambiguity among base classes.
3722e5dd7070Spatrick static void
detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> & Classes)3723e5dd7070Spatrick detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) {
3724e5dd7070Spatrick   llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3725e5dd7070Spatrick   llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3726e5dd7070Spatrick   llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3727e5dd7070Spatrick   for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3728e5dd7070Spatrick     if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3729e5dd7070Spatrick         !VirtualBases.insert(Class->RD).second) {
3730e5dd7070Spatrick       Class = MSRTTIClass::getNextChild(Class);
3731e5dd7070Spatrick       continue;
3732e5dd7070Spatrick     }
3733e5dd7070Spatrick     if (!UniqueBases.insert(Class->RD).second)
3734e5dd7070Spatrick       AmbiguousBases.insert(Class->RD);
3735e5dd7070Spatrick     Class++;
3736e5dd7070Spatrick   }
3737e5dd7070Spatrick   if (AmbiguousBases.empty())
3738e5dd7070Spatrick     return;
3739e5dd7070Spatrick   for (MSRTTIClass &Class : Classes)
3740e5dd7070Spatrick     if (AmbiguousBases.count(Class.RD))
3741e5dd7070Spatrick       Class.Flags |= MSRTTIClass::IsAmbiguous;
3742e5dd7070Spatrick }
3743e5dd7070Spatrick 
getClassHierarchyDescriptor()3744e5dd7070Spatrick llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3745e5dd7070Spatrick   SmallString<256> MangledName;
3746e5dd7070Spatrick   {
3747e5dd7070Spatrick     llvm::raw_svector_ostream Out(MangledName);
3748e5dd7070Spatrick     ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3749e5dd7070Spatrick   }
3750e5dd7070Spatrick 
3751e5dd7070Spatrick   // Check to see if we've already declared this ClassHierarchyDescriptor.
3752e5dd7070Spatrick   if (auto CHD = Module.getNamedGlobal(MangledName))
3753e5dd7070Spatrick     return CHD;
3754e5dd7070Spatrick 
3755e5dd7070Spatrick   // Serialize the class hierarchy and initialize the CHD Fields.
3756e5dd7070Spatrick   SmallVector<MSRTTIClass, 8> Classes;
3757e5dd7070Spatrick   serializeClassHierarchy(Classes, RD);
3758e5dd7070Spatrick   Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
3759e5dd7070Spatrick   detectAmbiguousBases(Classes);
3760e5dd7070Spatrick   int Flags = 0;
3761e5dd7070Spatrick   for (auto Class : Classes) {
3762e5dd7070Spatrick     if (Class.RD->getNumBases() > 1)
3763e5dd7070Spatrick       Flags |= HasBranchingHierarchy;
3764e5dd7070Spatrick     // Note: cl.exe does not calculate "HasAmbiguousBases" correctly.  We
3765e5dd7070Spatrick     // believe the field isn't actually used.
3766e5dd7070Spatrick     if (Class.Flags & MSRTTIClass::IsAmbiguous)
3767e5dd7070Spatrick       Flags |= HasAmbiguousBases;
3768e5dd7070Spatrick   }
3769e5dd7070Spatrick   if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3770e5dd7070Spatrick     Flags |= HasVirtualBranchingHierarchy;
3771e5dd7070Spatrick   // These gep indices are used to get the address of the first element of the
3772e5dd7070Spatrick   // base class array.
3773e5dd7070Spatrick   llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
3774e5dd7070Spatrick                                llvm::ConstantInt::get(CGM.IntTy, 0)};
3775e5dd7070Spatrick 
3776e5dd7070Spatrick   // Forward-declare the class hierarchy descriptor
3777e5dd7070Spatrick   auto Type = ABI.getClassHierarchyDescriptorType();
3778e5dd7070Spatrick   auto CHD = new llvm::GlobalVariable(Module, Type, /*isConstant=*/true, Linkage,
3779e5dd7070Spatrick                                       /*Initializer=*/nullptr,
3780e5dd7070Spatrick                                       MangledName);
3781e5dd7070Spatrick   if (CHD->isWeakForLinker())
3782e5dd7070Spatrick     CHD->setComdat(CGM.getModule().getOrInsertComdat(CHD->getName()));
3783e5dd7070Spatrick 
3784e5dd7070Spatrick   auto *Bases = getBaseClassArray(Classes);
3785e5dd7070Spatrick 
3786e5dd7070Spatrick   // Initialize the base class ClassHierarchyDescriptor.
3787e5dd7070Spatrick   llvm::Constant *Fields[] = {
3788e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, 0), // reserved by the runtime
3789e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, Flags),
3790e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, Classes.size()),
3791e5dd7070Spatrick       ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3792e5dd7070Spatrick           Bases->getValueType(), Bases,
3793e5dd7070Spatrick           llvm::ArrayRef<llvm::Value *>(GEPIndices))),
3794e5dd7070Spatrick   };
3795e5dd7070Spatrick   CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3796e5dd7070Spatrick   return CHD;
3797e5dd7070Spatrick }
3798e5dd7070Spatrick 
3799e5dd7070Spatrick llvm::GlobalVariable *
getBaseClassArray(SmallVectorImpl<MSRTTIClass> & Classes)3800e5dd7070Spatrick MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
3801e5dd7070Spatrick   SmallString<256> MangledName;
3802e5dd7070Spatrick   {
3803e5dd7070Spatrick     llvm::raw_svector_ostream Out(MangledName);
3804e5dd7070Spatrick     ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3805e5dd7070Spatrick   }
3806e5dd7070Spatrick 
3807e5dd7070Spatrick   // Forward-declare the base class array.
3808e5dd7070Spatrick   // cl.exe pads the base class array with 1 (in 32 bit mode) or 4 (in 64 bit
3809e5dd7070Spatrick   // mode) bytes of padding.  We provide a pointer sized amount of padding by
3810e5dd7070Spatrick   // adding +1 to Classes.size().  The sections have pointer alignment and are
3811e5dd7070Spatrick   // marked pick-any so it shouldn't matter.
3812e5dd7070Spatrick   llvm::Type *PtrType = ABI.getImageRelativeType(
3813e5dd7070Spatrick       ABI.getBaseClassDescriptorType()->getPointerTo());
3814e5dd7070Spatrick   auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3815e5dd7070Spatrick   auto *BCA =
3816e5dd7070Spatrick       new llvm::GlobalVariable(Module, ArrType,
3817e5dd7070Spatrick                                /*isConstant=*/true, Linkage,
3818e5dd7070Spatrick                                /*Initializer=*/nullptr, MangledName);
3819e5dd7070Spatrick   if (BCA->isWeakForLinker())
3820e5dd7070Spatrick     BCA->setComdat(CGM.getModule().getOrInsertComdat(BCA->getName()));
3821e5dd7070Spatrick 
3822e5dd7070Spatrick   // Initialize the BaseClassArray.
3823e5dd7070Spatrick   SmallVector<llvm::Constant *, 8> BaseClassArrayData;
3824e5dd7070Spatrick   for (MSRTTIClass &Class : Classes)
3825e5dd7070Spatrick     BaseClassArrayData.push_back(
3826e5dd7070Spatrick         ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3827e5dd7070Spatrick   BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3828e5dd7070Spatrick   BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3829e5dd7070Spatrick   return BCA;
3830e5dd7070Spatrick }
3831e5dd7070Spatrick 
3832e5dd7070Spatrick llvm::GlobalVariable *
getBaseClassDescriptor(const MSRTTIClass & Class)3833e5dd7070Spatrick MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {
3834e5dd7070Spatrick   // Compute the fields for the BaseClassDescriptor.  They are computed up front
3835e5dd7070Spatrick   // because they are mangled into the name of the object.
3836e5dd7070Spatrick   uint32_t OffsetInVBTable = 0;
3837e5dd7070Spatrick   int32_t VBPtrOffset = -1;
3838e5dd7070Spatrick   if (Class.VirtualRoot) {
3839e5dd7070Spatrick     auto &VTableContext = CGM.getMicrosoftVTableContext();
3840e5dd7070Spatrick     OffsetInVBTable = VTableContext.getVBTableIndex(RD, Class.VirtualRoot) * 4;
3841e5dd7070Spatrick     VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
3842e5dd7070Spatrick   }
3843e5dd7070Spatrick 
3844e5dd7070Spatrick   SmallString<256> MangledName;
3845e5dd7070Spatrick   {
3846e5dd7070Spatrick     llvm::raw_svector_ostream Out(MangledName);
3847e5dd7070Spatrick     ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3848e5dd7070Spatrick         Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3849e5dd7070Spatrick         Class.Flags, Out);
3850e5dd7070Spatrick   }
3851e5dd7070Spatrick 
3852e5dd7070Spatrick   // Check to see if we've already declared this object.
3853e5dd7070Spatrick   if (auto BCD = Module.getNamedGlobal(MangledName))
3854e5dd7070Spatrick     return BCD;
3855e5dd7070Spatrick 
3856e5dd7070Spatrick   // Forward-declare the base class descriptor.
3857e5dd7070Spatrick   auto Type = ABI.getBaseClassDescriptorType();
3858e5dd7070Spatrick   auto BCD =
3859e5dd7070Spatrick       new llvm::GlobalVariable(Module, Type, /*isConstant=*/true, Linkage,
3860e5dd7070Spatrick                                /*Initializer=*/nullptr, MangledName);
3861e5dd7070Spatrick   if (BCD->isWeakForLinker())
3862e5dd7070Spatrick     BCD->setComdat(CGM.getModule().getOrInsertComdat(BCD->getName()));
3863e5dd7070Spatrick 
3864e5dd7070Spatrick   // Initialize the BaseClassDescriptor.
3865e5dd7070Spatrick   llvm::Constant *Fields[] = {
3866e5dd7070Spatrick       ABI.getImageRelativeConstant(
3867e5dd7070Spatrick           ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))),
3868e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, Class.NumBases),
3869e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, Class.OffsetInVBase),
3870e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
3871e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, OffsetInVBTable),
3872e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, Class.Flags),
3873e5dd7070Spatrick       ABI.getImageRelativeConstant(
3874e5dd7070Spatrick           MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3875e5dd7070Spatrick   };
3876e5dd7070Spatrick   BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3877e5dd7070Spatrick   return BCD;
3878e5dd7070Spatrick }
3879e5dd7070Spatrick 
3880e5dd7070Spatrick llvm::GlobalVariable *
getCompleteObjectLocator(const VPtrInfo & Info)3881e5dd7070Spatrick MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo &Info) {
3882e5dd7070Spatrick   SmallString<256> MangledName;
3883e5dd7070Spatrick   {
3884e5dd7070Spatrick     llvm::raw_svector_ostream Out(MangledName);
3885e5dd7070Spatrick     ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.MangledPath, Out);
3886e5dd7070Spatrick   }
3887e5dd7070Spatrick 
3888e5dd7070Spatrick   // Check to see if we've already computed this complete object locator.
3889e5dd7070Spatrick   if (auto COL = Module.getNamedGlobal(MangledName))
3890e5dd7070Spatrick     return COL;
3891e5dd7070Spatrick 
3892e5dd7070Spatrick   // Compute the fields of the complete object locator.
3893e5dd7070Spatrick   int OffsetToTop = Info.FullOffsetInMDC.getQuantity();
3894e5dd7070Spatrick   int VFPtrOffset = 0;
3895e5dd7070Spatrick   // The offset includes the vtordisp if one exists.
3896e5dd7070Spatrick   if (const CXXRecordDecl *VBase = Info.getVBaseWithVPtr())
3897e5dd7070Spatrick     if (Context.getASTRecordLayout(RD)
3898e5dd7070Spatrick       .getVBaseOffsetsMap()
3899e5dd7070Spatrick       .find(VBase)
3900e5dd7070Spatrick       ->second.hasVtorDisp())
3901e5dd7070Spatrick       VFPtrOffset = Info.NonVirtualOffset.getQuantity() + 4;
3902e5dd7070Spatrick 
3903e5dd7070Spatrick   // Forward-declare the complete object locator.
3904e5dd7070Spatrick   llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3905e5dd7070Spatrick   auto COL = new llvm::GlobalVariable(Module, Type, /*isConstant=*/true, Linkage,
3906e5dd7070Spatrick     /*Initializer=*/nullptr, MangledName);
3907e5dd7070Spatrick 
3908e5dd7070Spatrick   // Initialize the CompleteObjectLocator.
3909e5dd7070Spatrick   llvm::Constant *Fields[] = {
3910e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, ABI.isImageRelative()),
3911e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, OffsetToTop),
3912e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, VFPtrOffset),
3913e5dd7070Spatrick       ABI.getImageRelativeConstant(
3914e5dd7070Spatrick           CGM.GetAddrOfRTTIDescriptor(Context.getTypeDeclType(RD))),
3915e5dd7070Spatrick       ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3916e5dd7070Spatrick       ABI.getImageRelativeConstant(COL),
3917e5dd7070Spatrick   };
3918e5dd7070Spatrick   llvm::ArrayRef<llvm::Constant *> FieldsRef(Fields);
3919e5dd7070Spatrick   if (!ABI.isImageRelative())
3920e5dd7070Spatrick     FieldsRef = FieldsRef.drop_back();
3921e5dd7070Spatrick   COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
3922e5dd7070Spatrick   if (COL->isWeakForLinker())
3923e5dd7070Spatrick     COL->setComdat(CGM.getModule().getOrInsertComdat(COL->getName()));
3924e5dd7070Spatrick   return COL;
3925e5dd7070Spatrick }
3926e5dd7070Spatrick 
decomposeTypeForEH(ASTContext & Context,QualType T,bool & IsConst,bool & IsVolatile,bool & IsUnaligned)3927e5dd7070Spatrick static QualType decomposeTypeForEH(ASTContext &Context, QualType T,
3928e5dd7070Spatrick                                    bool &IsConst, bool &IsVolatile,
3929e5dd7070Spatrick                                    bool &IsUnaligned) {
3930e5dd7070Spatrick   T = Context.getExceptionObjectType(T);
3931e5dd7070Spatrick 
3932e5dd7070Spatrick   // C++14 [except.handle]p3:
3933e5dd7070Spatrick   //   A handler is a match for an exception object of type E if [...]
3934e5dd7070Spatrick   //     - the handler is of type cv T or const T& where T is a pointer type and
3935e5dd7070Spatrick   //       E is a pointer type that can be converted to T by [...]
3936e5dd7070Spatrick   //         - a qualification conversion
3937e5dd7070Spatrick   IsConst = false;
3938e5dd7070Spatrick   IsVolatile = false;
3939e5dd7070Spatrick   IsUnaligned = false;
3940e5dd7070Spatrick   QualType PointeeType = T->getPointeeType();
3941e5dd7070Spatrick   if (!PointeeType.isNull()) {
3942e5dd7070Spatrick     IsConst = PointeeType.isConstQualified();
3943e5dd7070Spatrick     IsVolatile = PointeeType.isVolatileQualified();
3944e5dd7070Spatrick     IsUnaligned = PointeeType.getQualifiers().hasUnaligned();
3945e5dd7070Spatrick   }
3946e5dd7070Spatrick 
3947e5dd7070Spatrick   // Member pointer types like "const int A::*" are represented by having RTTI
3948e5dd7070Spatrick   // for "int A::*" and separately storing the const qualifier.
3949e5dd7070Spatrick   if (const auto *MPTy = T->getAs<MemberPointerType>())
3950e5dd7070Spatrick     T = Context.getMemberPointerType(PointeeType.getUnqualifiedType(),
3951e5dd7070Spatrick                                      MPTy->getClass());
3952e5dd7070Spatrick 
3953e5dd7070Spatrick   // Pointer types like "const int * const *" are represented by having RTTI
3954e5dd7070Spatrick   // for "const int **" and separately storing the const qualifier.
3955e5dd7070Spatrick   if (T->isPointerType())
3956e5dd7070Spatrick     T = Context.getPointerType(PointeeType.getUnqualifiedType());
3957e5dd7070Spatrick 
3958e5dd7070Spatrick   return T;
3959e5dd7070Spatrick }
3960e5dd7070Spatrick 
3961e5dd7070Spatrick CatchTypeInfo
getAddrOfCXXCatchHandlerType(QualType Type,QualType CatchHandlerType)3962e5dd7070Spatrick MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType Type,
3963e5dd7070Spatrick                                               QualType CatchHandlerType) {
3964e5dd7070Spatrick   // TypeDescriptors for exceptions never have qualified pointer types,
3965e5dd7070Spatrick   // qualifiers are stored separately in order to support qualification
3966e5dd7070Spatrick   // conversions.
3967e5dd7070Spatrick   bool IsConst, IsVolatile, IsUnaligned;
3968e5dd7070Spatrick   Type =
3969e5dd7070Spatrick       decomposeTypeForEH(getContext(), Type, IsConst, IsVolatile, IsUnaligned);
3970e5dd7070Spatrick 
3971e5dd7070Spatrick   bool IsReference = CatchHandlerType->isReferenceType();
3972e5dd7070Spatrick 
3973e5dd7070Spatrick   uint32_t Flags = 0;
3974e5dd7070Spatrick   if (IsConst)
3975e5dd7070Spatrick     Flags |= 1;
3976e5dd7070Spatrick   if (IsVolatile)
3977e5dd7070Spatrick     Flags |= 2;
3978e5dd7070Spatrick   if (IsUnaligned)
3979e5dd7070Spatrick     Flags |= 4;
3980e5dd7070Spatrick   if (IsReference)
3981e5dd7070Spatrick     Flags |= 8;
3982e5dd7070Spatrick 
3983e5dd7070Spatrick   return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(),
3984e5dd7070Spatrick                        Flags};
3985e5dd7070Spatrick }
3986e5dd7070Spatrick 
3987e5dd7070Spatrick /// Gets a TypeDescriptor.  Returns a llvm::Constant * rather than a
3988e5dd7070Spatrick /// llvm::GlobalVariable * because different type descriptors have different
3989e5dd7070Spatrick /// types, and need to be abstracted.  They are abstracting by casting the
3990e5dd7070Spatrick /// address to an Int8PtrTy.
getAddrOfRTTIDescriptor(QualType Type)3991e5dd7070Spatrick llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) {
3992e5dd7070Spatrick   SmallString<256> MangledName;
3993e5dd7070Spatrick   {
3994e5dd7070Spatrick     llvm::raw_svector_ostream Out(MangledName);
3995e5dd7070Spatrick     getMangleContext().mangleCXXRTTI(Type, Out);
3996e5dd7070Spatrick   }
3997e5dd7070Spatrick 
3998e5dd7070Spatrick   // Check to see if we've already declared this TypeDescriptor.
3999e5dd7070Spatrick   if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
4000e5dd7070Spatrick     return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
4001e5dd7070Spatrick 
4002e5dd7070Spatrick   // Note for the future: If we would ever like to do deferred emission of
4003e5dd7070Spatrick   // RTTI, check if emitting vtables opportunistically need any adjustment.
4004e5dd7070Spatrick 
4005e5dd7070Spatrick   // Compute the fields for the TypeDescriptor.
4006e5dd7070Spatrick   SmallString<256> TypeInfoString;
4007e5dd7070Spatrick   {
4008e5dd7070Spatrick     llvm::raw_svector_ostream Out(TypeInfoString);
4009e5dd7070Spatrick     getMangleContext().mangleCXXRTTIName(Type, Out);
4010e5dd7070Spatrick   }
4011e5dd7070Spatrick 
4012e5dd7070Spatrick   // Declare and initialize the TypeDescriptor.
4013e5dd7070Spatrick   llvm::Constant *Fields[] = {
4014e5dd7070Spatrick     getTypeInfoVTable(CGM),                        // VFPtr
4015e5dd7070Spatrick     llvm::ConstantPointerNull::get(CGM.Int8PtrTy), // Runtime data
4016e5dd7070Spatrick     llvm::ConstantDataArray::getString(CGM.getLLVMContext(), TypeInfoString)};
4017e5dd7070Spatrick   llvm::StructType *TypeDescriptorType =
4018e5dd7070Spatrick       getTypeDescriptorType(TypeInfoString);
4019e5dd7070Spatrick   auto *Var = new llvm::GlobalVariable(
4020e5dd7070Spatrick       CGM.getModule(), TypeDescriptorType, /*isConstant=*/false,
4021e5dd7070Spatrick       getLinkageForRTTI(Type),
4022e5dd7070Spatrick       llvm::ConstantStruct::get(TypeDescriptorType, Fields),
4023e5dd7070Spatrick       MangledName);
4024e5dd7070Spatrick   if (Var->isWeakForLinker())
4025e5dd7070Spatrick     Var->setComdat(CGM.getModule().getOrInsertComdat(Var->getName()));
4026e5dd7070Spatrick   return llvm::ConstantExpr::getBitCast(Var, CGM.Int8PtrTy);
4027e5dd7070Spatrick }
4028e5dd7070Spatrick 
4029e5dd7070Spatrick /// Gets or a creates a Microsoft CompleteObjectLocator.
4030e5dd7070Spatrick llvm::GlobalVariable *
getMSCompleteObjectLocator(const CXXRecordDecl * RD,const VPtrInfo & Info)4031e5dd7070Spatrick MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
4032e5dd7070Spatrick                                             const VPtrInfo &Info) {
4033e5dd7070Spatrick   return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
4034e5dd7070Spatrick }
4035e5dd7070Spatrick 
emitCXXStructor(GlobalDecl GD)4036e5dd7070Spatrick void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {
4037e5dd7070Spatrick   if (auto *ctor = dyn_cast<CXXConstructorDecl>(GD.getDecl())) {
4038e5dd7070Spatrick     // There are no constructor variants, always emit the complete destructor.
4039e5dd7070Spatrick     llvm::Function *Fn =
4040e5dd7070Spatrick         CGM.codegenCXXStructor(GD.getWithCtorType(Ctor_Complete));
4041e5dd7070Spatrick     CGM.maybeSetTrivialComdat(*ctor, *Fn);
4042e5dd7070Spatrick     return;
4043e5dd7070Spatrick   }
4044e5dd7070Spatrick 
4045e5dd7070Spatrick   auto *dtor = cast<CXXDestructorDecl>(GD.getDecl());
4046e5dd7070Spatrick 
4047e5dd7070Spatrick   // Emit the base destructor if the base and complete (vbase) destructors are
4048e5dd7070Spatrick   // equivalent. This effectively implements -mconstructor-aliases as part of
4049e5dd7070Spatrick   // the ABI.
4050e5dd7070Spatrick   if (GD.getDtorType() == Dtor_Complete &&
4051e5dd7070Spatrick       dtor->getParent()->getNumVBases() == 0)
4052e5dd7070Spatrick     GD = GD.getWithDtorType(Dtor_Base);
4053e5dd7070Spatrick 
4054e5dd7070Spatrick   // The base destructor is equivalent to the base destructor of its
4055e5dd7070Spatrick   // base class if there is exactly one non-virtual base class with a
4056e5dd7070Spatrick   // non-trivial destructor, there are no fields with a non-trivial
4057e5dd7070Spatrick   // destructor, and the body of the destructor is trivial.
4058e5dd7070Spatrick   if (GD.getDtorType() == Dtor_Base && !CGM.TryEmitBaseDestructorAsAlias(dtor))
4059e5dd7070Spatrick     return;
4060e5dd7070Spatrick 
4061e5dd7070Spatrick   llvm::Function *Fn = CGM.codegenCXXStructor(GD);
4062e5dd7070Spatrick   if (Fn->isWeakForLinker())
4063e5dd7070Spatrick     Fn->setComdat(CGM.getModule().getOrInsertComdat(Fn->getName()));
4064e5dd7070Spatrick }
4065e5dd7070Spatrick 
4066e5dd7070Spatrick llvm::Function *
getAddrOfCXXCtorClosure(const CXXConstructorDecl * CD,CXXCtorType CT)4067e5dd7070Spatrick MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
4068e5dd7070Spatrick                                          CXXCtorType CT) {
4069e5dd7070Spatrick   assert(CT == Ctor_CopyingClosure || CT == Ctor_DefaultClosure);
4070e5dd7070Spatrick 
4071e5dd7070Spatrick   // Calculate the mangled name.
4072e5dd7070Spatrick   SmallString<256> ThunkName;
4073e5dd7070Spatrick   llvm::raw_svector_ostream Out(ThunkName);
4074ec727ea7Spatrick   getMangleContext().mangleName(GlobalDecl(CD, CT), Out);
4075e5dd7070Spatrick 
4076e5dd7070Spatrick   // If the thunk has been generated previously, just return it.
4077e5dd7070Spatrick   if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
4078e5dd7070Spatrick     return cast<llvm::Function>(GV);
4079e5dd7070Spatrick 
4080e5dd7070Spatrick   // Create the llvm::Function.
4081e5dd7070Spatrick   const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSCtorClosure(CD, CT);
4082e5dd7070Spatrick   llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
4083e5dd7070Spatrick   const CXXRecordDecl *RD = CD->getParent();
4084e5dd7070Spatrick   QualType RecordTy = getContext().getRecordType(RD);
4085e5dd7070Spatrick   llvm::Function *ThunkFn = llvm::Function::Create(
4086e5dd7070Spatrick       ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.getModule());
4087e5dd7070Spatrick   ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
4088e5dd7070Spatrick       FnInfo.getEffectiveCallingConvention()));
4089e5dd7070Spatrick   if (ThunkFn->isWeakForLinker())
4090e5dd7070Spatrick     ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
4091e5dd7070Spatrick   bool IsCopy = CT == Ctor_CopyingClosure;
4092e5dd7070Spatrick 
4093e5dd7070Spatrick   // Start codegen.
4094e5dd7070Spatrick   CodeGenFunction CGF(CGM);
4095e5dd7070Spatrick   CGF.CurGD = GlobalDecl(CD, Ctor_Complete);
4096e5dd7070Spatrick 
4097e5dd7070Spatrick   // Build FunctionArgs.
4098e5dd7070Spatrick   FunctionArgList FunctionArgs;
4099e5dd7070Spatrick 
4100e5dd7070Spatrick   // A constructor always starts with a 'this' pointer as its first argument.
4101e5dd7070Spatrick   buildThisParam(CGF, FunctionArgs);
4102e5dd7070Spatrick 
4103e5dd7070Spatrick   // Following the 'this' pointer is a reference to the source object that we
4104e5dd7070Spatrick   // are copying from.
4105e5dd7070Spatrick   ImplicitParamDecl SrcParam(
4106e5dd7070Spatrick       getContext(), /*DC=*/nullptr, SourceLocation(),
4107e5dd7070Spatrick       &getContext().Idents.get("src"),
4108e5dd7070Spatrick       getContext().getLValueReferenceType(RecordTy,
4109e5dd7070Spatrick                                           /*SpelledAsLValue=*/true),
4110e5dd7070Spatrick       ImplicitParamDecl::Other);
4111e5dd7070Spatrick   if (IsCopy)
4112e5dd7070Spatrick     FunctionArgs.push_back(&SrcParam);
4113e5dd7070Spatrick 
4114e5dd7070Spatrick   // Constructors for classes which utilize virtual bases have an additional
4115e5dd7070Spatrick   // parameter which indicates whether or not it is being delegated to by a more
4116e5dd7070Spatrick   // derived constructor.
4117e5dd7070Spatrick   ImplicitParamDecl IsMostDerived(getContext(), /*DC=*/nullptr,
4118e5dd7070Spatrick                                   SourceLocation(),
4119e5dd7070Spatrick                                   &getContext().Idents.get("is_most_derived"),
4120e5dd7070Spatrick                                   getContext().IntTy, ImplicitParamDecl::Other);
4121e5dd7070Spatrick   // Only add the parameter to the list if the class has virtual bases.
4122e5dd7070Spatrick   if (RD->getNumVBases() > 0)
4123e5dd7070Spatrick     FunctionArgs.push_back(&IsMostDerived);
4124e5dd7070Spatrick 
4125e5dd7070Spatrick   // Start defining the function.
4126e5dd7070Spatrick   auto NL = ApplyDebugLocation::CreateEmpty(CGF);
4127e5dd7070Spatrick   CGF.StartFunction(GlobalDecl(), FnInfo.getReturnType(), ThunkFn, FnInfo,
4128e5dd7070Spatrick                     FunctionArgs, CD->getLocation(), SourceLocation());
4129e5dd7070Spatrick   // Create a scope with an artificial location for the body of this function.
4130e5dd7070Spatrick   auto AL = ApplyDebugLocation::CreateArtificial(CGF);
4131e5dd7070Spatrick   setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4132e5dd7070Spatrick   llvm::Value *This = getThisValue(CGF);
4133e5dd7070Spatrick 
4134e5dd7070Spatrick   llvm::Value *SrcVal =
4135e5dd7070Spatrick       IsCopy ? CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&SrcParam), "src")
4136e5dd7070Spatrick              : nullptr;
4137e5dd7070Spatrick 
4138e5dd7070Spatrick   CallArgList Args;
4139e5dd7070Spatrick 
4140e5dd7070Spatrick   // Push the this ptr.
4141e5dd7070Spatrick   Args.add(RValue::get(This), CD->getThisType());
4142e5dd7070Spatrick 
4143e5dd7070Spatrick   // Push the src ptr.
4144e5dd7070Spatrick   if (SrcVal)
4145e5dd7070Spatrick     Args.add(RValue::get(SrcVal), SrcParam.getType());
4146e5dd7070Spatrick 
4147e5dd7070Spatrick   // Add the rest of the default arguments.
4148e5dd7070Spatrick   SmallVector<const Stmt *, 4> ArgVec;
4149e5dd7070Spatrick   ArrayRef<ParmVarDecl *> params = CD->parameters().drop_front(IsCopy ? 1 : 0);
4150e5dd7070Spatrick   for (const ParmVarDecl *PD : params) {
4151e5dd7070Spatrick     assert(PD->hasDefaultArg() && "ctor closure lacks default args");
4152e5dd7070Spatrick     ArgVec.push_back(PD->getDefaultArg());
4153e5dd7070Spatrick   }
4154e5dd7070Spatrick 
4155e5dd7070Spatrick   CodeGenFunction::RunCleanupsScope Cleanups(CGF);
4156e5dd7070Spatrick 
4157e5dd7070Spatrick   const auto *FPT = CD->getType()->castAs<FunctionProtoType>();
4158*12c85518Srobert   CGF.EmitCallArgs(Args, FPT, llvm::ArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
4159e5dd7070Spatrick 
4160e5dd7070Spatrick   // Insert any ABI-specific implicit constructor arguments.
4161ec727ea7Spatrick   AddedStructorArgCounts ExtraArgs =
4162e5dd7070Spatrick       addImplicitConstructorArgs(CGF, CD, Ctor_Complete,
4163e5dd7070Spatrick                                  /*ForVirtualBase=*/false,
4164e5dd7070Spatrick                                  /*Delegating=*/false, Args);
4165e5dd7070Spatrick   // Call the destructor with our arguments.
4166e5dd7070Spatrick   llvm::Constant *CalleePtr =
4167e5dd7070Spatrick       CGM.getAddrOfCXXStructor(GlobalDecl(CD, Ctor_Complete));
4168e5dd7070Spatrick   CGCallee Callee =
4169e5dd7070Spatrick       CGCallee::forDirect(CalleePtr, GlobalDecl(CD, Ctor_Complete));
4170e5dd7070Spatrick   const CGFunctionInfo &CalleeInfo = CGM.getTypes().arrangeCXXConstructorCall(
4171e5dd7070Spatrick       Args, CD, Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4172e5dd7070Spatrick   CGF.EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args);
4173e5dd7070Spatrick 
4174e5dd7070Spatrick   Cleanups.ForceCleanup();
4175e5dd7070Spatrick 
4176e5dd7070Spatrick   // Emit the ret instruction, remove any temporary instructions created for the
4177e5dd7070Spatrick   // aid of CodeGen.
4178e5dd7070Spatrick   CGF.FinishFunction(SourceLocation());
4179e5dd7070Spatrick 
4180e5dd7070Spatrick   return ThunkFn;
4181e5dd7070Spatrick }
4182e5dd7070Spatrick 
getCatchableType(QualType T,uint32_t NVOffset,int32_t VBPtrOffset,uint32_t VBIndex)4183e5dd7070Spatrick llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType T,
4184e5dd7070Spatrick                                                   uint32_t NVOffset,
4185e5dd7070Spatrick                                                   int32_t VBPtrOffset,
4186e5dd7070Spatrick                                                   uint32_t VBIndex) {
4187e5dd7070Spatrick   assert(!T->isReferenceType());
4188e5dd7070Spatrick 
4189e5dd7070Spatrick   CXXRecordDecl *RD = T->getAsCXXRecordDecl();
4190e5dd7070Spatrick   const CXXConstructorDecl *CD =
4191e5dd7070Spatrick       RD ? CGM.getContext().getCopyConstructorForExceptionObject(RD) : nullptr;
4192e5dd7070Spatrick   CXXCtorType CT = Ctor_Complete;
4193e5dd7070Spatrick   if (CD)
4194e5dd7070Spatrick     if (!hasDefaultCXXMethodCC(getContext(), CD) || CD->getNumParams() != 1)
4195e5dd7070Spatrick       CT = Ctor_CopyingClosure;
4196e5dd7070Spatrick 
4197e5dd7070Spatrick   uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
4198e5dd7070Spatrick   SmallString<256> MangledName;
4199e5dd7070Spatrick   {
4200e5dd7070Spatrick     llvm::raw_svector_ostream Out(MangledName);
4201e5dd7070Spatrick     getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
4202e5dd7070Spatrick                                               VBPtrOffset, VBIndex, Out);
4203e5dd7070Spatrick   }
4204e5dd7070Spatrick   if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
4205e5dd7070Spatrick     return getImageRelativeConstant(GV);
4206e5dd7070Spatrick 
4207e5dd7070Spatrick   // The TypeDescriptor is used by the runtime to determine if a catch handler
4208e5dd7070Spatrick   // is appropriate for the exception object.
4209e5dd7070Spatrick   llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
4210e5dd7070Spatrick 
4211e5dd7070Spatrick   // The runtime is responsible for calling the copy constructor if the
4212e5dd7070Spatrick   // exception is caught by value.
4213e5dd7070Spatrick   llvm::Constant *CopyCtor;
4214e5dd7070Spatrick   if (CD) {
4215e5dd7070Spatrick     if (CT == Ctor_CopyingClosure)
4216e5dd7070Spatrick       CopyCtor = getAddrOfCXXCtorClosure(CD, Ctor_CopyingClosure);
4217e5dd7070Spatrick     else
4218e5dd7070Spatrick       CopyCtor = CGM.getAddrOfCXXStructor(GlobalDecl(CD, Ctor_Complete));
4219e5dd7070Spatrick 
4220e5dd7070Spatrick     CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.Int8PtrTy);
4221e5dd7070Spatrick   } else {
4222e5dd7070Spatrick     CopyCtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
4223e5dd7070Spatrick   }
4224e5dd7070Spatrick   CopyCtor = getImageRelativeConstant(CopyCtor);
4225e5dd7070Spatrick 
4226e5dd7070Spatrick   bool IsScalar = !RD;
4227e5dd7070Spatrick   bool HasVirtualBases = false;
4228e5dd7070Spatrick   bool IsStdBadAlloc = false; // std::bad_alloc is special for some reason.
4229e5dd7070Spatrick   QualType PointeeType = T;
4230e5dd7070Spatrick   if (T->isPointerType())
4231e5dd7070Spatrick     PointeeType = T->getPointeeType();
4232e5dd7070Spatrick   if (const CXXRecordDecl *RD = PointeeType->getAsCXXRecordDecl()) {
4233e5dd7070Spatrick     HasVirtualBases = RD->getNumVBases() > 0;
4234e5dd7070Spatrick     if (IdentifierInfo *II = RD->getIdentifier())
4235e5dd7070Spatrick       IsStdBadAlloc = II->isStr("bad_alloc") && RD->isInStdNamespace();
4236e5dd7070Spatrick   }
4237e5dd7070Spatrick 
4238e5dd7070Spatrick   // Encode the relevant CatchableType properties into the Flags bitfield.
4239e5dd7070Spatrick   // FIXME: Figure out how bits 2 or 8 can get set.
4240e5dd7070Spatrick   uint32_t Flags = 0;
4241e5dd7070Spatrick   if (IsScalar)
4242e5dd7070Spatrick     Flags |= 1;
4243e5dd7070Spatrick   if (HasVirtualBases)
4244e5dd7070Spatrick     Flags |= 4;
4245e5dd7070Spatrick   if (IsStdBadAlloc)
4246e5dd7070Spatrick     Flags |= 16;
4247e5dd7070Spatrick 
4248e5dd7070Spatrick   llvm::Constant *Fields[] = {
4249e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, Flags),       // Flags
4250e5dd7070Spatrick       TD,                                             // TypeDescriptor
4251e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, NVOffset),    // NonVirtualAdjustment
4252e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset), // OffsetToVBPtr
4253e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, VBIndex),     // VBTableIndex
4254e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, Size),        // Size
4255e5dd7070Spatrick       CopyCtor                                        // CopyCtor
4256e5dd7070Spatrick   };
4257e5dd7070Spatrick   llvm::StructType *CTType = getCatchableTypeType();
4258e5dd7070Spatrick   auto *GV = new llvm::GlobalVariable(
4259e5dd7070Spatrick       CGM.getModule(), CTType, /*isConstant=*/true, getLinkageForRTTI(T),
4260e5dd7070Spatrick       llvm::ConstantStruct::get(CTType, Fields), MangledName);
4261e5dd7070Spatrick   GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4262e5dd7070Spatrick   GV->setSection(".xdata");
4263e5dd7070Spatrick   if (GV->isWeakForLinker())
4264e5dd7070Spatrick     GV->setComdat(CGM.getModule().getOrInsertComdat(GV->getName()));
4265e5dd7070Spatrick   return getImageRelativeConstant(GV);
4266e5dd7070Spatrick }
4267e5dd7070Spatrick 
getCatchableTypeArray(QualType T)4268e5dd7070Spatrick llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) {
4269e5dd7070Spatrick   assert(!T->isReferenceType());
4270e5dd7070Spatrick 
4271e5dd7070Spatrick   // See if we've already generated a CatchableTypeArray for this type before.
4272e5dd7070Spatrick   llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4273e5dd7070Spatrick   if (CTA)
4274e5dd7070Spatrick     return CTA;
4275e5dd7070Spatrick 
4276e5dd7070Spatrick   // Ensure that we don't have duplicate entries in our CatchableTypeArray by
4277e5dd7070Spatrick   // using a SmallSetVector.  Duplicates may arise due to virtual bases
4278e5dd7070Spatrick   // occurring more than once in the hierarchy.
4279e5dd7070Spatrick   llvm::SmallSetVector<llvm::Constant *, 2> CatchableTypes;
4280e5dd7070Spatrick 
4281e5dd7070Spatrick   // C++14 [except.handle]p3:
4282e5dd7070Spatrick   //   A handler is a match for an exception object of type E if [...]
4283e5dd7070Spatrick   //     - the handler is of type cv T or cv T& and T is an unambiguous public
4284e5dd7070Spatrick   //       base class of E, or
4285e5dd7070Spatrick   //     - the handler is of type cv T or const T& where T is a pointer type and
4286e5dd7070Spatrick   //       E is a pointer type that can be converted to T by [...]
4287e5dd7070Spatrick   //         - a standard pointer conversion (4.10) not involving conversions to
4288e5dd7070Spatrick   //           pointers to private or protected or ambiguous classes
4289e5dd7070Spatrick   const CXXRecordDecl *MostDerivedClass = nullptr;
4290e5dd7070Spatrick   bool IsPointer = T->isPointerType();
4291e5dd7070Spatrick   if (IsPointer)
4292e5dd7070Spatrick     MostDerivedClass = T->getPointeeType()->getAsCXXRecordDecl();
4293e5dd7070Spatrick   else
4294e5dd7070Spatrick     MostDerivedClass = T->getAsCXXRecordDecl();
4295e5dd7070Spatrick 
4296e5dd7070Spatrick   // Collect all the unambiguous public bases of the MostDerivedClass.
4297e5dd7070Spatrick   if (MostDerivedClass) {
4298e5dd7070Spatrick     const ASTContext &Context = getContext();
4299e5dd7070Spatrick     const ASTRecordLayout &MostDerivedLayout =
4300e5dd7070Spatrick         Context.getASTRecordLayout(MostDerivedClass);
4301e5dd7070Spatrick     MicrosoftVTableContext &VTableContext = CGM.getMicrosoftVTableContext();
4302e5dd7070Spatrick     SmallVector<MSRTTIClass, 8> Classes;
4303e5dd7070Spatrick     serializeClassHierarchy(Classes, MostDerivedClass);
4304e5dd7070Spatrick     Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
4305e5dd7070Spatrick     detectAmbiguousBases(Classes);
4306e5dd7070Spatrick     for (const MSRTTIClass &Class : Classes) {
4307e5dd7070Spatrick       // Skip any ambiguous or private bases.
4308e5dd7070Spatrick       if (Class.Flags &
4309e5dd7070Spatrick           (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4310e5dd7070Spatrick         continue;
4311e5dd7070Spatrick       // Write down how to convert from a derived pointer to a base pointer.
4312e5dd7070Spatrick       uint32_t OffsetInVBTable = 0;
4313e5dd7070Spatrick       int32_t VBPtrOffset = -1;
4314e5dd7070Spatrick       if (Class.VirtualRoot) {
4315e5dd7070Spatrick         OffsetInVBTable =
4316e5dd7070Spatrick           VTableContext.getVBTableIndex(MostDerivedClass, Class.VirtualRoot)*4;
4317e5dd7070Spatrick         VBPtrOffset = MostDerivedLayout.getVBPtrOffset().getQuantity();
4318e5dd7070Spatrick       }
4319e5dd7070Spatrick 
4320e5dd7070Spatrick       // Turn our record back into a pointer if the exception object is a
4321e5dd7070Spatrick       // pointer.
4322e5dd7070Spatrick       QualType RTTITy = QualType(Class.RD->getTypeForDecl(), 0);
4323e5dd7070Spatrick       if (IsPointer)
4324e5dd7070Spatrick         RTTITy = Context.getPointerType(RTTITy);
4325e5dd7070Spatrick       CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
4326e5dd7070Spatrick                                              VBPtrOffset, OffsetInVBTable));
4327e5dd7070Spatrick     }
4328e5dd7070Spatrick   }
4329e5dd7070Spatrick 
4330e5dd7070Spatrick   // C++14 [except.handle]p3:
4331e5dd7070Spatrick   //   A handler is a match for an exception object of type E if
4332e5dd7070Spatrick   //     - The handler is of type cv T or cv T& and E and T are the same type
4333e5dd7070Spatrick   //       (ignoring the top-level cv-qualifiers)
4334e5dd7070Spatrick   CatchableTypes.insert(getCatchableType(T));
4335e5dd7070Spatrick 
4336e5dd7070Spatrick   // C++14 [except.handle]p3:
4337e5dd7070Spatrick   //   A handler is a match for an exception object of type E if
4338e5dd7070Spatrick   //     - the handler is of type cv T or const T& where T is a pointer type and
4339e5dd7070Spatrick   //       E is a pointer type that can be converted to T by [...]
4340e5dd7070Spatrick   //         - a standard pointer conversion (4.10) not involving conversions to
4341e5dd7070Spatrick   //           pointers to private or protected or ambiguous classes
4342e5dd7070Spatrick   //
4343e5dd7070Spatrick   // C++14 [conv.ptr]p2:
4344e5dd7070Spatrick   //   A prvalue of type "pointer to cv T," where T is an object type, can be
4345e5dd7070Spatrick   //   converted to a prvalue of type "pointer to cv void".
4346e5dd7070Spatrick   if (IsPointer && T->getPointeeType()->isObjectType())
4347e5dd7070Spatrick     CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4348e5dd7070Spatrick 
4349e5dd7070Spatrick   // C++14 [except.handle]p3:
4350e5dd7070Spatrick   //   A handler is a match for an exception object of type E if [...]
4351e5dd7070Spatrick   //     - the handler is of type cv T or const T& where T is a pointer or
4352e5dd7070Spatrick   //       pointer to member type and E is std::nullptr_t.
4353e5dd7070Spatrick   //
4354e5dd7070Spatrick   // We cannot possibly list all possible pointer types here, making this
4355e5dd7070Spatrick   // implementation incompatible with the standard.  However, MSVC includes an
4356e5dd7070Spatrick   // entry for pointer-to-void in this case.  Let's do the same.
4357e5dd7070Spatrick   if (T->isNullPtrType())
4358e5dd7070Spatrick     CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4359e5dd7070Spatrick 
4360e5dd7070Spatrick   uint32_t NumEntries = CatchableTypes.size();
4361e5dd7070Spatrick   llvm::Type *CTType =
4362e5dd7070Spatrick       getImageRelativeType(getCatchableTypeType()->getPointerTo());
4363e5dd7070Spatrick   llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4364e5dd7070Spatrick   llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4365e5dd7070Spatrick   llvm::Constant *Fields[] = {
4366e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, NumEntries), // NumEntries
4367e5dd7070Spatrick       llvm::ConstantArray::get(
4368*12c85518Srobert           AT, llvm::ArrayRef(CatchableTypes.begin(),
4369e5dd7070Spatrick                              CatchableTypes.end())) // CatchableTypes
4370e5dd7070Spatrick   };
4371e5dd7070Spatrick   SmallString<256> MangledName;
4372e5dd7070Spatrick   {
4373e5dd7070Spatrick     llvm::raw_svector_ostream Out(MangledName);
4374e5dd7070Spatrick     getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4375e5dd7070Spatrick   }
4376e5dd7070Spatrick   CTA = new llvm::GlobalVariable(
4377e5dd7070Spatrick       CGM.getModule(), CTAType, /*isConstant=*/true, getLinkageForRTTI(T),
4378e5dd7070Spatrick       llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4379e5dd7070Spatrick   CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4380e5dd7070Spatrick   CTA->setSection(".xdata");
4381e5dd7070Spatrick   if (CTA->isWeakForLinker())
4382e5dd7070Spatrick     CTA->setComdat(CGM.getModule().getOrInsertComdat(CTA->getName()));
4383e5dd7070Spatrick   return CTA;
4384e5dd7070Spatrick }
4385e5dd7070Spatrick 
getThrowInfo(QualType T)4386e5dd7070Spatrick llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) {
4387e5dd7070Spatrick   bool IsConst, IsVolatile, IsUnaligned;
4388e5dd7070Spatrick   T = decomposeTypeForEH(getContext(), T, IsConst, IsVolatile, IsUnaligned);
4389e5dd7070Spatrick 
4390e5dd7070Spatrick   // The CatchableTypeArray enumerates the various (CV-unqualified) types that
4391e5dd7070Spatrick   // the exception object may be caught as.
4392e5dd7070Spatrick   llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4393e5dd7070Spatrick   // The first field in a CatchableTypeArray is the number of CatchableTypes.
4394e5dd7070Spatrick   // This is used as a component of the mangled name which means that we need to
4395e5dd7070Spatrick   // know what it is in order to see if we have previously generated the
4396e5dd7070Spatrick   // ThrowInfo.
4397e5dd7070Spatrick   uint32_t NumEntries =
4398e5dd7070Spatrick       cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
4399e5dd7070Spatrick           ->getLimitedValue();
4400e5dd7070Spatrick 
4401e5dd7070Spatrick   SmallString<256> MangledName;
4402e5dd7070Spatrick   {
4403e5dd7070Spatrick     llvm::raw_svector_ostream Out(MangledName);
4404e5dd7070Spatrick     getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4405e5dd7070Spatrick                                           NumEntries, Out);
4406e5dd7070Spatrick   }
4407e5dd7070Spatrick 
4408e5dd7070Spatrick   // Reuse a previously generated ThrowInfo if we have generated an appropriate
4409e5dd7070Spatrick   // one before.
4410e5dd7070Spatrick   if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
4411e5dd7070Spatrick     return GV;
4412e5dd7070Spatrick 
4413e5dd7070Spatrick   // The RTTI TypeDescriptor uses an unqualified type but catch clauses must
4414e5dd7070Spatrick   // be at least as CV qualified.  Encode this requirement into the Flags
4415e5dd7070Spatrick   // bitfield.
4416e5dd7070Spatrick   uint32_t Flags = 0;
4417e5dd7070Spatrick   if (IsConst)
4418e5dd7070Spatrick     Flags |= 1;
4419e5dd7070Spatrick   if (IsVolatile)
4420e5dd7070Spatrick     Flags |= 2;
4421e5dd7070Spatrick   if (IsUnaligned)
4422e5dd7070Spatrick     Flags |= 4;
4423e5dd7070Spatrick 
4424e5dd7070Spatrick   // The cleanup-function (a destructor) must be called when the exception
4425e5dd7070Spatrick   // object's lifetime ends.
4426e5dd7070Spatrick   llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.Int8PtrTy);
4427e5dd7070Spatrick   if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
4428e5dd7070Spatrick     if (CXXDestructorDecl *DtorD = RD->getDestructor())
4429e5dd7070Spatrick       if (!DtorD->isTrivial())
4430e5dd7070Spatrick         CleanupFn = llvm::ConstantExpr::getBitCast(
4431e5dd7070Spatrick             CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete)),
4432e5dd7070Spatrick             CGM.Int8PtrTy);
4433e5dd7070Spatrick   // This is unused as far as we can tell, initialize it to null.
4434e5dd7070Spatrick   llvm::Constant *ForwardCompat =
4435e5dd7070Spatrick       getImageRelativeConstant(llvm::Constant::getNullValue(CGM.Int8PtrTy));
4436e5dd7070Spatrick   llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4437e5dd7070Spatrick       llvm::ConstantExpr::getBitCast(CTA, CGM.Int8PtrTy));
4438e5dd7070Spatrick   llvm::StructType *TIType = getThrowInfoType();
4439e5dd7070Spatrick   llvm::Constant *Fields[] = {
4440e5dd7070Spatrick       llvm::ConstantInt::get(CGM.IntTy, Flags), // Flags
4441e5dd7070Spatrick       getImageRelativeConstant(CleanupFn),      // CleanupFn
4442e5dd7070Spatrick       ForwardCompat,                            // ForwardCompat
4443e5dd7070Spatrick       PointerToCatchableTypes                   // CatchableTypeArray
4444e5dd7070Spatrick   };
4445e5dd7070Spatrick   auto *GV = new llvm::GlobalVariable(
4446e5dd7070Spatrick       CGM.getModule(), TIType, /*isConstant=*/true, getLinkageForRTTI(T),
4447a9ac8606Spatrick       llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4448e5dd7070Spatrick   GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4449e5dd7070Spatrick   GV->setSection(".xdata");
4450e5dd7070Spatrick   if (GV->isWeakForLinker())
4451e5dd7070Spatrick     GV->setComdat(CGM.getModule().getOrInsertComdat(GV->getName()));
4452e5dd7070Spatrick   return GV;
4453e5dd7070Spatrick }
4454e5dd7070Spatrick 
emitThrow(CodeGenFunction & CGF,const CXXThrowExpr * E)4455e5dd7070Spatrick void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
4456e5dd7070Spatrick   const Expr *SubExpr = E->getSubExpr();
4457*12c85518Srobert   assert(SubExpr && "SubExpr cannot be null");
4458e5dd7070Spatrick   QualType ThrowType = SubExpr->getType();
4459e5dd7070Spatrick   // The exception object lives on the stack and it's address is passed to the
4460e5dd7070Spatrick   // runtime function.
4461e5dd7070Spatrick   Address AI = CGF.CreateMemTemp(ThrowType);
4462e5dd7070Spatrick   CGF.EmitAnyExprToMem(SubExpr, AI, ThrowType.getQualifiers(),
4463e5dd7070Spatrick                        /*IsInit=*/true);
4464e5dd7070Spatrick 
4465e5dd7070Spatrick   // The so-called ThrowInfo is used to describe how the exception object may be
4466e5dd7070Spatrick   // caught.
4467e5dd7070Spatrick   llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4468e5dd7070Spatrick 
4469e5dd7070Spatrick   // Call into the runtime to throw the exception.
4470e5dd7070Spatrick   llvm::Value *Args[] = {
4471e5dd7070Spatrick     CGF.Builder.CreateBitCast(AI.getPointer(), CGM.Int8PtrTy),
4472e5dd7070Spatrick     TI
4473e5dd7070Spatrick   };
4474e5dd7070Spatrick   CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(), Args);
4475e5dd7070Spatrick }
4476e5dd7070Spatrick 
4477e5dd7070Spatrick std::pair<llvm::Value *, const CXXRecordDecl *>
LoadVTablePtr(CodeGenFunction & CGF,Address This,const CXXRecordDecl * RD)4478e5dd7070Spatrick MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
4479e5dd7070Spatrick                                const CXXRecordDecl *RD) {
4480e5dd7070Spatrick   std::tie(This, std::ignore, RD) =
4481e5dd7070Spatrick       performBaseAdjustment(CGF, This, QualType(RD->getTypeForDecl(), 0));
4482e5dd7070Spatrick   return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
4483e5dd7070Spatrick }
4484a9ac8606Spatrick 
isPermittedToBeHomogeneousAggregate(const CXXRecordDecl * RD) const4485a9ac8606Spatrick bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4486*12c85518Srobert     const CXXRecordDecl *RD) const {
4487*12c85518Srobert   // All aggregates are permitted to be HFA on non-ARM platforms, which mostly
4488*12c85518Srobert   // affects vectorcall on x64/x86.
4489*12c85518Srobert   if (!CGM.getTarget().getTriple().isAArch64())
4490*12c85518Srobert     return true;
4491*12c85518Srobert   // MSVC Windows on Arm64 has its own rules for determining if a type is HFA
4492*12c85518Srobert   // that are inconsistent with the AAPCS64 ABI. The following are our best
4493*12c85518Srobert   // determination of those rules so far, based on observation of MSVC's
4494*12c85518Srobert   // behavior.
4495*12c85518Srobert   if (RD->isEmpty())
4496*12c85518Srobert     return false;
4497*12c85518Srobert   if (RD->isPolymorphic())
4498*12c85518Srobert     return false;
4499*12c85518Srobert   if (RD->hasNonTrivialCopyAssignment())
4500*12c85518Srobert     return false;
4501*12c85518Srobert   if (RD->hasNonTrivialDestructor())
4502*12c85518Srobert     return false;
4503*12c85518Srobert   if (RD->hasNonTrivialDefaultConstructor())
4504*12c85518Srobert     return false;
4505*12c85518Srobert   // These two are somewhat redundant given the caller
4506*12c85518Srobert   // (ABIInfo::isHomogeneousAggregate) checks the bases and fields, but that
4507*12c85518Srobert   // caller doesn't consider empty bases/fields to be non-homogenous, but it
4508*12c85518Srobert   // looks like Microsoft's AArch64 ABI does care about these empty types &
4509*12c85518Srobert   // anything containing/derived from one is non-homogeneous.
4510*12c85518Srobert   // Instead we could add another CXXABI entry point to query this property and
4511*12c85518Srobert   // have ABIInfo::isHomogeneousAggregate use that property.
4512*12c85518Srobert   // I don't think any other of the features listed above could be true of a
4513*12c85518Srobert   // base/field while not true of the outer struct. For example, if you have a
4514*12c85518Srobert   // base/field that has an non-trivial copy assignment/dtor/default ctor, then
4515*12c85518Srobert   // the outer struct's corresponding operation must be non-trivial.
4516*12c85518Srobert   for (const CXXBaseSpecifier &B : RD->bases()) {
4517*12c85518Srobert     if (const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4518*12c85518Srobert       if (!isPermittedToBeHomogeneousAggregate(FRD))
4519*12c85518Srobert         return false;
4520*12c85518Srobert     }
4521*12c85518Srobert   }
4522*12c85518Srobert   // empty fields seem to be caught by the ABIInfo::isHomogeneousAggregate
4523*12c85518Srobert   // checking for padding - but maybe there are ways to end up with an empty
4524*12c85518Srobert   // field without padding? Not that I know of, so don't check fields here &
4525*12c85518Srobert   // rely on the padding check.
4526*12c85518Srobert   return true;
4527a9ac8606Spatrick }
4528