xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/ItaniumCXXABI.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===------- ItaniumCXXABI.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 Itanium C++ ABI.  The class
10e5dd7070Spatrick // in this file generates structures that follow the Itanium C++ ABI, which is
11e5dd7070Spatrick // documented at:
12a9ac8606Spatrick //  https://itanium-cxx-abi.github.io/cxx-abi/abi.html
13a9ac8606Spatrick //  https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
14e5dd7070Spatrick //
15e5dd7070Spatrick // It also supports the closely-related ARM ABI, documented at:
16a9ac8606Spatrick // https://developer.arm.com/documentation/ihi0041/g/
17e5dd7070Spatrick //
18e5dd7070Spatrick //===----------------------------------------------------------------------===//
19e5dd7070Spatrick 
20e5dd7070Spatrick #include "CGCXXABI.h"
21e5dd7070Spatrick #include "CGCleanup.h"
22e5dd7070Spatrick #include "CGRecordLayout.h"
23e5dd7070Spatrick #include "CGVTables.h"
24e5dd7070Spatrick #include "CodeGenFunction.h"
25e5dd7070Spatrick #include "CodeGenModule.h"
26e5dd7070Spatrick #include "TargetInfo.h"
27e5dd7070Spatrick #include "clang/AST/Attr.h"
28e5dd7070Spatrick #include "clang/AST/Mangle.h"
29e5dd7070Spatrick #include "clang/AST/StmtCXX.h"
30e5dd7070Spatrick #include "clang/AST/Type.h"
31e5dd7070Spatrick #include "clang/CodeGen/ConstantInitBuilder.h"
32e5dd7070Spatrick #include "llvm/IR/DataLayout.h"
33e5dd7070Spatrick #include "llvm/IR/GlobalValue.h"
34e5dd7070Spatrick #include "llvm/IR/Instructions.h"
35e5dd7070Spatrick #include "llvm/IR/Intrinsics.h"
36e5dd7070Spatrick #include "llvm/IR/Value.h"
37e5dd7070Spatrick #include "llvm/Support/ScopedPrinter.h"
38e5dd7070Spatrick 
39e5dd7070Spatrick using namespace clang;
40e5dd7070Spatrick using namespace CodeGen;
41e5dd7070Spatrick 
42e5dd7070Spatrick namespace {
43e5dd7070Spatrick class ItaniumCXXABI : public CodeGen::CGCXXABI {
44e5dd7070Spatrick   /// VTables - All the vtables which have been defined.
45e5dd7070Spatrick   llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
46e5dd7070Spatrick 
47e5dd7070Spatrick   /// All the thread wrapper functions that have been used.
48e5dd7070Spatrick   llvm::SmallVector<std::pair<const VarDecl *, llvm::Function *>, 8>
49e5dd7070Spatrick       ThreadWrappers;
50e5dd7070Spatrick 
51e5dd7070Spatrick protected:
52e5dd7070Spatrick   bool UseARMMethodPtrABI;
53e5dd7070Spatrick   bool UseARMGuardVarABI;
54e5dd7070Spatrick   bool Use32BitVTableOffsetABI;
55e5dd7070Spatrick 
getMangleContext()56e5dd7070Spatrick   ItaniumMangleContext &getMangleContext() {
57e5dd7070Spatrick     return cast<ItaniumMangleContext>(CodeGen::CGCXXABI::getMangleContext());
58e5dd7070Spatrick   }
59e5dd7070Spatrick 
60e5dd7070Spatrick public:
ItaniumCXXABI(CodeGen::CodeGenModule & CGM,bool UseARMMethodPtrABI=false,bool UseARMGuardVarABI=false)61e5dd7070Spatrick   ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
62e5dd7070Spatrick                 bool UseARMMethodPtrABI = false,
63e5dd7070Spatrick                 bool UseARMGuardVarABI = false) :
64e5dd7070Spatrick     CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
65e5dd7070Spatrick     UseARMGuardVarABI(UseARMGuardVarABI),
66e5dd7070Spatrick     Use32BitVTableOffsetABI(false) { }
67e5dd7070Spatrick 
68e5dd7070Spatrick   bool classifyReturnType(CGFunctionInfo &FI) const override;
69e5dd7070Spatrick 
getRecordArgABI(const CXXRecordDecl * RD) const70e5dd7070Spatrick   RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
71e5dd7070Spatrick     // If C++ prohibits us from making a copy, pass by address.
72e5dd7070Spatrick     if (!RD->canPassInRegisters())
73e5dd7070Spatrick       return RAA_Indirect;
74e5dd7070Spatrick     return RAA_Default;
75e5dd7070Spatrick   }
76e5dd7070Spatrick 
isThisCompleteObject(GlobalDecl GD) const77e5dd7070Spatrick   bool isThisCompleteObject(GlobalDecl GD) const override {
78e5dd7070Spatrick     // The Itanium ABI has separate complete-object vs.  base-object
79e5dd7070Spatrick     // variants of both constructors and destructors.
80e5dd7070Spatrick     if (isa<CXXDestructorDecl>(GD.getDecl())) {
81e5dd7070Spatrick       switch (GD.getDtorType()) {
82e5dd7070Spatrick       case Dtor_Complete:
83e5dd7070Spatrick       case Dtor_Deleting:
84e5dd7070Spatrick         return true;
85e5dd7070Spatrick 
86e5dd7070Spatrick       case Dtor_Base:
87e5dd7070Spatrick         return false;
88e5dd7070Spatrick 
89e5dd7070Spatrick       case Dtor_Comdat:
90e5dd7070Spatrick         llvm_unreachable("emitting dtor comdat as function?");
91e5dd7070Spatrick       }
92e5dd7070Spatrick       llvm_unreachable("bad dtor kind");
93e5dd7070Spatrick     }
94e5dd7070Spatrick     if (isa<CXXConstructorDecl>(GD.getDecl())) {
95e5dd7070Spatrick       switch (GD.getCtorType()) {
96e5dd7070Spatrick       case Ctor_Complete:
97e5dd7070Spatrick         return true;
98e5dd7070Spatrick 
99e5dd7070Spatrick       case Ctor_Base:
100e5dd7070Spatrick         return false;
101e5dd7070Spatrick 
102e5dd7070Spatrick       case Ctor_CopyingClosure:
103e5dd7070Spatrick       case Ctor_DefaultClosure:
104e5dd7070Spatrick         llvm_unreachable("closure ctors in Itanium ABI?");
105e5dd7070Spatrick 
106e5dd7070Spatrick       case Ctor_Comdat:
107e5dd7070Spatrick         llvm_unreachable("emitting ctor comdat as function?");
108e5dd7070Spatrick       }
109e5dd7070Spatrick       llvm_unreachable("bad dtor kind");
110e5dd7070Spatrick     }
111e5dd7070Spatrick 
112e5dd7070Spatrick     // No other kinds.
113e5dd7070Spatrick     return false;
114e5dd7070Spatrick   }
115e5dd7070Spatrick 
116e5dd7070Spatrick   bool isZeroInitializable(const MemberPointerType *MPT) override;
117e5dd7070Spatrick 
118e5dd7070Spatrick   llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
119e5dd7070Spatrick 
120e5dd7070Spatrick   CGCallee
121e5dd7070Spatrick     EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
122e5dd7070Spatrick                                     const Expr *E,
123e5dd7070Spatrick                                     Address This,
124e5dd7070Spatrick                                     llvm::Value *&ThisPtrForCall,
125e5dd7070Spatrick                                     llvm::Value *MemFnPtr,
126e5dd7070Spatrick                                     const MemberPointerType *MPT) override;
127e5dd7070Spatrick 
128e5dd7070Spatrick   llvm::Value *
129e5dd7070Spatrick     EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
130e5dd7070Spatrick                                  Address Base,
131e5dd7070Spatrick                                  llvm::Value *MemPtr,
132e5dd7070Spatrick                                  const MemberPointerType *MPT) override;
133e5dd7070Spatrick 
134e5dd7070Spatrick   llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
135e5dd7070Spatrick                                            const CastExpr *E,
136e5dd7070Spatrick                                            llvm::Value *Src) override;
137e5dd7070Spatrick   llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
138e5dd7070Spatrick                                               llvm::Constant *Src) override;
139e5dd7070Spatrick 
140e5dd7070Spatrick   llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override;
141e5dd7070Spatrick 
142e5dd7070Spatrick   llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD) override;
143e5dd7070Spatrick   llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
144e5dd7070Spatrick                                         CharUnits offset) override;
145e5dd7070Spatrick   llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override;
146e5dd7070Spatrick   llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD,
147e5dd7070Spatrick                                      CharUnits ThisAdjustment);
148e5dd7070Spatrick 
149e5dd7070Spatrick   llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
150e5dd7070Spatrick                                            llvm::Value *L, llvm::Value *R,
151e5dd7070Spatrick                                            const MemberPointerType *MPT,
152e5dd7070Spatrick                                            bool Inequality) override;
153e5dd7070Spatrick 
154e5dd7070Spatrick   llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
155e5dd7070Spatrick                                          llvm::Value *Addr,
156e5dd7070Spatrick                                          const MemberPointerType *MPT) override;
157e5dd7070Spatrick 
158e5dd7070Spatrick   void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE,
159e5dd7070Spatrick                                Address Ptr, QualType ElementType,
160e5dd7070Spatrick                                const CXXDestructorDecl *Dtor) override;
161e5dd7070Spatrick 
162e5dd7070Spatrick   void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) override;
163e5dd7070Spatrick   void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) override;
164e5dd7070Spatrick 
165e5dd7070Spatrick   void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override;
166e5dd7070Spatrick 
167e5dd7070Spatrick   llvm::CallInst *
168e5dd7070Spatrick   emitTerminateForUnexpectedException(CodeGenFunction &CGF,
169e5dd7070Spatrick                                       llvm::Value *Exn) override;
170e5dd7070Spatrick 
171e5dd7070Spatrick   void EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD);
172e5dd7070Spatrick   llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
173e5dd7070Spatrick   CatchTypeInfo
getAddrOfCXXCatchHandlerType(QualType Ty,QualType CatchHandlerType)174e5dd7070Spatrick   getAddrOfCXXCatchHandlerType(QualType Ty,
175e5dd7070Spatrick                                QualType CatchHandlerType) override {
176e5dd7070Spatrick     return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0};
177e5dd7070Spatrick   }
178e5dd7070Spatrick 
179e5dd7070Spatrick   bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override;
180e5dd7070Spatrick   void EmitBadTypeidCall(CodeGenFunction &CGF) override;
181e5dd7070Spatrick   llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
182e5dd7070Spatrick                           Address ThisPtr,
183e5dd7070Spatrick                           llvm::Type *StdTypeInfoPtrTy) override;
184e5dd7070Spatrick 
185e5dd7070Spatrick   bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
186e5dd7070Spatrick                                           QualType SrcRecordTy) override;
187e5dd7070Spatrick 
188e5dd7070Spatrick   llvm::Value *EmitDynamicCastCall(CodeGenFunction &CGF, Address Value,
189e5dd7070Spatrick                                    QualType SrcRecordTy, QualType DestTy,
190e5dd7070Spatrick                                    QualType DestRecordTy,
191e5dd7070Spatrick                                    llvm::BasicBlock *CastEnd) override;
192e5dd7070Spatrick 
193e5dd7070Spatrick   llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF, Address Value,
194e5dd7070Spatrick                                      QualType SrcRecordTy,
195e5dd7070Spatrick                                      QualType DestTy) override;
196e5dd7070Spatrick 
197e5dd7070Spatrick   bool EmitBadCastCall(CodeGenFunction &CGF) override;
198e5dd7070Spatrick 
199e5dd7070Spatrick   llvm::Value *
200e5dd7070Spatrick     GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
201e5dd7070Spatrick                               const CXXRecordDecl *ClassDecl,
202e5dd7070Spatrick                               const CXXRecordDecl *BaseClassDecl) override;
203e5dd7070Spatrick 
204e5dd7070Spatrick   void EmitCXXConstructors(const CXXConstructorDecl *D) override;
205e5dd7070Spatrick 
206ec727ea7Spatrick   AddedStructorArgCounts
207e5dd7070Spatrick   buildStructorSignature(GlobalDecl GD,
208e5dd7070Spatrick                          SmallVectorImpl<CanQualType> &ArgTys) override;
209e5dd7070Spatrick 
useThunkForDtorVariant(const CXXDestructorDecl * Dtor,CXXDtorType DT) const210e5dd7070Spatrick   bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
211e5dd7070Spatrick                               CXXDtorType DT) const override {
212e5dd7070Spatrick     // Itanium does not emit any destructor variant as an inline thunk.
213e5dd7070Spatrick     // Delegating may occur as an optimization, but all variants are either
214e5dd7070Spatrick     // emitted with external linkage or as linkonce if they are inline and used.
215e5dd7070Spatrick     return false;
216e5dd7070Spatrick   }
217e5dd7070Spatrick 
218e5dd7070Spatrick   void EmitCXXDestructors(const CXXDestructorDecl *D) override;
219e5dd7070Spatrick 
220e5dd7070Spatrick   void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
221e5dd7070Spatrick                                  FunctionArgList &Params) override;
222e5dd7070Spatrick 
223e5dd7070Spatrick   void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
224e5dd7070Spatrick 
225ec727ea7Spatrick   AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
226ec727ea7Spatrick                                                const CXXConstructorDecl *D,
227ec727ea7Spatrick                                                CXXCtorType Type,
228ec727ea7Spatrick                                                bool ForVirtualBase,
229ec727ea7Spatrick                                                bool Delegating) override;
230ec727ea7Spatrick 
231ec727ea7Spatrick   llvm::Value *getCXXDestructorImplicitParam(CodeGenFunction &CGF,
232ec727ea7Spatrick                                              const CXXDestructorDecl *DD,
233ec727ea7Spatrick                                              CXXDtorType Type,
234ec727ea7Spatrick                                              bool ForVirtualBase,
235ec727ea7Spatrick                                              bool Delegating) override;
236e5dd7070Spatrick 
237e5dd7070Spatrick   void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
238e5dd7070Spatrick                           CXXDtorType Type, bool ForVirtualBase,
239e5dd7070Spatrick                           bool Delegating, Address This,
240e5dd7070Spatrick                           QualType ThisTy) override;
241e5dd7070Spatrick 
242e5dd7070Spatrick   void emitVTableDefinitions(CodeGenVTables &CGVT,
243e5dd7070Spatrick                              const CXXRecordDecl *RD) override;
244e5dd7070Spatrick 
245e5dd7070Spatrick   bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
246e5dd7070Spatrick                                            CodeGenFunction::VPtr Vptr) override;
247e5dd7070Spatrick 
doStructorsInitializeVPtrs(const CXXRecordDecl * VTableClass)248e5dd7070Spatrick   bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) override {
249e5dd7070Spatrick     return true;
250e5dd7070Spatrick   }
251e5dd7070Spatrick 
252e5dd7070Spatrick   llvm::Constant *
253e5dd7070Spatrick   getVTableAddressPoint(BaseSubobject Base,
254e5dd7070Spatrick                         const CXXRecordDecl *VTableClass) override;
255e5dd7070Spatrick 
256e5dd7070Spatrick   llvm::Value *getVTableAddressPointInStructor(
257e5dd7070Spatrick       CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
258e5dd7070Spatrick       BaseSubobject Base, const CXXRecordDecl *NearestVBase) override;
259e5dd7070Spatrick 
260e5dd7070Spatrick   llvm::Value *getVTableAddressPointInStructorWithVTT(
261e5dd7070Spatrick       CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
262e5dd7070Spatrick       BaseSubobject Base, const CXXRecordDecl *NearestVBase);
263e5dd7070Spatrick 
264e5dd7070Spatrick   llvm::Constant *
265e5dd7070Spatrick   getVTableAddressPointForConstExpr(BaseSubobject Base,
266e5dd7070Spatrick                                     const CXXRecordDecl *VTableClass) override;
267e5dd7070Spatrick 
268e5dd7070Spatrick   llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
269e5dd7070Spatrick                                         CharUnits VPtrOffset) override;
270e5dd7070Spatrick 
271e5dd7070Spatrick   CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
272e5dd7070Spatrick                                      Address This, llvm::Type *Ty,
273e5dd7070Spatrick                                      SourceLocation Loc) override;
274e5dd7070Spatrick 
275e5dd7070Spatrick   llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
276e5dd7070Spatrick                                          const CXXDestructorDecl *Dtor,
277e5dd7070Spatrick                                          CXXDtorType DtorType, Address This,
278e5dd7070Spatrick                                          DeleteOrMemberCallExpr E) override;
279e5dd7070Spatrick 
280e5dd7070Spatrick   void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
281e5dd7070Spatrick 
282e5dd7070Spatrick   bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const override;
283e5dd7070Spatrick   bool canSpeculativelyEmitVTableAsBaseClass(const CXXRecordDecl *RD) const;
284e5dd7070Spatrick 
setThunkLinkage(llvm::Function * Thunk,bool ForVTable,GlobalDecl GD,bool ReturnAdjustment)285e5dd7070Spatrick   void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD,
286e5dd7070Spatrick                        bool ReturnAdjustment) override {
287e5dd7070Spatrick     // Allow inlining of thunks by emitting them with available_externally
288e5dd7070Spatrick     // linkage together with vtables when needed.
289e5dd7070Spatrick     if (ForVTable && !Thunk->hasLocalLinkage())
290e5dd7070Spatrick       Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
291e5dd7070Spatrick     CGM.setGVProperties(Thunk, GD);
292e5dd7070Spatrick   }
293e5dd7070Spatrick 
exportThunk()294e5dd7070Spatrick   bool exportThunk() override { return true; }
295e5dd7070Spatrick 
296e5dd7070Spatrick   llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
297e5dd7070Spatrick                                      const ThisAdjustment &TA) override;
298e5dd7070Spatrick 
299e5dd7070Spatrick   llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
300e5dd7070Spatrick                                        const ReturnAdjustment &RA) override;
301e5dd7070Spatrick 
getSrcArgforCopyCtor(const CXXConstructorDecl *,FunctionArgList & Args) const302e5dd7070Spatrick   size_t getSrcArgforCopyCtor(const CXXConstructorDecl *,
303e5dd7070Spatrick                               FunctionArgList &Args) const override {
304e5dd7070Spatrick     assert(!Args.empty() && "expected the arglist to not be empty!");
305e5dd7070Spatrick     return Args.size() - 1;
306e5dd7070Spatrick   }
307e5dd7070Spatrick 
GetPureVirtualCallName()308e5dd7070Spatrick   StringRef GetPureVirtualCallName() override { return "__cxa_pure_virtual"; }
GetDeletedVirtualCallName()309e5dd7070Spatrick   StringRef GetDeletedVirtualCallName() override
310e5dd7070Spatrick     { return "__cxa_deleted_virtual"; }
311e5dd7070Spatrick 
312e5dd7070Spatrick   CharUnits getArrayCookieSizeImpl(QualType elementType) override;
313e5dd7070Spatrick   Address InitializeArrayCookie(CodeGenFunction &CGF,
314e5dd7070Spatrick                                 Address NewPtr,
315e5dd7070Spatrick                                 llvm::Value *NumElements,
316e5dd7070Spatrick                                 const CXXNewExpr *expr,
317e5dd7070Spatrick                                 QualType ElementType) override;
318e5dd7070Spatrick   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
319e5dd7070Spatrick                                    Address allocPtr,
320e5dd7070Spatrick                                    CharUnits cookieSize) override;
321e5dd7070Spatrick 
322e5dd7070Spatrick   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
323e5dd7070Spatrick                        llvm::GlobalVariable *DeclPtr,
324e5dd7070Spatrick                        bool PerformInit) override;
325e5dd7070Spatrick   void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
326e5dd7070Spatrick                           llvm::FunctionCallee dtor,
327e5dd7070Spatrick                           llvm::Constant *addr) override;
328e5dd7070Spatrick 
329e5dd7070Spatrick   llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD,
330e5dd7070Spatrick                                                 llvm::Value *Val);
331e5dd7070Spatrick   void EmitThreadLocalInitFuncs(
332e5dd7070Spatrick       CodeGenModule &CGM,
333e5dd7070Spatrick       ArrayRef<const VarDecl *> CXXThreadLocals,
334e5dd7070Spatrick       ArrayRef<llvm::Function *> CXXThreadLocalInits,
335e5dd7070Spatrick       ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override;
336e5dd7070Spatrick 
usesThreadWrapperFunction(const VarDecl * VD) const337e5dd7070Spatrick   bool usesThreadWrapperFunction(const VarDecl *VD) const override {
338e5dd7070Spatrick     return !isEmittedWithConstantInitializer(VD) ||
339*12c85518Srobert            mayNeedDestruction(VD);
340e5dd7070Spatrick   }
341e5dd7070Spatrick   LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,
342e5dd7070Spatrick                                       QualType LValType) override;
343e5dd7070Spatrick 
344e5dd7070Spatrick   bool NeedsVTTParameter(GlobalDecl GD) override;
345e5dd7070Spatrick 
346e5dd7070Spatrick   /**************************** RTTI Uniqueness ******************************/
347e5dd7070Spatrick 
348e5dd7070Spatrick protected:
349e5dd7070Spatrick   /// Returns true if the ABI requires RTTI type_info objects to be unique
350e5dd7070Spatrick   /// across a program.
shouldRTTIBeUnique() const351e5dd7070Spatrick   virtual bool shouldRTTIBeUnique() const { return true; }
352e5dd7070Spatrick 
353e5dd7070Spatrick public:
354e5dd7070Spatrick   /// What sort of unique-RTTI behavior should we use?
355e5dd7070Spatrick   enum RTTIUniquenessKind {
356e5dd7070Spatrick     /// We are guaranteeing, or need to guarantee, that the RTTI string
357e5dd7070Spatrick     /// is unique.
358e5dd7070Spatrick     RUK_Unique,
359e5dd7070Spatrick 
360e5dd7070Spatrick     /// We are not guaranteeing uniqueness for the RTTI string, so we
361e5dd7070Spatrick     /// can demote to hidden visibility but must use string comparisons.
362e5dd7070Spatrick     RUK_NonUniqueHidden,
363e5dd7070Spatrick 
364e5dd7070Spatrick     /// We are not guaranteeing uniqueness for the RTTI string, so we
365e5dd7070Spatrick     /// have to use string comparisons, but we also have to emit it with
366e5dd7070Spatrick     /// non-hidden visibility.
367e5dd7070Spatrick     RUK_NonUniqueVisible
368e5dd7070Spatrick   };
369e5dd7070Spatrick 
370e5dd7070Spatrick   /// Return the required visibility status for the given type and linkage in
371e5dd7070Spatrick   /// the current ABI.
372e5dd7070Spatrick   RTTIUniquenessKind
373e5dd7070Spatrick   classifyRTTIUniqueness(QualType CanTy,
374e5dd7070Spatrick                          llvm::GlobalValue::LinkageTypes Linkage) const;
375e5dd7070Spatrick   friend class ItaniumRTTIBuilder;
376e5dd7070Spatrick 
377e5dd7070Spatrick   void emitCXXStructor(GlobalDecl GD) override;
378e5dd7070Spatrick 
379e5dd7070Spatrick   std::pair<llvm::Value *, const CXXRecordDecl *>
380e5dd7070Spatrick   LoadVTablePtr(CodeGenFunction &CGF, Address This,
381e5dd7070Spatrick                 const CXXRecordDecl *RD) override;
382e5dd7070Spatrick 
383e5dd7070Spatrick  private:
hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl * RD) const384e5dd7070Spatrick    bool hasAnyUnusedVirtualInlineFunction(const CXXRecordDecl *RD) const {
385e5dd7070Spatrick      const auto &VtableLayout =
386e5dd7070Spatrick          CGM.getItaniumVTableContext().getVTableLayout(RD);
387e5dd7070Spatrick 
388e5dd7070Spatrick      for (const auto &VtableComponent : VtableLayout.vtable_components()) {
389e5dd7070Spatrick        // Skip empty slot.
390e5dd7070Spatrick        if (!VtableComponent.isUsedFunctionPointerKind())
391e5dd7070Spatrick          continue;
392e5dd7070Spatrick 
393e5dd7070Spatrick        const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
394e5dd7070Spatrick        if (!Method->getCanonicalDecl()->isInlined())
395e5dd7070Spatrick          continue;
396e5dd7070Spatrick 
397e5dd7070Spatrick        StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
398e5dd7070Spatrick        auto *Entry = CGM.GetGlobalValue(Name);
399e5dd7070Spatrick        // This checks if virtual inline function has already been emitted.
400e5dd7070Spatrick        // Note that it is possible that this inline function would be emitted
401e5dd7070Spatrick        // after trying to emit vtable speculatively. Because of this we do
402e5dd7070Spatrick        // an extra pass after emitting all deferred vtables to find and emit
403e5dd7070Spatrick        // these vtables opportunistically.
404e5dd7070Spatrick        if (!Entry || Entry->isDeclaration())
405e5dd7070Spatrick          return true;
406e5dd7070Spatrick      }
407e5dd7070Spatrick      return false;
408e5dd7070Spatrick   }
409e5dd7070Spatrick 
isVTableHidden(const CXXRecordDecl * RD) const410e5dd7070Spatrick   bool isVTableHidden(const CXXRecordDecl *RD) const {
411e5dd7070Spatrick     const auto &VtableLayout =
412e5dd7070Spatrick             CGM.getItaniumVTableContext().getVTableLayout(RD);
413e5dd7070Spatrick 
414e5dd7070Spatrick     for (const auto &VtableComponent : VtableLayout.vtable_components()) {
415e5dd7070Spatrick       if (VtableComponent.isRTTIKind()) {
416e5dd7070Spatrick         const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
417e5dd7070Spatrick         if (RTTIDecl->getVisibility() == Visibility::HiddenVisibility)
418e5dd7070Spatrick           return true;
419e5dd7070Spatrick       } else if (VtableComponent.isUsedFunctionPointerKind()) {
420e5dd7070Spatrick         const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
421e5dd7070Spatrick         if (Method->getVisibility() == Visibility::HiddenVisibility &&
422e5dd7070Spatrick             !Method->isDefined())
423e5dd7070Spatrick           return true;
424e5dd7070Spatrick       }
425e5dd7070Spatrick     }
426e5dd7070Spatrick     return false;
427e5dd7070Spatrick   }
428e5dd7070Spatrick };
429e5dd7070Spatrick 
430e5dd7070Spatrick class ARMCXXABI : public ItaniumCXXABI {
431e5dd7070Spatrick public:
ARMCXXABI(CodeGen::CodeGenModule & CGM)432e5dd7070Spatrick   ARMCXXABI(CodeGen::CodeGenModule &CGM) :
433e5dd7070Spatrick     ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true,
434e5dd7070Spatrick                   /*UseARMGuardVarABI=*/true) {}
435e5dd7070Spatrick 
constructorsAndDestructorsReturnThis() const436*12c85518Srobert   bool constructorsAndDestructorsReturnThis() const override { return true; }
437e5dd7070Spatrick 
438e5dd7070Spatrick   void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,
439e5dd7070Spatrick                            QualType ResTy) override;
440e5dd7070Spatrick 
441e5dd7070Spatrick   CharUnits getArrayCookieSizeImpl(QualType elementType) override;
442e5dd7070Spatrick   Address InitializeArrayCookie(CodeGenFunction &CGF,
443e5dd7070Spatrick                                 Address NewPtr,
444e5dd7070Spatrick                                 llvm::Value *NumElements,
445e5dd7070Spatrick                                 const CXXNewExpr *expr,
446e5dd7070Spatrick                                 QualType ElementType) override;
447e5dd7070Spatrick   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr,
448e5dd7070Spatrick                                    CharUnits cookieSize) override;
449e5dd7070Spatrick };
450e5dd7070Spatrick 
451a9ac8606Spatrick class AppleARM64CXXABI : public ARMCXXABI {
452e5dd7070Spatrick public:
AppleARM64CXXABI(CodeGen::CodeGenModule & CGM)453a9ac8606Spatrick   AppleARM64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {
454e5dd7070Spatrick     Use32BitVTableOffsetABI = true;
455e5dd7070Spatrick   }
456e5dd7070Spatrick 
457e5dd7070Spatrick   // ARM64 libraries are prepared for non-unique RTTI.
shouldRTTIBeUnique() const458e5dd7070Spatrick   bool shouldRTTIBeUnique() const override { return false; }
459e5dd7070Spatrick };
460e5dd7070Spatrick 
461e5dd7070Spatrick class FuchsiaCXXABI final : public ItaniumCXXABI {
462e5dd7070Spatrick public:
FuchsiaCXXABI(CodeGen::CodeGenModule & CGM)463e5dd7070Spatrick   explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM)
464e5dd7070Spatrick       : ItaniumCXXABI(CGM) {}
465e5dd7070Spatrick 
466e5dd7070Spatrick private:
constructorsAndDestructorsReturnThis() const467*12c85518Srobert   bool constructorsAndDestructorsReturnThis() const override { return true; }
468e5dd7070Spatrick };
469e5dd7070Spatrick 
470e5dd7070Spatrick class WebAssemblyCXXABI final : public ItaniumCXXABI {
471e5dd7070Spatrick public:
WebAssemblyCXXABI(CodeGen::CodeGenModule & CGM)472e5dd7070Spatrick   explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM)
473e5dd7070Spatrick       : ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true,
474e5dd7070Spatrick                       /*UseARMGuardVarABI=*/true) {}
475e5dd7070Spatrick   void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) override;
476a9ac8606Spatrick   llvm::CallInst *
477a9ac8606Spatrick   emitTerminateForUnexpectedException(CodeGenFunction &CGF,
478a9ac8606Spatrick                                       llvm::Value *Exn) override;
479e5dd7070Spatrick 
480e5dd7070Spatrick private:
constructorsAndDestructorsReturnThis() const481*12c85518Srobert   bool constructorsAndDestructorsReturnThis() const override { return true; }
canCallMismatchedFunctionType() const482e5dd7070Spatrick   bool canCallMismatchedFunctionType() const override { return false; }
483e5dd7070Spatrick };
484ec727ea7Spatrick 
485ec727ea7Spatrick class XLCXXABI final : public ItaniumCXXABI {
486ec727ea7Spatrick public:
XLCXXABI(CodeGen::CodeGenModule & CGM)487ec727ea7Spatrick   explicit XLCXXABI(CodeGen::CodeGenModule &CGM)
488ec727ea7Spatrick       : ItaniumCXXABI(CGM) {}
489ec727ea7Spatrick 
490ec727ea7Spatrick   void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
491ec727ea7Spatrick                           llvm::FunctionCallee dtor,
492ec727ea7Spatrick                           llvm::Constant *addr) override;
493ec727ea7Spatrick 
useSinitAndSterm() const494ec727ea7Spatrick   bool useSinitAndSterm() const override { return true; }
495ec727ea7Spatrick 
496ec727ea7Spatrick private:
497ec727ea7Spatrick   void emitCXXStermFinalizer(const VarDecl &D, llvm::Function *dtorStub,
498ec727ea7Spatrick                              llvm::Constant *addr);
499ec727ea7Spatrick };
500e5dd7070Spatrick }
501e5dd7070Spatrick 
CreateItaniumCXXABI(CodeGenModule & CGM)502e5dd7070Spatrick CodeGen::CGCXXABI *CodeGen::CreateItaniumCXXABI(CodeGenModule &CGM) {
503a9ac8606Spatrick   switch (CGM.getContext().getCXXABIKind()) {
504e5dd7070Spatrick   // For IR-generation purposes, there's no significant difference
505e5dd7070Spatrick   // between the ARM and iOS ABIs.
506e5dd7070Spatrick   case TargetCXXABI::GenericARM:
507e5dd7070Spatrick   case TargetCXXABI::iOS:
508e5dd7070Spatrick   case TargetCXXABI::WatchOS:
509e5dd7070Spatrick     return new ARMCXXABI(CGM);
510e5dd7070Spatrick 
511a9ac8606Spatrick   case TargetCXXABI::AppleARM64:
512a9ac8606Spatrick     return new AppleARM64CXXABI(CGM);
513e5dd7070Spatrick 
514e5dd7070Spatrick   case TargetCXXABI::Fuchsia:
515e5dd7070Spatrick     return new FuchsiaCXXABI(CGM);
516e5dd7070Spatrick 
517e5dd7070Spatrick   // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't
518e5dd7070Spatrick   // include the other 32-bit ARM oddities: constructor/destructor return values
519e5dd7070Spatrick   // and array cookies.
520e5dd7070Spatrick   case TargetCXXABI::GenericAArch64:
521e5dd7070Spatrick     return new ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true,
522e5dd7070Spatrick                              /*UseARMGuardVarABI=*/true);
523e5dd7070Spatrick 
524e5dd7070Spatrick   case TargetCXXABI::GenericMIPS:
525e5dd7070Spatrick     return new ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true);
526e5dd7070Spatrick 
527e5dd7070Spatrick   case TargetCXXABI::WebAssembly:
528e5dd7070Spatrick     return new WebAssemblyCXXABI(CGM);
529e5dd7070Spatrick 
530ec727ea7Spatrick   case TargetCXXABI::XL:
531ec727ea7Spatrick     return new XLCXXABI(CGM);
532ec727ea7Spatrick 
533e5dd7070Spatrick   case TargetCXXABI::GenericItanium:
534e5dd7070Spatrick     if (CGM.getContext().getTargetInfo().getTriple().getArch()
535e5dd7070Spatrick         == llvm::Triple::le32) {
536e5dd7070Spatrick       // For PNaCl, use ARM-style method pointers so that PNaCl code
537e5dd7070Spatrick       // does not assume anything about the alignment of function
538e5dd7070Spatrick       // pointers.
539e5dd7070Spatrick       return new ItaniumCXXABI(CGM, /*UseARMMethodPtrABI=*/true);
540e5dd7070Spatrick     }
541e5dd7070Spatrick     return new ItaniumCXXABI(CGM);
542e5dd7070Spatrick 
543e5dd7070Spatrick   case TargetCXXABI::Microsoft:
544e5dd7070Spatrick     llvm_unreachable("Microsoft ABI is not Itanium-based");
545e5dd7070Spatrick   }
546e5dd7070Spatrick   llvm_unreachable("bad ABI kind");
547e5dd7070Spatrick }
548e5dd7070Spatrick 
549e5dd7070Spatrick llvm::Type *
ConvertMemberPointerType(const MemberPointerType * MPT)550e5dd7070Spatrick ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
551e5dd7070Spatrick   if (MPT->isMemberDataPointer())
552e5dd7070Spatrick     return CGM.PtrDiffTy;
553e5dd7070Spatrick   return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
554e5dd7070Spatrick }
555e5dd7070Spatrick 
556e5dd7070Spatrick /// In the Itanium and ARM ABIs, method pointers have the form:
557e5dd7070Spatrick ///   struct { ptrdiff_t ptr; ptrdiff_t adj; } memptr;
558e5dd7070Spatrick ///
559e5dd7070Spatrick /// In the Itanium ABI:
560e5dd7070Spatrick ///  - method pointers are virtual if (memptr.ptr & 1) is nonzero
561e5dd7070Spatrick ///  - the this-adjustment is (memptr.adj)
562e5dd7070Spatrick ///  - the virtual offset is (memptr.ptr - 1)
563e5dd7070Spatrick ///
564e5dd7070Spatrick /// In the ARM ABI:
565e5dd7070Spatrick ///  - method pointers are virtual if (memptr.adj & 1) is nonzero
566e5dd7070Spatrick ///  - the this-adjustment is (memptr.adj >> 1)
567e5dd7070Spatrick ///  - the virtual offset is (memptr.ptr)
568e5dd7070Spatrick /// ARM uses 'adj' for the virtual flag because Thumb functions
569e5dd7070Spatrick /// may be only single-byte aligned.
570e5dd7070Spatrick ///
571e5dd7070Spatrick /// If the member is virtual, the adjusted 'this' pointer points
572e5dd7070Spatrick /// to a vtable pointer from which the virtual offset is applied.
573e5dd7070Spatrick ///
574e5dd7070Spatrick /// If the member is non-virtual, memptr.ptr is the address of
575e5dd7070Spatrick /// the function to call.
EmitLoadOfMemberFunctionPointer(CodeGenFunction & CGF,const Expr * E,Address ThisAddr,llvm::Value * & ThisPtrForCall,llvm::Value * MemFnPtr,const MemberPointerType * MPT)576e5dd7070Spatrick CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
577e5dd7070Spatrick     CodeGenFunction &CGF, const Expr *E, Address ThisAddr,
578e5dd7070Spatrick     llvm::Value *&ThisPtrForCall,
579e5dd7070Spatrick     llvm::Value *MemFnPtr, const MemberPointerType *MPT) {
580e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
581e5dd7070Spatrick 
582e5dd7070Spatrick   const FunctionProtoType *FPT =
583e5dd7070Spatrick     MPT->getPointeeType()->getAs<FunctionProtoType>();
584e5dd7070Spatrick   auto *RD =
585e5dd7070Spatrick       cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
586e5dd7070Spatrick 
587e5dd7070Spatrick   llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
588e5dd7070Spatrick       CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr));
589e5dd7070Spatrick 
590e5dd7070Spatrick   llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
591e5dd7070Spatrick 
592e5dd7070Spatrick   llvm::BasicBlock *FnVirtual = CGF.createBasicBlock("memptr.virtual");
593e5dd7070Spatrick   llvm::BasicBlock *FnNonVirtual = CGF.createBasicBlock("memptr.nonvirtual");
594e5dd7070Spatrick   llvm::BasicBlock *FnEnd = CGF.createBasicBlock("memptr.end");
595e5dd7070Spatrick 
596e5dd7070Spatrick   // Extract memptr.adj, which is in the second field.
597e5dd7070Spatrick   llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, "memptr.adj");
598e5dd7070Spatrick 
599e5dd7070Spatrick   // Compute the true adjustment.
600e5dd7070Spatrick   llvm::Value *Adj = RawAdj;
601e5dd7070Spatrick   if (UseARMMethodPtrABI)
602e5dd7070Spatrick     Adj = Builder.CreateAShr(Adj, ptrdiff_1, "memptr.adj.shifted");
603e5dd7070Spatrick 
604e5dd7070Spatrick   // Apply the adjustment and cast back to the original struct type
605e5dd7070Spatrick   // for consistency.
606e5dd7070Spatrick   llvm::Value *This = ThisAddr.getPointer();
607e5dd7070Spatrick   llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
608a9ac8606Spatrick   Ptr = Builder.CreateInBoundsGEP(Builder.getInt8Ty(), Ptr, Adj);
609e5dd7070Spatrick   This = Builder.CreateBitCast(Ptr, This->getType(), "this.adjusted");
610e5dd7070Spatrick   ThisPtrForCall = This;
611e5dd7070Spatrick 
612e5dd7070Spatrick   // Load the function pointer.
613e5dd7070Spatrick   llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, "memptr.ptr");
614e5dd7070Spatrick 
615e5dd7070Spatrick   // If the LSB in the function pointer is 1, the function pointer points to
616e5dd7070Spatrick   // a virtual function.
617e5dd7070Spatrick   llvm::Value *IsVirtual;
618e5dd7070Spatrick   if (UseARMMethodPtrABI)
619e5dd7070Spatrick     IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
620e5dd7070Spatrick   else
621e5dd7070Spatrick     IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
622e5dd7070Spatrick   IsVirtual = Builder.CreateIsNotNull(IsVirtual, "memptr.isvirtual");
623e5dd7070Spatrick   Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
624e5dd7070Spatrick 
625e5dd7070Spatrick   // In the virtual path, the adjustment left 'This' pointing to the
626e5dd7070Spatrick   // vtable of the correct base subobject.  The "function pointer" is an
627e5dd7070Spatrick   // offset within the vtable (+1 for the virtual flag on non-ARM).
628e5dd7070Spatrick   CGF.EmitBlock(FnVirtual);
629e5dd7070Spatrick 
630e5dd7070Spatrick   // Cast the adjusted this to a pointer to vtable pointer and load.
631e5dd7070Spatrick   llvm::Type *VTableTy = Builder.getInt8PtrTy();
632e5dd7070Spatrick   CharUnits VTablePtrAlign =
633e5dd7070Spatrick     CGF.CGM.getDynamicOffsetAlignment(ThisAddr.getAlignment(), RD,
634e5dd7070Spatrick                                       CGF.getPointerAlign());
635*12c85518Srobert   llvm::Value *VTable = CGF.GetVTablePtr(
636*12c85518Srobert       Address(This, ThisAddr.getElementType(), VTablePtrAlign), VTableTy, RD);
637e5dd7070Spatrick 
638e5dd7070Spatrick   // Apply the offset.
639e5dd7070Spatrick   // On ARM64, to reserve extra space in virtual member function pointers,
640e5dd7070Spatrick   // we only pay attention to the low 32 bits of the offset.
641e5dd7070Spatrick   llvm::Value *VTableOffset = FnAsInt;
642e5dd7070Spatrick   if (!UseARMMethodPtrABI)
643e5dd7070Spatrick     VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
644e5dd7070Spatrick   if (Use32BitVTableOffsetABI) {
645e5dd7070Spatrick     VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.Int32Ty);
646e5dd7070Spatrick     VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
647e5dd7070Spatrick   }
648e5dd7070Spatrick 
649e5dd7070Spatrick   // Check the address of the function pointer if CFI on member function
650e5dd7070Spatrick   // pointers is enabled.
651e5dd7070Spatrick   llvm::Constant *CheckSourceLocation;
652e5dd7070Spatrick   llvm::Constant *CheckTypeDesc;
653e5dd7070Spatrick   bool ShouldEmitCFICheck = CGF.SanOpts.has(SanitizerKind::CFIMFCall) &&
654e5dd7070Spatrick                             CGM.HasHiddenLTOVisibility(RD);
655e5dd7070Spatrick   bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
656e5dd7070Spatrick                            CGM.HasHiddenLTOVisibility(RD);
657ec727ea7Spatrick   bool ShouldEmitWPDInfo =
658ec727ea7Spatrick       CGM.getCodeGenOpts().WholeProgramVTables &&
659*12c85518Srobert       // Don't insert type tests if we are forcing public visibility.
660*12c85518Srobert       !CGM.AlwaysHasLTOVisibilityPublic(RD);
661e5dd7070Spatrick   llvm::Value *VirtualFn = nullptr;
662e5dd7070Spatrick 
663e5dd7070Spatrick   {
664e5dd7070Spatrick     CodeGenFunction::SanitizerScope SanScope(&CGF);
665e5dd7070Spatrick     llvm::Value *TypeId = nullptr;
666e5dd7070Spatrick     llvm::Value *CheckResult = nullptr;
667e5dd7070Spatrick 
668ec727ea7Spatrick     if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
669ec727ea7Spatrick       // If doing CFI, VFE or WPD, we will need the metadata node to check
670ec727ea7Spatrick       // against.
671e5dd7070Spatrick       llvm::Metadata *MD =
672e5dd7070Spatrick           CGM.CreateMetadataIdentifierForVirtualMemPtrType(QualType(MPT, 0));
673e5dd7070Spatrick       TypeId = llvm::MetadataAsValue::get(CGF.getLLVMContext(), MD);
674e5dd7070Spatrick     }
675e5dd7070Spatrick 
676ec727ea7Spatrick     if (ShouldEmitVFEInfo) {
677a9ac8606Spatrick       llvm::Value *VFPAddr =
678a9ac8606Spatrick           Builder.CreateGEP(CGF.Int8Ty, VTable, VTableOffset);
679e5dd7070Spatrick 
680e5dd7070Spatrick       // If doing VFE, load from the vtable with a type.checked.load intrinsic
681e5dd7070Spatrick       // call. Note that we use the GEP to calculate the address to load from
682e5dd7070Spatrick       // and pass 0 as the offset to the intrinsic. This is because every
683e5dd7070Spatrick       // vtable slot of the correct type is marked with matching metadata, and
684e5dd7070Spatrick       // we know that the load must be from one of these slots.
685e5dd7070Spatrick       llvm::Value *CheckedLoad = Builder.CreateCall(
686e5dd7070Spatrick           CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
687e5dd7070Spatrick           {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
688e5dd7070Spatrick       CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
689e5dd7070Spatrick       VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
690e5dd7070Spatrick       VirtualFn = Builder.CreateBitCast(VirtualFn, FTy->getPointerTo(),
691e5dd7070Spatrick                                         "memptr.virtualfn");
692e5dd7070Spatrick     } else {
693e5dd7070Spatrick       // When not doing VFE, emit a normal load, as it allows more
694e5dd7070Spatrick       // optimisations than type.checked.load.
695ec727ea7Spatrick       if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
696a9ac8606Spatrick         llvm::Value *VFPAddr =
697a9ac8606Spatrick             Builder.CreateGEP(CGF.Int8Ty, VTable, VTableOffset);
698*12c85518Srobert         llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
699*12c85518Srobert                                       ? llvm::Intrinsic::type_test
700*12c85518Srobert                                       : llvm::Intrinsic::public_type_test;
701*12c85518Srobert 
702e5dd7070Spatrick         CheckResult = Builder.CreateCall(
703*12c85518Srobert             CGM.getIntrinsic(IID),
704e5dd7070Spatrick             {Builder.CreateBitCast(VFPAddr, CGF.Int8PtrTy), TypeId});
705e5dd7070Spatrick       }
706ec727ea7Spatrick 
707ec727ea7Spatrick       if (CGM.getItaniumVTableContext().isRelativeLayout()) {
708ec727ea7Spatrick         VirtualFn = CGF.Builder.CreateCall(
709ec727ea7Spatrick             CGM.getIntrinsic(llvm::Intrinsic::load_relative,
710ec727ea7Spatrick                              {VTableOffset->getType()}),
711ec727ea7Spatrick             {VTable, VTableOffset});
712ec727ea7Spatrick         VirtualFn = CGF.Builder.CreateBitCast(VirtualFn, FTy->getPointerTo());
713ec727ea7Spatrick       } else {
714a9ac8606Spatrick         llvm::Value *VFPAddr =
715a9ac8606Spatrick             CGF.Builder.CreateGEP(CGF.Int8Ty, VTable, VTableOffset);
716ec727ea7Spatrick         VFPAddr = CGF.Builder.CreateBitCast(
717ec727ea7Spatrick             VFPAddr, FTy->getPointerTo()->getPointerTo());
718ec727ea7Spatrick         VirtualFn = CGF.Builder.CreateAlignedLoad(
719a9ac8606Spatrick             FTy->getPointerTo(), VFPAddr, CGF.getPointerAlign(),
720a9ac8606Spatrick             "memptr.virtualfn");
721ec727ea7Spatrick       }
722e5dd7070Spatrick     }
723e5dd7070Spatrick     assert(VirtualFn && "Virtual fuction pointer not created!");
724ec727ea7Spatrick     assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
725ec727ea7Spatrick             CheckResult) &&
726e5dd7070Spatrick            "Check result required but not created!");
727e5dd7070Spatrick 
728e5dd7070Spatrick     if (ShouldEmitCFICheck) {
729e5dd7070Spatrick       // If doing CFI, emit the check.
730e5dd7070Spatrick       CheckSourceLocation = CGF.EmitCheckSourceLocation(E->getBeginLoc());
731e5dd7070Spatrick       CheckTypeDesc = CGF.EmitCheckTypeDescriptor(QualType(MPT, 0));
732e5dd7070Spatrick       llvm::Constant *StaticData[] = {
733e5dd7070Spatrick           llvm::ConstantInt::get(CGF.Int8Ty, CodeGenFunction::CFITCK_VMFCall),
734e5dd7070Spatrick           CheckSourceLocation,
735e5dd7070Spatrick           CheckTypeDesc,
736e5dd7070Spatrick       };
737e5dd7070Spatrick 
738e5dd7070Spatrick       if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
739a9ac8606Spatrick         CGF.EmitTrapCheck(CheckResult, SanitizerHandler::CFICheckFail);
740e5dd7070Spatrick       } else {
741e5dd7070Spatrick         llvm::Value *AllVtables = llvm::MetadataAsValue::get(
742e5dd7070Spatrick             CGM.getLLVMContext(),
743e5dd7070Spatrick             llvm::MDString::get(CGM.getLLVMContext(), "all-vtables"));
744e5dd7070Spatrick         llvm::Value *ValidVtable = Builder.CreateCall(
745e5dd7070Spatrick             CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
746e5dd7070Spatrick         CGF.EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIMFCall),
747e5dd7070Spatrick                       SanitizerHandler::CFICheckFail, StaticData,
748e5dd7070Spatrick                       {VTable, ValidVtable});
749e5dd7070Spatrick       }
750e5dd7070Spatrick 
751e5dd7070Spatrick       FnVirtual = Builder.GetInsertBlock();
752e5dd7070Spatrick     }
753e5dd7070Spatrick   } // End of sanitizer scope
754e5dd7070Spatrick 
755e5dd7070Spatrick   CGF.EmitBranch(FnEnd);
756e5dd7070Spatrick 
757e5dd7070Spatrick   // In the non-virtual path, the function pointer is actually a
758e5dd7070Spatrick   // function pointer.
759e5dd7070Spatrick   CGF.EmitBlock(FnNonVirtual);
760e5dd7070Spatrick   llvm::Value *NonVirtualFn =
761e5dd7070Spatrick     Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(), "memptr.nonvirtualfn");
762e5dd7070Spatrick 
763e5dd7070Spatrick   // Check the function pointer if CFI on member function pointers is enabled.
764e5dd7070Spatrick   if (ShouldEmitCFICheck) {
765e5dd7070Spatrick     CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
766e5dd7070Spatrick     if (RD->hasDefinition()) {
767e5dd7070Spatrick       CodeGenFunction::SanitizerScope SanScope(&CGF);
768e5dd7070Spatrick 
769e5dd7070Spatrick       llvm::Constant *StaticData[] = {
770e5dd7070Spatrick           llvm::ConstantInt::get(CGF.Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
771e5dd7070Spatrick           CheckSourceLocation,
772e5dd7070Spatrick           CheckTypeDesc,
773e5dd7070Spatrick       };
774e5dd7070Spatrick 
775e5dd7070Spatrick       llvm::Value *Bit = Builder.getFalse();
776e5dd7070Spatrick       llvm::Value *CastedNonVirtualFn =
777e5dd7070Spatrick           Builder.CreateBitCast(NonVirtualFn, CGF.Int8PtrTy);
778e5dd7070Spatrick       for (const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {
779e5dd7070Spatrick         llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
780e5dd7070Spatrick             getContext().getMemberPointerType(
781e5dd7070Spatrick                 MPT->getPointeeType(),
782e5dd7070Spatrick                 getContext().getRecordType(Base).getTypePtr()));
783e5dd7070Spatrick         llvm::Value *TypeId =
784e5dd7070Spatrick             llvm::MetadataAsValue::get(CGF.getLLVMContext(), MD);
785e5dd7070Spatrick 
786e5dd7070Spatrick         llvm::Value *TypeTest =
787e5dd7070Spatrick             Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
788e5dd7070Spatrick                                {CastedNonVirtualFn, TypeId});
789e5dd7070Spatrick         Bit = Builder.CreateOr(Bit, TypeTest);
790e5dd7070Spatrick       }
791e5dd7070Spatrick 
792e5dd7070Spatrick       CGF.EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
793e5dd7070Spatrick                     SanitizerHandler::CFICheckFail, StaticData,
794e5dd7070Spatrick                     {CastedNonVirtualFn, llvm::UndefValue::get(CGF.IntPtrTy)});
795e5dd7070Spatrick 
796e5dd7070Spatrick       FnNonVirtual = Builder.GetInsertBlock();
797e5dd7070Spatrick     }
798e5dd7070Spatrick   }
799e5dd7070Spatrick 
800e5dd7070Spatrick   // We're done.
801e5dd7070Spatrick   CGF.EmitBlock(FnEnd);
802e5dd7070Spatrick   llvm::PHINode *CalleePtr = Builder.CreatePHI(FTy->getPointerTo(), 2);
803e5dd7070Spatrick   CalleePtr->addIncoming(VirtualFn, FnVirtual);
804e5dd7070Spatrick   CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
805e5dd7070Spatrick 
806e5dd7070Spatrick   CGCallee Callee(FPT, CalleePtr);
807e5dd7070Spatrick   return Callee;
808e5dd7070Spatrick }
809e5dd7070Spatrick 
810e5dd7070Spatrick /// Compute an l-value by applying the given pointer-to-member to a
811e5dd7070Spatrick /// base object.
EmitMemberDataPointerAddress(CodeGenFunction & CGF,const Expr * E,Address Base,llvm::Value * MemPtr,const MemberPointerType * MPT)812e5dd7070Spatrick llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
813e5dd7070Spatrick     CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr,
814e5dd7070Spatrick     const MemberPointerType *MPT) {
815e5dd7070Spatrick   assert(MemPtr->getType() == CGM.PtrDiffTy);
816e5dd7070Spatrick 
817e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
818e5dd7070Spatrick 
819e5dd7070Spatrick   // Cast to char*.
820e5dd7070Spatrick   Base = Builder.CreateElementBitCast(Base, CGF.Int8Ty);
821e5dd7070Spatrick 
822e5dd7070Spatrick   // Apply the offset, which we assume is non-null.
823a9ac8606Spatrick   llvm::Value *Addr = Builder.CreateInBoundsGEP(
824a9ac8606Spatrick       Base.getElementType(), Base.getPointer(), MemPtr, "memptr.offset");
825e5dd7070Spatrick 
826e5dd7070Spatrick   // Cast the address to the appropriate pointer type, adopting the
827e5dd7070Spatrick   // address space of the base pointer.
828e5dd7070Spatrick   llvm::Type *PType = CGF.ConvertTypeForMem(MPT->getPointeeType())
829e5dd7070Spatrick                             ->getPointerTo(Base.getAddressSpace());
830e5dd7070Spatrick   return Builder.CreateBitCast(Addr, PType);
831e5dd7070Spatrick }
832e5dd7070Spatrick 
833e5dd7070Spatrick /// Perform a bitcast, derived-to-base, or base-to-derived member pointer
834e5dd7070Spatrick /// conversion.
835e5dd7070Spatrick ///
836e5dd7070Spatrick /// Bitcast conversions are always a no-op under Itanium.
837e5dd7070Spatrick ///
838e5dd7070Spatrick /// Obligatory offset/adjustment diagram:
839e5dd7070Spatrick ///         <-- offset -->          <-- adjustment -->
840e5dd7070Spatrick ///   |--------------------------|----------------------|--------------------|
841e5dd7070Spatrick ///   ^Derived address point     ^Base address point    ^Member address point
842e5dd7070Spatrick ///
843e5dd7070Spatrick /// So when converting a base member pointer to a derived member pointer,
844e5dd7070Spatrick /// we add the offset to the adjustment because the address point has
845e5dd7070Spatrick /// decreased;  and conversely, when converting a derived MP to a base MP
846e5dd7070Spatrick /// we subtract the offset from the adjustment because the address point
847e5dd7070Spatrick /// has increased.
848e5dd7070Spatrick ///
849e5dd7070Spatrick /// The standard forbids (at compile time) conversion to and from
850e5dd7070Spatrick /// virtual bases, which is why we don't have to consider them here.
851e5dd7070Spatrick ///
852e5dd7070Spatrick /// The standard forbids (at run time) casting a derived MP to a base
853e5dd7070Spatrick /// MP when the derived MP does not point to a member of the base.
854e5dd7070Spatrick /// This is why -1 is a reasonable choice for null data member
855e5dd7070Spatrick /// pointers.
856e5dd7070Spatrick llvm::Value *
EmitMemberPointerConversion(CodeGenFunction & CGF,const CastExpr * E,llvm::Value * src)857e5dd7070Spatrick ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
858e5dd7070Spatrick                                            const CastExpr *E,
859e5dd7070Spatrick                                            llvm::Value *src) {
860e5dd7070Spatrick   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
861e5dd7070Spatrick          E->getCastKind() == CK_BaseToDerivedMemberPointer ||
862e5dd7070Spatrick          E->getCastKind() == CK_ReinterpretMemberPointer);
863e5dd7070Spatrick 
864e5dd7070Spatrick   // Under Itanium, reinterprets don't require any additional processing.
865e5dd7070Spatrick   if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
866e5dd7070Spatrick 
867e5dd7070Spatrick   // Use constant emission if we can.
868e5dd7070Spatrick   if (isa<llvm::Constant>(src))
869e5dd7070Spatrick     return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
870e5dd7070Spatrick 
871e5dd7070Spatrick   llvm::Constant *adj = getMemberPointerAdjustment(E);
872e5dd7070Spatrick   if (!adj) return src;
873e5dd7070Spatrick 
874e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
875e5dd7070Spatrick   bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
876e5dd7070Spatrick 
877e5dd7070Spatrick   const MemberPointerType *destTy =
878e5dd7070Spatrick     E->getType()->castAs<MemberPointerType>();
879e5dd7070Spatrick 
880e5dd7070Spatrick   // For member data pointers, this is just a matter of adding the
881e5dd7070Spatrick   // offset if the source is non-null.
882e5dd7070Spatrick   if (destTy->isMemberDataPointer()) {
883e5dd7070Spatrick     llvm::Value *dst;
884e5dd7070Spatrick     if (isDerivedToBase)
885e5dd7070Spatrick       dst = Builder.CreateNSWSub(src, adj, "adj");
886e5dd7070Spatrick     else
887e5dd7070Spatrick       dst = Builder.CreateNSWAdd(src, adj, "adj");
888e5dd7070Spatrick 
889e5dd7070Spatrick     // Null check.
890e5dd7070Spatrick     llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
891e5dd7070Spatrick     llvm::Value *isNull = Builder.CreateICmpEQ(src, null, "memptr.isnull");
892e5dd7070Spatrick     return Builder.CreateSelect(isNull, src, dst);
893e5dd7070Spatrick   }
894e5dd7070Spatrick 
895e5dd7070Spatrick   // The this-adjustment is left-shifted by 1 on ARM.
896e5dd7070Spatrick   if (UseARMMethodPtrABI) {
897e5dd7070Spatrick     uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
898e5dd7070Spatrick     offset <<= 1;
899e5dd7070Spatrick     adj = llvm::ConstantInt::get(adj->getType(), offset);
900e5dd7070Spatrick   }
901e5dd7070Spatrick 
902e5dd7070Spatrick   llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, "src.adj");
903e5dd7070Spatrick   llvm::Value *dstAdj;
904e5dd7070Spatrick   if (isDerivedToBase)
905e5dd7070Spatrick     dstAdj = Builder.CreateNSWSub(srcAdj, adj, "adj");
906e5dd7070Spatrick   else
907e5dd7070Spatrick     dstAdj = Builder.CreateNSWAdd(srcAdj, adj, "adj");
908e5dd7070Spatrick 
909e5dd7070Spatrick   return Builder.CreateInsertValue(src, dstAdj, 1);
910e5dd7070Spatrick }
911e5dd7070Spatrick 
912e5dd7070Spatrick llvm::Constant *
EmitMemberPointerConversion(const CastExpr * E,llvm::Constant * src)913e5dd7070Spatrick ItaniumCXXABI::EmitMemberPointerConversion(const CastExpr *E,
914e5dd7070Spatrick                                            llvm::Constant *src) {
915e5dd7070Spatrick   assert(E->getCastKind() == CK_DerivedToBaseMemberPointer ||
916e5dd7070Spatrick          E->getCastKind() == CK_BaseToDerivedMemberPointer ||
917e5dd7070Spatrick          E->getCastKind() == CK_ReinterpretMemberPointer);
918e5dd7070Spatrick 
919e5dd7070Spatrick   // Under Itanium, reinterprets don't require any additional processing.
920e5dd7070Spatrick   if (E->getCastKind() == CK_ReinterpretMemberPointer) return src;
921e5dd7070Spatrick 
922e5dd7070Spatrick   // If the adjustment is trivial, we don't need to do anything.
923e5dd7070Spatrick   llvm::Constant *adj = getMemberPointerAdjustment(E);
924e5dd7070Spatrick   if (!adj) return src;
925e5dd7070Spatrick 
926e5dd7070Spatrick   bool isDerivedToBase = (E->getCastKind() == CK_DerivedToBaseMemberPointer);
927e5dd7070Spatrick 
928e5dd7070Spatrick   const MemberPointerType *destTy =
929e5dd7070Spatrick     E->getType()->castAs<MemberPointerType>();
930e5dd7070Spatrick 
931e5dd7070Spatrick   // For member data pointers, this is just a matter of adding the
932e5dd7070Spatrick   // offset if the source is non-null.
933e5dd7070Spatrick   if (destTy->isMemberDataPointer()) {
934e5dd7070Spatrick     // null maps to null.
935e5dd7070Spatrick     if (src->isAllOnesValue()) return src;
936e5dd7070Spatrick 
937e5dd7070Spatrick     if (isDerivedToBase)
938e5dd7070Spatrick       return llvm::ConstantExpr::getNSWSub(src, adj);
939e5dd7070Spatrick     else
940e5dd7070Spatrick       return llvm::ConstantExpr::getNSWAdd(src, adj);
941e5dd7070Spatrick   }
942e5dd7070Spatrick 
943e5dd7070Spatrick   // The this-adjustment is left-shifted by 1 on ARM.
944e5dd7070Spatrick   if (UseARMMethodPtrABI) {
945e5dd7070Spatrick     uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
946e5dd7070Spatrick     offset <<= 1;
947e5dd7070Spatrick     adj = llvm::ConstantInt::get(adj->getType(), offset);
948e5dd7070Spatrick   }
949e5dd7070Spatrick 
950*12c85518Srobert   llvm::Constant *srcAdj = src->getAggregateElement(1);
951e5dd7070Spatrick   llvm::Constant *dstAdj;
952e5dd7070Spatrick   if (isDerivedToBase)
953e5dd7070Spatrick     dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
954e5dd7070Spatrick   else
955e5dd7070Spatrick     dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
956e5dd7070Spatrick 
957*12c85518Srobert   llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
958*12c85518Srobert   assert(res != nullptr && "Folding must succeed");
959*12c85518Srobert   return res;
960e5dd7070Spatrick }
961e5dd7070Spatrick 
962e5dd7070Spatrick llvm::Constant *
EmitNullMemberPointer(const MemberPointerType * MPT)963e5dd7070Spatrick ItaniumCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
964e5dd7070Spatrick   // Itanium C++ ABI 2.3:
965e5dd7070Spatrick   //   A NULL pointer is represented as -1.
966e5dd7070Spatrick   if (MPT->isMemberDataPointer())
967e5dd7070Spatrick     return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, /*isSigned=*/true);
968e5dd7070Spatrick 
969e5dd7070Spatrick   llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
970e5dd7070Spatrick   llvm::Constant *Values[2] = { Zero, Zero };
971e5dd7070Spatrick   return llvm::ConstantStruct::getAnon(Values);
972e5dd7070Spatrick }
973e5dd7070Spatrick 
974e5dd7070Spatrick llvm::Constant *
EmitMemberDataPointer(const MemberPointerType * MPT,CharUnits offset)975e5dd7070Spatrick ItaniumCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
976e5dd7070Spatrick                                      CharUnits offset) {
977e5dd7070Spatrick   // Itanium C++ ABI 2.3:
978e5dd7070Spatrick   //   A pointer to data member is an offset from the base address of
979e5dd7070Spatrick   //   the class object containing it, represented as a ptrdiff_t
980e5dd7070Spatrick   return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.getQuantity());
981e5dd7070Spatrick }
982e5dd7070Spatrick 
983e5dd7070Spatrick llvm::Constant *
EmitMemberFunctionPointer(const CXXMethodDecl * MD)984e5dd7070Spatrick ItaniumCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
985e5dd7070Spatrick   return BuildMemberPointer(MD, CharUnits::Zero());
986e5dd7070Spatrick }
987e5dd7070Spatrick 
BuildMemberPointer(const CXXMethodDecl * MD,CharUnits ThisAdjustment)988e5dd7070Spatrick llvm::Constant *ItaniumCXXABI::BuildMemberPointer(const CXXMethodDecl *MD,
989e5dd7070Spatrick                                                   CharUnits ThisAdjustment) {
990e5dd7070Spatrick   assert(MD->isInstance() && "Member function must not be static!");
991e5dd7070Spatrick 
992e5dd7070Spatrick   CodeGenTypes &Types = CGM.getTypes();
993e5dd7070Spatrick 
994e5dd7070Spatrick   // Get the function pointer (or index if this is a virtual function).
995e5dd7070Spatrick   llvm::Constant *MemPtr[2];
996e5dd7070Spatrick   if (MD->isVirtual()) {
997e5dd7070Spatrick     uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
998ec727ea7Spatrick     uint64_t VTableOffset;
999ec727ea7Spatrick     if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1000ec727ea7Spatrick       // Multiply by 4-byte relative offsets.
1001ec727ea7Spatrick       VTableOffset = Index * 4;
1002ec727ea7Spatrick     } else {
1003e5dd7070Spatrick       const ASTContext &Context = getContext();
1004ec727ea7Spatrick       CharUnits PointerWidth = Context.toCharUnitsFromBits(
1005*12c85518Srobert           Context.getTargetInfo().getPointerWidth(LangAS::Default));
1006ec727ea7Spatrick       VTableOffset = Index * PointerWidth.getQuantity();
1007ec727ea7Spatrick     }
1008e5dd7070Spatrick 
1009e5dd7070Spatrick     if (UseARMMethodPtrABI) {
1010e5dd7070Spatrick       // ARM C++ ABI 3.2.1:
1011e5dd7070Spatrick       //   This ABI specifies that adj contains twice the this
1012e5dd7070Spatrick       //   adjustment, plus 1 if the member function is virtual. The
1013e5dd7070Spatrick       //   least significant bit of adj then makes exactly the same
1014e5dd7070Spatrick       //   discrimination as the least significant bit of ptr does for
1015e5dd7070Spatrick       //   Itanium.
1016e5dd7070Spatrick       MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1017e5dd7070Spatrick       MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1018e5dd7070Spatrick                                          2 * ThisAdjustment.getQuantity() + 1);
1019e5dd7070Spatrick     } else {
1020e5dd7070Spatrick       // Itanium C++ ABI 2.3:
1021e5dd7070Spatrick       //   For a virtual function, [the pointer field] is 1 plus the
1022e5dd7070Spatrick       //   virtual table offset (in bytes) of the function,
1023e5dd7070Spatrick       //   represented as a ptrdiff_t.
1024e5dd7070Spatrick       MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1025e5dd7070Spatrick       MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1026e5dd7070Spatrick                                          ThisAdjustment.getQuantity());
1027e5dd7070Spatrick     }
1028e5dd7070Spatrick   } else {
1029e5dd7070Spatrick     const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
1030e5dd7070Spatrick     llvm::Type *Ty;
1031e5dd7070Spatrick     // Check whether the function has a computable LLVM signature.
1032e5dd7070Spatrick     if (Types.isFuncTypeConvertible(FPT)) {
1033e5dd7070Spatrick       // The function has a computable LLVM signature; use the correct type.
1034e5dd7070Spatrick       Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
1035e5dd7070Spatrick     } else {
1036e5dd7070Spatrick       // Use an arbitrary non-function type to tell GetAddrOfFunction that the
1037e5dd7070Spatrick       // function type is incomplete.
1038e5dd7070Spatrick       Ty = CGM.PtrDiffTy;
1039e5dd7070Spatrick     }
1040e5dd7070Spatrick     llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
1041e5dd7070Spatrick 
1042e5dd7070Spatrick     MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1043e5dd7070Spatrick     MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1044e5dd7070Spatrick                                        (UseARMMethodPtrABI ? 2 : 1) *
1045e5dd7070Spatrick                                        ThisAdjustment.getQuantity());
1046e5dd7070Spatrick   }
1047e5dd7070Spatrick 
1048e5dd7070Spatrick   return llvm::ConstantStruct::getAnon(MemPtr);
1049e5dd7070Spatrick }
1050e5dd7070Spatrick 
EmitMemberPointer(const APValue & MP,QualType MPType)1051e5dd7070Spatrick llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,
1052e5dd7070Spatrick                                                  QualType MPType) {
1053e5dd7070Spatrick   const MemberPointerType *MPT = MPType->castAs<MemberPointerType>();
1054e5dd7070Spatrick   const ValueDecl *MPD = MP.getMemberPointerDecl();
1055e5dd7070Spatrick   if (!MPD)
1056e5dd7070Spatrick     return EmitNullMemberPointer(MPT);
1057e5dd7070Spatrick 
1058a9ac8606Spatrick   CharUnits ThisAdjustment = getContext().getMemberPointerPathAdjustment(MP);
1059e5dd7070Spatrick 
1060e5dd7070Spatrick   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD))
1061e5dd7070Spatrick     return BuildMemberPointer(MD, ThisAdjustment);
1062e5dd7070Spatrick 
1063e5dd7070Spatrick   CharUnits FieldOffset =
1064e5dd7070Spatrick     getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD));
1065e5dd7070Spatrick   return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
1066e5dd7070Spatrick }
1067e5dd7070Spatrick 
1068e5dd7070Spatrick /// The comparison algorithm is pretty easy: the member pointers are
1069e5dd7070Spatrick /// the same if they're either bitwise identical *or* both null.
1070e5dd7070Spatrick ///
1071e5dd7070Spatrick /// ARM is different here only because null-ness is more complicated.
1072e5dd7070Spatrick llvm::Value *
EmitMemberPointerComparison(CodeGenFunction & CGF,llvm::Value * L,llvm::Value * R,const MemberPointerType * MPT,bool Inequality)1073e5dd7070Spatrick ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
1074e5dd7070Spatrick                                            llvm::Value *L,
1075e5dd7070Spatrick                                            llvm::Value *R,
1076e5dd7070Spatrick                                            const MemberPointerType *MPT,
1077e5dd7070Spatrick                                            bool Inequality) {
1078e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
1079e5dd7070Spatrick 
1080e5dd7070Spatrick   llvm::ICmpInst::Predicate Eq;
1081e5dd7070Spatrick   llvm::Instruction::BinaryOps And, Or;
1082e5dd7070Spatrick   if (Inequality) {
1083e5dd7070Spatrick     Eq = llvm::ICmpInst::ICMP_NE;
1084e5dd7070Spatrick     And = llvm::Instruction::Or;
1085e5dd7070Spatrick     Or = llvm::Instruction::And;
1086e5dd7070Spatrick   } else {
1087e5dd7070Spatrick     Eq = llvm::ICmpInst::ICMP_EQ;
1088e5dd7070Spatrick     And = llvm::Instruction::And;
1089e5dd7070Spatrick     Or = llvm::Instruction::Or;
1090e5dd7070Spatrick   }
1091e5dd7070Spatrick 
1092e5dd7070Spatrick   // Member data pointers are easy because there's a unique null
1093e5dd7070Spatrick   // value, so it just comes down to bitwise equality.
1094e5dd7070Spatrick   if (MPT->isMemberDataPointer())
1095e5dd7070Spatrick     return Builder.CreateICmp(Eq, L, R);
1096e5dd7070Spatrick 
1097e5dd7070Spatrick   // For member function pointers, the tautologies are more complex.
1098e5dd7070Spatrick   // The Itanium tautology is:
1099e5dd7070Spatrick   //   (L == R) <==> (L.ptr == R.ptr && (L.ptr == 0 || L.adj == R.adj))
1100e5dd7070Spatrick   // The ARM tautology is:
1101e5dd7070Spatrick   //   (L == R) <==> (L.ptr == R.ptr &&
1102e5dd7070Spatrick   //                  (L.adj == R.adj ||
1103e5dd7070Spatrick   //                   (L.ptr == 0 && ((L.adj|R.adj) & 1) == 0)))
1104e5dd7070Spatrick   // The inequality tautologies have exactly the same structure, except
1105e5dd7070Spatrick   // applying De Morgan's laws.
1106e5dd7070Spatrick 
1107e5dd7070Spatrick   llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, "lhs.memptr.ptr");
1108e5dd7070Spatrick   llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, "rhs.memptr.ptr");
1109e5dd7070Spatrick 
1110e5dd7070Spatrick   // This condition tests whether L.ptr == R.ptr.  This must always be
1111e5dd7070Spatrick   // true for equality to hold.
1112e5dd7070Spatrick   llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, "cmp.ptr");
1113e5dd7070Spatrick 
1114e5dd7070Spatrick   // This condition, together with the assumption that L.ptr == R.ptr,
1115e5dd7070Spatrick   // tests whether the pointers are both null.  ARM imposes an extra
1116e5dd7070Spatrick   // condition.
1117e5dd7070Spatrick   llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
1118e5dd7070Spatrick   llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero, "cmp.ptr.null");
1119e5dd7070Spatrick 
1120e5dd7070Spatrick   // This condition tests whether L.adj == R.adj.  If this isn't
1121e5dd7070Spatrick   // true, the pointers are unequal unless they're both null.
1122e5dd7070Spatrick   llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, "lhs.memptr.adj");
1123e5dd7070Spatrick   llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, "rhs.memptr.adj");
1124e5dd7070Spatrick   llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, "cmp.adj");
1125e5dd7070Spatrick 
1126e5dd7070Spatrick   // Null member function pointers on ARM clear the low bit of Adj,
1127e5dd7070Spatrick   // so the zero condition has to check that neither low bit is set.
1128e5dd7070Spatrick   if (UseARMMethodPtrABI) {
1129e5dd7070Spatrick     llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1130e5dd7070Spatrick 
1131e5dd7070Spatrick     // Compute (l.adj | r.adj) & 1 and test it against zero.
1132e5dd7070Spatrick     llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, "or.adj");
1133e5dd7070Spatrick     llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1134e5dd7070Spatrick     llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
1135e5dd7070Spatrick                                                       "cmp.or.adj");
1136e5dd7070Spatrick     EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
1137e5dd7070Spatrick   }
1138e5dd7070Spatrick 
1139e5dd7070Spatrick   // Tie together all our conditions.
1140e5dd7070Spatrick   llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
1141e5dd7070Spatrick   Result = Builder.CreateBinOp(And, PtrEq, Result,
1142e5dd7070Spatrick                                Inequality ? "memptr.ne" : "memptr.eq");
1143e5dd7070Spatrick   return Result;
1144e5dd7070Spatrick }
1145e5dd7070Spatrick 
1146e5dd7070Spatrick llvm::Value *
EmitMemberPointerIsNotNull(CodeGenFunction & CGF,llvm::Value * MemPtr,const MemberPointerType * MPT)1147e5dd7070Spatrick ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
1148e5dd7070Spatrick                                           llvm::Value *MemPtr,
1149e5dd7070Spatrick                                           const MemberPointerType *MPT) {
1150e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
1151e5dd7070Spatrick 
1152e5dd7070Spatrick   /// For member data pointers, this is just a check against -1.
1153e5dd7070Spatrick   if (MPT->isMemberDataPointer()) {
1154e5dd7070Spatrick     assert(MemPtr->getType() == CGM.PtrDiffTy);
1155e5dd7070Spatrick     llvm::Value *NegativeOne =
1156e5dd7070Spatrick       llvm::Constant::getAllOnesValue(MemPtr->getType());
1157e5dd7070Spatrick     return Builder.CreateICmpNE(MemPtr, NegativeOne, "memptr.tobool");
1158e5dd7070Spatrick   }
1159e5dd7070Spatrick 
1160e5dd7070Spatrick   // In Itanium, a member function pointer is not null if 'ptr' is not null.
1161e5dd7070Spatrick   llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, "memptr.ptr");
1162e5dd7070Spatrick 
1163e5dd7070Spatrick   llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1164e5dd7070Spatrick   llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero, "memptr.tobool");
1165e5dd7070Spatrick 
1166e5dd7070Spatrick   // On ARM, a member function pointer is also non-null if the low bit of 'adj'
1167e5dd7070Spatrick   // (the virtual bit) is set.
1168e5dd7070Spatrick   if (UseARMMethodPtrABI) {
1169e5dd7070Spatrick     llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1170e5dd7070Spatrick     llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, "memptr.adj");
1171e5dd7070Spatrick     llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, "memptr.virtualbit");
1172e5dd7070Spatrick     llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1173e5dd7070Spatrick                                                   "memptr.isvirtual");
1174e5dd7070Spatrick     Result = Builder.CreateOr(Result, IsVirtual);
1175e5dd7070Spatrick   }
1176e5dd7070Spatrick 
1177e5dd7070Spatrick   return Result;
1178e5dd7070Spatrick }
1179e5dd7070Spatrick 
classifyReturnType(CGFunctionInfo & FI) const1180e5dd7070Spatrick bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
1181e5dd7070Spatrick   const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();
1182e5dd7070Spatrick   if (!RD)
1183e5dd7070Spatrick     return false;
1184e5dd7070Spatrick 
1185e5dd7070Spatrick   // If C++ prohibits us from making a copy, return by address.
1186e5dd7070Spatrick   if (!RD->canPassInRegisters()) {
1187e5dd7070Spatrick     auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
1188e5dd7070Spatrick     FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
1189e5dd7070Spatrick     return true;
1190e5dd7070Spatrick   }
1191e5dd7070Spatrick   return false;
1192e5dd7070Spatrick }
1193e5dd7070Spatrick 
1194e5dd7070Spatrick /// The Itanium ABI requires non-zero initialization only for data
1195e5dd7070Spatrick /// member pointers, for which '0' is a valid offset.
isZeroInitializable(const MemberPointerType * MPT)1196e5dd7070Spatrick bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
1197e5dd7070Spatrick   return MPT->isMemberFunctionPointer();
1198e5dd7070Spatrick }
1199e5dd7070Spatrick 
1200e5dd7070Spatrick /// The Itanium ABI always places an offset to the complete object
1201e5dd7070Spatrick /// at entry -2 in the vtable.
emitVirtualObjectDelete(CodeGenFunction & CGF,const CXXDeleteExpr * DE,Address Ptr,QualType ElementType,const CXXDestructorDecl * Dtor)1202e5dd7070Spatrick void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
1203e5dd7070Spatrick                                             const CXXDeleteExpr *DE,
1204e5dd7070Spatrick                                             Address Ptr,
1205e5dd7070Spatrick                                             QualType ElementType,
1206e5dd7070Spatrick                                             const CXXDestructorDecl *Dtor) {
1207e5dd7070Spatrick   bool UseGlobalDelete = DE->isGlobalDelete();
1208e5dd7070Spatrick   if (UseGlobalDelete) {
1209e5dd7070Spatrick     // Derive the complete-object pointer, which is what we need
1210e5dd7070Spatrick     // to pass to the deallocation function.
1211e5dd7070Spatrick 
1212e5dd7070Spatrick     // Grab the vtable pointer as an intptr_t*.
1213e5dd7070Spatrick     auto *ClassDecl =
1214e5dd7070Spatrick         cast<CXXRecordDecl>(ElementType->castAs<RecordType>()->getDecl());
1215e5dd7070Spatrick     llvm::Value *VTable =
1216e5dd7070Spatrick         CGF.GetVTablePtr(Ptr, CGF.IntPtrTy->getPointerTo(), ClassDecl);
1217e5dd7070Spatrick 
1218e5dd7070Spatrick     // Track back to entry -2 and pull out the offset there.
1219e5dd7070Spatrick     llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
1220a9ac8606Spatrick         CGF.IntPtrTy, VTable, -2, "complete-offset.ptr");
1221a9ac8606Spatrick     llvm::Value *Offset = CGF.Builder.CreateAlignedLoad(CGF.IntPtrTy, OffsetPtr,                                                        CGF.getPointerAlign());
1222e5dd7070Spatrick 
1223e5dd7070Spatrick     // Apply the offset.
1224e5dd7070Spatrick     llvm::Value *CompletePtr =
1225e5dd7070Spatrick       CGF.Builder.CreateBitCast(Ptr.getPointer(), CGF.Int8PtrTy);
1226a9ac8606Spatrick     CompletePtr =
1227a9ac8606Spatrick         CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, CompletePtr, Offset);
1228e5dd7070Spatrick 
1229e5dd7070Spatrick     // If we're supposed to call the global delete, make sure we do so
1230e5dd7070Spatrick     // even if the destructor throws.
1231e5dd7070Spatrick     CGF.pushCallObjectDeleteCleanup(DE->getOperatorDelete(), CompletePtr,
1232e5dd7070Spatrick                                     ElementType);
1233e5dd7070Spatrick   }
1234e5dd7070Spatrick 
1235e5dd7070Spatrick   // FIXME: Provide a source location here even though there's no
1236e5dd7070Spatrick   // CXXMemberCallExpr for dtor call.
1237e5dd7070Spatrick   CXXDtorType DtorType = UseGlobalDelete ? Dtor_Complete : Dtor_Deleting;
1238e5dd7070Spatrick   EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
1239e5dd7070Spatrick 
1240e5dd7070Spatrick   if (UseGlobalDelete)
1241e5dd7070Spatrick     CGF.PopCleanupBlock();
1242e5dd7070Spatrick }
1243e5dd7070Spatrick 
emitRethrow(CodeGenFunction & CGF,bool isNoReturn)1244e5dd7070Spatrick void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, bool isNoReturn) {
1245e5dd7070Spatrick   // void __cxa_rethrow();
1246e5dd7070Spatrick 
1247e5dd7070Spatrick   llvm::FunctionType *FTy =
1248e5dd7070Spatrick     llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
1249e5dd7070Spatrick 
1250e5dd7070Spatrick   llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
1251e5dd7070Spatrick 
1252e5dd7070Spatrick   if (isNoReturn)
1253*12c85518Srobert     CGF.EmitNoreturnRuntimeCallOrInvoke(Fn, std::nullopt);
1254e5dd7070Spatrick   else
1255e5dd7070Spatrick     CGF.EmitRuntimeCallOrInvoke(Fn);
1256e5dd7070Spatrick }
1257e5dd7070Spatrick 
getAllocateExceptionFn(CodeGenModule & CGM)1258e5dd7070Spatrick static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM) {
1259e5dd7070Spatrick   // void *__cxa_allocate_exception(size_t thrown_size);
1260e5dd7070Spatrick 
1261e5dd7070Spatrick   llvm::FunctionType *FTy =
1262e5dd7070Spatrick     llvm::FunctionType::get(CGM.Int8PtrTy, CGM.SizeTy, /*isVarArg=*/false);
1263e5dd7070Spatrick 
1264e5dd7070Spatrick   return CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception");
1265e5dd7070Spatrick }
1266e5dd7070Spatrick 
getThrowFn(CodeGenModule & CGM)1267e5dd7070Spatrick static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM) {
1268e5dd7070Spatrick   // void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
1269e5dd7070Spatrick   //                  void (*dest) (void *));
1270e5dd7070Spatrick 
1271e5dd7070Spatrick   llvm::Type *Args[3] = { CGM.Int8PtrTy, CGM.Int8PtrTy, CGM.Int8PtrTy };
1272e5dd7070Spatrick   llvm::FunctionType *FTy =
1273e5dd7070Spatrick     llvm::FunctionType::get(CGM.VoidTy, Args, /*isVarArg=*/false);
1274e5dd7070Spatrick 
1275e5dd7070Spatrick   return CGM.CreateRuntimeFunction(FTy, "__cxa_throw");
1276e5dd7070Spatrick }
1277e5dd7070Spatrick 
emitThrow(CodeGenFunction & CGF,const CXXThrowExpr * E)1278e5dd7070Spatrick void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
1279e5dd7070Spatrick   QualType ThrowType = E->getSubExpr()->getType();
1280e5dd7070Spatrick   // Now allocate the exception object.
1281e5dd7070Spatrick   llvm::Type *SizeTy = CGF.ConvertType(getContext().getSizeType());
1282e5dd7070Spatrick   uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1283e5dd7070Spatrick 
1284e5dd7070Spatrick   llvm::FunctionCallee AllocExceptionFn = getAllocateExceptionFn(CGM);
1285e5dd7070Spatrick   llvm::CallInst *ExceptionPtr = CGF.EmitNounwindRuntimeCall(
1286e5dd7070Spatrick       AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize), "exception");
1287e5dd7070Spatrick 
1288e5dd7070Spatrick   CharUnits ExnAlign = CGF.getContext().getExnObjectAlignment();
1289*12c85518Srobert   CGF.EmitAnyExprToExn(
1290*12c85518Srobert       E->getSubExpr(), Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));
1291e5dd7070Spatrick 
1292e5dd7070Spatrick   // Now throw the exception.
1293e5dd7070Spatrick   llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1294e5dd7070Spatrick                                                          /*ForEH=*/true);
1295e5dd7070Spatrick 
1296e5dd7070Spatrick   // The address of the destructor.  If the exception type has a
1297e5dd7070Spatrick   // trivial destructor (or isn't a record), we just pass null.
1298e5dd7070Spatrick   llvm::Constant *Dtor = nullptr;
1299e5dd7070Spatrick   if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {
1300e5dd7070Spatrick     CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
1301e5dd7070Spatrick     if (!Record->hasTrivialDestructor()) {
1302e5dd7070Spatrick       CXXDestructorDecl *DtorD = Record->getDestructor();
1303e5dd7070Spatrick       Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, Dtor_Complete));
1304e5dd7070Spatrick       Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy);
1305e5dd7070Spatrick     }
1306e5dd7070Spatrick   }
1307e5dd7070Spatrick   if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1308e5dd7070Spatrick 
1309e5dd7070Spatrick   llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
1310e5dd7070Spatrick   CGF.EmitNoreturnRuntimeCallOrInvoke(getThrowFn(CGM), args);
1311e5dd7070Spatrick }
1312e5dd7070Spatrick 
getItaniumDynamicCastFn(CodeGenFunction & CGF)1313e5dd7070Spatrick static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF) {
1314e5dd7070Spatrick   // void *__dynamic_cast(const void *sub,
1315e5dd7070Spatrick   //                      const abi::__class_type_info *src,
1316e5dd7070Spatrick   //                      const abi::__class_type_info *dst,
1317e5dd7070Spatrick   //                      std::ptrdiff_t src2dst_offset);
1318e5dd7070Spatrick 
1319e5dd7070Spatrick   llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
1320e5dd7070Spatrick   llvm::Type *PtrDiffTy =
1321e5dd7070Spatrick     CGF.ConvertType(CGF.getContext().getPointerDiffType());
1322e5dd7070Spatrick 
1323e5dd7070Spatrick   llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
1324e5dd7070Spatrick 
1325e5dd7070Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
1326e5dd7070Spatrick 
1327e5dd7070Spatrick   // Mark the function as nounwind readonly.
1328*12c85518Srobert   llvm::AttrBuilder FuncAttrs(CGF.getLLVMContext());
1329*12c85518Srobert   FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1330*12c85518Srobert   FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1331e5dd7070Spatrick   llvm::AttributeList Attrs = llvm::AttributeList::get(
1332e5dd7070Spatrick       CGF.getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1333e5dd7070Spatrick 
1334e5dd7070Spatrick   return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs);
1335e5dd7070Spatrick }
1336e5dd7070Spatrick 
getBadCastFn(CodeGenFunction & CGF)1337e5dd7070Spatrick static llvm::FunctionCallee getBadCastFn(CodeGenFunction &CGF) {
1338e5dd7070Spatrick   // void __cxa_bad_cast();
1339e5dd7070Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
1340e5dd7070Spatrick   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_cast");
1341e5dd7070Spatrick }
1342e5dd7070Spatrick 
1343e5dd7070Spatrick /// Compute the src2dst_offset hint as described in the
1344e5dd7070Spatrick /// Itanium C++ ABI [2.9.7]
computeOffsetHint(ASTContext & Context,const CXXRecordDecl * Src,const CXXRecordDecl * Dst)1345e5dd7070Spatrick static CharUnits computeOffsetHint(ASTContext &Context,
1346e5dd7070Spatrick                                    const CXXRecordDecl *Src,
1347e5dd7070Spatrick                                    const CXXRecordDecl *Dst) {
1348e5dd7070Spatrick   CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
1349e5dd7070Spatrick                      /*DetectVirtual=*/false);
1350e5dd7070Spatrick 
1351e5dd7070Spatrick   // If Dst is not derived from Src we can skip the whole computation below and
1352e5dd7070Spatrick   // return that Src is not a public base of Dst.  Record all inheritance paths.
1353e5dd7070Spatrick   if (!Dst->isDerivedFrom(Src, Paths))
1354e5dd7070Spatrick     return CharUnits::fromQuantity(-2ULL);
1355e5dd7070Spatrick 
1356e5dd7070Spatrick   unsigned NumPublicPaths = 0;
1357e5dd7070Spatrick   CharUnits Offset;
1358e5dd7070Spatrick 
1359e5dd7070Spatrick   // Now walk all possible inheritance paths.
1360e5dd7070Spatrick   for (const CXXBasePath &Path : Paths) {
1361e5dd7070Spatrick     if (Path.Access != AS_public)  // Ignore non-public inheritance.
1362e5dd7070Spatrick       continue;
1363e5dd7070Spatrick 
1364e5dd7070Spatrick     ++NumPublicPaths;
1365e5dd7070Spatrick 
1366e5dd7070Spatrick     for (const CXXBasePathElement &PathElement : Path) {
1367e5dd7070Spatrick       // If the path contains a virtual base class we can't give any hint.
1368e5dd7070Spatrick       // -1: no hint.
1369e5dd7070Spatrick       if (PathElement.Base->isVirtual())
1370e5dd7070Spatrick         return CharUnits::fromQuantity(-1ULL);
1371e5dd7070Spatrick 
1372e5dd7070Spatrick       if (NumPublicPaths > 1) // Won't use offsets, skip computation.
1373e5dd7070Spatrick         continue;
1374e5dd7070Spatrick 
1375e5dd7070Spatrick       // Accumulate the base class offsets.
1376e5dd7070Spatrick       const ASTRecordLayout &L = Context.getASTRecordLayout(PathElement.Class);
1377e5dd7070Spatrick       Offset += L.getBaseClassOffset(
1378e5dd7070Spatrick           PathElement.Base->getType()->getAsCXXRecordDecl());
1379e5dd7070Spatrick     }
1380e5dd7070Spatrick   }
1381e5dd7070Spatrick 
1382e5dd7070Spatrick   // -2: Src is not a public base of Dst.
1383e5dd7070Spatrick   if (NumPublicPaths == 0)
1384e5dd7070Spatrick     return CharUnits::fromQuantity(-2ULL);
1385e5dd7070Spatrick 
1386e5dd7070Spatrick   // -3: Src is a multiple public base type but never a virtual base type.
1387e5dd7070Spatrick   if (NumPublicPaths > 1)
1388e5dd7070Spatrick     return CharUnits::fromQuantity(-3ULL);
1389e5dd7070Spatrick 
1390e5dd7070Spatrick   // Otherwise, the Src type is a unique public nonvirtual base type of Dst.
1391e5dd7070Spatrick   // Return the offset of Src from the origin of Dst.
1392e5dd7070Spatrick   return Offset;
1393e5dd7070Spatrick }
1394e5dd7070Spatrick 
getBadTypeidFn(CodeGenFunction & CGF)1395e5dd7070Spatrick static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF) {
1396e5dd7070Spatrick   // void __cxa_bad_typeid();
1397e5dd7070Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
1398e5dd7070Spatrick 
1399e5dd7070Spatrick   return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
1400e5dd7070Spatrick }
1401e5dd7070Spatrick 
shouldTypeidBeNullChecked(bool IsDeref,QualType SrcRecordTy)1402e5dd7070Spatrick bool ItaniumCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
1403e5dd7070Spatrick                                               QualType SrcRecordTy) {
1404e5dd7070Spatrick   return IsDeref;
1405e5dd7070Spatrick }
1406e5dd7070Spatrick 
EmitBadTypeidCall(CodeGenFunction & CGF)1407e5dd7070Spatrick void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1408e5dd7070Spatrick   llvm::FunctionCallee Fn = getBadTypeidFn(CGF);
1409e5dd7070Spatrick   llvm::CallBase *Call = CGF.EmitRuntimeCallOrInvoke(Fn);
1410e5dd7070Spatrick   Call->setDoesNotReturn();
1411e5dd7070Spatrick   CGF.Builder.CreateUnreachable();
1412e5dd7070Spatrick }
1413e5dd7070Spatrick 
EmitTypeid(CodeGenFunction & CGF,QualType SrcRecordTy,Address ThisPtr,llvm::Type * StdTypeInfoPtrTy)1414e5dd7070Spatrick llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
1415e5dd7070Spatrick                                        QualType SrcRecordTy,
1416e5dd7070Spatrick                                        Address ThisPtr,
1417e5dd7070Spatrick                                        llvm::Type *StdTypeInfoPtrTy) {
1418e5dd7070Spatrick   auto *ClassDecl =
1419e5dd7070Spatrick       cast<CXXRecordDecl>(SrcRecordTy->castAs<RecordType>()->getDecl());
1420e5dd7070Spatrick   llvm::Value *Value =
1421e5dd7070Spatrick       CGF.GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo(), ClassDecl);
1422e5dd7070Spatrick 
1423ec727ea7Spatrick   if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1424ec727ea7Spatrick     // Load the type info.
1425ec727ea7Spatrick     Value = CGF.Builder.CreateBitCast(Value, CGM.Int8PtrTy);
1426ec727ea7Spatrick     Value = CGF.Builder.CreateCall(
1427ec727ea7Spatrick         CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1428ec727ea7Spatrick         {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});
1429ec727ea7Spatrick 
1430ec727ea7Spatrick     // Setup to dereference again since this is a proxy we accessed.
1431ec727ea7Spatrick     Value = CGF.Builder.CreateBitCast(Value, StdTypeInfoPtrTy->getPointerTo());
1432ec727ea7Spatrick   } else {
1433e5dd7070Spatrick     // Load the type info.
1434a9ac8606Spatrick     Value =
1435a9ac8606Spatrick         CGF.Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy, Value, -1ULL);
1436ec727ea7Spatrick   }
1437a9ac8606Spatrick   return CGF.Builder.CreateAlignedLoad(StdTypeInfoPtrTy, Value,
1438a9ac8606Spatrick                                        CGF.getPointerAlign());
1439e5dd7070Spatrick }
1440e5dd7070Spatrick 
shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,QualType SrcRecordTy)1441e5dd7070Spatrick bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
1442e5dd7070Spatrick                                                        QualType SrcRecordTy) {
1443e5dd7070Spatrick   return SrcIsPtr;
1444e5dd7070Spatrick }
1445e5dd7070Spatrick 
EmitDynamicCastCall(CodeGenFunction & CGF,Address ThisAddr,QualType SrcRecordTy,QualType DestTy,QualType DestRecordTy,llvm::BasicBlock * CastEnd)1446e5dd7070Spatrick llvm::Value *ItaniumCXXABI::EmitDynamicCastCall(
1447e5dd7070Spatrick     CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1448e5dd7070Spatrick     QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1449e5dd7070Spatrick   llvm::Type *PtrDiffLTy =
1450e5dd7070Spatrick       CGF.ConvertType(CGF.getContext().getPointerDiffType());
1451e5dd7070Spatrick   llvm::Type *DestLTy = CGF.ConvertType(DestTy);
1452e5dd7070Spatrick 
1453e5dd7070Spatrick   llvm::Value *SrcRTTI =
1454e5dd7070Spatrick       CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
1455e5dd7070Spatrick   llvm::Value *DestRTTI =
1456e5dd7070Spatrick       CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
1457e5dd7070Spatrick 
1458e5dd7070Spatrick   // Compute the offset hint.
1459e5dd7070Spatrick   const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
1460e5dd7070Spatrick   const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl();
1461e5dd7070Spatrick   llvm::Value *OffsetHint = llvm::ConstantInt::get(
1462e5dd7070Spatrick       PtrDiffLTy,
1463e5dd7070Spatrick       computeOffsetHint(CGF.getContext(), SrcDecl, DestDecl).getQuantity());
1464e5dd7070Spatrick 
1465e5dd7070Spatrick   // Emit the call to __dynamic_cast.
1466e5dd7070Spatrick   llvm::Value *Value = ThisAddr.getPointer();
1467e5dd7070Spatrick   Value = CGF.EmitCastToVoidPtr(Value);
1468e5dd7070Spatrick 
1469e5dd7070Spatrick   llvm::Value *args[] = {Value, SrcRTTI, DestRTTI, OffsetHint};
1470e5dd7070Spatrick   Value = CGF.EmitNounwindRuntimeCall(getItaniumDynamicCastFn(CGF), args);
1471e5dd7070Spatrick   Value = CGF.Builder.CreateBitCast(Value, DestLTy);
1472e5dd7070Spatrick 
1473e5dd7070Spatrick   /// C++ [expr.dynamic.cast]p9:
1474e5dd7070Spatrick   ///   A failed cast to reference type throws std::bad_cast
1475e5dd7070Spatrick   if (DestTy->isReferenceType()) {
1476e5dd7070Spatrick     llvm::BasicBlock *BadCastBlock =
1477e5dd7070Spatrick         CGF.createBasicBlock("dynamic_cast.bad_cast");
1478e5dd7070Spatrick 
1479e5dd7070Spatrick     llvm::Value *IsNull = CGF.Builder.CreateIsNull(Value);
1480e5dd7070Spatrick     CGF.Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1481e5dd7070Spatrick 
1482e5dd7070Spatrick     CGF.EmitBlock(BadCastBlock);
1483e5dd7070Spatrick     EmitBadCastCall(CGF);
1484e5dd7070Spatrick   }
1485e5dd7070Spatrick 
1486e5dd7070Spatrick   return Value;
1487e5dd7070Spatrick }
1488e5dd7070Spatrick 
EmitDynamicCastToVoid(CodeGenFunction & CGF,Address ThisAddr,QualType SrcRecordTy,QualType DestTy)1489e5dd7070Spatrick llvm::Value *ItaniumCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF,
1490e5dd7070Spatrick                                                   Address ThisAddr,
1491e5dd7070Spatrick                                                   QualType SrcRecordTy,
1492e5dd7070Spatrick                                                   QualType DestTy) {
1493e5dd7070Spatrick   llvm::Type *DestLTy = CGF.ConvertType(DestTy);
1494e5dd7070Spatrick   auto *ClassDecl =
1495e5dd7070Spatrick       cast<CXXRecordDecl>(SrcRecordTy->castAs<RecordType>()->getDecl());
1496ec727ea7Spatrick   llvm::Value *OffsetToTop;
1497ec727ea7Spatrick   if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1498e5dd7070Spatrick     // Get the vtable pointer.
1499ec727ea7Spatrick     llvm::Value *VTable =
1500ec727ea7Spatrick         CGF.GetVTablePtr(ThisAddr, CGM.Int32Ty->getPointerTo(), ClassDecl);
1501e5dd7070Spatrick 
1502e5dd7070Spatrick     // Get the offset-to-top from the vtable.
1503e5dd7070Spatrick     OffsetToTop =
1504a9ac8606Spatrick         CGF.Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1505ec727ea7Spatrick     OffsetToTop = CGF.Builder.CreateAlignedLoad(
1506a9ac8606Spatrick         CGM.Int32Ty, OffsetToTop, CharUnits::fromQuantity(4), "offset.to.top");
1507ec727ea7Spatrick   } else {
1508ec727ea7Spatrick     llvm::Type *PtrDiffLTy =
1509ec727ea7Spatrick         CGF.ConvertType(CGF.getContext().getPointerDiffType());
1510e5dd7070Spatrick 
1511ec727ea7Spatrick     // Get the vtable pointer.
1512ec727ea7Spatrick     llvm::Value *VTable =
1513ec727ea7Spatrick         CGF.GetVTablePtr(ThisAddr, PtrDiffLTy->getPointerTo(), ClassDecl);
1514ec727ea7Spatrick 
1515ec727ea7Spatrick     // Get the offset-to-top from the vtable.
1516a9ac8606Spatrick     OffsetToTop =
1517a9ac8606Spatrick         CGF.Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1518ec727ea7Spatrick     OffsetToTop = CGF.Builder.CreateAlignedLoad(
1519a9ac8606Spatrick         PtrDiffLTy, OffsetToTop, CGF.getPointerAlign(), "offset.to.top");
1520ec727ea7Spatrick   }
1521e5dd7070Spatrick   // Finally, add the offset to the pointer.
1522e5dd7070Spatrick   llvm::Value *Value = ThisAddr.getPointer();
1523e5dd7070Spatrick   Value = CGF.EmitCastToVoidPtr(Value);
1524a9ac8606Spatrick   Value = CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, Value, OffsetToTop);
1525e5dd7070Spatrick   return CGF.Builder.CreateBitCast(Value, DestLTy);
1526e5dd7070Spatrick }
1527e5dd7070Spatrick 
EmitBadCastCall(CodeGenFunction & CGF)1528e5dd7070Spatrick bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1529e5dd7070Spatrick   llvm::FunctionCallee Fn = getBadCastFn(CGF);
1530e5dd7070Spatrick   llvm::CallBase *Call = CGF.EmitRuntimeCallOrInvoke(Fn);
1531e5dd7070Spatrick   Call->setDoesNotReturn();
1532e5dd7070Spatrick   CGF.Builder.CreateUnreachable();
1533e5dd7070Spatrick   return true;
1534e5dd7070Spatrick }
1535e5dd7070Spatrick 
1536e5dd7070Spatrick llvm::Value *
GetVirtualBaseClassOffset(CodeGenFunction & CGF,Address This,const CXXRecordDecl * ClassDecl,const CXXRecordDecl * BaseClassDecl)1537e5dd7070Spatrick ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
1538e5dd7070Spatrick                                          Address This,
1539e5dd7070Spatrick                                          const CXXRecordDecl *ClassDecl,
1540e5dd7070Spatrick                                          const CXXRecordDecl *BaseClassDecl) {
1541e5dd7070Spatrick   llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1542e5dd7070Spatrick   CharUnits VBaseOffsetOffset =
1543e5dd7070Spatrick       CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1544e5dd7070Spatrick                                                                BaseClassDecl);
1545e5dd7070Spatrick   llvm::Value *VBaseOffsetPtr =
1546a9ac8606Spatrick     CGF.Builder.CreateConstGEP1_64(
1547a9ac8606Spatrick         CGF.Int8Ty, VTablePtr, VBaseOffsetOffset.getQuantity(),
1548e5dd7070Spatrick         "vbase.offset.ptr");
1549ec727ea7Spatrick 
1550ec727ea7Spatrick   llvm::Value *VBaseOffset;
1551ec727ea7Spatrick   if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1552ec727ea7Spatrick     VBaseOffsetPtr =
1553ec727ea7Spatrick         CGF.Builder.CreateBitCast(VBaseOffsetPtr, CGF.Int32Ty->getPointerTo());
1554ec727ea7Spatrick     VBaseOffset = CGF.Builder.CreateAlignedLoad(
1555a9ac8606Spatrick         CGF.Int32Ty, VBaseOffsetPtr, CharUnits::fromQuantity(4),
1556a9ac8606Spatrick         "vbase.offset");
1557ec727ea7Spatrick   } else {
1558e5dd7070Spatrick     VBaseOffsetPtr = CGF.Builder.CreateBitCast(VBaseOffsetPtr,
1559e5dd7070Spatrick                                                CGM.PtrDiffTy->getPointerTo());
1560ec727ea7Spatrick     VBaseOffset = CGF.Builder.CreateAlignedLoad(
1561a9ac8606Spatrick         CGM.PtrDiffTy, VBaseOffsetPtr, CGF.getPointerAlign(), "vbase.offset");
1562ec727ea7Spatrick   }
1563e5dd7070Spatrick   return VBaseOffset;
1564e5dd7070Spatrick }
1565e5dd7070Spatrick 
EmitCXXConstructors(const CXXConstructorDecl * D)1566e5dd7070Spatrick void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
1567e5dd7070Spatrick   // Just make sure we're in sync with TargetCXXABI.
1568e5dd7070Spatrick   assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1569e5dd7070Spatrick 
1570e5dd7070Spatrick   // The constructor used for constructing this as a base class;
1571e5dd7070Spatrick   // ignores virtual bases.
1572e5dd7070Spatrick   CGM.EmitGlobal(GlobalDecl(D, Ctor_Base));
1573e5dd7070Spatrick 
1574e5dd7070Spatrick   // The constructor used for constructing this as a complete class;
1575e5dd7070Spatrick   // constructs the virtual bases, then calls the base constructor.
1576e5dd7070Spatrick   if (!D->getParent()->isAbstract()) {
1577e5dd7070Spatrick     // We don't need to emit the complete ctor if the class is abstract.
1578e5dd7070Spatrick     CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete));
1579e5dd7070Spatrick   }
1580e5dd7070Spatrick }
1581e5dd7070Spatrick 
1582ec727ea7Spatrick CGCXXABI::AddedStructorArgCounts
buildStructorSignature(GlobalDecl GD,SmallVectorImpl<CanQualType> & ArgTys)1583e5dd7070Spatrick ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
1584e5dd7070Spatrick                                       SmallVectorImpl<CanQualType> &ArgTys) {
1585e5dd7070Spatrick   ASTContext &Context = getContext();
1586e5dd7070Spatrick 
1587e5dd7070Spatrick   // All parameters are already in place except VTT, which goes after 'this'.
1588e5dd7070Spatrick   // These are Clang types, so we don't need to worry about sret yet.
1589e5dd7070Spatrick 
1590e5dd7070Spatrick   // Check if we need to add a VTT parameter (which has type void **).
1591e5dd7070Spatrick   if ((isa<CXXConstructorDecl>(GD.getDecl()) ? GD.getCtorType() == Ctor_Base
1592e5dd7070Spatrick                                              : GD.getDtorType() == Dtor_Base) &&
1593e5dd7070Spatrick       cast<CXXMethodDecl>(GD.getDecl())->getParent()->getNumVBases() != 0) {
1594e5dd7070Spatrick     ArgTys.insert(ArgTys.begin() + 1,
1595e5dd7070Spatrick                   Context.getPointerType(Context.VoidPtrTy));
1596ec727ea7Spatrick     return AddedStructorArgCounts::prefix(1);
1597e5dd7070Spatrick   }
1598ec727ea7Spatrick   return AddedStructorArgCounts{};
1599e5dd7070Spatrick }
1600e5dd7070Spatrick 
EmitCXXDestructors(const CXXDestructorDecl * D)1601e5dd7070Spatrick void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
1602e5dd7070Spatrick   // The destructor used for destructing this as a base class; ignores
1603e5dd7070Spatrick   // virtual bases.
1604e5dd7070Spatrick   CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));
1605e5dd7070Spatrick 
1606e5dd7070Spatrick   // The destructor used for destructing this as a most-derived class;
1607e5dd7070Spatrick   // call the base destructor and then destructs any virtual bases.
1608e5dd7070Spatrick   CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete));
1609e5dd7070Spatrick 
1610e5dd7070Spatrick   // The destructor in a virtual table is always a 'deleting'
1611e5dd7070Spatrick   // destructor, which calls the complete destructor and then uses the
1612e5dd7070Spatrick   // appropriate operator delete.
1613e5dd7070Spatrick   if (D->isVirtual())
1614e5dd7070Spatrick     CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting));
1615e5dd7070Spatrick }
1616e5dd7070Spatrick 
addImplicitStructorParams(CodeGenFunction & CGF,QualType & ResTy,FunctionArgList & Params)1617e5dd7070Spatrick void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1618e5dd7070Spatrick                                               QualType &ResTy,
1619e5dd7070Spatrick                                               FunctionArgList &Params) {
1620e5dd7070Spatrick   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
1621e5dd7070Spatrick   assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1622e5dd7070Spatrick 
1623e5dd7070Spatrick   // Check if we need a VTT parameter as well.
1624e5dd7070Spatrick   if (NeedsVTTParameter(CGF.CurGD)) {
1625e5dd7070Spatrick     ASTContext &Context = getContext();
1626e5dd7070Spatrick 
1627e5dd7070Spatrick     // FIXME: avoid the fake decl
1628e5dd7070Spatrick     QualType T = Context.getPointerType(Context.VoidPtrTy);
1629e5dd7070Spatrick     auto *VTTDecl = ImplicitParamDecl::Create(
1630e5dd7070Spatrick         Context, /*DC=*/nullptr, MD->getLocation(), &Context.Idents.get("vtt"),
1631e5dd7070Spatrick         T, ImplicitParamDecl::CXXVTT);
1632e5dd7070Spatrick     Params.insert(Params.begin() + 1, VTTDecl);
1633e5dd7070Spatrick     getStructorImplicitParamDecl(CGF) = VTTDecl;
1634e5dd7070Spatrick   }
1635e5dd7070Spatrick }
1636e5dd7070Spatrick 
EmitInstanceFunctionProlog(CodeGenFunction & CGF)1637e5dd7070Spatrick void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1638e5dd7070Spatrick   // Naked functions have no prolog.
1639e5dd7070Spatrick   if (CGF.CurFuncDecl && CGF.CurFuncDecl->hasAttr<NakedAttr>())
1640e5dd7070Spatrick     return;
1641e5dd7070Spatrick 
1642e5dd7070Spatrick   /// Initialize the 'this' slot. In the Itanium C++ ABI, no prologue
1643e5dd7070Spatrick   /// adjustments are required, because they are all handled by thunks.
1644e5dd7070Spatrick   setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1645e5dd7070Spatrick 
1646e5dd7070Spatrick   /// Initialize the 'vtt' slot if needed.
1647e5dd7070Spatrick   if (getStructorImplicitParamDecl(CGF)) {
1648e5dd7070Spatrick     getStructorImplicitParamValue(CGF) = CGF.Builder.CreateLoad(
1649e5dd7070Spatrick         CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), "vtt");
1650e5dd7070Spatrick   }
1651e5dd7070Spatrick 
1652e5dd7070Spatrick   /// If this is a function that the ABI specifies returns 'this', initialize
1653e5dd7070Spatrick   /// the return slot to 'this' at the start of the function.
1654e5dd7070Spatrick   ///
1655e5dd7070Spatrick   /// Unlike the setting of return types, this is done within the ABI
1656e5dd7070Spatrick   /// implementation instead of by clients of CGCXXABI because:
1657e5dd7070Spatrick   /// 1) getThisValue is currently protected
1658e5dd7070Spatrick   /// 2) in theory, an ABI could implement 'this' returns some other way;
1659e5dd7070Spatrick   ///    HasThisReturn only specifies a contract, not the implementation
1660e5dd7070Spatrick   if (HasThisReturn(CGF.CurGD))
1661e5dd7070Spatrick     CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
1662e5dd7070Spatrick }
1663e5dd7070Spatrick 
getImplicitConstructorArgs(CodeGenFunction & CGF,const CXXConstructorDecl * D,CXXCtorType Type,bool ForVirtualBase,bool Delegating)1664ec727ea7Spatrick CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
1665e5dd7070Spatrick     CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
1666ec727ea7Spatrick     bool ForVirtualBase, bool Delegating) {
1667e5dd7070Spatrick   if (!NeedsVTTParameter(GlobalDecl(D, Type)))
1668e5dd7070Spatrick     return AddedStructorArgs{};
1669e5dd7070Spatrick 
1670e5dd7070Spatrick   // Insert the implicit 'vtt' argument as the second argument.
1671e5dd7070Spatrick   llvm::Value *VTT =
1672e5dd7070Spatrick       CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, Delegating);
1673e5dd7070Spatrick   QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1674ec727ea7Spatrick   return AddedStructorArgs::prefix({{VTT, VTTTy}});
1675ec727ea7Spatrick }
1676ec727ea7Spatrick 
getCXXDestructorImplicitParam(CodeGenFunction & CGF,const CXXDestructorDecl * DD,CXXDtorType Type,bool ForVirtualBase,bool Delegating)1677ec727ea7Spatrick llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
1678ec727ea7Spatrick     CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type,
1679ec727ea7Spatrick     bool ForVirtualBase, bool Delegating) {
1680ec727ea7Spatrick   GlobalDecl GD(DD, Type);
1681ec727ea7Spatrick   return CGF.GetVTTParameter(GD, ForVirtualBase, Delegating);
1682e5dd7070Spatrick }
1683e5dd7070Spatrick 
EmitDestructorCall(CodeGenFunction & CGF,const CXXDestructorDecl * DD,CXXDtorType Type,bool ForVirtualBase,bool Delegating,Address This,QualType ThisTy)1684e5dd7070Spatrick void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
1685e5dd7070Spatrick                                        const CXXDestructorDecl *DD,
1686e5dd7070Spatrick                                        CXXDtorType Type, bool ForVirtualBase,
1687e5dd7070Spatrick                                        bool Delegating, Address This,
1688e5dd7070Spatrick                                        QualType ThisTy) {
1689e5dd7070Spatrick   GlobalDecl GD(DD, Type);
1690ec727ea7Spatrick   llvm::Value *VTT =
1691ec727ea7Spatrick       getCXXDestructorImplicitParam(CGF, DD, Type, ForVirtualBase, Delegating);
1692e5dd7070Spatrick   QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1693e5dd7070Spatrick 
1694e5dd7070Spatrick   CGCallee Callee;
1695e5dd7070Spatrick   if (getContext().getLangOpts().AppleKext &&
1696e5dd7070Spatrick       Type != Dtor_Base && DD->isVirtual())
1697e5dd7070Spatrick     Callee = CGF.BuildAppleKextVirtualDestructorCall(DD, Type, DD->getParent());
1698e5dd7070Spatrick   else
1699e5dd7070Spatrick     Callee = CGCallee::forDirect(CGM.getAddrOfCXXStructor(GD), GD);
1700e5dd7070Spatrick 
1701e5dd7070Spatrick   CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, VTT, VTTTy,
1702e5dd7070Spatrick                             nullptr);
1703e5dd7070Spatrick }
1704e5dd7070Spatrick 
emitVTableDefinitions(CodeGenVTables & CGVT,const CXXRecordDecl * RD)1705e5dd7070Spatrick void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
1706e5dd7070Spatrick                                           const CXXRecordDecl *RD) {
1707e5dd7070Spatrick   llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());
1708e5dd7070Spatrick   if (VTable->hasInitializer())
1709e5dd7070Spatrick     return;
1710e5dd7070Spatrick 
1711e5dd7070Spatrick   ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
1712e5dd7070Spatrick   const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);
1713e5dd7070Spatrick   llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
1714e5dd7070Spatrick   llvm::Constant *RTTI =
1715e5dd7070Spatrick       CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1716e5dd7070Spatrick 
1717e5dd7070Spatrick   // Create and set the initializer.
1718ec727ea7Spatrick   ConstantInitBuilder builder(CGM);
1719ec727ea7Spatrick   auto components = builder.beginStruct();
1720ec727ea7Spatrick   CGVT.createVTableInitializer(components, VTLayout, RTTI,
1721ec727ea7Spatrick                                llvm::GlobalValue::isLocalLinkage(Linkage));
1722ec727ea7Spatrick   components.finishAndSetAsInitializer(VTable);
1723e5dd7070Spatrick 
1724e5dd7070Spatrick   // Set the correct linkage.
1725e5dd7070Spatrick   VTable->setLinkage(Linkage);
1726e5dd7070Spatrick 
1727e5dd7070Spatrick   if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1728e5dd7070Spatrick     VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1729e5dd7070Spatrick 
1730e5dd7070Spatrick   // Set the right visibility.
1731e5dd7070Spatrick   CGM.setGVProperties(VTable, RD);
1732e5dd7070Spatrick 
1733e5dd7070Spatrick   // If this is the magic class __cxxabiv1::__fundamental_type_info,
1734e5dd7070Spatrick   // we will emit the typeinfo for the fundamental types. This is the
1735e5dd7070Spatrick   // same behaviour as GCC.
1736e5dd7070Spatrick   const DeclContext *DC = RD->getDeclContext();
1737e5dd7070Spatrick   if (RD->getIdentifier() &&
1738e5dd7070Spatrick       RD->getIdentifier()->isStr("__fundamental_type_info") &&
1739e5dd7070Spatrick       isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1740e5dd7070Spatrick       cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&
1741e5dd7070Spatrick       DC->getParent()->isTranslationUnit())
1742e5dd7070Spatrick     EmitFundamentalRTTIDescriptors(RD);
1743e5dd7070Spatrick 
1744a9ac8606Spatrick   // Always emit type metadata on non-available_externally definitions, and on
1745a9ac8606Spatrick   // available_externally definitions if we are performing whole program
1746a9ac8606Spatrick   // devirtualization. For WPD we need the type metadata on all vtable
1747a9ac8606Spatrick   // definitions to ensure we associate derived classes with base classes
1748a9ac8606Spatrick   // defined in headers but with a strong definition only in a shared library.
1749a9ac8606Spatrick   if (!VTable->isDeclarationForLinker() ||
1750a9ac8606Spatrick       CGM.getCodeGenOpts().WholeProgramVTables) {
1751e5dd7070Spatrick     CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
1752a9ac8606Spatrick     // For available_externally definitions, add the vtable to
1753a9ac8606Spatrick     // @llvm.compiler.used so that it isn't deleted before whole program
1754a9ac8606Spatrick     // analysis.
1755a9ac8606Spatrick     if (VTable->isDeclarationForLinker()) {
1756a9ac8606Spatrick       assert(CGM.getCodeGenOpts().WholeProgramVTables);
1757a9ac8606Spatrick       CGM.addCompilerUsedGlobal(VTable);
1758a9ac8606Spatrick     }
1759a9ac8606Spatrick   }
1760ec727ea7Spatrick 
1761*12c85518Srobert   if (VTContext.isRelativeLayout()) {
1762*12c85518Srobert     CGVT.RemoveHwasanMetadata(VTable);
1763*12c85518Srobert     if (!VTable->isDSOLocal())
1764ec727ea7Spatrick       CGVT.GenerateRelativeVTableAlias(VTable, VTable->getName());
1765e5dd7070Spatrick   }
1766*12c85518Srobert }
1767e5dd7070Spatrick 
isVirtualOffsetNeededForVTableField(CodeGenFunction & CGF,CodeGenFunction::VPtr Vptr)1768e5dd7070Spatrick bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1769e5dd7070Spatrick     CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
1770e5dd7070Spatrick   if (Vptr.NearestVBase == nullptr)
1771e5dd7070Spatrick     return false;
1772e5dd7070Spatrick   return NeedsVTTParameter(CGF.CurGD);
1773e5dd7070Spatrick }
1774e5dd7070Spatrick 
getVTableAddressPointInStructor(CodeGenFunction & CGF,const CXXRecordDecl * VTableClass,BaseSubobject Base,const CXXRecordDecl * NearestVBase)1775e5dd7070Spatrick llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1776e5dd7070Spatrick     CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
1777e5dd7070Spatrick     const CXXRecordDecl *NearestVBase) {
1778e5dd7070Spatrick 
1779e5dd7070Spatrick   if ((Base.getBase()->getNumVBases() || NearestVBase != nullptr) &&
1780e5dd7070Spatrick       NeedsVTTParameter(CGF.CurGD)) {
1781e5dd7070Spatrick     return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
1782e5dd7070Spatrick                                                   NearestVBase);
1783e5dd7070Spatrick   }
1784e5dd7070Spatrick   return getVTableAddressPoint(Base, VTableClass);
1785e5dd7070Spatrick }
1786e5dd7070Spatrick 
1787e5dd7070Spatrick llvm::Constant *
getVTableAddressPoint(BaseSubobject Base,const CXXRecordDecl * VTableClass)1788e5dd7070Spatrick ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
1789e5dd7070Spatrick                                      const CXXRecordDecl *VTableClass) {
1790e5dd7070Spatrick   llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());
1791e5dd7070Spatrick 
1792e5dd7070Spatrick   // Find the appropriate vtable within the vtable group, and the address point
1793e5dd7070Spatrick   // within that vtable.
1794e5dd7070Spatrick   VTableLayout::AddressPointLocation AddressPoint =
1795e5dd7070Spatrick       CGM.getItaniumVTableContext()
1796e5dd7070Spatrick           .getVTableLayout(VTableClass)
1797e5dd7070Spatrick           .getAddressPoint(Base);
1798e5dd7070Spatrick   llvm::Value *Indices[] = {
1799e5dd7070Spatrick     llvm::ConstantInt::get(CGM.Int32Ty, 0),
1800e5dd7070Spatrick     llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.VTableIndex),
1801e5dd7070Spatrick     llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.AddressPointIndex),
1802e5dd7070Spatrick   };
1803e5dd7070Spatrick 
1804e5dd7070Spatrick   return llvm::ConstantExpr::getGetElementPtr(VTable->getValueType(), VTable,
1805e5dd7070Spatrick                                               Indices, /*InBounds=*/true,
1806e5dd7070Spatrick                                               /*InRangeIndex=*/1);
1807e5dd7070Spatrick }
1808e5dd7070Spatrick 
1809a9ac8606Spatrick // Check whether all the non-inline virtual methods for the class have the
1810a9ac8606Spatrick // specified attribute.
1811a9ac8606Spatrick template <typename T>
CXXRecordAllNonInlineVirtualsHaveAttr(const CXXRecordDecl * RD)1812a9ac8606Spatrick static bool CXXRecordAllNonInlineVirtualsHaveAttr(const CXXRecordDecl *RD) {
1813a9ac8606Spatrick   bool FoundNonInlineVirtualMethodWithAttr = false;
1814a9ac8606Spatrick   for (const auto *D : RD->noload_decls()) {
1815a9ac8606Spatrick     if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1816a9ac8606Spatrick       if (!FD->isVirtualAsWritten() || FD->isInlineSpecified() ||
1817a9ac8606Spatrick           FD->doesThisDeclarationHaveABody())
1818a9ac8606Spatrick         continue;
1819a9ac8606Spatrick       if (!D->hasAttr<T>())
1820a9ac8606Spatrick         return false;
1821a9ac8606Spatrick       FoundNonInlineVirtualMethodWithAttr = true;
1822a9ac8606Spatrick     }
1823a9ac8606Spatrick   }
1824a9ac8606Spatrick 
1825a9ac8606Spatrick   // We didn't find any non-inline virtual methods missing the attribute.  We
1826a9ac8606Spatrick   // will return true when we found at least one non-inline virtual with the
1827a9ac8606Spatrick   // attribute.  (This lets our caller know that the attribute needs to be
1828a9ac8606Spatrick   // propagated up to the vtable.)
1829a9ac8606Spatrick   return FoundNonInlineVirtualMethodWithAttr;
1830a9ac8606Spatrick }
1831a9ac8606Spatrick 
getVTableAddressPointInStructorWithVTT(CodeGenFunction & CGF,const CXXRecordDecl * VTableClass,BaseSubobject Base,const CXXRecordDecl * NearestVBase)1832e5dd7070Spatrick llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1833e5dd7070Spatrick     CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
1834e5dd7070Spatrick     const CXXRecordDecl *NearestVBase) {
1835e5dd7070Spatrick   assert((Base.getBase()->getNumVBases() || NearestVBase != nullptr) &&
1836e5dd7070Spatrick          NeedsVTTParameter(CGF.CurGD) && "This class doesn't have VTT");
1837e5dd7070Spatrick 
1838e5dd7070Spatrick   // Get the secondary vpointer index.
1839e5dd7070Spatrick   uint64_t VirtualPointerIndex =
1840e5dd7070Spatrick       CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
1841e5dd7070Spatrick 
1842e5dd7070Spatrick   /// Load the VTT.
1843e5dd7070Spatrick   llvm::Value *VTT = CGF.LoadCXXVTT();
1844e5dd7070Spatrick   if (VirtualPointerIndex)
1845a9ac8606Spatrick     VTT = CGF.Builder.CreateConstInBoundsGEP1_64(
1846a9ac8606Spatrick         CGF.VoidPtrTy, VTT, VirtualPointerIndex);
1847e5dd7070Spatrick 
1848e5dd7070Spatrick   // And load the address point from the VTT.
1849a9ac8606Spatrick   return CGF.Builder.CreateAlignedLoad(CGF.VoidPtrTy, VTT,
1850a9ac8606Spatrick                                        CGF.getPointerAlign());
1851e5dd7070Spatrick }
1852e5dd7070Spatrick 
getVTableAddressPointForConstExpr(BaseSubobject Base,const CXXRecordDecl * VTableClass)1853e5dd7070Spatrick llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
1854e5dd7070Spatrick     BaseSubobject Base, const CXXRecordDecl *VTableClass) {
1855e5dd7070Spatrick   return getVTableAddressPoint(Base, VTableClass);
1856e5dd7070Spatrick }
1857e5dd7070Spatrick 
getAddrOfVTable(const CXXRecordDecl * RD,CharUnits VPtrOffset)1858e5dd7070Spatrick llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
1859e5dd7070Spatrick                                                      CharUnits VPtrOffset) {
1860e5dd7070Spatrick   assert(VPtrOffset.isZero() && "Itanium ABI only supports zero vptr offsets");
1861e5dd7070Spatrick 
1862e5dd7070Spatrick   llvm::GlobalVariable *&VTable = VTables[RD];
1863e5dd7070Spatrick   if (VTable)
1864e5dd7070Spatrick     return VTable;
1865e5dd7070Spatrick 
1866e5dd7070Spatrick   // Queue up this vtable for possible deferred emission.
1867e5dd7070Spatrick   CGM.addDeferredVTable(RD);
1868e5dd7070Spatrick 
1869e5dd7070Spatrick   SmallString<256> Name;
1870e5dd7070Spatrick   llvm::raw_svector_ostream Out(Name);
1871e5dd7070Spatrick   getMangleContext().mangleCXXVTable(RD, Out);
1872e5dd7070Spatrick 
1873e5dd7070Spatrick   const VTableLayout &VTLayout =
1874e5dd7070Spatrick       CGM.getItaniumVTableContext().getVTableLayout(RD);
1875e5dd7070Spatrick   llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1876e5dd7070Spatrick 
1877e5dd7070Spatrick   // Use pointer alignment for the vtable. Otherwise we would align them based
1878e5dd7070Spatrick   // on the size of the initializer which doesn't make sense as only single
1879e5dd7070Spatrick   // values are read.
1880ec727ea7Spatrick   unsigned PAlign = CGM.getItaniumVTableContext().isRelativeLayout()
1881ec727ea7Spatrick                         ? 32
1882*12c85518Srobert                         : CGM.getTarget().getPointerAlign(LangAS::Default);
1883e5dd7070Spatrick 
1884e5dd7070Spatrick   VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1885e5dd7070Spatrick       Name, VTableType, llvm::GlobalValue::ExternalLinkage,
1886*12c85518Srobert       getContext().toCharUnitsFromBits(PAlign).getAsAlign());
1887e5dd7070Spatrick   VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1888e5dd7070Spatrick 
1889a9ac8606Spatrick   // In MS C++ if you have a class with virtual functions in which you are using
1890a9ac8606Spatrick   // selective member import/export, then all virtual functions must be exported
1891a9ac8606Spatrick   // unless they are inline, otherwise a link error will result. To match this
1892a9ac8606Spatrick   // behavior, for such classes, we dllimport the vtable if it is defined
1893a9ac8606Spatrick   // externally and all the non-inline virtual methods are marked dllimport, and
1894a9ac8606Spatrick   // we dllexport the vtable if it is defined in this TU and all the non-inline
1895a9ac8606Spatrick   // virtual methods are marked dllexport.
1896a9ac8606Spatrick   if (CGM.getTarget().hasPS4DLLImportExport()) {
1897a9ac8606Spatrick     if ((!RD->hasAttr<DLLImportAttr>()) && (!RD->hasAttr<DLLExportAttr>())) {
1898a9ac8606Spatrick       if (CGM.getVTables().isVTableExternal(RD)) {
1899a9ac8606Spatrick         if (CXXRecordAllNonInlineVirtualsHaveAttr<DLLImportAttr>(RD))
1900a9ac8606Spatrick           VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1901a9ac8606Spatrick       } else {
1902a9ac8606Spatrick         if (CXXRecordAllNonInlineVirtualsHaveAttr<DLLExportAttr>(RD))
1903a9ac8606Spatrick           VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1904a9ac8606Spatrick       }
1905a9ac8606Spatrick     }
1906a9ac8606Spatrick   }
1907e5dd7070Spatrick   CGM.setGVProperties(VTable, RD);
1908e5dd7070Spatrick 
1909e5dd7070Spatrick   return VTable;
1910e5dd7070Spatrick }
1911e5dd7070Spatrick 
getVirtualFunctionPointer(CodeGenFunction & CGF,GlobalDecl GD,Address This,llvm::Type * Ty,SourceLocation Loc)1912e5dd7070Spatrick CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
1913e5dd7070Spatrick                                                   GlobalDecl GD,
1914e5dd7070Spatrick                                                   Address This,
1915e5dd7070Spatrick                                                   llvm::Type *Ty,
1916e5dd7070Spatrick                                                   SourceLocation Loc) {
1917a9ac8606Spatrick   llvm::Type *TyPtr = Ty->getPointerTo();
1918e5dd7070Spatrick   auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl());
1919ec727ea7Spatrick   llvm::Value *VTable = CGF.GetVTablePtr(
1920a9ac8606Spatrick       This, TyPtr->getPointerTo(), MethodDecl->getParent());
1921e5dd7070Spatrick 
1922e5dd7070Spatrick   uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
1923e5dd7070Spatrick   llvm::Value *VFunc;
1924e5dd7070Spatrick   if (CGF.ShouldEmitVTableTypeCheckedLoad(MethodDecl->getParent())) {
1925e5dd7070Spatrick     VFunc = CGF.EmitVTableTypeCheckedLoad(
1926*12c85518Srobert         MethodDecl->getParent(), VTable, TyPtr,
1927*12c85518Srobert         VTableIndex *
1928*12c85518Srobert             CGM.getContext().getTargetInfo().getPointerWidth(LangAS::Default) /
1929*12c85518Srobert             8);
1930e5dd7070Spatrick   } else {
1931e5dd7070Spatrick     CGF.EmitTypeMetadataCodeForVCall(MethodDecl->getParent(), VTable, Loc);
1932e5dd7070Spatrick 
1933ec727ea7Spatrick     llvm::Value *VFuncLoad;
1934ec727ea7Spatrick     if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1935ec727ea7Spatrick       VTable = CGF.Builder.CreateBitCast(VTable, CGM.Int8PtrTy);
1936ec727ea7Spatrick       llvm::Value *Load = CGF.Builder.CreateCall(
1937ec727ea7Spatrick           CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1938ec727ea7Spatrick           {VTable, llvm::ConstantInt::get(CGM.Int32Ty, 4 * VTableIndex)});
1939a9ac8606Spatrick       VFuncLoad = CGF.Builder.CreateBitCast(Load, TyPtr);
1940ec727ea7Spatrick     } else {
1941ec727ea7Spatrick       VTable =
1942a9ac8606Spatrick           CGF.Builder.CreateBitCast(VTable, TyPtr->getPointerTo());
1943a9ac8606Spatrick       llvm::Value *VTableSlotPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
1944a9ac8606Spatrick           TyPtr, VTable, VTableIndex, "vfn");
1945ec727ea7Spatrick       VFuncLoad =
1946a9ac8606Spatrick           CGF.Builder.CreateAlignedLoad(TyPtr, VTableSlotPtr,
1947a9ac8606Spatrick                                         CGF.getPointerAlign());
1948ec727ea7Spatrick     }
1949e5dd7070Spatrick 
1950e5dd7070Spatrick     // Add !invariant.load md to virtual function load to indicate that
1951e5dd7070Spatrick     // function didn't change inside vtable.
1952e5dd7070Spatrick     // It's safe to add it without -fstrict-vtable-pointers, but it would not
1953e5dd7070Spatrick     // help in devirtualization because it will only matter if we will have 2
1954e5dd7070Spatrick     // the same virtual function loads from the same vtable load, which won't
1955e5dd7070Spatrick     // happen without enabled devirtualization with -fstrict-vtable-pointers.
1956e5dd7070Spatrick     if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1957ec727ea7Spatrick         CGM.getCodeGenOpts().StrictVTablePointers) {
1958ec727ea7Spatrick       if (auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
1959ec727ea7Spatrick         VFuncLoadInstr->setMetadata(
1960e5dd7070Spatrick             llvm::LLVMContext::MD_invariant_load,
1961e5dd7070Spatrick             llvm::MDNode::get(CGM.getLLVMContext(),
1962e5dd7070Spatrick                               llvm::ArrayRef<llvm::Metadata *>()));
1963ec727ea7Spatrick       }
1964ec727ea7Spatrick     }
1965e5dd7070Spatrick     VFunc = VFuncLoad;
1966e5dd7070Spatrick   }
1967e5dd7070Spatrick 
1968e5dd7070Spatrick   CGCallee Callee(GD, VFunc);
1969e5dd7070Spatrick   return Callee;
1970e5dd7070Spatrick }
1971e5dd7070Spatrick 
EmitVirtualDestructorCall(CodeGenFunction & CGF,const CXXDestructorDecl * Dtor,CXXDtorType DtorType,Address This,DeleteOrMemberCallExpr E)1972e5dd7070Spatrick llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
1973e5dd7070Spatrick     CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType,
1974e5dd7070Spatrick     Address This, DeleteOrMemberCallExpr E) {
1975e5dd7070Spatrick   auto *CE = E.dyn_cast<const CXXMemberCallExpr *>();
1976e5dd7070Spatrick   auto *D = E.dyn_cast<const CXXDeleteExpr *>();
1977e5dd7070Spatrick   assert((CE != nullptr) ^ (D != nullptr));
1978e5dd7070Spatrick   assert(CE == nullptr || CE->arg_begin() == CE->arg_end());
1979e5dd7070Spatrick   assert(DtorType == Dtor_Deleting || DtorType == Dtor_Complete);
1980e5dd7070Spatrick 
1981e5dd7070Spatrick   GlobalDecl GD(Dtor, DtorType);
1982e5dd7070Spatrick   const CGFunctionInfo *FInfo =
1983e5dd7070Spatrick       &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
1984e5dd7070Spatrick   llvm::FunctionType *Ty = CGF.CGM.getTypes().GetFunctionType(*FInfo);
1985e5dd7070Spatrick   CGCallee Callee = CGCallee::forVirtual(CE, GD, This, Ty);
1986e5dd7070Spatrick 
1987e5dd7070Spatrick   QualType ThisTy;
1988e5dd7070Spatrick   if (CE) {
1989e5dd7070Spatrick     ThisTy = CE->getObjectType();
1990e5dd7070Spatrick   } else {
1991e5dd7070Spatrick     ThisTy = D->getDestroyedType();
1992e5dd7070Spatrick   }
1993e5dd7070Spatrick 
1994e5dd7070Spatrick   CGF.EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy, nullptr,
1995e5dd7070Spatrick                             QualType(), nullptr);
1996e5dd7070Spatrick   return nullptr;
1997e5dd7070Spatrick }
1998e5dd7070Spatrick 
emitVirtualInheritanceTables(const CXXRecordDecl * RD)1999e5dd7070Spatrick void ItaniumCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {
2000e5dd7070Spatrick   CodeGenVTables &VTables = CGM.getVTables();
2001e5dd7070Spatrick   llvm::GlobalVariable *VTT = VTables.GetAddrOfVTT(RD);
2002e5dd7070Spatrick   VTables.EmitVTTDefinition(VTT, CGM.getVTableLinkage(RD), RD);
2003e5dd7070Spatrick }
2004e5dd7070Spatrick 
canSpeculativelyEmitVTableAsBaseClass(const CXXRecordDecl * RD) const2005e5dd7070Spatrick bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2006e5dd7070Spatrick     const CXXRecordDecl *RD) const {
2007e5dd7070Spatrick   // We don't emit available_externally vtables if we are in -fapple-kext mode
2008e5dd7070Spatrick   // because kext mode does not permit devirtualization.
2009e5dd7070Spatrick   if (CGM.getLangOpts().AppleKext)
2010e5dd7070Spatrick     return false;
2011e5dd7070Spatrick 
2012e5dd7070Spatrick   // If the vtable is hidden then it is not safe to emit an available_externally
2013e5dd7070Spatrick   // copy of vtable.
2014e5dd7070Spatrick   if (isVTableHidden(RD))
2015e5dd7070Spatrick     return false;
2016e5dd7070Spatrick 
2017e5dd7070Spatrick   if (CGM.getCodeGenOpts().ForceEmitVTables)
2018e5dd7070Spatrick     return true;
2019e5dd7070Spatrick 
2020e5dd7070Spatrick   // If we don't have any not emitted inline virtual function then we are safe
2021e5dd7070Spatrick   // to emit an available_externally copy of vtable.
2022e5dd7070Spatrick   // FIXME we can still emit a copy of the vtable if we
2023e5dd7070Spatrick   // can emit definition of the inline functions.
2024e5dd7070Spatrick   if (hasAnyUnusedVirtualInlineFunction(RD))
2025e5dd7070Spatrick     return false;
2026e5dd7070Spatrick 
2027e5dd7070Spatrick   // For a class with virtual bases, we must also be able to speculatively
2028e5dd7070Spatrick   // emit the VTT, because CodeGen doesn't have separate notions of "can emit
2029e5dd7070Spatrick   // the vtable" and "can emit the VTT". For a base subobject, this means we
2030e5dd7070Spatrick   // need to be able to emit non-virtual base vtables.
2031e5dd7070Spatrick   if (RD->getNumVBases()) {
2032e5dd7070Spatrick     for (const auto &B : RD->bases()) {
2033e5dd7070Spatrick       auto *BRD = B.getType()->getAsCXXRecordDecl();
2034e5dd7070Spatrick       assert(BRD && "no class for base specifier");
2035e5dd7070Spatrick       if (B.isVirtual() || !BRD->isDynamicClass())
2036e5dd7070Spatrick         continue;
2037e5dd7070Spatrick       if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2038e5dd7070Spatrick         return false;
2039e5dd7070Spatrick     }
2040e5dd7070Spatrick   }
2041e5dd7070Spatrick 
2042e5dd7070Spatrick   return true;
2043e5dd7070Spatrick }
2044e5dd7070Spatrick 
canSpeculativelyEmitVTable(const CXXRecordDecl * RD) const2045e5dd7070Spatrick bool ItaniumCXXABI::canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const {
2046e5dd7070Spatrick   if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2047e5dd7070Spatrick     return false;
2048e5dd7070Spatrick 
2049e5dd7070Spatrick   // For a complete-object vtable (or more specifically, for the VTT), we need
2050e5dd7070Spatrick   // to be able to speculatively emit the vtables of all dynamic virtual bases.
2051e5dd7070Spatrick   for (const auto &B : RD->vbases()) {
2052e5dd7070Spatrick     auto *BRD = B.getType()->getAsCXXRecordDecl();
2053e5dd7070Spatrick     assert(BRD && "no class for base specifier");
2054e5dd7070Spatrick     if (!BRD->isDynamicClass())
2055e5dd7070Spatrick       continue;
2056e5dd7070Spatrick     if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2057e5dd7070Spatrick       return false;
2058e5dd7070Spatrick   }
2059e5dd7070Spatrick 
2060e5dd7070Spatrick   return true;
2061e5dd7070Spatrick }
performTypeAdjustment(CodeGenFunction & CGF,Address InitialPtr,int64_t NonVirtualAdjustment,int64_t VirtualAdjustment,bool IsReturnAdjustment)2062e5dd7070Spatrick static llvm::Value *performTypeAdjustment(CodeGenFunction &CGF,
2063e5dd7070Spatrick                                           Address InitialPtr,
2064e5dd7070Spatrick                                           int64_t NonVirtualAdjustment,
2065e5dd7070Spatrick                                           int64_t VirtualAdjustment,
2066e5dd7070Spatrick                                           bool IsReturnAdjustment) {
2067e5dd7070Spatrick   if (!NonVirtualAdjustment && !VirtualAdjustment)
2068e5dd7070Spatrick     return InitialPtr.getPointer();
2069e5dd7070Spatrick 
2070e5dd7070Spatrick   Address V = CGF.Builder.CreateElementBitCast(InitialPtr, CGF.Int8Ty);
2071e5dd7070Spatrick 
2072e5dd7070Spatrick   // In a base-to-derived cast, the non-virtual adjustment is applied first.
2073e5dd7070Spatrick   if (NonVirtualAdjustment && !IsReturnAdjustment) {
2074e5dd7070Spatrick     V = CGF.Builder.CreateConstInBoundsByteGEP(V,
2075e5dd7070Spatrick                               CharUnits::fromQuantity(NonVirtualAdjustment));
2076e5dd7070Spatrick   }
2077e5dd7070Spatrick 
2078e5dd7070Spatrick   // Perform the virtual adjustment if we have one.
2079e5dd7070Spatrick   llvm::Value *ResultPtr;
2080e5dd7070Spatrick   if (VirtualAdjustment) {
2081e5dd7070Spatrick     Address VTablePtrPtr = CGF.Builder.CreateElementBitCast(V, CGF.Int8PtrTy);
2082e5dd7070Spatrick     llvm::Value *VTablePtr = CGF.Builder.CreateLoad(VTablePtrPtr);
2083e5dd7070Spatrick 
2084ec727ea7Spatrick     llvm::Value *Offset;
2085a9ac8606Spatrick     llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
2086a9ac8606Spatrick         CGF.Int8Ty, VTablePtr, VirtualAdjustment);
2087ec727ea7Spatrick     if (CGF.CGM.getItaniumVTableContext().isRelativeLayout()) {
2088ec727ea7Spatrick       // Load the adjustment offset from the vtable as a 32-bit int.
2089ec727ea7Spatrick       OffsetPtr =
2090ec727ea7Spatrick           CGF.Builder.CreateBitCast(OffsetPtr, CGF.Int32Ty->getPointerTo());
2091ec727ea7Spatrick       Offset =
2092a9ac8606Spatrick           CGF.Builder.CreateAlignedLoad(CGF.Int32Ty, OffsetPtr,
2093a9ac8606Spatrick                                         CharUnits::fromQuantity(4));
2094ec727ea7Spatrick     } else {
2095ec727ea7Spatrick       llvm::Type *PtrDiffTy =
2096ec727ea7Spatrick           CGF.ConvertType(CGF.getContext().getPointerDiffType());
2097e5dd7070Spatrick 
2098ec727ea7Spatrick       OffsetPtr =
2099ec727ea7Spatrick           CGF.Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo());
2100e5dd7070Spatrick 
2101e5dd7070Spatrick       // Load the adjustment offset from the vtable.
2102a9ac8606Spatrick       Offset = CGF.Builder.CreateAlignedLoad(PtrDiffTy, OffsetPtr,
2103a9ac8606Spatrick                                              CGF.getPointerAlign());
2104ec727ea7Spatrick     }
2105e5dd7070Spatrick     // Adjust our pointer.
2106a9ac8606Spatrick     ResultPtr = CGF.Builder.CreateInBoundsGEP(
2107a9ac8606Spatrick         V.getElementType(), V.getPointer(), Offset);
2108e5dd7070Spatrick   } else {
2109e5dd7070Spatrick     ResultPtr = V.getPointer();
2110e5dd7070Spatrick   }
2111e5dd7070Spatrick 
2112e5dd7070Spatrick   // In a derived-to-base conversion, the non-virtual adjustment is
2113e5dd7070Spatrick   // applied second.
2114e5dd7070Spatrick   if (NonVirtualAdjustment && IsReturnAdjustment) {
2115a9ac8606Spatrick     ResultPtr = CGF.Builder.CreateConstInBoundsGEP1_64(CGF.Int8Ty, ResultPtr,
2116e5dd7070Spatrick                                                        NonVirtualAdjustment);
2117e5dd7070Spatrick   }
2118e5dd7070Spatrick 
2119e5dd7070Spatrick   // Cast back to the original type.
2120e5dd7070Spatrick   return CGF.Builder.CreateBitCast(ResultPtr, InitialPtr.getType());
2121e5dd7070Spatrick }
2122e5dd7070Spatrick 
performThisAdjustment(CodeGenFunction & CGF,Address This,const ThisAdjustment & TA)2123e5dd7070Spatrick llvm::Value *ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF,
2124e5dd7070Spatrick                                                   Address This,
2125e5dd7070Spatrick                                                   const ThisAdjustment &TA) {
2126e5dd7070Spatrick   return performTypeAdjustment(CGF, This, TA.NonVirtual,
2127e5dd7070Spatrick                                TA.Virtual.Itanium.VCallOffsetOffset,
2128e5dd7070Spatrick                                /*IsReturnAdjustment=*/false);
2129e5dd7070Spatrick }
2130e5dd7070Spatrick 
2131e5dd7070Spatrick llvm::Value *
performReturnAdjustment(CodeGenFunction & CGF,Address Ret,const ReturnAdjustment & RA)2132e5dd7070Spatrick ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
2133e5dd7070Spatrick                                        const ReturnAdjustment &RA) {
2134e5dd7070Spatrick   return performTypeAdjustment(CGF, Ret, RA.NonVirtual,
2135e5dd7070Spatrick                                RA.Virtual.Itanium.VBaseOffsetOffset,
2136e5dd7070Spatrick                                /*IsReturnAdjustment=*/true);
2137e5dd7070Spatrick }
2138e5dd7070Spatrick 
EmitReturnFromThunk(CodeGenFunction & CGF,RValue RV,QualType ResultType)2139e5dd7070Spatrick void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
2140e5dd7070Spatrick                                     RValue RV, QualType ResultType) {
2141e5dd7070Spatrick   if (!isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
2142e5dd7070Spatrick     return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2143e5dd7070Spatrick 
2144e5dd7070Spatrick   // Destructor thunks in the ARM ABI have indeterminate results.
2145e5dd7070Spatrick   llvm::Type *T = CGF.ReturnValue.getElementType();
2146e5dd7070Spatrick   RValue Undef = RValue::get(llvm::UndefValue::get(T));
2147e5dd7070Spatrick   return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2148e5dd7070Spatrick }
2149e5dd7070Spatrick 
2150e5dd7070Spatrick /************************** Array allocation cookies **************************/
2151e5dd7070Spatrick 
getArrayCookieSizeImpl(QualType elementType)2152e5dd7070Spatrick CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2153e5dd7070Spatrick   // The array cookie is a size_t; pad that up to the element alignment.
2154e5dd7070Spatrick   // The cookie is actually right-justified in that space.
2155e5dd7070Spatrick   return std::max(CharUnits::fromQuantity(CGM.SizeSizeInBytes),
2156a9ac8606Spatrick                   CGM.getContext().getPreferredTypeAlignInChars(elementType));
2157e5dd7070Spatrick }
2158e5dd7070Spatrick 
InitializeArrayCookie(CodeGenFunction & CGF,Address NewPtr,llvm::Value * NumElements,const CXXNewExpr * expr,QualType ElementType)2159e5dd7070Spatrick Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2160e5dd7070Spatrick                                              Address NewPtr,
2161e5dd7070Spatrick                                              llvm::Value *NumElements,
2162e5dd7070Spatrick                                              const CXXNewExpr *expr,
2163e5dd7070Spatrick                                              QualType ElementType) {
2164e5dd7070Spatrick   assert(requiresArrayCookie(expr));
2165e5dd7070Spatrick 
2166e5dd7070Spatrick   unsigned AS = NewPtr.getAddressSpace();
2167e5dd7070Spatrick 
2168e5dd7070Spatrick   ASTContext &Ctx = getContext();
2169e5dd7070Spatrick   CharUnits SizeSize = CGF.getSizeSize();
2170e5dd7070Spatrick 
2171e5dd7070Spatrick   // The size of the cookie.
2172e5dd7070Spatrick   CharUnits CookieSize =
2173a9ac8606Spatrick       std::max(SizeSize, Ctx.getPreferredTypeAlignInChars(ElementType));
2174e5dd7070Spatrick   assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2175e5dd7070Spatrick 
2176e5dd7070Spatrick   // Compute an offset to the cookie.
2177e5dd7070Spatrick   Address CookiePtr = NewPtr;
2178e5dd7070Spatrick   CharUnits CookieOffset = CookieSize - SizeSize;
2179e5dd7070Spatrick   if (!CookieOffset.isZero())
2180e5dd7070Spatrick     CookiePtr = CGF.Builder.CreateConstInBoundsByteGEP(CookiePtr, CookieOffset);
2181e5dd7070Spatrick 
2182e5dd7070Spatrick   // Write the number of elements into the appropriate slot.
2183e5dd7070Spatrick   Address NumElementsPtr =
2184e5dd7070Spatrick       CGF.Builder.CreateElementBitCast(CookiePtr, CGF.SizeTy);
2185e5dd7070Spatrick   llvm::Instruction *SI = CGF.Builder.CreateStore(NumElements, NumElementsPtr);
2186e5dd7070Spatrick 
2187e5dd7070Spatrick   // Handle the array cookie specially in ASan.
2188e5dd7070Spatrick   if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2189e5dd7070Spatrick       (expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2190e5dd7070Spatrick        CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2191e5dd7070Spatrick     // The store to the CookiePtr does not need to be instrumented.
2192e5dd7070Spatrick     CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
2193e5dd7070Spatrick     llvm::FunctionType *FTy =
2194e5dd7070Spatrick         llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.getType(), false);
2195e5dd7070Spatrick     llvm::FunctionCallee F =
2196e5dd7070Spatrick         CGM.CreateRuntimeFunction(FTy, "__asan_poison_cxx_array_cookie");
2197e5dd7070Spatrick     CGF.Builder.CreateCall(F, NumElementsPtr.getPointer());
2198e5dd7070Spatrick   }
2199e5dd7070Spatrick 
2200e5dd7070Spatrick   // Finally, compute a pointer to the actual data buffer by skipping
2201e5dd7070Spatrick   // over the cookie completely.
2202e5dd7070Spatrick   return CGF.Builder.CreateConstInBoundsByteGEP(NewPtr, CookieSize);
2203e5dd7070Spatrick }
2204e5dd7070Spatrick 
readArrayCookieImpl(CodeGenFunction & CGF,Address allocPtr,CharUnits cookieSize)2205e5dd7070Spatrick llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2206e5dd7070Spatrick                                                 Address allocPtr,
2207e5dd7070Spatrick                                                 CharUnits cookieSize) {
2208e5dd7070Spatrick   // The element size is right-justified in the cookie.
2209e5dd7070Spatrick   Address numElementsPtr = allocPtr;
2210e5dd7070Spatrick   CharUnits numElementsOffset = cookieSize - CGF.getSizeSize();
2211e5dd7070Spatrick   if (!numElementsOffset.isZero())
2212e5dd7070Spatrick     numElementsPtr =
2213e5dd7070Spatrick       CGF.Builder.CreateConstInBoundsByteGEP(numElementsPtr, numElementsOffset);
2214e5dd7070Spatrick 
2215e5dd7070Spatrick   unsigned AS = allocPtr.getAddressSpace();
2216e5dd7070Spatrick   numElementsPtr = CGF.Builder.CreateElementBitCast(numElementsPtr, CGF.SizeTy);
2217e5dd7070Spatrick   if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2218e5dd7070Spatrick     return CGF.Builder.CreateLoad(numElementsPtr);
2219e5dd7070Spatrick   // In asan mode emit a function call instead of a regular load and let the
2220e5dd7070Spatrick   // run-time deal with it: if the shadow is properly poisoned return the
2221e5dd7070Spatrick   // cookie, otherwise return 0 to avoid an infinite loop calling DTORs.
2222e5dd7070Spatrick   // We can't simply ignore this load using nosanitize metadata because
2223e5dd7070Spatrick   // the metadata may be lost.
2224e5dd7070Spatrick   llvm::FunctionType *FTy =
2225e5dd7070Spatrick       llvm::FunctionType::get(CGF.SizeTy, CGF.SizeTy->getPointerTo(0), false);
2226e5dd7070Spatrick   llvm::FunctionCallee F =
2227e5dd7070Spatrick       CGM.CreateRuntimeFunction(FTy, "__asan_load_cxx_array_cookie");
2228e5dd7070Spatrick   return CGF.Builder.CreateCall(F, numElementsPtr.getPointer());
2229e5dd7070Spatrick }
2230e5dd7070Spatrick 
getArrayCookieSizeImpl(QualType elementType)2231e5dd7070Spatrick CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2232e5dd7070Spatrick   // ARM says that the cookie is always:
2233e5dd7070Spatrick   //   struct array_cookie {
2234e5dd7070Spatrick   //     std::size_t element_size; // element_size != 0
2235e5dd7070Spatrick   //     std::size_t element_count;
2236e5dd7070Spatrick   //   };
2237e5dd7070Spatrick   // But the base ABI doesn't give anything an alignment greater than
2238e5dd7070Spatrick   // 8, so we can dismiss this as typical ABI-author blindness to
2239e5dd7070Spatrick   // actual language complexity and round up to the element alignment.
2240e5dd7070Spatrick   return std::max(CharUnits::fromQuantity(2 * CGM.SizeSizeInBytes),
2241e5dd7070Spatrick                   CGM.getContext().getTypeAlignInChars(elementType));
2242e5dd7070Spatrick }
2243e5dd7070Spatrick 
InitializeArrayCookie(CodeGenFunction & CGF,Address newPtr,llvm::Value * numElements,const CXXNewExpr * expr,QualType elementType)2244e5dd7070Spatrick Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2245e5dd7070Spatrick                                          Address newPtr,
2246e5dd7070Spatrick                                          llvm::Value *numElements,
2247e5dd7070Spatrick                                          const CXXNewExpr *expr,
2248e5dd7070Spatrick                                          QualType elementType) {
2249e5dd7070Spatrick   assert(requiresArrayCookie(expr));
2250e5dd7070Spatrick 
2251e5dd7070Spatrick   // The cookie is always at the start of the buffer.
2252e5dd7070Spatrick   Address cookie = newPtr;
2253e5dd7070Spatrick 
2254e5dd7070Spatrick   // The first element is the element size.
2255e5dd7070Spatrick   cookie = CGF.Builder.CreateElementBitCast(cookie, CGF.SizeTy);
2256e5dd7070Spatrick   llvm::Value *elementSize = llvm::ConstantInt::get(CGF.SizeTy,
2257e5dd7070Spatrick                  getContext().getTypeSizeInChars(elementType).getQuantity());
2258e5dd7070Spatrick   CGF.Builder.CreateStore(elementSize, cookie);
2259e5dd7070Spatrick 
2260e5dd7070Spatrick   // The second element is the element count.
2261e5dd7070Spatrick   cookie = CGF.Builder.CreateConstInBoundsGEP(cookie, 1);
2262e5dd7070Spatrick   CGF.Builder.CreateStore(numElements, cookie);
2263e5dd7070Spatrick 
2264e5dd7070Spatrick   // Finally, compute a pointer to the actual data buffer by skipping
2265e5dd7070Spatrick   // over the cookie completely.
2266e5dd7070Spatrick   CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2267e5dd7070Spatrick   return CGF.Builder.CreateConstInBoundsByteGEP(newPtr, cookieSize);
2268e5dd7070Spatrick }
2269e5dd7070Spatrick 
readArrayCookieImpl(CodeGenFunction & CGF,Address allocPtr,CharUnits cookieSize)2270e5dd7070Spatrick llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2271e5dd7070Spatrick                                             Address allocPtr,
2272e5dd7070Spatrick                                             CharUnits cookieSize) {
2273e5dd7070Spatrick   // The number of elements is at offset sizeof(size_t) relative to
2274e5dd7070Spatrick   // the allocated pointer.
2275e5dd7070Spatrick   Address numElementsPtr
2276e5dd7070Spatrick     = CGF.Builder.CreateConstInBoundsByteGEP(allocPtr, CGF.getSizeSize());
2277e5dd7070Spatrick 
2278e5dd7070Spatrick   numElementsPtr = CGF.Builder.CreateElementBitCast(numElementsPtr, CGF.SizeTy);
2279e5dd7070Spatrick   return CGF.Builder.CreateLoad(numElementsPtr);
2280e5dd7070Spatrick }
2281e5dd7070Spatrick 
2282e5dd7070Spatrick /*********************** Static local initialization **************************/
2283e5dd7070Spatrick 
getGuardAcquireFn(CodeGenModule & CGM,llvm::PointerType * GuardPtrTy)2284e5dd7070Spatrick static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM,
2285e5dd7070Spatrick                                               llvm::PointerType *GuardPtrTy) {
2286e5dd7070Spatrick   // int __cxa_guard_acquire(__guard *guard_object);
2287e5dd7070Spatrick   llvm::FunctionType *FTy =
2288e5dd7070Spatrick     llvm::FunctionType::get(CGM.getTypes().ConvertType(CGM.getContext().IntTy),
2289e5dd7070Spatrick                             GuardPtrTy, /*isVarArg=*/false);
2290e5dd7070Spatrick   return CGM.CreateRuntimeFunction(
2291e5dd7070Spatrick       FTy, "__cxa_guard_acquire",
2292e5dd7070Spatrick       llvm::AttributeList::get(CGM.getLLVMContext(),
2293e5dd7070Spatrick                                llvm::AttributeList::FunctionIndex,
2294e5dd7070Spatrick                                llvm::Attribute::NoUnwind));
2295e5dd7070Spatrick }
2296e5dd7070Spatrick 
getGuardReleaseFn(CodeGenModule & CGM,llvm::PointerType * GuardPtrTy)2297e5dd7070Spatrick static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM,
2298e5dd7070Spatrick                                               llvm::PointerType *GuardPtrTy) {
2299e5dd7070Spatrick   // void __cxa_guard_release(__guard *guard_object);
2300e5dd7070Spatrick   llvm::FunctionType *FTy =
2301e5dd7070Spatrick     llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
2302e5dd7070Spatrick   return CGM.CreateRuntimeFunction(
2303e5dd7070Spatrick       FTy, "__cxa_guard_release",
2304e5dd7070Spatrick       llvm::AttributeList::get(CGM.getLLVMContext(),
2305e5dd7070Spatrick                                llvm::AttributeList::FunctionIndex,
2306e5dd7070Spatrick                                llvm::Attribute::NoUnwind));
2307e5dd7070Spatrick }
2308e5dd7070Spatrick 
getGuardAbortFn(CodeGenModule & CGM,llvm::PointerType * GuardPtrTy)2309e5dd7070Spatrick static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM,
2310e5dd7070Spatrick                                             llvm::PointerType *GuardPtrTy) {
2311e5dd7070Spatrick   // void __cxa_guard_abort(__guard *guard_object);
2312e5dd7070Spatrick   llvm::FunctionType *FTy =
2313e5dd7070Spatrick     llvm::FunctionType::get(CGM.VoidTy, GuardPtrTy, /*isVarArg=*/false);
2314e5dd7070Spatrick   return CGM.CreateRuntimeFunction(
2315e5dd7070Spatrick       FTy, "__cxa_guard_abort",
2316e5dd7070Spatrick       llvm::AttributeList::get(CGM.getLLVMContext(),
2317e5dd7070Spatrick                                llvm::AttributeList::FunctionIndex,
2318e5dd7070Spatrick                                llvm::Attribute::NoUnwind));
2319e5dd7070Spatrick }
2320e5dd7070Spatrick 
2321e5dd7070Spatrick namespace {
2322e5dd7070Spatrick   struct CallGuardAbort final : EHScopeStack::Cleanup {
2323e5dd7070Spatrick     llvm::GlobalVariable *Guard;
CallGuardAbort__anon449188eb0211::CallGuardAbort2324e5dd7070Spatrick     CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2325e5dd7070Spatrick 
Emit__anon449188eb0211::CallGuardAbort2326e5dd7070Spatrick     void Emit(CodeGenFunction &CGF, Flags flags) override {
2327e5dd7070Spatrick       CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()),
2328e5dd7070Spatrick                                   Guard);
2329e5dd7070Spatrick     }
2330e5dd7070Spatrick   };
2331e5dd7070Spatrick }
2332e5dd7070Spatrick 
2333e5dd7070Spatrick /// The ARM code here follows the Itanium code closely enough that we
2334e5dd7070Spatrick /// just special-case it at particular places.
EmitGuardedInit(CodeGenFunction & CGF,const VarDecl & D,llvm::GlobalVariable * var,bool shouldPerformInit)2335e5dd7070Spatrick void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
2336e5dd7070Spatrick                                     const VarDecl &D,
2337e5dd7070Spatrick                                     llvm::GlobalVariable *var,
2338e5dd7070Spatrick                                     bool shouldPerformInit) {
2339e5dd7070Spatrick   CGBuilderTy &Builder = CGF.Builder;
2340e5dd7070Spatrick 
2341e5dd7070Spatrick   // Inline variables that weren't instantiated from variable templates have
2342e5dd7070Spatrick   // partially-ordered initialization within their translation unit.
2343e5dd7070Spatrick   bool NonTemplateInline =
2344e5dd7070Spatrick       D.isInline() &&
2345e5dd7070Spatrick       !isTemplateInstantiation(D.getTemplateSpecializationKind());
2346e5dd7070Spatrick 
2347e5dd7070Spatrick   // We only need to use thread-safe statics for local non-TLS variables and
2348e5dd7070Spatrick   // inline variables; other global initialization is always single-threaded
2349e5dd7070Spatrick   // or (through lazy dynamic loading in multiple threads) unsequenced.
2350e5dd7070Spatrick   bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2351e5dd7070Spatrick                     (D.isLocalVarDecl() || NonTemplateInline) &&
2352e5dd7070Spatrick                     !D.getTLSKind();
2353e5dd7070Spatrick 
2354e5dd7070Spatrick   // If we have a global variable with internal linkage and thread-safe statics
2355e5dd7070Spatrick   // are disabled, we can just let the guard variable be of type i8.
2356e5dd7070Spatrick   bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
2357e5dd7070Spatrick 
2358e5dd7070Spatrick   llvm::IntegerType *guardTy;
2359e5dd7070Spatrick   CharUnits guardAlignment;
2360e5dd7070Spatrick   if (useInt8GuardVariable) {
2361e5dd7070Spatrick     guardTy = CGF.Int8Ty;
2362e5dd7070Spatrick     guardAlignment = CharUnits::One();
2363e5dd7070Spatrick   } else {
2364e5dd7070Spatrick     // Guard variables are 64 bits in the generic ABI and size width on ARM
2365e5dd7070Spatrick     // (i.e. 32-bit on AArch32, 64-bit on AArch64).
2366e5dd7070Spatrick     if (UseARMGuardVarABI) {
2367e5dd7070Spatrick       guardTy = CGF.SizeTy;
2368e5dd7070Spatrick       guardAlignment = CGF.getSizeAlign();
2369e5dd7070Spatrick     } else {
2370e5dd7070Spatrick       guardTy = CGF.Int64Ty;
2371*12c85518Srobert       guardAlignment =
2372*12c85518Srobert           CharUnits::fromQuantity(CGM.getDataLayout().getABITypeAlign(guardTy));
2373e5dd7070Spatrick     }
2374e5dd7070Spatrick   }
2375a9ac8606Spatrick   llvm::PointerType *guardPtrTy = guardTy->getPointerTo(
2376a9ac8606Spatrick       CGF.CGM.getDataLayout().getDefaultGlobalsAddressSpace());
2377e5dd7070Spatrick 
2378e5dd7070Spatrick   // Create the guard variable if we don't already have it (as we
2379e5dd7070Spatrick   // might if we're double-emitting this function body).
2380e5dd7070Spatrick   llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2381e5dd7070Spatrick   if (!guard) {
2382e5dd7070Spatrick     // Mangle the name for the guard.
2383e5dd7070Spatrick     SmallString<256> guardName;
2384e5dd7070Spatrick     {
2385e5dd7070Spatrick       llvm::raw_svector_ostream out(guardName);
2386e5dd7070Spatrick       getMangleContext().mangleStaticGuardVariable(&D, out);
2387e5dd7070Spatrick     }
2388e5dd7070Spatrick 
2389e5dd7070Spatrick     // Create the guard variable with a zero-initializer.
2390*12c85518Srobert     // Just absorb linkage, visibility and dll storage class  from the guarded
2391*12c85518Srobert     // variable.
2392e5dd7070Spatrick     guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,
2393e5dd7070Spatrick                                      false, var->getLinkage(),
2394e5dd7070Spatrick                                      llvm::ConstantInt::get(guardTy, 0),
2395e5dd7070Spatrick                                      guardName.str());
2396e5dd7070Spatrick     guard->setDSOLocal(var->isDSOLocal());
2397e5dd7070Spatrick     guard->setVisibility(var->getVisibility());
2398*12c85518Srobert     guard->setDLLStorageClass(var->getDLLStorageClass());
2399e5dd7070Spatrick     // If the variable is thread-local, so is its guard variable.
2400e5dd7070Spatrick     guard->setThreadLocalMode(var->getThreadLocalMode());
2401e5dd7070Spatrick     guard->setAlignment(guardAlignment.getAsAlign());
2402e5dd7070Spatrick 
2403e5dd7070Spatrick     // The ABI says: "It is suggested that it be emitted in the same COMDAT
2404e5dd7070Spatrick     // group as the associated data object." In practice, this doesn't work for
2405e5dd7070Spatrick     // non-ELF and non-Wasm object formats, so only do it for ELF and Wasm.
2406e5dd7070Spatrick     llvm::Comdat *C = var->getComdat();
2407e5dd7070Spatrick     if (!D.isLocalVarDecl() && C &&
2408e5dd7070Spatrick         (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2409e5dd7070Spatrick          CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2410e5dd7070Spatrick       guard->setComdat(C);
2411e5dd7070Spatrick     } else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2412e5dd7070Spatrick       guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2413e5dd7070Spatrick     }
2414e5dd7070Spatrick 
2415e5dd7070Spatrick     CGM.setStaticLocalDeclGuardAddress(&D, guard);
2416e5dd7070Spatrick   }
2417e5dd7070Spatrick 
2418*12c85518Srobert   Address guardAddr = Address(guard, guard->getValueType(), guardAlignment);
2419e5dd7070Spatrick 
2420e5dd7070Spatrick   // Test whether the variable has completed initialization.
2421e5dd7070Spatrick   //
2422e5dd7070Spatrick   // Itanium C++ ABI 3.3.2:
2423e5dd7070Spatrick   //   The following is pseudo-code showing how these functions can be used:
2424e5dd7070Spatrick   //     if (obj_guard.first_byte == 0) {
2425e5dd7070Spatrick   //       if ( __cxa_guard_acquire (&obj_guard) ) {
2426e5dd7070Spatrick   //         try {
2427e5dd7070Spatrick   //           ... initialize the object ...;
2428e5dd7070Spatrick   //         } catch (...) {
2429e5dd7070Spatrick   //            __cxa_guard_abort (&obj_guard);
2430e5dd7070Spatrick   //            throw;
2431e5dd7070Spatrick   //         }
2432e5dd7070Spatrick   //         ... queue object destructor with __cxa_atexit() ...;
2433e5dd7070Spatrick   //         __cxa_guard_release (&obj_guard);
2434e5dd7070Spatrick   //       }
2435e5dd7070Spatrick   //     }
2436*12c85518Srobert   //
2437*12c85518Srobert   // If threadsafe statics are enabled, but we don't have inline atomics, just
2438*12c85518Srobert   // call __cxa_guard_acquire unconditionally.  The "inline" check isn't
2439*12c85518Srobert   // actually inline, and the user might not expect calls to __atomic libcalls.
2440e5dd7070Spatrick 
2441*12c85518Srobert   unsigned MaxInlineWidthInBits = CGF.getTarget().getMaxAtomicInlineWidth();
2442*12c85518Srobert   llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
2443*12c85518Srobert   if (!threadsafe || MaxInlineWidthInBits) {
2444e5dd7070Spatrick     // Load the first byte of the guard variable.
2445e5dd7070Spatrick     llvm::LoadInst *LI =
2446e5dd7070Spatrick         Builder.CreateLoad(Builder.CreateElementBitCast(guardAddr, CGM.Int8Ty));
2447e5dd7070Spatrick 
2448e5dd7070Spatrick     // Itanium ABI:
2449e5dd7070Spatrick     //   An implementation supporting thread-safety on multiprocessor
2450e5dd7070Spatrick     //   systems must also guarantee that references to the initialized
2451e5dd7070Spatrick     //   object do not occur before the load of the initialization flag.
2452e5dd7070Spatrick     //
2453e5dd7070Spatrick     // In LLVM, we do this by marking the load Acquire.
2454e5dd7070Spatrick     if (threadsafe)
2455e5dd7070Spatrick       LI->setAtomic(llvm::AtomicOrdering::Acquire);
2456e5dd7070Spatrick 
2457e5dd7070Spatrick     // For ARM, we should only check the first bit, rather than the entire byte:
2458e5dd7070Spatrick     //
2459e5dd7070Spatrick     // ARM C++ ABI 3.2.3.1:
2460e5dd7070Spatrick     //   To support the potential use of initialization guard variables
2461e5dd7070Spatrick     //   as semaphores that are the target of ARM SWP and LDREX/STREX
2462e5dd7070Spatrick     //   synchronizing instructions we define a static initialization
2463e5dd7070Spatrick     //   guard variable to be a 4-byte aligned, 4-byte word with the
2464e5dd7070Spatrick     //   following inline access protocol.
2465e5dd7070Spatrick     //     #define INITIALIZED 1
2466e5dd7070Spatrick     //     if ((obj_guard & INITIALIZED) != INITIALIZED) {
2467e5dd7070Spatrick     //       if (__cxa_guard_acquire(&obj_guard))
2468e5dd7070Spatrick     //         ...
2469e5dd7070Spatrick     //     }
2470e5dd7070Spatrick     //
2471e5dd7070Spatrick     // and similarly for ARM64:
2472e5dd7070Spatrick     //
2473e5dd7070Spatrick     // ARM64 C++ ABI 3.2.2:
2474e5dd7070Spatrick     //   This ABI instead only specifies the value bit 0 of the static guard
2475e5dd7070Spatrick     //   variable; all other bits are platform defined. Bit 0 shall be 0 when the
2476e5dd7070Spatrick     //   variable is not initialized and 1 when it is.
2477e5dd7070Spatrick     llvm::Value *V =
2478e5dd7070Spatrick         (UseARMGuardVarABI && !useInt8GuardVariable)
2479e5dd7070Spatrick             ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2480e5dd7070Spatrick             : LI;
2481e5dd7070Spatrick     llvm::Value *NeedsInit = Builder.CreateIsNull(V, "guard.uninitialized");
2482e5dd7070Spatrick 
2483e5dd7070Spatrick     llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
2484e5dd7070Spatrick 
2485e5dd7070Spatrick     // Check if the first byte of the guard variable is zero.
2486e5dd7070Spatrick     CGF.EmitCXXGuardedInitBranch(NeedsInit, InitCheckBlock, EndBlock,
2487e5dd7070Spatrick                                  CodeGenFunction::GuardKind::VariableGuard, &D);
2488e5dd7070Spatrick 
2489e5dd7070Spatrick     CGF.EmitBlock(InitCheckBlock);
2490*12c85518Srobert   }
2491*12c85518Srobert 
2492*12c85518Srobert   // The semantics of dynamic initialization of variables with static or thread
2493*12c85518Srobert   // storage duration depends on whether they are declared at block-scope. The
2494*12c85518Srobert   // initialization of such variables at block-scope can be aborted with an
2495*12c85518Srobert   // exception and later retried (per C++20 [stmt.dcl]p4), and recursive entry
2496*12c85518Srobert   // to their initialization has undefined behavior (also per C++20
2497*12c85518Srobert   // [stmt.dcl]p4). For such variables declared at non-block scope, exceptions
2498*12c85518Srobert   // lead to termination (per C++20 [except.terminate]p1), and recursive
2499*12c85518Srobert   // references to the variables are governed only by the lifetime rules (per
2500*12c85518Srobert   // C++20 [class.cdtor]p2), which means such references are perfectly fine as
2501*12c85518Srobert   // long as they avoid touching memory. As a result, block-scope variables must
2502*12c85518Srobert   // not be marked as initialized until after initialization completes (unless
2503*12c85518Srobert   // the mark is reverted following an exception), but non-block-scope variables
2504*12c85518Srobert   // must be marked prior to initialization so that recursive accesses during
2505*12c85518Srobert   // initialization do not restart initialization.
2506e5dd7070Spatrick 
2507e5dd7070Spatrick   // Variables used when coping with thread-safe statics and exceptions.
2508e5dd7070Spatrick   if (threadsafe) {
2509e5dd7070Spatrick     // Call __cxa_guard_acquire.
2510e5dd7070Spatrick     llvm::Value *V
2511e5dd7070Spatrick       = CGF.EmitNounwindRuntimeCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
2512e5dd7070Spatrick 
2513e5dd7070Spatrick     llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
2514e5dd7070Spatrick 
2515e5dd7070Spatrick     Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
2516e5dd7070Spatrick                          InitBlock, EndBlock);
2517e5dd7070Spatrick 
2518e5dd7070Spatrick     // Call __cxa_guard_abort along the exceptional edge.
2519e5dd7070Spatrick     CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard);
2520e5dd7070Spatrick 
2521e5dd7070Spatrick     CGF.EmitBlock(InitBlock);
2522*12c85518Srobert   } else if (!D.isLocalVarDecl()) {
2523*12c85518Srobert     // For non-local variables, store 1 into the first byte of the guard
2524*12c85518Srobert     // variable before the object initialization begins so that references
2525*12c85518Srobert     // to the variable during initialization don't restart initialization.
2526*12c85518Srobert     Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2527*12c85518Srobert                         Builder.CreateElementBitCast(guardAddr, CGM.Int8Ty));
2528e5dd7070Spatrick   }
2529e5dd7070Spatrick 
2530e5dd7070Spatrick   // Emit the initializer and add a global destructor if appropriate.
2531e5dd7070Spatrick   CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit);
2532e5dd7070Spatrick 
2533e5dd7070Spatrick   if (threadsafe) {
2534e5dd7070Spatrick     // Pop the guard-abort cleanup if we pushed one.
2535e5dd7070Spatrick     CGF.PopCleanupBlock();
2536e5dd7070Spatrick 
2537e5dd7070Spatrick     // Call __cxa_guard_release.  This cannot throw.
2538e5dd7070Spatrick     CGF.EmitNounwindRuntimeCall(getGuardReleaseFn(CGM, guardPtrTy),
2539e5dd7070Spatrick                                 guardAddr.getPointer());
2540*12c85518Srobert   } else if (D.isLocalVarDecl()) {
2541*12c85518Srobert     // For local variables, store 1 into the first byte of the guard variable
2542*12c85518Srobert     // after the object initialization completes so that initialization is
2543*12c85518Srobert     // retried if initialization is interrupted by an exception.
2544a9ac8606Spatrick     Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2545a9ac8606Spatrick                         Builder.CreateElementBitCast(guardAddr, CGM.Int8Ty));
2546e5dd7070Spatrick   }
2547e5dd7070Spatrick 
2548e5dd7070Spatrick   CGF.EmitBlock(EndBlock);
2549e5dd7070Spatrick }
2550e5dd7070Spatrick 
2551e5dd7070Spatrick /// Register a global destructor using __cxa_atexit.
emitGlobalDtorWithCXAAtExit(CodeGenFunction & CGF,llvm::FunctionCallee dtor,llvm::Constant * addr,bool TLS)2552e5dd7070Spatrick static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
2553e5dd7070Spatrick                                         llvm::FunctionCallee dtor,
2554e5dd7070Spatrick                                         llvm::Constant *addr, bool TLS) {
2555a9ac8606Spatrick   assert(!CGF.getTarget().getTriple().isOSAIX() &&
2556a9ac8606Spatrick          "unexpected call to emitGlobalDtorWithCXAAtExit");
2557e5dd7070Spatrick   assert((TLS || CGF.getTypes().getCodeGenOpts().CXAAtExit) &&
2558e5dd7070Spatrick          "__cxa_atexit is disabled");
2559e5dd7070Spatrick   const char *Name = "__cxa_atexit";
2560e5dd7070Spatrick   if (TLS) {
2561e5dd7070Spatrick     const llvm::Triple &T = CGF.getTarget().getTriple();
2562e5dd7070Spatrick     Name = T.isOSDarwin() ?  "_tlv_atexit" : "__cxa_thread_atexit";
2563e5dd7070Spatrick   }
2564e5dd7070Spatrick 
2565e5dd7070Spatrick   // We're assuming that the destructor function is something we can
2566e5dd7070Spatrick   // reasonably call with the default CC.  Go ahead and cast it to the
2567e5dd7070Spatrick   // right prototype.
2568e5dd7070Spatrick   llvm::Type *dtorTy =
2569e5dd7070Spatrick     llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo();
2570e5dd7070Spatrick 
2571e5dd7070Spatrick   // Preserve address space of addr.
2572e5dd7070Spatrick   auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2573e5dd7070Spatrick   auto AddrInt8PtrTy =
2574e5dd7070Spatrick       AddrAS ? CGF.Int8Ty->getPointerTo(AddrAS) : CGF.Int8PtrTy;
2575e5dd7070Spatrick 
2576e5dd7070Spatrick   // Create a variable that binds the atexit to this shared object.
2577e5dd7070Spatrick   llvm::Constant *handle =
2578e5dd7070Spatrick       CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
2579e5dd7070Spatrick   auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2580e5dd7070Spatrick   GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2581e5dd7070Spatrick 
2582e5dd7070Spatrick   // extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d);
2583e5dd7070Spatrick   llvm::Type *paramTys[] = {dtorTy, AddrInt8PtrTy, handle->getType()};
2584e5dd7070Spatrick   llvm::FunctionType *atexitTy =
2585e5dd7070Spatrick     llvm::FunctionType::get(CGF.IntTy, paramTys, false);
2586e5dd7070Spatrick 
2587e5dd7070Spatrick   // Fetch the actual function.
2588e5dd7070Spatrick   llvm::FunctionCallee atexit = CGF.CGM.CreateRuntimeFunction(atexitTy, Name);
2589e5dd7070Spatrick   if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2590e5dd7070Spatrick     fn->setDoesNotThrow();
2591e5dd7070Spatrick 
2592e5dd7070Spatrick   if (!addr)
2593e5dd7070Spatrick     // addr is null when we are trying to register a dtor annotated with
2594e5dd7070Spatrick     // __attribute__((destructor)) in a constructor function. Using null here is
2595e5dd7070Spatrick     // okay because this argument is just passed back to the destructor
2596e5dd7070Spatrick     // function.
2597e5dd7070Spatrick     addr = llvm::Constant::getNullValue(CGF.Int8PtrTy);
2598e5dd7070Spatrick 
2599e5dd7070Spatrick   llvm::Value *args[] = {llvm::ConstantExpr::getBitCast(
2600e5dd7070Spatrick                              cast<llvm::Constant>(dtor.getCallee()), dtorTy),
2601e5dd7070Spatrick                          llvm::ConstantExpr::getBitCast(addr, AddrInt8PtrTy),
2602e5dd7070Spatrick                          handle};
2603e5dd7070Spatrick   CGF.EmitNounwindRuntimeCall(atexit, args);
2604e5dd7070Spatrick }
2605e5dd7070Spatrick 
createGlobalInitOrCleanupFn(CodeGen::CodeGenModule & CGM,StringRef FnName)2606a9ac8606Spatrick static llvm::Function *createGlobalInitOrCleanupFn(CodeGen::CodeGenModule &CGM,
2607a9ac8606Spatrick                                                    StringRef FnName) {
2608a9ac8606Spatrick   // Create a function that registers/unregisters destructors that have the same
2609a9ac8606Spatrick   // priority.
2610a9ac8606Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
2611a9ac8606Spatrick   llvm::Function *GlobalInitOrCleanupFn = CGM.CreateGlobalInitOrCleanUpFunction(
2612a9ac8606Spatrick       FTy, FnName, CGM.getTypes().arrangeNullaryFunction(), SourceLocation());
2613a9ac8606Spatrick 
2614a9ac8606Spatrick   return GlobalInitOrCleanupFn;
2615a9ac8606Spatrick }
2616a9ac8606Spatrick 
unregisterGlobalDtorsWithUnAtExit()2617a9ac8606Spatrick void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
2618a9ac8606Spatrick   for (const auto &I : DtorsUsingAtExit) {
2619a9ac8606Spatrick     int Priority = I.first;
2620a9ac8606Spatrick     std::string GlobalCleanupFnName =
2621a9ac8606Spatrick         std::string("__GLOBAL_cleanup_") + llvm::to_string(Priority);
2622a9ac8606Spatrick 
2623a9ac8606Spatrick     llvm::Function *GlobalCleanupFn =
2624a9ac8606Spatrick         createGlobalInitOrCleanupFn(*this, GlobalCleanupFnName);
2625a9ac8606Spatrick 
2626a9ac8606Spatrick     CodeGenFunction CGF(*this);
2627a9ac8606Spatrick     CGF.StartFunction(GlobalDecl(), getContext().VoidTy, GlobalCleanupFn,
2628a9ac8606Spatrick                       getTypes().arrangeNullaryFunction(), FunctionArgList(),
2629a9ac8606Spatrick                       SourceLocation(), SourceLocation());
2630a9ac8606Spatrick     auto AL = ApplyDebugLocation::CreateArtificial(CGF);
2631a9ac8606Spatrick 
2632a9ac8606Spatrick     // Get the destructor function type, void(*)(void).
2633a9ac8606Spatrick     llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.VoidTy, false);
2634a9ac8606Spatrick     llvm::Type *dtorTy = dtorFuncTy->getPointerTo();
2635a9ac8606Spatrick 
2636a9ac8606Spatrick     // Destructor functions are run/unregistered in non-ascending
2637a9ac8606Spatrick     // order of their priorities.
2638a9ac8606Spatrick     const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2639a9ac8606Spatrick     auto itv = Dtors.rbegin();
2640a9ac8606Spatrick     while (itv != Dtors.rend()) {
2641a9ac8606Spatrick       llvm::Function *Dtor = *itv;
2642a9ac8606Spatrick 
2643a9ac8606Spatrick       // We're assuming that the destructor function is something we can
2644a9ac8606Spatrick       // reasonably call with the correct CC.  Go ahead and cast it to the
2645a9ac8606Spatrick       // right prototype.
2646a9ac8606Spatrick       llvm::Constant *dtor = llvm::ConstantExpr::getBitCast(Dtor, dtorTy);
2647a9ac8606Spatrick       llvm::Value *V = CGF.unregisterGlobalDtorWithUnAtExit(dtor);
2648a9ac8606Spatrick       llvm::Value *NeedsDestruct =
2649a9ac8606Spatrick           CGF.Builder.CreateIsNull(V, "needs_destruct");
2650a9ac8606Spatrick 
2651a9ac8606Spatrick       llvm::BasicBlock *DestructCallBlock =
2652a9ac8606Spatrick           CGF.createBasicBlock("destruct.call");
2653a9ac8606Spatrick       llvm::BasicBlock *EndBlock = CGF.createBasicBlock(
2654a9ac8606Spatrick           (itv + 1) != Dtors.rend() ? "unatexit.call" : "destruct.end");
2655a9ac8606Spatrick       // Check if unatexit returns a value of 0. If it does, jump to
2656a9ac8606Spatrick       // DestructCallBlock, otherwise jump to EndBlock directly.
2657a9ac8606Spatrick       CGF.Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
2658a9ac8606Spatrick 
2659a9ac8606Spatrick       CGF.EmitBlock(DestructCallBlock);
2660a9ac8606Spatrick 
2661a9ac8606Spatrick       // Emit the call to casted Dtor.
2662a9ac8606Spatrick       llvm::CallInst *CI = CGF.Builder.CreateCall(dtorFuncTy, dtor);
2663a9ac8606Spatrick       // Make sure the call and the callee agree on calling convention.
2664a9ac8606Spatrick       CI->setCallingConv(Dtor->getCallingConv());
2665a9ac8606Spatrick 
2666a9ac8606Spatrick       CGF.EmitBlock(EndBlock);
2667a9ac8606Spatrick 
2668a9ac8606Spatrick       itv++;
2669a9ac8606Spatrick     }
2670a9ac8606Spatrick 
2671a9ac8606Spatrick     CGF.FinishFunction();
2672a9ac8606Spatrick     AddGlobalDtor(GlobalCleanupFn, Priority);
2673a9ac8606Spatrick   }
2674a9ac8606Spatrick }
2675a9ac8606Spatrick 
registerGlobalDtorsWithAtExit()2676e5dd7070Spatrick void CodeGenModule::registerGlobalDtorsWithAtExit() {
2677e5dd7070Spatrick   for (const auto &I : DtorsUsingAtExit) {
2678e5dd7070Spatrick     int Priority = I.first;
2679a9ac8606Spatrick     std::string GlobalInitFnName =
2680a9ac8606Spatrick         std::string("__GLOBAL_init_") + llvm::to_string(Priority);
2681a9ac8606Spatrick     llvm::Function *GlobalInitFn =
2682a9ac8606Spatrick         createGlobalInitOrCleanupFn(*this, GlobalInitFnName);
2683e5dd7070Spatrick 
2684a9ac8606Spatrick     CodeGenFunction CGF(*this);
2685a9ac8606Spatrick     CGF.StartFunction(GlobalDecl(), getContext().VoidTy, GlobalInitFn,
2686a9ac8606Spatrick                       getTypes().arrangeNullaryFunction(), FunctionArgList(),
2687a9ac8606Spatrick                       SourceLocation(), SourceLocation());
2688a9ac8606Spatrick     auto AL = ApplyDebugLocation::CreateArtificial(CGF);
2689a9ac8606Spatrick 
2690e5dd7070Spatrick     // Since constructor functions are run in non-descending order of their
2691e5dd7070Spatrick     // priorities, destructors are registered in non-descending order of their
2692e5dd7070Spatrick     // priorities, and since destructor functions are run in the reverse order
2693e5dd7070Spatrick     // of their registration, destructor functions are run in non-ascending
2694e5dd7070Spatrick     // order of their priorities.
2695a9ac8606Spatrick     const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2696e5dd7070Spatrick     for (auto *Dtor : Dtors) {
2697e5dd7070Spatrick       // Register the destructor function calling __cxa_atexit if it is
2698e5dd7070Spatrick       // available. Otherwise fall back on calling atexit.
2699a9ac8606Spatrick       if (getCodeGenOpts().CXAAtExit) {
2700e5dd7070Spatrick         emitGlobalDtorWithCXAAtExit(CGF, Dtor, nullptr, false);
2701a9ac8606Spatrick       } else {
2702a9ac8606Spatrick         // Get the destructor function type, void(*)(void).
2703a9ac8606Spatrick         llvm::Type *dtorTy =
2704a9ac8606Spatrick             llvm::FunctionType::get(CGF.VoidTy, false)->getPointerTo();
2705a9ac8606Spatrick 
2706a9ac8606Spatrick         // We're assuming that the destructor function is something we can
2707a9ac8606Spatrick         // reasonably call with the correct CC.  Go ahead and cast it to the
2708a9ac8606Spatrick         // right prototype.
2709a9ac8606Spatrick         CGF.registerGlobalDtorWithAtExit(
2710a9ac8606Spatrick             llvm::ConstantExpr::getBitCast(Dtor, dtorTy));
2711a9ac8606Spatrick       }
2712e5dd7070Spatrick     }
2713e5dd7070Spatrick 
2714e5dd7070Spatrick     CGF.FinishFunction();
2715*12c85518Srobert     AddGlobalCtor(GlobalInitFn, Priority);
2716e5dd7070Spatrick   }
2717a9ac8606Spatrick 
2718a9ac8606Spatrick   if (getCXXABI().useSinitAndSterm())
2719a9ac8606Spatrick     unregisterGlobalDtorsWithUnAtExit();
2720e5dd7070Spatrick }
2721e5dd7070Spatrick 
2722e5dd7070Spatrick /// Register a global destructor as best as we know how.
registerGlobalDtor(CodeGenFunction & CGF,const VarDecl & D,llvm::FunctionCallee dtor,llvm::Constant * addr)2723e5dd7070Spatrick void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
2724e5dd7070Spatrick                                        llvm::FunctionCallee dtor,
2725e5dd7070Spatrick                                        llvm::Constant *addr) {
2726e5dd7070Spatrick   if (D.isNoDestroy(CGM.getContext()))
2727e5dd7070Spatrick     return;
2728e5dd7070Spatrick 
2729e5dd7070Spatrick   // emitGlobalDtorWithCXAAtExit will emit a call to either __cxa_thread_atexit
2730e5dd7070Spatrick   // or __cxa_atexit depending on whether this VarDecl is a thread-local storage
2731e5dd7070Spatrick   // or not. CXAAtExit controls only __cxa_atexit, so use it if it is enabled.
2732e5dd7070Spatrick   // We can always use __cxa_thread_atexit.
2733e5dd7070Spatrick   if (CGM.getCodeGenOpts().CXAAtExit || D.getTLSKind())
2734e5dd7070Spatrick     return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr, D.getTLSKind());
2735e5dd7070Spatrick 
2736e5dd7070Spatrick   // In Apple kexts, we want to add a global destructor entry.
2737e5dd7070Spatrick   // FIXME: shouldn't this be guarded by some variable?
2738e5dd7070Spatrick   if (CGM.getLangOpts().AppleKext) {
2739e5dd7070Spatrick     // Generate a global destructor entry.
2740e5dd7070Spatrick     return CGM.AddCXXDtorEntry(dtor, addr);
2741e5dd7070Spatrick   }
2742e5dd7070Spatrick 
2743e5dd7070Spatrick   CGF.registerGlobalDtorWithAtExit(D, dtor, addr);
2744e5dd7070Spatrick }
2745e5dd7070Spatrick 
isThreadWrapperReplaceable(const VarDecl * VD,CodeGen::CodeGenModule & CGM)2746e5dd7070Spatrick static bool isThreadWrapperReplaceable(const VarDecl *VD,
2747e5dd7070Spatrick                                        CodeGen::CodeGenModule &CGM) {
2748e5dd7070Spatrick   assert(!VD->isStaticLocal() && "static local VarDecls don't need wrappers!");
2749e5dd7070Spatrick   // Darwin prefers to have references to thread local variables to go through
2750e5dd7070Spatrick   // the thread wrapper instead of directly referencing the backing variable.
2751e5dd7070Spatrick   return VD->getTLSKind() == VarDecl::TLS_Dynamic &&
2752e5dd7070Spatrick          CGM.getTarget().getTriple().isOSDarwin();
2753e5dd7070Spatrick }
2754e5dd7070Spatrick 
2755e5dd7070Spatrick /// Get the appropriate linkage for the wrapper function. This is essentially
2756e5dd7070Spatrick /// the weak form of the variable's linkage; every translation unit which needs
2757e5dd7070Spatrick /// the wrapper emits a copy, and we want the linker to merge them.
2758e5dd7070Spatrick static llvm::GlobalValue::LinkageTypes
getThreadLocalWrapperLinkage(const VarDecl * VD,CodeGen::CodeGenModule & CGM)2759e5dd7070Spatrick getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) {
2760e5dd7070Spatrick   llvm::GlobalValue::LinkageTypes VarLinkage =
2761e5dd7070Spatrick       CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
2762e5dd7070Spatrick 
2763e5dd7070Spatrick   // For internal linkage variables, we don't need an external or weak wrapper.
2764e5dd7070Spatrick   if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
2765e5dd7070Spatrick     return VarLinkage;
2766e5dd7070Spatrick 
2767e5dd7070Spatrick   // If the thread wrapper is replaceable, give it appropriate linkage.
2768e5dd7070Spatrick   if (isThreadWrapperReplaceable(VD, CGM))
2769e5dd7070Spatrick     if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
2770e5dd7070Spatrick         !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
2771e5dd7070Spatrick       return VarLinkage;
2772e5dd7070Spatrick   return llvm::GlobalValue::WeakODRLinkage;
2773e5dd7070Spatrick }
2774e5dd7070Spatrick 
2775e5dd7070Spatrick llvm::Function *
getOrCreateThreadLocalWrapper(const VarDecl * VD,llvm::Value * Val)2776e5dd7070Spatrick ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD,
2777e5dd7070Spatrick                                              llvm::Value *Val) {
2778e5dd7070Spatrick   // Mangle the name for the thread_local wrapper function.
2779e5dd7070Spatrick   SmallString<256> WrapperName;
2780e5dd7070Spatrick   {
2781e5dd7070Spatrick     llvm::raw_svector_ostream Out(WrapperName);
2782e5dd7070Spatrick     getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
2783e5dd7070Spatrick   }
2784e5dd7070Spatrick 
2785e5dd7070Spatrick   // FIXME: If VD is a definition, we should regenerate the function attributes
2786e5dd7070Spatrick   // before returning.
2787e5dd7070Spatrick   if (llvm::Value *V = CGM.getModule().getNamedValue(WrapperName))
2788e5dd7070Spatrick     return cast<llvm::Function>(V);
2789e5dd7070Spatrick 
2790e5dd7070Spatrick   QualType RetQT = VD->getType();
2791e5dd7070Spatrick   if (RetQT->isReferenceType())
2792e5dd7070Spatrick     RetQT = RetQT.getNonReferenceType();
2793e5dd7070Spatrick 
2794e5dd7070Spatrick   const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
2795e5dd7070Spatrick       getContext().getPointerType(RetQT), FunctionArgList());
2796e5dd7070Spatrick 
2797e5dd7070Spatrick   llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
2798e5dd7070Spatrick   llvm::Function *Wrapper =
2799e5dd7070Spatrick       llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM),
2800e5dd7070Spatrick                              WrapperName.str(), &CGM.getModule());
2801e5dd7070Spatrick 
2802e5dd7070Spatrick   if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
2803e5dd7070Spatrick     Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
2804e5dd7070Spatrick 
2805a9ac8606Spatrick   CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper, /*IsThunk=*/false);
2806e5dd7070Spatrick 
2807e5dd7070Spatrick   // Always resolve references to the wrapper at link time.
2808e5dd7070Spatrick   if (!Wrapper->hasLocalLinkage())
2809e5dd7070Spatrick     if (!isThreadWrapperReplaceable(VD, CGM) ||
2810e5dd7070Spatrick         llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
2811e5dd7070Spatrick         llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
2812e5dd7070Spatrick         VD->getVisibility() == HiddenVisibility)
2813e5dd7070Spatrick       Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
2814e5dd7070Spatrick 
2815e5dd7070Spatrick   if (isThreadWrapperReplaceable(VD, CGM)) {
2816e5dd7070Spatrick     Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2817e5dd7070Spatrick     Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
2818e5dd7070Spatrick   }
2819e5dd7070Spatrick 
2820e5dd7070Spatrick   ThreadWrappers.push_back({VD, Wrapper});
2821e5dd7070Spatrick   return Wrapper;
2822e5dd7070Spatrick }
2823e5dd7070Spatrick 
EmitThreadLocalInitFuncs(CodeGenModule & CGM,ArrayRef<const VarDecl * > CXXThreadLocals,ArrayRef<llvm::Function * > CXXThreadLocalInits,ArrayRef<const VarDecl * > CXXThreadLocalInitVars)2824e5dd7070Spatrick void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2825e5dd7070Spatrick     CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
2826e5dd7070Spatrick     ArrayRef<llvm::Function *> CXXThreadLocalInits,
2827e5dd7070Spatrick     ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
2828e5dd7070Spatrick   llvm::Function *InitFunc = nullptr;
2829e5dd7070Spatrick 
2830e5dd7070Spatrick   // Separate initializers into those with ordered (or partially-ordered)
2831e5dd7070Spatrick   // initialization and those with unordered initialization.
2832e5dd7070Spatrick   llvm::SmallVector<llvm::Function *, 8> OrderedInits;
2833e5dd7070Spatrick   llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
2834e5dd7070Spatrick   for (unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
2835e5dd7070Spatrick     if (isTemplateInstantiation(
2836e5dd7070Spatrick             CXXThreadLocalInitVars[I]->getTemplateSpecializationKind()))
2837e5dd7070Spatrick       UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
2838e5dd7070Spatrick           CXXThreadLocalInits[I];
2839e5dd7070Spatrick     else
2840e5dd7070Spatrick       OrderedInits.push_back(CXXThreadLocalInits[I]);
2841e5dd7070Spatrick   }
2842e5dd7070Spatrick 
2843e5dd7070Spatrick   if (!OrderedInits.empty()) {
2844e5dd7070Spatrick     // Generate a guarded initialization function.
2845e5dd7070Spatrick     llvm::FunctionType *FTy =
2846e5dd7070Spatrick         llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
2847e5dd7070Spatrick     const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
2848ec727ea7Spatrick     InitFunc = CGM.CreateGlobalInitOrCleanUpFunction(FTy, "__tls_init", FI,
2849e5dd7070Spatrick                                                      SourceLocation(),
2850e5dd7070Spatrick                                                      /*TLS=*/true);
2851e5dd7070Spatrick     llvm::GlobalVariable *Guard = new llvm::GlobalVariable(
2852e5dd7070Spatrick         CGM.getModule(), CGM.Int8Ty, /*isConstant=*/false,
2853e5dd7070Spatrick         llvm::GlobalVariable::InternalLinkage,
2854e5dd7070Spatrick         llvm::ConstantInt::get(CGM.Int8Ty, 0), "__tls_guard");
2855e5dd7070Spatrick     Guard->setThreadLocal(true);
2856ec727ea7Spatrick     Guard->setThreadLocalMode(CGM.GetDefaultLLVMTLSModel());
2857e5dd7070Spatrick 
2858e5dd7070Spatrick     CharUnits GuardAlign = CharUnits::One();
2859e5dd7070Spatrick     Guard->setAlignment(GuardAlign.getAsAlign());
2860e5dd7070Spatrick 
2861e5dd7070Spatrick     CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(
2862*12c85518Srobert         InitFunc, OrderedInits, ConstantAddress(Guard, CGM.Int8Ty, GuardAlign));
2863e5dd7070Spatrick     // On Darwin platforms, use CXX_FAST_TLS calling convention.
2864e5dd7070Spatrick     if (CGM.getTarget().getTriple().isOSDarwin()) {
2865e5dd7070Spatrick       InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2866e5dd7070Spatrick       InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
2867e5dd7070Spatrick     }
2868e5dd7070Spatrick   }
2869e5dd7070Spatrick 
2870e5dd7070Spatrick   // Create declarations for thread wrappers for all thread-local variables
2871e5dd7070Spatrick   // with non-discardable definitions in this translation unit.
2872e5dd7070Spatrick   for (const VarDecl *VD : CXXThreadLocals) {
2873e5dd7070Spatrick     if (VD->hasDefinition() &&
2874e5dd7070Spatrick         !isDiscardableGVALinkage(getContext().GetGVALinkageForVariable(VD))) {
2875e5dd7070Spatrick       llvm::GlobalValue *GV = CGM.GetGlobalValue(CGM.getMangledName(VD));
2876e5dd7070Spatrick       getOrCreateThreadLocalWrapper(VD, GV);
2877e5dd7070Spatrick     }
2878e5dd7070Spatrick   }
2879e5dd7070Spatrick 
2880e5dd7070Spatrick   // Emit all referenced thread wrappers.
2881e5dd7070Spatrick   for (auto VDAndWrapper : ThreadWrappers) {
2882e5dd7070Spatrick     const VarDecl *VD = VDAndWrapper.first;
2883e5dd7070Spatrick     llvm::GlobalVariable *Var =
2884e5dd7070Spatrick         cast<llvm::GlobalVariable>(CGM.GetGlobalValue(CGM.getMangledName(VD)));
2885e5dd7070Spatrick     llvm::Function *Wrapper = VDAndWrapper.second;
2886e5dd7070Spatrick 
2887e5dd7070Spatrick     // Some targets require that all access to thread local variables go through
2888e5dd7070Spatrick     // the thread wrapper.  This means that we cannot attempt to create a thread
2889e5dd7070Spatrick     // wrapper or a thread helper.
2890e5dd7070Spatrick     if (!VD->hasDefinition()) {
2891e5dd7070Spatrick       if (isThreadWrapperReplaceable(VD, CGM)) {
2892e5dd7070Spatrick         Wrapper->setLinkage(llvm::Function::ExternalLinkage);
2893e5dd7070Spatrick         continue;
2894e5dd7070Spatrick       }
2895e5dd7070Spatrick 
2896e5dd7070Spatrick       // If this isn't a TU in which this variable is defined, the thread
2897e5dd7070Spatrick       // wrapper is discardable.
2898e5dd7070Spatrick       if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
2899e5dd7070Spatrick         Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
2900e5dd7070Spatrick     }
2901e5dd7070Spatrick 
2902e5dd7070Spatrick     CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Wrapper);
2903e5dd7070Spatrick 
2904e5dd7070Spatrick     // Mangle the name for the thread_local initialization function.
2905e5dd7070Spatrick     SmallString<256> InitFnName;
2906e5dd7070Spatrick     {
2907e5dd7070Spatrick       llvm::raw_svector_ostream Out(InitFnName);
2908e5dd7070Spatrick       getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
2909e5dd7070Spatrick     }
2910e5dd7070Spatrick 
2911e5dd7070Spatrick     llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.VoidTy, false);
2912e5dd7070Spatrick 
2913e5dd7070Spatrick     // If we have a definition for the variable, emit the initialization
2914e5dd7070Spatrick     // function as an alias to the global Init function (if any). Otherwise,
2915e5dd7070Spatrick     // produce a declaration of the initialization function.
2916e5dd7070Spatrick     llvm::GlobalValue *Init = nullptr;
2917e5dd7070Spatrick     bool InitIsInitFunc = false;
2918e5dd7070Spatrick     bool HasConstantInitialization = false;
2919e5dd7070Spatrick     if (!usesThreadWrapperFunction(VD)) {
2920e5dd7070Spatrick       HasConstantInitialization = true;
2921e5dd7070Spatrick     } else if (VD->hasDefinition()) {
2922e5dd7070Spatrick       InitIsInitFunc = true;
2923e5dd7070Spatrick       llvm::Function *InitFuncToUse = InitFunc;
2924e5dd7070Spatrick       if (isTemplateInstantiation(VD->getTemplateSpecializationKind()))
2925e5dd7070Spatrick         InitFuncToUse = UnorderedInits.lookup(VD->getCanonicalDecl());
2926e5dd7070Spatrick       if (InitFuncToUse)
2927e5dd7070Spatrick         Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
2928e5dd7070Spatrick                                          InitFuncToUse);
2929e5dd7070Spatrick     } else {
2930e5dd7070Spatrick       // Emit a weak global function referring to the initialization function.
2931e5dd7070Spatrick       // This function will not exist if the TU defining the thread_local
2932e5dd7070Spatrick       // variable in question does not need any dynamic initialization for
2933e5dd7070Spatrick       // its thread_local variables.
2934e5dd7070Spatrick       Init = llvm::Function::Create(InitFnTy,
2935e5dd7070Spatrick                                     llvm::GlobalVariable::ExternalWeakLinkage,
2936e5dd7070Spatrick                                     InitFnName.str(), &CGM.getModule());
2937e5dd7070Spatrick       const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
2938a9ac8606Spatrick       CGM.SetLLVMFunctionAttributes(
2939a9ac8606Spatrick           GlobalDecl(), FI, cast<llvm::Function>(Init), /*IsThunk=*/false);
2940e5dd7070Spatrick     }
2941e5dd7070Spatrick 
2942e5dd7070Spatrick     if (Init) {
2943e5dd7070Spatrick       Init->setVisibility(Var->getVisibility());
2944e5dd7070Spatrick       // Don't mark an extern_weak function DSO local on windows.
2945e5dd7070Spatrick       if (!CGM.getTriple().isOSWindows() || !Init->hasExternalWeakLinkage())
2946e5dd7070Spatrick         Init->setDSOLocal(Var->isDSOLocal());
2947e5dd7070Spatrick     }
2948e5dd7070Spatrick 
2949e5dd7070Spatrick     llvm::LLVMContext &Context = CGM.getModule().getContext();
2950a9ac8606Spatrick 
2951a9ac8606Spatrick     // The linker on AIX is not happy with missing weak symbols.  However,
2952a9ac8606Spatrick     // other TUs will not know whether the initialization routine exists
2953a9ac8606Spatrick     // so create an empty, init function to satisfy the linker.
2954a9ac8606Spatrick     // This is needed whenever a thread wrapper function is not used, and
2955a9ac8606Spatrick     // also when the symbol is weak.
2956a9ac8606Spatrick     if (CGM.getTriple().isOSAIX() && VD->hasDefinition() &&
2957a9ac8606Spatrick         isEmittedWithConstantInitializer(VD, true) &&
2958*12c85518Srobert         !mayNeedDestruction(VD)) {
2959a9ac8606Spatrick       // Init should be null.  If it were non-null, then the logic above would
2960a9ac8606Spatrick       // either be defining the function to be an alias or declaring the
2961a9ac8606Spatrick       // function with the expectation that the definition of the variable
2962a9ac8606Spatrick       // is elsewhere.
2963a9ac8606Spatrick       assert(Init == nullptr && "Expected Init to be null.");
2964a9ac8606Spatrick 
2965a9ac8606Spatrick       llvm::Function *Func = llvm::Function::Create(
2966a9ac8606Spatrick           InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.getModule());
2967a9ac8606Spatrick       const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
2968a9ac8606Spatrick       CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI,
2969a9ac8606Spatrick                                     cast<llvm::Function>(Func),
2970a9ac8606Spatrick                                     /*IsThunk=*/false);
2971a9ac8606Spatrick       // Create a function body that just returns
2972a9ac8606Spatrick       llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Func);
2973a9ac8606Spatrick       CGBuilderTy Builder(CGM, Entry);
2974a9ac8606Spatrick       Builder.CreateRetVoid();
2975a9ac8606Spatrick     }
2976a9ac8606Spatrick 
2977e5dd7070Spatrick     llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, "", Wrapper);
2978e5dd7070Spatrick     CGBuilderTy Builder(CGM, Entry);
2979e5dd7070Spatrick     if (HasConstantInitialization) {
2980e5dd7070Spatrick       // No dynamic initialization to invoke.
2981e5dd7070Spatrick     } else if (InitIsInitFunc) {
2982e5dd7070Spatrick       if (Init) {
2983e5dd7070Spatrick         llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy, Init);
2984e5dd7070Spatrick         if (isThreadWrapperReplaceable(VD, CGM)) {
2985e5dd7070Spatrick           CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2986e5dd7070Spatrick           llvm::Function *Fn =
2987e5dd7070Spatrick               cast<llvm::Function>(cast<llvm::GlobalAlias>(Init)->getAliasee());
2988e5dd7070Spatrick           Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2989e5dd7070Spatrick         }
2990e5dd7070Spatrick       }
2991a9ac8606Spatrick     } else if (CGM.getTriple().isOSAIX()) {
2992a9ac8606Spatrick       // On AIX, except if constinit and also neither of class type or of
2993a9ac8606Spatrick       // (possibly multi-dimensional) array of class type, thread_local vars
2994a9ac8606Spatrick       // will have init routines regardless of whether they are
2995a9ac8606Spatrick       // const-initialized.  Since the routine is guaranteed to exist, we can
2996a9ac8606Spatrick       // unconditionally call it without testing for its existance.  This
2997a9ac8606Spatrick       // avoids potentially unresolved weak symbols which the AIX linker
2998a9ac8606Spatrick       // isn't happy with.
2999a9ac8606Spatrick       Builder.CreateCall(InitFnTy, Init);
3000e5dd7070Spatrick     } else {
3001e5dd7070Spatrick       // Don't know whether we have an init function. Call it if it exists.
3002e5dd7070Spatrick       llvm::Value *Have = Builder.CreateIsNotNull(Init);
3003e5dd7070Spatrick       llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context, "", Wrapper);
3004e5dd7070Spatrick       llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context, "", Wrapper);
3005e5dd7070Spatrick       Builder.CreateCondBr(Have, InitBB, ExitBB);
3006e5dd7070Spatrick 
3007e5dd7070Spatrick       Builder.SetInsertPoint(InitBB);
3008e5dd7070Spatrick       Builder.CreateCall(InitFnTy, Init);
3009e5dd7070Spatrick       Builder.CreateBr(ExitBB);
3010e5dd7070Spatrick 
3011e5dd7070Spatrick       Builder.SetInsertPoint(ExitBB);
3012e5dd7070Spatrick     }
3013e5dd7070Spatrick 
3014e5dd7070Spatrick     // For a reference, the result of the wrapper function is a pointer to
3015e5dd7070Spatrick     // the referenced object.
3016*12c85518Srobert     llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3017*12c85518Srobert 
3018e5dd7070Spatrick     if (VD->getType()->isReferenceType()) {
3019e5dd7070Spatrick       CharUnits Align = CGM.getContext().getDeclAlign(VD);
3020*12c85518Srobert       Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3021e5dd7070Spatrick     }
3022e5dd7070Spatrick     if (Val->getType() != Wrapper->getReturnType())
3023e5dd7070Spatrick       Val = Builder.CreatePointerBitCastOrAddrSpaceCast(
3024e5dd7070Spatrick           Val, Wrapper->getReturnType(), "");
3025*12c85518Srobert 
3026e5dd7070Spatrick     Builder.CreateRet(Val);
3027e5dd7070Spatrick   }
3028e5dd7070Spatrick }
3029e5dd7070Spatrick 
EmitThreadLocalVarDeclLValue(CodeGenFunction & CGF,const VarDecl * VD,QualType LValType)3030e5dd7070Spatrick LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
3031e5dd7070Spatrick                                                    const VarDecl *VD,
3032e5dd7070Spatrick                                                    QualType LValType) {
3033e5dd7070Spatrick   llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD);
3034e5dd7070Spatrick   llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3035e5dd7070Spatrick 
3036e5dd7070Spatrick   llvm::CallInst *CallVal = CGF.Builder.CreateCall(Wrapper);
3037e5dd7070Spatrick   CallVal->setCallingConv(Wrapper->getCallingConv());
3038e5dd7070Spatrick 
3039e5dd7070Spatrick   LValue LV;
3040e5dd7070Spatrick   if (VD->getType()->isReferenceType())
3041e5dd7070Spatrick     LV = CGF.MakeNaturalAlignAddrLValue(CallVal, LValType);
3042e5dd7070Spatrick   else
3043e5dd7070Spatrick     LV = CGF.MakeAddrLValue(CallVal, LValType,
3044e5dd7070Spatrick                             CGF.getContext().getDeclAlign(VD));
3045e5dd7070Spatrick   // FIXME: need setObjCGCLValueClass?
3046e5dd7070Spatrick   return LV;
3047e5dd7070Spatrick }
3048e5dd7070Spatrick 
3049e5dd7070Spatrick /// Return whether the given global decl needs a VTT parameter, which it does
3050e5dd7070Spatrick /// if it's a base constructor or destructor with virtual bases.
NeedsVTTParameter(GlobalDecl GD)3051e5dd7070Spatrick bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
3052e5dd7070Spatrick   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
3053e5dd7070Spatrick 
3054e5dd7070Spatrick   // We don't have any virtual bases, just return early.
3055e5dd7070Spatrick   if (!MD->getParent()->getNumVBases())
3056e5dd7070Spatrick     return false;
3057e5dd7070Spatrick 
3058e5dd7070Spatrick   // Check if we have a base constructor.
3059e5dd7070Spatrick   if (isa<CXXConstructorDecl>(MD) && GD.getCtorType() == Ctor_Base)
3060e5dd7070Spatrick     return true;
3061e5dd7070Spatrick 
3062e5dd7070Spatrick   // Check if we have a base destructor.
3063e5dd7070Spatrick   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
3064e5dd7070Spatrick     return true;
3065e5dd7070Spatrick 
3066e5dd7070Spatrick   return false;
3067e5dd7070Spatrick }
3068e5dd7070Spatrick 
3069e5dd7070Spatrick namespace {
3070e5dd7070Spatrick class ItaniumRTTIBuilder {
3071e5dd7070Spatrick   CodeGenModule &CGM;  // Per-module state.
3072e5dd7070Spatrick   llvm::LLVMContext &VMContext;
3073e5dd7070Spatrick   const ItaniumCXXABI &CXXABI;  // Per-module state.
3074e5dd7070Spatrick 
3075e5dd7070Spatrick   /// Fields - The fields of the RTTI descriptor currently being built.
3076e5dd7070Spatrick   SmallVector<llvm::Constant *, 16> Fields;
3077e5dd7070Spatrick 
3078e5dd7070Spatrick   /// GetAddrOfTypeName - Returns the mangled type name of the given type.
3079e5dd7070Spatrick   llvm::GlobalVariable *
3080e5dd7070Spatrick   GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
3081e5dd7070Spatrick 
3082e5dd7070Spatrick   /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI
3083e5dd7070Spatrick   /// descriptor of the given type.
3084e5dd7070Spatrick   llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
3085e5dd7070Spatrick 
3086e5dd7070Spatrick   /// BuildVTablePointer - Build the vtable pointer for the given type.
3087e5dd7070Spatrick   void BuildVTablePointer(const Type *Ty);
3088e5dd7070Spatrick 
3089e5dd7070Spatrick   /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
3090e5dd7070Spatrick   /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
3091e5dd7070Spatrick   void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
3092e5dd7070Spatrick 
3093e5dd7070Spatrick   /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
3094e5dd7070Spatrick   /// classes with bases that do not satisfy the abi::__si_class_type_info
3095e5dd7070Spatrick   /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
3096e5dd7070Spatrick   void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
3097e5dd7070Spatrick 
3098e5dd7070Spatrick   /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
3099e5dd7070Spatrick   /// for pointer types.
3100e5dd7070Spatrick   void BuildPointerTypeInfo(QualType PointeeTy);
3101e5dd7070Spatrick 
3102e5dd7070Spatrick   /// BuildObjCObjectTypeInfo - Build the appropriate kind of
3103e5dd7070Spatrick   /// type_info for an object type.
3104e5dd7070Spatrick   void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
3105e5dd7070Spatrick 
3106e5dd7070Spatrick   /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
3107e5dd7070Spatrick   /// struct, used for member pointer types.
3108e5dd7070Spatrick   void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
3109e5dd7070Spatrick 
3110e5dd7070Spatrick public:
ItaniumRTTIBuilder(const ItaniumCXXABI & ABI)3111e5dd7070Spatrick   ItaniumRTTIBuilder(const ItaniumCXXABI &ABI)
3112e5dd7070Spatrick       : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), CXXABI(ABI) {}
3113e5dd7070Spatrick 
3114e5dd7070Spatrick   // Pointer type info flags.
3115e5dd7070Spatrick   enum {
3116e5dd7070Spatrick     /// PTI_Const - Type has const qualifier.
3117e5dd7070Spatrick     PTI_Const = 0x1,
3118e5dd7070Spatrick 
3119e5dd7070Spatrick     /// PTI_Volatile - Type has volatile qualifier.
3120e5dd7070Spatrick     PTI_Volatile = 0x2,
3121e5dd7070Spatrick 
3122e5dd7070Spatrick     /// PTI_Restrict - Type has restrict qualifier.
3123e5dd7070Spatrick     PTI_Restrict = 0x4,
3124e5dd7070Spatrick 
3125e5dd7070Spatrick     /// PTI_Incomplete - Type is incomplete.
3126e5dd7070Spatrick     PTI_Incomplete = 0x8,
3127e5dd7070Spatrick 
3128e5dd7070Spatrick     /// PTI_ContainingClassIncomplete - Containing class is incomplete.
3129e5dd7070Spatrick     /// (in pointer to member).
3130e5dd7070Spatrick     PTI_ContainingClassIncomplete = 0x10,
3131e5dd7070Spatrick 
3132e5dd7070Spatrick     /// PTI_TransactionSafe - Pointee is transaction_safe function (C++ TM TS).
3133e5dd7070Spatrick     //PTI_TransactionSafe = 0x20,
3134e5dd7070Spatrick 
3135e5dd7070Spatrick     /// PTI_Noexcept - Pointee is noexcept function (C++1z).
3136e5dd7070Spatrick     PTI_Noexcept = 0x40,
3137e5dd7070Spatrick   };
3138e5dd7070Spatrick 
3139e5dd7070Spatrick   // VMI type info flags.
3140e5dd7070Spatrick   enum {
3141e5dd7070Spatrick     /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
3142e5dd7070Spatrick     VMI_NonDiamondRepeat = 0x1,
3143e5dd7070Spatrick 
3144e5dd7070Spatrick     /// VMI_DiamondShaped - Class is diamond shaped.
3145e5dd7070Spatrick     VMI_DiamondShaped = 0x2
3146e5dd7070Spatrick   };
3147e5dd7070Spatrick 
3148e5dd7070Spatrick   // Base class type info flags.
3149e5dd7070Spatrick   enum {
3150e5dd7070Spatrick     /// BCTI_Virtual - Base class is virtual.
3151e5dd7070Spatrick     BCTI_Virtual = 0x1,
3152e5dd7070Spatrick 
3153e5dd7070Spatrick     /// BCTI_Public - Base class is public.
3154e5dd7070Spatrick     BCTI_Public = 0x2
3155e5dd7070Spatrick   };
3156e5dd7070Spatrick 
3157e5dd7070Spatrick   /// BuildTypeInfo - Build the RTTI type info struct for the given type, or
3158e5dd7070Spatrick   /// link to an existing RTTI descriptor if one already exists.
3159e5dd7070Spatrick   llvm::Constant *BuildTypeInfo(QualType Ty);
3160e5dd7070Spatrick 
3161e5dd7070Spatrick   /// BuildTypeInfo - Build the RTTI type info struct for the given type.
3162e5dd7070Spatrick   llvm::Constant *BuildTypeInfo(
3163e5dd7070Spatrick       QualType Ty,
3164e5dd7070Spatrick       llvm::GlobalVariable::LinkageTypes Linkage,
3165e5dd7070Spatrick       llvm::GlobalValue::VisibilityTypes Visibility,
3166e5dd7070Spatrick       llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3167e5dd7070Spatrick };
3168e5dd7070Spatrick }
3169e5dd7070Spatrick 
GetAddrOfTypeName(QualType Ty,llvm::GlobalVariable::LinkageTypes Linkage)3170e5dd7070Spatrick llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3171e5dd7070Spatrick     QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) {
3172e5dd7070Spatrick   SmallString<256> Name;
3173e5dd7070Spatrick   llvm::raw_svector_ostream Out(Name);
3174e5dd7070Spatrick   CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
3175e5dd7070Spatrick 
3176e5dd7070Spatrick   // We know that the mangled name of the type starts at index 4 of the
3177e5dd7070Spatrick   // mangled name of the typename, so we can just index into it in order to
3178e5dd7070Spatrick   // get the mangled name of the type.
3179e5dd7070Spatrick   llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
3180e5dd7070Spatrick                                                             Name.substr(4));
3181e5dd7070Spatrick   auto Align = CGM.getContext().getTypeAlignInChars(CGM.getContext().CharTy);
3182e5dd7070Spatrick 
3183e5dd7070Spatrick   llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable(
3184*12c85518Srobert       Name, Init->getType(), Linkage, Align.getAsAlign());
3185e5dd7070Spatrick 
3186e5dd7070Spatrick   GV->setInitializer(Init);
3187e5dd7070Spatrick 
3188e5dd7070Spatrick   return GV;
3189e5dd7070Spatrick }
3190e5dd7070Spatrick 
3191e5dd7070Spatrick llvm::Constant *
GetAddrOfExternalRTTIDescriptor(QualType Ty)3192e5dd7070Spatrick ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
3193e5dd7070Spatrick   // Mangle the RTTI name.
3194e5dd7070Spatrick   SmallString<256> Name;
3195e5dd7070Spatrick   llvm::raw_svector_ostream Out(Name);
3196e5dd7070Spatrick   CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
3197e5dd7070Spatrick 
3198e5dd7070Spatrick   // Look for an existing global.
3199e5dd7070Spatrick   llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
3200e5dd7070Spatrick 
3201e5dd7070Spatrick   if (!GV) {
3202e5dd7070Spatrick     // Create a new global variable.
3203e5dd7070Spatrick     // Note for the future: If we would ever like to do deferred emission of
3204e5dd7070Spatrick     // RTTI, check if emitting vtables opportunistically need any adjustment.
3205e5dd7070Spatrick 
3206e5dd7070Spatrick     GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
3207e5dd7070Spatrick                                   /*isConstant=*/true,
3208e5dd7070Spatrick                                   llvm::GlobalValue::ExternalLinkage, nullptr,
3209e5dd7070Spatrick                                   Name);
3210e5dd7070Spatrick     const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
3211e5dd7070Spatrick     CGM.setGVProperties(GV, RD);
3212a9ac8606Spatrick     // Import the typeinfo symbol when all non-inline virtual methods are
3213a9ac8606Spatrick     // imported.
3214a9ac8606Spatrick     if (CGM.getTarget().hasPS4DLLImportExport()) {
3215a9ac8606Spatrick       if (RD && CXXRecordAllNonInlineVirtualsHaveAttr<DLLImportAttr>(RD)) {
3216a9ac8606Spatrick         GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3217a9ac8606Spatrick         CGM.setDSOLocal(GV);
3218a9ac8606Spatrick       }
3219a9ac8606Spatrick     }
3220e5dd7070Spatrick   }
3221e5dd7070Spatrick 
3222e5dd7070Spatrick   return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
3223e5dd7070Spatrick }
3224e5dd7070Spatrick 
3225e5dd7070Spatrick /// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
3226e5dd7070Spatrick /// info for that type is defined in the standard library.
TypeInfoIsInStandardLibrary(const BuiltinType * Ty)3227e5dd7070Spatrick static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
3228e5dd7070Spatrick   // Itanium C++ ABI 2.9.2:
3229e5dd7070Spatrick   //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
3230e5dd7070Spatrick   //   the run-time support library. Specifically, the run-time support
3231e5dd7070Spatrick   //   library should contain type_info objects for the types X, X* and
3232e5dd7070Spatrick   //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,
3233e5dd7070Spatrick   //   unsigned char, signed char, short, unsigned short, int, unsigned int,
3234e5dd7070Spatrick   //   long, unsigned long, long long, unsigned long long, float, double,
3235e5dd7070Spatrick   //   long double, char16_t, char32_t, and the IEEE 754r decimal and
3236e5dd7070Spatrick   //   half-precision floating point types.
3237e5dd7070Spatrick   //
3238e5dd7070Spatrick   // GCC also emits RTTI for __int128.
3239e5dd7070Spatrick   // FIXME: We do not emit RTTI information for decimal types here.
3240e5dd7070Spatrick 
3241e5dd7070Spatrick   // Types added here must also be added to EmitFundamentalRTTIDescriptors.
3242e5dd7070Spatrick   switch (Ty->getKind()) {
3243e5dd7070Spatrick     case BuiltinType::Void:
3244e5dd7070Spatrick     case BuiltinType::NullPtr:
3245e5dd7070Spatrick     case BuiltinType::Bool:
3246e5dd7070Spatrick     case BuiltinType::WChar_S:
3247e5dd7070Spatrick     case BuiltinType::WChar_U:
3248e5dd7070Spatrick     case BuiltinType::Char_U:
3249e5dd7070Spatrick     case BuiltinType::Char_S:
3250e5dd7070Spatrick     case BuiltinType::UChar:
3251e5dd7070Spatrick     case BuiltinType::SChar:
3252e5dd7070Spatrick     case BuiltinType::Short:
3253e5dd7070Spatrick     case BuiltinType::UShort:
3254e5dd7070Spatrick     case BuiltinType::Int:
3255e5dd7070Spatrick     case BuiltinType::UInt:
3256e5dd7070Spatrick     case BuiltinType::Long:
3257e5dd7070Spatrick     case BuiltinType::ULong:
3258e5dd7070Spatrick     case BuiltinType::LongLong:
3259e5dd7070Spatrick     case BuiltinType::ULongLong:
3260e5dd7070Spatrick     case BuiltinType::Half:
3261e5dd7070Spatrick     case BuiltinType::Float:
3262e5dd7070Spatrick     case BuiltinType::Double:
3263e5dd7070Spatrick     case BuiltinType::LongDouble:
3264e5dd7070Spatrick     case BuiltinType::Float16:
3265e5dd7070Spatrick     case BuiltinType::Float128:
3266*12c85518Srobert     case BuiltinType::Ibm128:
3267e5dd7070Spatrick     case BuiltinType::Char8:
3268e5dd7070Spatrick     case BuiltinType::Char16:
3269e5dd7070Spatrick     case BuiltinType::Char32:
3270e5dd7070Spatrick     case BuiltinType::Int128:
3271e5dd7070Spatrick     case BuiltinType::UInt128:
3272e5dd7070Spatrick       return true;
3273e5dd7070Spatrick 
3274e5dd7070Spatrick #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3275e5dd7070Spatrick     case BuiltinType::Id:
3276e5dd7070Spatrick #include "clang/Basic/OpenCLImageTypes.def"
3277e5dd7070Spatrick #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3278e5dd7070Spatrick     case BuiltinType::Id:
3279e5dd7070Spatrick #include "clang/Basic/OpenCLExtensionTypes.def"
3280e5dd7070Spatrick     case BuiltinType::OCLSampler:
3281e5dd7070Spatrick     case BuiltinType::OCLEvent:
3282e5dd7070Spatrick     case BuiltinType::OCLClkEvent:
3283e5dd7070Spatrick     case BuiltinType::OCLQueue:
3284e5dd7070Spatrick     case BuiltinType::OCLReserveID:
3285e5dd7070Spatrick #define SVE_TYPE(Name, Id, SingletonId) \
3286e5dd7070Spatrick     case BuiltinType::Id:
3287e5dd7070Spatrick #include "clang/Basic/AArch64SVEACLETypes.def"
3288a9ac8606Spatrick #define PPC_VECTOR_TYPE(Name, Id, Size) \
3289a9ac8606Spatrick     case BuiltinType::Id:
3290a9ac8606Spatrick #include "clang/Basic/PPCTypes.def"
3291a9ac8606Spatrick #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3292a9ac8606Spatrick #include "clang/Basic/RISCVVTypes.def"
3293e5dd7070Spatrick     case BuiltinType::ShortAccum:
3294e5dd7070Spatrick     case BuiltinType::Accum:
3295e5dd7070Spatrick     case BuiltinType::LongAccum:
3296e5dd7070Spatrick     case BuiltinType::UShortAccum:
3297e5dd7070Spatrick     case BuiltinType::UAccum:
3298e5dd7070Spatrick     case BuiltinType::ULongAccum:
3299e5dd7070Spatrick     case BuiltinType::ShortFract:
3300e5dd7070Spatrick     case BuiltinType::Fract:
3301e5dd7070Spatrick     case BuiltinType::LongFract:
3302e5dd7070Spatrick     case BuiltinType::UShortFract:
3303e5dd7070Spatrick     case BuiltinType::UFract:
3304e5dd7070Spatrick     case BuiltinType::ULongFract:
3305e5dd7070Spatrick     case BuiltinType::SatShortAccum:
3306e5dd7070Spatrick     case BuiltinType::SatAccum:
3307e5dd7070Spatrick     case BuiltinType::SatLongAccum:
3308e5dd7070Spatrick     case BuiltinType::SatUShortAccum:
3309e5dd7070Spatrick     case BuiltinType::SatUAccum:
3310e5dd7070Spatrick     case BuiltinType::SatULongAccum:
3311e5dd7070Spatrick     case BuiltinType::SatShortFract:
3312e5dd7070Spatrick     case BuiltinType::SatFract:
3313e5dd7070Spatrick     case BuiltinType::SatLongFract:
3314e5dd7070Spatrick     case BuiltinType::SatUShortFract:
3315e5dd7070Spatrick     case BuiltinType::SatUFract:
3316e5dd7070Spatrick     case BuiltinType::SatULongFract:
3317ec727ea7Spatrick     case BuiltinType::BFloat16:
3318e5dd7070Spatrick       return false;
3319e5dd7070Spatrick 
3320e5dd7070Spatrick     case BuiltinType::Dependent:
3321e5dd7070Spatrick #define BUILTIN_TYPE(Id, SingletonId)
3322e5dd7070Spatrick #define PLACEHOLDER_TYPE(Id, SingletonId) \
3323e5dd7070Spatrick     case BuiltinType::Id:
3324e5dd7070Spatrick #include "clang/AST/BuiltinTypes.def"
3325e5dd7070Spatrick       llvm_unreachable("asking for RRTI for a placeholder type!");
3326e5dd7070Spatrick 
3327e5dd7070Spatrick     case BuiltinType::ObjCId:
3328e5dd7070Spatrick     case BuiltinType::ObjCClass:
3329e5dd7070Spatrick     case BuiltinType::ObjCSel:
3330e5dd7070Spatrick       llvm_unreachable("FIXME: Objective-C types are unsupported!");
3331e5dd7070Spatrick   }
3332e5dd7070Spatrick 
3333e5dd7070Spatrick   llvm_unreachable("Invalid BuiltinType Kind!");
3334e5dd7070Spatrick }
3335e5dd7070Spatrick 
TypeInfoIsInStandardLibrary(const PointerType * PointerTy)3336e5dd7070Spatrick static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
3337e5dd7070Spatrick   QualType PointeeTy = PointerTy->getPointeeType();
3338e5dd7070Spatrick   const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3339e5dd7070Spatrick   if (!BuiltinTy)
3340e5dd7070Spatrick     return false;
3341e5dd7070Spatrick 
3342e5dd7070Spatrick   // Check the qualifiers.
3343e5dd7070Spatrick   Qualifiers Quals = PointeeTy.getQualifiers();
3344e5dd7070Spatrick   Quals.removeConst();
3345e5dd7070Spatrick 
3346e5dd7070Spatrick   if (!Quals.empty())
3347e5dd7070Spatrick     return false;
3348e5dd7070Spatrick 
3349e5dd7070Spatrick   return TypeInfoIsInStandardLibrary(BuiltinTy);
3350e5dd7070Spatrick }
3351e5dd7070Spatrick 
3352e5dd7070Spatrick /// IsStandardLibraryRTTIDescriptor - Returns whether the type
3353e5dd7070Spatrick /// information for the given type exists in the standard library.
IsStandardLibraryRTTIDescriptor(QualType Ty)3354e5dd7070Spatrick static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
3355e5dd7070Spatrick   // Type info for builtin types is defined in the standard library.
3356e5dd7070Spatrick   if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3357e5dd7070Spatrick     return TypeInfoIsInStandardLibrary(BuiltinTy);
3358e5dd7070Spatrick 
3359e5dd7070Spatrick   // Type info for some pointer types to builtin types is defined in the
3360e5dd7070Spatrick   // standard library.
3361e5dd7070Spatrick   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3362e5dd7070Spatrick     return TypeInfoIsInStandardLibrary(PointerTy);
3363e5dd7070Spatrick 
3364e5dd7070Spatrick   return false;
3365e5dd7070Spatrick }
3366e5dd7070Spatrick 
3367e5dd7070Spatrick /// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
3368e5dd7070Spatrick /// the given type exists somewhere else, and that we should not emit the type
3369e5dd7070Spatrick /// information in this translation unit.  Assumes that it is not a
3370e5dd7070Spatrick /// standard-library type.
ShouldUseExternalRTTIDescriptor(CodeGenModule & CGM,QualType Ty)3371e5dd7070Spatrick static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
3372e5dd7070Spatrick                                             QualType Ty) {
3373e5dd7070Spatrick   ASTContext &Context = CGM.getContext();
3374e5dd7070Spatrick 
3375e5dd7070Spatrick   // If RTTI is disabled, assume it might be disabled in the
3376e5dd7070Spatrick   // translation unit that defines any potential key function, too.
3377e5dd7070Spatrick   if (!Context.getLangOpts().RTTI) return false;
3378e5dd7070Spatrick 
3379e5dd7070Spatrick   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3380e5dd7070Spatrick     const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
3381e5dd7070Spatrick     if (!RD->hasDefinition())
3382e5dd7070Spatrick       return false;
3383e5dd7070Spatrick 
3384e5dd7070Spatrick     if (!RD->isDynamicClass())
3385e5dd7070Spatrick       return false;
3386e5dd7070Spatrick 
3387e5dd7070Spatrick     // FIXME: this may need to be reconsidered if the key function
3388e5dd7070Spatrick     // changes.
3389e5dd7070Spatrick     // N.B. We must always emit the RTTI data ourselves if there exists a key
3390e5dd7070Spatrick     // function.
3391e5dd7070Spatrick     bool IsDLLImport = RD->hasAttr<DLLImportAttr>();
3392e5dd7070Spatrick 
3393e5dd7070Spatrick     // Don't import the RTTI but emit it locally.
3394e5dd7070Spatrick     if (CGM.getTriple().isWindowsGNUEnvironment())
3395e5dd7070Spatrick       return false;
3396e5dd7070Spatrick 
3397a9ac8606Spatrick     if (CGM.getVTables().isVTableExternal(RD)) {
3398a9ac8606Spatrick       if (CGM.getTarget().hasPS4DLLImportExport())
3399a9ac8606Spatrick         return true;
3400a9ac8606Spatrick 
3401e5dd7070Spatrick       return IsDLLImport && !CGM.getTriple().isWindowsItaniumEnvironment()
3402e5dd7070Spatrick                  ? false
3403e5dd7070Spatrick                  : true;
3404a9ac8606Spatrick     }
3405e5dd7070Spatrick     if (IsDLLImport)
3406e5dd7070Spatrick       return true;
3407e5dd7070Spatrick   }
3408e5dd7070Spatrick 
3409e5dd7070Spatrick   return false;
3410e5dd7070Spatrick }
3411e5dd7070Spatrick 
3412e5dd7070Spatrick /// IsIncompleteClassType - Returns whether the given record type is incomplete.
IsIncompleteClassType(const RecordType * RecordTy)3413e5dd7070Spatrick static bool IsIncompleteClassType(const RecordType *RecordTy) {
3414e5dd7070Spatrick   return !RecordTy->getDecl()->isCompleteDefinition();
3415e5dd7070Spatrick }
3416e5dd7070Spatrick 
3417e5dd7070Spatrick /// ContainsIncompleteClassType - Returns whether the given type contains an
3418e5dd7070Spatrick /// incomplete class type. This is true if
3419e5dd7070Spatrick ///
3420e5dd7070Spatrick ///   * The given type is an incomplete class type.
3421e5dd7070Spatrick ///   * The given type is a pointer type whose pointee type contains an
3422e5dd7070Spatrick ///     incomplete class type.
3423e5dd7070Spatrick ///   * The given type is a member pointer type whose class is an incomplete
3424e5dd7070Spatrick ///     class type.
3425e5dd7070Spatrick ///   * The given type is a member pointer type whoise pointee type contains an
3426e5dd7070Spatrick ///     incomplete class type.
3427e5dd7070Spatrick /// is an indirect or direct pointer to an incomplete class type.
ContainsIncompleteClassType(QualType Ty)3428e5dd7070Spatrick static bool ContainsIncompleteClassType(QualType Ty) {
3429e5dd7070Spatrick   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3430e5dd7070Spatrick     if (IsIncompleteClassType(RecordTy))
3431e5dd7070Spatrick       return true;
3432e5dd7070Spatrick   }
3433e5dd7070Spatrick 
3434e5dd7070Spatrick   if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3435e5dd7070Spatrick     return ContainsIncompleteClassType(PointerTy->getPointeeType());
3436e5dd7070Spatrick 
3437e5dd7070Spatrick   if (const MemberPointerType *MemberPointerTy =
3438e5dd7070Spatrick       dyn_cast<MemberPointerType>(Ty)) {
3439e5dd7070Spatrick     // Check if the class type is incomplete.
3440e5dd7070Spatrick     const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
3441e5dd7070Spatrick     if (IsIncompleteClassType(ClassType))
3442e5dd7070Spatrick       return true;
3443e5dd7070Spatrick 
3444e5dd7070Spatrick     return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
3445e5dd7070Spatrick   }
3446e5dd7070Spatrick 
3447e5dd7070Spatrick   return false;
3448e5dd7070Spatrick }
3449e5dd7070Spatrick 
3450e5dd7070Spatrick // CanUseSingleInheritance - Return whether the given record decl has a "single,
3451e5dd7070Spatrick // public, non-virtual base at offset zero (i.e. the derived class is dynamic
3452e5dd7070Spatrick // iff the base is)", according to Itanium C++ ABI, 2.95p6b.
CanUseSingleInheritance(const CXXRecordDecl * RD)3453e5dd7070Spatrick static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
3454e5dd7070Spatrick   // Check the number of bases.
3455e5dd7070Spatrick   if (RD->getNumBases() != 1)
3456e5dd7070Spatrick     return false;
3457e5dd7070Spatrick 
3458e5dd7070Spatrick   // Get the base.
3459e5dd7070Spatrick   CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
3460e5dd7070Spatrick 
3461e5dd7070Spatrick   // Check that the base is not virtual.
3462e5dd7070Spatrick   if (Base->isVirtual())
3463e5dd7070Spatrick     return false;
3464e5dd7070Spatrick 
3465e5dd7070Spatrick   // Check that the base is public.
3466e5dd7070Spatrick   if (Base->getAccessSpecifier() != AS_public)
3467e5dd7070Spatrick     return false;
3468e5dd7070Spatrick 
3469e5dd7070Spatrick   // Check that the class is dynamic iff the base is.
3470e5dd7070Spatrick   auto *BaseDecl =
3471e5dd7070Spatrick       cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
3472e5dd7070Spatrick   if (!BaseDecl->isEmpty() &&
3473e5dd7070Spatrick       BaseDecl->isDynamicClass() != RD->isDynamicClass())
3474e5dd7070Spatrick     return false;
3475e5dd7070Spatrick 
3476e5dd7070Spatrick   return true;
3477e5dd7070Spatrick }
3478e5dd7070Spatrick 
BuildVTablePointer(const Type * Ty)3479e5dd7070Spatrick void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
3480e5dd7070Spatrick   // abi::__class_type_info.
3481e5dd7070Spatrick   static const char * const ClassTypeInfo =
3482e5dd7070Spatrick     "_ZTVN10__cxxabiv117__class_type_infoE";
3483e5dd7070Spatrick   // abi::__si_class_type_info.
3484e5dd7070Spatrick   static const char * const SIClassTypeInfo =
3485e5dd7070Spatrick     "_ZTVN10__cxxabiv120__si_class_type_infoE";
3486e5dd7070Spatrick   // abi::__vmi_class_type_info.
3487e5dd7070Spatrick   static const char * const VMIClassTypeInfo =
3488e5dd7070Spatrick     "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3489e5dd7070Spatrick 
3490e5dd7070Spatrick   const char *VTableName = nullptr;
3491e5dd7070Spatrick 
3492e5dd7070Spatrick   switch (Ty->getTypeClass()) {
3493e5dd7070Spatrick #define TYPE(Class, Base)
3494e5dd7070Spatrick #define ABSTRACT_TYPE(Class, Base)
3495e5dd7070Spatrick #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3496e5dd7070Spatrick #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3497e5dd7070Spatrick #define DEPENDENT_TYPE(Class, Base) case Type::Class:
3498e5dd7070Spatrick #include "clang/AST/TypeNodes.inc"
3499e5dd7070Spatrick     llvm_unreachable("Non-canonical and dependent types shouldn't get here");
3500e5dd7070Spatrick 
3501e5dd7070Spatrick   case Type::LValueReference:
3502e5dd7070Spatrick   case Type::RValueReference:
3503e5dd7070Spatrick     llvm_unreachable("References shouldn't get here");
3504e5dd7070Spatrick 
3505e5dd7070Spatrick   case Type::Auto:
3506e5dd7070Spatrick   case Type::DeducedTemplateSpecialization:
3507e5dd7070Spatrick     llvm_unreachable("Undeduced type shouldn't get here");
3508e5dd7070Spatrick 
3509e5dd7070Spatrick   case Type::Pipe:
3510e5dd7070Spatrick     llvm_unreachable("Pipe types shouldn't get here");
3511e5dd7070Spatrick 
3512e5dd7070Spatrick   case Type::Builtin:
3513*12c85518Srobert   case Type::BitInt:
3514e5dd7070Spatrick   // GCC treats vector and complex types as fundamental types.
3515e5dd7070Spatrick   case Type::Vector:
3516e5dd7070Spatrick   case Type::ExtVector:
3517ec727ea7Spatrick   case Type::ConstantMatrix:
3518e5dd7070Spatrick   case Type::Complex:
3519e5dd7070Spatrick   case Type::Atomic:
3520e5dd7070Spatrick   // FIXME: GCC treats block pointers as fundamental types?!
3521e5dd7070Spatrick   case Type::BlockPointer:
3522e5dd7070Spatrick     // abi::__fundamental_type_info.
3523e5dd7070Spatrick     VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
3524e5dd7070Spatrick     break;
3525e5dd7070Spatrick 
3526e5dd7070Spatrick   case Type::ConstantArray:
3527e5dd7070Spatrick   case Type::IncompleteArray:
3528e5dd7070Spatrick   case Type::VariableArray:
3529e5dd7070Spatrick     // abi::__array_type_info.
3530e5dd7070Spatrick     VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
3531e5dd7070Spatrick     break;
3532e5dd7070Spatrick 
3533e5dd7070Spatrick   case Type::FunctionNoProto:
3534e5dd7070Spatrick   case Type::FunctionProto:
3535e5dd7070Spatrick     // abi::__function_type_info.
3536e5dd7070Spatrick     VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
3537e5dd7070Spatrick     break;
3538e5dd7070Spatrick 
3539e5dd7070Spatrick   case Type::Enum:
3540e5dd7070Spatrick     // abi::__enum_type_info.
3541e5dd7070Spatrick     VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
3542e5dd7070Spatrick     break;
3543e5dd7070Spatrick 
3544e5dd7070Spatrick   case Type::Record: {
3545e5dd7070Spatrick     const CXXRecordDecl *RD =
3546e5dd7070Spatrick       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3547e5dd7070Spatrick 
3548e5dd7070Spatrick     if (!RD->hasDefinition() || !RD->getNumBases()) {
3549e5dd7070Spatrick       VTableName = ClassTypeInfo;
3550e5dd7070Spatrick     } else if (CanUseSingleInheritance(RD)) {
3551e5dd7070Spatrick       VTableName = SIClassTypeInfo;
3552e5dd7070Spatrick     } else {
3553e5dd7070Spatrick       VTableName = VMIClassTypeInfo;
3554e5dd7070Spatrick     }
3555e5dd7070Spatrick 
3556e5dd7070Spatrick     break;
3557e5dd7070Spatrick   }
3558e5dd7070Spatrick 
3559e5dd7070Spatrick   case Type::ObjCObject:
3560e5dd7070Spatrick     // Ignore protocol qualifiers.
3561e5dd7070Spatrick     Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3562e5dd7070Spatrick 
3563e5dd7070Spatrick     // Handle id and Class.
3564e5dd7070Spatrick     if (isa<BuiltinType>(Ty)) {
3565e5dd7070Spatrick       VTableName = ClassTypeInfo;
3566e5dd7070Spatrick       break;
3567e5dd7070Spatrick     }
3568e5dd7070Spatrick 
3569e5dd7070Spatrick     assert(isa<ObjCInterfaceType>(Ty));
3570*12c85518Srobert     [[fallthrough]];
3571e5dd7070Spatrick 
3572e5dd7070Spatrick   case Type::ObjCInterface:
3573e5dd7070Spatrick     if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3574e5dd7070Spatrick       VTableName = SIClassTypeInfo;
3575e5dd7070Spatrick     } else {
3576e5dd7070Spatrick       VTableName = ClassTypeInfo;
3577e5dd7070Spatrick     }
3578e5dd7070Spatrick     break;
3579e5dd7070Spatrick 
3580e5dd7070Spatrick   case Type::ObjCObjectPointer:
3581e5dd7070Spatrick   case Type::Pointer:
3582e5dd7070Spatrick     // abi::__pointer_type_info.
3583e5dd7070Spatrick     VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
3584e5dd7070Spatrick     break;
3585e5dd7070Spatrick 
3586e5dd7070Spatrick   case Type::MemberPointer:
3587e5dd7070Spatrick     // abi::__pointer_to_member_type_info.
3588e5dd7070Spatrick     VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3589e5dd7070Spatrick     break;
3590e5dd7070Spatrick   }
3591e5dd7070Spatrick 
3592ec727ea7Spatrick   llvm::Constant *VTable = nullptr;
3593ec727ea7Spatrick 
3594ec727ea7Spatrick   // Check if the alias exists. If it doesn't, then get or create the global.
3595ec727ea7Spatrick   if (CGM.getItaniumVTableContext().isRelativeLayout())
3596ec727ea7Spatrick     VTable = CGM.getModule().getNamedAlias(VTableName);
3597ec727ea7Spatrick   if (!VTable)
3598ec727ea7Spatrick     VTable = CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
3599ec727ea7Spatrick 
3600e5dd7070Spatrick   CGM.setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3601e5dd7070Spatrick 
3602e5dd7070Spatrick   llvm::Type *PtrDiffTy =
3603e5dd7070Spatrick       CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
3604e5dd7070Spatrick 
3605e5dd7070Spatrick   // The vtable address point is 2.
3606ec727ea7Spatrick   if (CGM.getItaniumVTableContext().isRelativeLayout()) {
3607ec727ea7Spatrick     // The vtable address point is 8 bytes after its start:
3608ec727ea7Spatrick     // 4 for the offset to top + 4 for the relative offset to rtti.
3609ec727ea7Spatrick     llvm::Constant *Eight = llvm::ConstantInt::get(CGM.Int32Ty, 8);
3610ec727ea7Spatrick     VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
3611e5dd7070Spatrick     VTable =
3612ec727ea7Spatrick         llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.Int8Ty, VTable, Eight);
3613ec727ea7Spatrick   } else {
3614ec727ea7Spatrick     llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3615ec727ea7Spatrick     VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.Int8PtrTy, VTable,
3616ec727ea7Spatrick                                                           Two);
3617ec727ea7Spatrick   }
3618e5dd7070Spatrick   VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
3619e5dd7070Spatrick 
3620e5dd7070Spatrick   Fields.push_back(VTable);
3621e5dd7070Spatrick }
3622e5dd7070Spatrick 
3623e5dd7070Spatrick /// Return the linkage that the type info and type info name constants
3624e5dd7070Spatrick /// should have for the given type.
getTypeInfoLinkage(CodeGenModule & CGM,QualType Ty)3625e5dd7070Spatrick static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
3626e5dd7070Spatrick                                                              QualType Ty) {
3627e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p7:
3628e5dd7070Spatrick   //   In addition, it and all of the intermediate abi::__pointer_type_info
3629e5dd7070Spatrick   //   structs in the chain down to the abi::__class_type_info for the
3630e5dd7070Spatrick   //   incomplete class type must be prevented from resolving to the
3631e5dd7070Spatrick   //   corresponding type_info structs for the complete class type, possibly
3632e5dd7070Spatrick   //   by making them local static objects. Finally, a dummy class RTTI is
3633e5dd7070Spatrick   //   generated for the incomplete type that will not resolve to the final
3634e5dd7070Spatrick   //   complete class RTTI (because the latter need not exist), possibly by
3635e5dd7070Spatrick   //   making it a local static object.
3636e5dd7070Spatrick   if (ContainsIncompleteClassType(Ty))
3637e5dd7070Spatrick     return llvm::GlobalValue::InternalLinkage;
3638e5dd7070Spatrick 
3639e5dd7070Spatrick   switch (Ty->getLinkage()) {
3640e5dd7070Spatrick   case NoLinkage:
3641e5dd7070Spatrick   case InternalLinkage:
3642e5dd7070Spatrick   case UniqueExternalLinkage:
3643e5dd7070Spatrick     return llvm::GlobalValue::InternalLinkage;
3644e5dd7070Spatrick 
3645e5dd7070Spatrick   case VisibleNoLinkage:
3646e5dd7070Spatrick   case ModuleInternalLinkage:
3647e5dd7070Spatrick   case ModuleLinkage:
3648e5dd7070Spatrick   case ExternalLinkage:
3649e5dd7070Spatrick     // RTTI is not enabled, which means that this type info struct is going
3650e5dd7070Spatrick     // to be used for exception handling. Give it linkonce_odr linkage.
3651e5dd7070Spatrick     if (!CGM.getLangOpts().RTTI)
3652e5dd7070Spatrick       return llvm::GlobalValue::LinkOnceODRLinkage;
3653e5dd7070Spatrick 
3654e5dd7070Spatrick     if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
3655e5dd7070Spatrick       const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
3656e5dd7070Spatrick       if (RD->hasAttr<WeakAttr>())
3657e5dd7070Spatrick         return llvm::GlobalValue::WeakODRLinkage;
3658e5dd7070Spatrick       if (CGM.getTriple().isWindowsItaniumEnvironment())
3659e5dd7070Spatrick         if (RD->hasAttr<DLLImportAttr>() &&
3660e5dd7070Spatrick             ShouldUseExternalRTTIDescriptor(CGM, Ty))
3661e5dd7070Spatrick           return llvm::GlobalValue::ExternalLinkage;
3662e5dd7070Spatrick       // MinGW always uses LinkOnceODRLinkage for type info.
3663e5dd7070Spatrick       if (RD->isDynamicClass() &&
3664e5dd7070Spatrick           !CGM.getContext()
3665e5dd7070Spatrick                .getTargetInfo()
3666e5dd7070Spatrick                .getTriple()
3667e5dd7070Spatrick                .isWindowsGNUEnvironment())
3668e5dd7070Spatrick         return CGM.getVTableLinkage(RD);
3669e5dd7070Spatrick     }
3670e5dd7070Spatrick 
3671e5dd7070Spatrick     return llvm::GlobalValue::LinkOnceODRLinkage;
3672e5dd7070Spatrick   }
3673e5dd7070Spatrick 
3674e5dd7070Spatrick   llvm_unreachable("Invalid linkage!");
3675e5dd7070Spatrick }
3676e5dd7070Spatrick 
BuildTypeInfo(QualType Ty)3677e5dd7070Spatrick llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) {
3678e5dd7070Spatrick   // We want to operate on the canonical type.
3679e5dd7070Spatrick   Ty = Ty.getCanonicalType();
3680e5dd7070Spatrick 
3681e5dd7070Spatrick   // Check if we've already emitted an RTTI descriptor for this type.
3682e5dd7070Spatrick   SmallString<256> Name;
3683e5dd7070Spatrick   llvm::raw_svector_ostream Out(Name);
3684e5dd7070Spatrick   CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
3685e5dd7070Spatrick 
3686e5dd7070Spatrick   llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
3687e5dd7070Spatrick   if (OldGV && !OldGV->isDeclaration()) {
3688e5dd7070Spatrick     assert(!OldGV->hasAvailableExternallyLinkage() &&
3689e5dd7070Spatrick            "available_externally typeinfos not yet implemented");
3690e5dd7070Spatrick 
3691e5dd7070Spatrick     return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);
3692e5dd7070Spatrick   }
3693e5dd7070Spatrick 
3694e5dd7070Spatrick   // Check if there is already an external RTTI descriptor for this type.
3695e5dd7070Spatrick   if (IsStandardLibraryRTTIDescriptor(Ty) ||
3696e5dd7070Spatrick       ShouldUseExternalRTTIDescriptor(CGM, Ty))
3697e5dd7070Spatrick     return GetAddrOfExternalRTTIDescriptor(Ty);
3698e5dd7070Spatrick 
3699e5dd7070Spatrick   // Emit the standard library with external linkage.
3700e5dd7070Spatrick   llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(CGM, Ty);
3701e5dd7070Spatrick 
3702e5dd7070Spatrick   // Give the type_info object and name the formal visibility of the
3703e5dd7070Spatrick   // type itself.
3704e5dd7070Spatrick   llvm::GlobalValue::VisibilityTypes llvmVisibility;
3705e5dd7070Spatrick   if (llvm::GlobalValue::isLocalLinkage(Linkage))
3706e5dd7070Spatrick     // If the linkage is local, only default visibility makes sense.
3707e5dd7070Spatrick     llvmVisibility = llvm::GlobalValue::DefaultVisibility;
3708e5dd7070Spatrick   else if (CXXABI.classifyRTTIUniqueness(Ty, Linkage) ==
3709e5dd7070Spatrick            ItaniumCXXABI::RUK_NonUniqueHidden)
3710e5dd7070Spatrick     llvmVisibility = llvm::GlobalValue::HiddenVisibility;
3711e5dd7070Spatrick   else
3712e5dd7070Spatrick     llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
3713e5dd7070Spatrick 
3714e5dd7070Spatrick   llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3715e5dd7070Spatrick       llvm::GlobalValue::DefaultStorageClass;
3716*12c85518Srobert   if (auto RD = Ty->getAsCXXRecordDecl()) {
3717*12c85518Srobert     if ((CGM.getTriple().isWindowsItaniumEnvironment() &&
3718*12c85518Srobert          RD->hasAttr<DLLExportAttr>()) ||
3719*12c85518Srobert         (CGM.shouldMapVisibilityToDLLExport(RD) &&
3720*12c85518Srobert          !llvm::GlobalValue::isLocalLinkage(Linkage) &&
3721*12c85518Srobert          llvmVisibility == llvm::GlobalValue::DefaultVisibility))
3722e5dd7070Spatrick       DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
3723e5dd7070Spatrick   }
3724e5dd7070Spatrick   return BuildTypeInfo(Ty, Linkage, llvmVisibility, DLLStorageClass);
3725e5dd7070Spatrick }
3726e5dd7070Spatrick 
BuildTypeInfo(QualType Ty,llvm::GlobalVariable::LinkageTypes Linkage,llvm::GlobalValue::VisibilityTypes Visibility,llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass)3727e5dd7070Spatrick llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
3728e5dd7070Spatrick       QualType Ty,
3729e5dd7070Spatrick       llvm::GlobalVariable::LinkageTypes Linkage,
3730e5dd7070Spatrick       llvm::GlobalValue::VisibilityTypes Visibility,
3731e5dd7070Spatrick       llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
3732e5dd7070Spatrick   // Add the vtable pointer.
3733e5dd7070Spatrick   BuildVTablePointer(cast<Type>(Ty));
3734e5dd7070Spatrick 
3735e5dd7070Spatrick   // And the name.
3736e5dd7070Spatrick   llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
3737e5dd7070Spatrick   llvm::Constant *TypeNameField;
3738e5dd7070Spatrick 
3739e5dd7070Spatrick   // If we're supposed to demote the visibility, be sure to set a flag
3740e5dd7070Spatrick   // to use a string comparison for type_info comparisons.
3741e5dd7070Spatrick   ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
3742e5dd7070Spatrick       CXXABI.classifyRTTIUniqueness(Ty, Linkage);
3743e5dd7070Spatrick   if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
3744e5dd7070Spatrick     // The flag is the sign bit, which on ARM64 is defined to be clear
3745e5dd7070Spatrick     // for global pointers.  This is very ARM64-specific.
3746e5dd7070Spatrick     TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);
3747e5dd7070Spatrick     llvm::Constant *flag =
3748e5dd7070Spatrick         llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63);
3749e5dd7070Spatrick     TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
3750e5dd7070Spatrick     TypeNameField =
3751e5dd7070Spatrick         llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.Int8PtrTy);
3752e5dd7070Spatrick   } else {
3753e5dd7070Spatrick     TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy);
3754e5dd7070Spatrick   }
3755e5dd7070Spatrick   Fields.push_back(TypeNameField);
3756e5dd7070Spatrick 
3757e5dd7070Spatrick   switch (Ty->getTypeClass()) {
3758e5dd7070Spatrick #define TYPE(Class, Base)
3759e5dd7070Spatrick #define ABSTRACT_TYPE(Class, Base)
3760e5dd7070Spatrick #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3761e5dd7070Spatrick #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3762e5dd7070Spatrick #define DEPENDENT_TYPE(Class, Base) case Type::Class:
3763e5dd7070Spatrick #include "clang/AST/TypeNodes.inc"
3764e5dd7070Spatrick     llvm_unreachable("Non-canonical and dependent types shouldn't get here");
3765e5dd7070Spatrick 
3766e5dd7070Spatrick   // GCC treats vector types as fundamental types.
3767e5dd7070Spatrick   case Type::Builtin:
3768e5dd7070Spatrick   case Type::Vector:
3769e5dd7070Spatrick   case Type::ExtVector:
3770ec727ea7Spatrick   case Type::ConstantMatrix:
3771e5dd7070Spatrick   case Type::Complex:
3772e5dd7070Spatrick   case Type::BlockPointer:
3773e5dd7070Spatrick     // Itanium C++ ABI 2.9.5p4:
3774e5dd7070Spatrick     // abi::__fundamental_type_info adds no data members to std::type_info.
3775e5dd7070Spatrick     break;
3776e5dd7070Spatrick 
3777e5dd7070Spatrick   case Type::LValueReference:
3778e5dd7070Spatrick   case Type::RValueReference:
3779e5dd7070Spatrick     llvm_unreachable("References shouldn't get here");
3780e5dd7070Spatrick 
3781e5dd7070Spatrick   case Type::Auto:
3782e5dd7070Spatrick   case Type::DeducedTemplateSpecialization:
3783e5dd7070Spatrick     llvm_unreachable("Undeduced type shouldn't get here");
3784e5dd7070Spatrick 
3785e5dd7070Spatrick   case Type::Pipe:
3786ec727ea7Spatrick     break;
3787ec727ea7Spatrick 
3788*12c85518Srobert   case Type::BitInt:
3789ec727ea7Spatrick     break;
3790e5dd7070Spatrick 
3791e5dd7070Spatrick   case Type::ConstantArray:
3792e5dd7070Spatrick   case Type::IncompleteArray:
3793e5dd7070Spatrick   case Type::VariableArray:
3794e5dd7070Spatrick     // Itanium C++ ABI 2.9.5p5:
3795e5dd7070Spatrick     // abi::__array_type_info adds no data members to std::type_info.
3796e5dd7070Spatrick     break;
3797e5dd7070Spatrick 
3798e5dd7070Spatrick   case Type::FunctionNoProto:
3799e5dd7070Spatrick   case Type::FunctionProto:
3800e5dd7070Spatrick     // Itanium C++ ABI 2.9.5p5:
3801e5dd7070Spatrick     // abi::__function_type_info adds no data members to std::type_info.
3802e5dd7070Spatrick     break;
3803e5dd7070Spatrick 
3804e5dd7070Spatrick   case Type::Enum:
3805e5dd7070Spatrick     // Itanium C++ ABI 2.9.5p5:
3806e5dd7070Spatrick     // abi::__enum_type_info adds no data members to std::type_info.
3807e5dd7070Spatrick     break;
3808e5dd7070Spatrick 
3809e5dd7070Spatrick   case Type::Record: {
3810e5dd7070Spatrick     const CXXRecordDecl *RD =
3811e5dd7070Spatrick       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3812e5dd7070Spatrick     if (!RD->hasDefinition() || !RD->getNumBases()) {
3813e5dd7070Spatrick       // We don't need to emit any fields.
3814e5dd7070Spatrick       break;
3815e5dd7070Spatrick     }
3816e5dd7070Spatrick 
3817e5dd7070Spatrick     if (CanUseSingleInheritance(RD))
3818e5dd7070Spatrick       BuildSIClassTypeInfo(RD);
3819e5dd7070Spatrick     else
3820e5dd7070Spatrick       BuildVMIClassTypeInfo(RD);
3821e5dd7070Spatrick 
3822e5dd7070Spatrick     break;
3823e5dd7070Spatrick   }
3824e5dd7070Spatrick 
3825e5dd7070Spatrick   case Type::ObjCObject:
3826e5dd7070Spatrick   case Type::ObjCInterface:
3827e5dd7070Spatrick     BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
3828e5dd7070Spatrick     break;
3829e5dd7070Spatrick 
3830e5dd7070Spatrick   case Type::ObjCObjectPointer:
3831e5dd7070Spatrick     BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
3832e5dd7070Spatrick     break;
3833e5dd7070Spatrick 
3834e5dd7070Spatrick   case Type::Pointer:
3835e5dd7070Spatrick     BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
3836e5dd7070Spatrick     break;
3837e5dd7070Spatrick 
3838e5dd7070Spatrick   case Type::MemberPointer:
3839e5dd7070Spatrick     BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
3840e5dd7070Spatrick     break;
3841e5dd7070Spatrick 
3842e5dd7070Spatrick   case Type::Atomic:
3843e5dd7070Spatrick     // No fields, at least for the moment.
3844e5dd7070Spatrick     break;
3845e5dd7070Spatrick   }
3846e5dd7070Spatrick 
3847e5dd7070Spatrick   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
3848e5dd7070Spatrick 
3849e5dd7070Spatrick   SmallString<256> Name;
3850e5dd7070Spatrick   llvm::raw_svector_ostream Out(Name);
3851e5dd7070Spatrick   CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
3852e5dd7070Spatrick   llvm::Module &M = CGM.getModule();
3853e5dd7070Spatrick   llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
3854e5dd7070Spatrick   llvm::GlobalVariable *GV =
3855e5dd7070Spatrick       new llvm::GlobalVariable(M, Init->getType(),
3856e5dd7070Spatrick                                /*isConstant=*/true, Linkage, Init, Name);
3857e5dd7070Spatrick 
3858a9ac8606Spatrick   // Export the typeinfo in the same circumstances as the vtable is exported.
3859a9ac8606Spatrick   auto GVDLLStorageClass = DLLStorageClass;
3860a9ac8606Spatrick   if (CGM.getTarget().hasPS4DLLImportExport()) {
3861a9ac8606Spatrick     if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3862a9ac8606Spatrick       const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
3863a9ac8606Spatrick       if (RD->hasAttr<DLLExportAttr>() ||
3864a9ac8606Spatrick           CXXRecordAllNonInlineVirtualsHaveAttr<DLLExportAttr>(RD)) {
3865a9ac8606Spatrick         GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
3866a9ac8606Spatrick       }
3867a9ac8606Spatrick     }
3868a9ac8606Spatrick   }
3869a9ac8606Spatrick 
3870e5dd7070Spatrick   // If there's already an old global variable, replace it with the new one.
3871e5dd7070Spatrick   if (OldGV) {
3872e5dd7070Spatrick     GV->takeName(OldGV);
3873e5dd7070Spatrick     llvm::Constant *NewPtr =
3874e5dd7070Spatrick       llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
3875e5dd7070Spatrick     OldGV->replaceAllUsesWith(NewPtr);
3876e5dd7070Spatrick     OldGV->eraseFromParent();
3877e5dd7070Spatrick   }
3878e5dd7070Spatrick 
3879e5dd7070Spatrick   if (CGM.supportsCOMDAT() && GV->isWeakForLinker())
3880e5dd7070Spatrick     GV->setComdat(M.getOrInsertComdat(GV->getName()));
3881e5dd7070Spatrick 
3882*12c85518Srobert   CharUnits Align = CGM.getContext().toCharUnitsFromBits(
3883*12c85518Srobert       CGM.getTarget().getPointerAlign(LangAS::Default));
3884e5dd7070Spatrick   GV->setAlignment(Align.getAsAlign());
3885e5dd7070Spatrick 
3886e5dd7070Spatrick   // The Itanium ABI specifies that type_info objects must be globally
3887e5dd7070Spatrick   // unique, with one exception: if the type is an incomplete class
3888e5dd7070Spatrick   // type or a (possibly indirect) pointer to one.  That exception
3889e5dd7070Spatrick   // affects the general case of comparing type_info objects produced
3890e5dd7070Spatrick   // by the typeid operator, which is why the comparison operators on
3891e5dd7070Spatrick   // std::type_info generally use the type_info name pointers instead
3892e5dd7070Spatrick   // of the object addresses.  However, the language's built-in uses
3893e5dd7070Spatrick   // of RTTI generally require class types to be complete, even when
3894e5dd7070Spatrick   // manipulating pointers to those class types.  This allows the
3895e5dd7070Spatrick   // implementation of dynamic_cast to rely on address equality tests,
3896e5dd7070Spatrick   // which is much faster.
3897e5dd7070Spatrick 
3898e5dd7070Spatrick   // All of this is to say that it's important that both the type_info
3899e5dd7070Spatrick   // object and the type_info name be uniqued when weakly emitted.
3900e5dd7070Spatrick 
3901e5dd7070Spatrick   TypeName->setVisibility(Visibility);
3902e5dd7070Spatrick   CGM.setDSOLocal(TypeName);
3903e5dd7070Spatrick 
3904e5dd7070Spatrick   GV->setVisibility(Visibility);
3905e5dd7070Spatrick   CGM.setDSOLocal(GV);
3906e5dd7070Spatrick 
3907e5dd7070Spatrick   TypeName->setDLLStorageClass(DLLStorageClass);
3908a9ac8606Spatrick   GV->setDLLStorageClass(CGM.getTarget().hasPS4DLLImportExport()
3909a9ac8606Spatrick                              ? GVDLLStorageClass
3910a9ac8606Spatrick                              : DLLStorageClass);
3911e5dd7070Spatrick 
3912e5dd7070Spatrick   TypeName->setPartition(CGM.getCodeGenOpts().SymbolPartition);
3913e5dd7070Spatrick   GV->setPartition(CGM.getCodeGenOpts().SymbolPartition);
3914e5dd7070Spatrick 
3915e5dd7070Spatrick   return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
3916e5dd7070Spatrick }
3917e5dd7070Spatrick 
3918e5dd7070Spatrick /// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
3919e5dd7070Spatrick /// for the given Objective-C object type.
BuildObjCObjectTypeInfo(const ObjCObjectType * OT)3920e5dd7070Spatrick void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
3921e5dd7070Spatrick   // Drop qualifiers.
3922e5dd7070Spatrick   const Type *T = OT->getBaseType().getTypePtr();
3923e5dd7070Spatrick   assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
3924e5dd7070Spatrick 
3925e5dd7070Spatrick   // The builtin types are abi::__class_type_infos and don't require
3926e5dd7070Spatrick   // extra fields.
3927e5dd7070Spatrick   if (isa<BuiltinType>(T)) return;
3928e5dd7070Spatrick 
3929e5dd7070Spatrick   ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
3930e5dd7070Spatrick   ObjCInterfaceDecl *Super = Class->getSuperClass();
3931e5dd7070Spatrick 
3932e5dd7070Spatrick   // Root classes are also __class_type_info.
3933e5dd7070Spatrick   if (!Super) return;
3934e5dd7070Spatrick 
3935e5dd7070Spatrick   QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
3936e5dd7070Spatrick 
3937e5dd7070Spatrick   // Everything else is single inheritance.
3938e5dd7070Spatrick   llvm::Constant *BaseTypeInfo =
3939e5dd7070Spatrick       ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(SuperTy);
3940e5dd7070Spatrick   Fields.push_back(BaseTypeInfo);
3941e5dd7070Spatrick }
3942e5dd7070Spatrick 
3943e5dd7070Spatrick /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
3944e5dd7070Spatrick /// inheritance, according to the Itanium C++ ABI, 2.95p6b.
BuildSIClassTypeInfo(const CXXRecordDecl * RD)3945e5dd7070Spatrick void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
3946e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p6b:
3947e5dd7070Spatrick   // It adds to abi::__class_type_info a single member pointing to the
3948e5dd7070Spatrick   // type_info structure for the base type,
3949e5dd7070Spatrick   llvm::Constant *BaseTypeInfo =
3950e5dd7070Spatrick     ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(RD->bases_begin()->getType());
3951e5dd7070Spatrick   Fields.push_back(BaseTypeInfo);
3952e5dd7070Spatrick }
3953e5dd7070Spatrick 
3954e5dd7070Spatrick namespace {
3955e5dd7070Spatrick   /// SeenBases - Contains virtual and non-virtual bases seen when traversing
3956e5dd7070Spatrick   /// a class hierarchy.
3957e5dd7070Spatrick   struct SeenBases {
3958e5dd7070Spatrick     llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
3959e5dd7070Spatrick     llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
3960e5dd7070Spatrick   };
3961e5dd7070Spatrick }
3962e5dd7070Spatrick 
3963e5dd7070Spatrick /// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
3964e5dd7070Spatrick /// abi::__vmi_class_type_info.
3965e5dd7070Spatrick ///
ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier * Base,SeenBases & Bases)3966e5dd7070Spatrick static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base,
3967e5dd7070Spatrick                                              SeenBases &Bases) {
3968e5dd7070Spatrick 
3969e5dd7070Spatrick   unsigned Flags = 0;
3970e5dd7070Spatrick 
3971e5dd7070Spatrick   auto *BaseDecl =
3972e5dd7070Spatrick       cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
3973e5dd7070Spatrick 
3974e5dd7070Spatrick   if (Base->isVirtual()) {
3975e5dd7070Spatrick     // Mark the virtual base as seen.
3976e5dd7070Spatrick     if (!Bases.VirtualBases.insert(BaseDecl).second) {
3977e5dd7070Spatrick       // If this virtual base has been seen before, then the class is diamond
3978e5dd7070Spatrick       // shaped.
3979e5dd7070Spatrick       Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
3980e5dd7070Spatrick     } else {
3981e5dd7070Spatrick       if (Bases.NonVirtualBases.count(BaseDecl))
3982e5dd7070Spatrick         Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3983e5dd7070Spatrick     }
3984e5dd7070Spatrick   } else {
3985e5dd7070Spatrick     // Mark the non-virtual base as seen.
3986e5dd7070Spatrick     if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
3987e5dd7070Spatrick       // If this non-virtual base has been seen before, then the class has non-
3988e5dd7070Spatrick       // diamond shaped repeated inheritance.
3989e5dd7070Spatrick       Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3990e5dd7070Spatrick     } else {
3991e5dd7070Spatrick       if (Bases.VirtualBases.count(BaseDecl))
3992e5dd7070Spatrick         Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3993e5dd7070Spatrick     }
3994e5dd7070Spatrick   }
3995e5dd7070Spatrick 
3996e5dd7070Spatrick   // Walk all bases.
3997e5dd7070Spatrick   for (const auto &I : BaseDecl->bases())
3998e5dd7070Spatrick     Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
3999e5dd7070Spatrick 
4000e5dd7070Spatrick   return Flags;
4001e5dd7070Spatrick }
4002e5dd7070Spatrick 
ComputeVMIClassTypeInfoFlags(const CXXRecordDecl * RD)4003e5dd7070Spatrick static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
4004e5dd7070Spatrick   unsigned Flags = 0;
4005e5dd7070Spatrick   SeenBases Bases;
4006e5dd7070Spatrick 
4007e5dd7070Spatrick   // Walk all bases.
4008e5dd7070Spatrick   for (const auto &I : RD->bases())
4009e5dd7070Spatrick     Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
4010e5dd7070Spatrick 
4011e5dd7070Spatrick   return Flags;
4012e5dd7070Spatrick }
4013e5dd7070Spatrick 
4014e5dd7070Spatrick /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
4015e5dd7070Spatrick /// classes with bases that do not satisfy the abi::__si_class_type_info
4016e5dd7070Spatrick /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
BuildVMIClassTypeInfo(const CXXRecordDecl * RD)4017e5dd7070Spatrick void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
4018e5dd7070Spatrick   llvm::Type *UnsignedIntLTy =
4019e5dd7070Spatrick     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
4020e5dd7070Spatrick 
4021e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p6c:
4022e5dd7070Spatrick   //   __flags is a word with flags describing details about the class
4023e5dd7070Spatrick   //   structure, which may be referenced by using the __flags_masks
4024e5dd7070Spatrick   //   enumeration. These flags refer to both direct and indirect bases.
4025e5dd7070Spatrick   unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
4026e5dd7070Spatrick   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4027e5dd7070Spatrick 
4028e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p6c:
4029e5dd7070Spatrick   //   __base_count is a word with the number of direct proper base class
4030e5dd7070Spatrick   //   descriptions that follow.
4031e5dd7070Spatrick   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
4032e5dd7070Spatrick 
4033e5dd7070Spatrick   if (!RD->getNumBases())
4034e5dd7070Spatrick     return;
4035e5dd7070Spatrick 
4036e5dd7070Spatrick   // Now add the base class descriptions.
4037e5dd7070Spatrick 
4038e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p6c:
4039e5dd7070Spatrick   //   __base_info[] is an array of base class descriptions -- one for every
4040e5dd7070Spatrick   //   direct proper base. Each description is of the type:
4041e5dd7070Spatrick   //
4042e5dd7070Spatrick   //   struct abi::__base_class_type_info {
4043e5dd7070Spatrick   //   public:
4044e5dd7070Spatrick   //     const __class_type_info *__base_type;
4045e5dd7070Spatrick   //     long __offset_flags;
4046e5dd7070Spatrick   //
4047e5dd7070Spatrick   //     enum __offset_flags_masks {
4048e5dd7070Spatrick   //       __virtual_mask = 0x1,
4049e5dd7070Spatrick   //       __public_mask = 0x2,
4050e5dd7070Spatrick   //       __offset_shift = 8
4051e5dd7070Spatrick   //     };
4052e5dd7070Spatrick   //   };
4053e5dd7070Spatrick 
4054e5dd7070Spatrick   // If we're in mingw and 'long' isn't wide enough for a pointer, use 'long
4055e5dd7070Spatrick   // long' instead of 'long' for __offset_flags. libstdc++abi uses long long on
4056e5dd7070Spatrick   // LLP64 platforms.
4057e5dd7070Spatrick   // FIXME: Consider updating libc++abi to match, and extend this logic to all
4058e5dd7070Spatrick   // LLP64 platforms.
4059e5dd7070Spatrick   QualType OffsetFlagsTy = CGM.getContext().LongTy;
4060e5dd7070Spatrick   const TargetInfo &TI = CGM.getContext().getTargetInfo();
4061*12c85518Srobert   if (TI.getTriple().isOSCygMing() &&
4062*12c85518Srobert       TI.getPointerWidth(LangAS::Default) > TI.getLongWidth())
4063e5dd7070Spatrick     OffsetFlagsTy = CGM.getContext().LongLongTy;
4064e5dd7070Spatrick   llvm::Type *OffsetFlagsLTy =
4065e5dd7070Spatrick       CGM.getTypes().ConvertType(OffsetFlagsTy);
4066e5dd7070Spatrick 
4067e5dd7070Spatrick   for (const auto &Base : RD->bases()) {
4068e5dd7070Spatrick     // The __base_type member points to the RTTI for the base type.
4069e5dd7070Spatrick     Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType()));
4070e5dd7070Spatrick 
4071e5dd7070Spatrick     auto *BaseDecl =
4072e5dd7070Spatrick         cast<CXXRecordDecl>(Base.getType()->castAs<RecordType>()->getDecl());
4073e5dd7070Spatrick 
4074e5dd7070Spatrick     int64_t OffsetFlags = 0;
4075e5dd7070Spatrick 
4076e5dd7070Spatrick     // All but the lower 8 bits of __offset_flags are a signed offset.
4077e5dd7070Spatrick     // For a non-virtual base, this is the offset in the object of the base
4078e5dd7070Spatrick     // subobject. For a virtual base, this is the offset in the virtual table of
4079e5dd7070Spatrick     // the virtual base offset for the virtual base referenced (negative).
4080e5dd7070Spatrick     CharUnits Offset;
4081e5dd7070Spatrick     if (Base.isVirtual())
4082e5dd7070Spatrick       Offset =
4083e5dd7070Spatrick         CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
4084e5dd7070Spatrick     else {
4085e5dd7070Spatrick       const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
4086e5dd7070Spatrick       Offset = Layout.getBaseClassOffset(BaseDecl);
4087e5dd7070Spatrick     };
4088e5dd7070Spatrick 
4089e5dd7070Spatrick     OffsetFlags = uint64_t(Offset.getQuantity()) << 8;
4090e5dd7070Spatrick 
4091e5dd7070Spatrick     // The low-order byte of __offset_flags contains flags, as given by the
4092e5dd7070Spatrick     // masks from the enumeration __offset_flags_masks.
4093e5dd7070Spatrick     if (Base.isVirtual())
4094e5dd7070Spatrick       OffsetFlags |= BCTI_Virtual;
4095e5dd7070Spatrick     if (Base.getAccessSpecifier() == AS_public)
4096e5dd7070Spatrick       OffsetFlags |= BCTI_Public;
4097e5dd7070Spatrick 
4098e5dd7070Spatrick     Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
4099e5dd7070Spatrick   }
4100e5dd7070Spatrick }
4101e5dd7070Spatrick 
4102e5dd7070Spatrick /// Compute the flags for a __pbase_type_info, and remove the corresponding
4103e5dd7070Spatrick /// pieces from \p Type.
extractPBaseFlags(ASTContext & Ctx,QualType & Type)4104e5dd7070Spatrick static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type) {
4105e5dd7070Spatrick   unsigned Flags = 0;
4106e5dd7070Spatrick 
4107e5dd7070Spatrick   if (Type.isConstQualified())
4108e5dd7070Spatrick     Flags |= ItaniumRTTIBuilder::PTI_Const;
4109e5dd7070Spatrick   if (Type.isVolatileQualified())
4110e5dd7070Spatrick     Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4111e5dd7070Spatrick   if (Type.isRestrictQualified())
4112e5dd7070Spatrick     Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4113e5dd7070Spatrick   Type = Type.getUnqualifiedType();
4114e5dd7070Spatrick 
4115e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p7:
4116e5dd7070Spatrick   //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
4117e5dd7070Spatrick   //   incomplete class type, the incomplete target type flag is set.
4118e5dd7070Spatrick   if (ContainsIncompleteClassType(Type))
4119e5dd7070Spatrick     Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4120e5dd7070Spatrick 
4121e5dd7070Spatrick   if (auto *Proto = Type->getAs<FunctionProtoType>()) {
4122e5dd7070Spatrick     if (Proto->isNothrow()) {
4123e5dd7070Spatrick       Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4124e5dd7070Spatrick       Type = Ctx.getFunctionTypeWithExceptionSpec(Type, EST_None);
4125e5dd7070Spatrick     }
4126e5dd7070Spatrick   }
4127e5dd7070Spatrick 
4128e5dd7070Spatrick   return Flags;
4129e5dd7070Spatrick }
4130e5dd7070Spatrick 
4131e5dd7070Spatrick /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
4132e5dd7070Spatrick /// used for pointer types.
BuildPointerTypeInfo(QualType PointeeTy)4133e5dd7070Spatrick void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
4134e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p7:
4135e5dd7070Spatrick   //   __flags is a flag word describing the cv-qualification and other
4136e5dd7070Spatrick   //   attributes of the type pointed to
4137e5dd7070Spatrick   unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);
4138e5dd7070Spatrick 
4139e5dd7070Spatrick   llvm::Type *UnsignedIntLTy =
4140e5dd7070Spatrick     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
4141e5dd7070Spatrick   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4142e5dd7070Spatrick 
4143e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p7:
4144e5dd7070Spatrick   //  __pointee is a pointer to the std::type_info derivation for the
4145e5dd7070Spatrick   //  unqualified type being pointed to.
4146e5dd7070Spatrick   llvm::Constant *PointeeTypeInfo =
4147e5dd7070Spatrick       ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(PointeeTy);
4148e5dd7070Spatrick   Fields.push_back(PointeeTypeInfo);
4149e5dd7070Spatrick }
4150e5dd7070Spatrick 
4151e5dd7070Spatrick /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
4152e5dd7070Spatrick /// struct, used for member pointer types.
4153e5dd7070Spatrick void
BuildPointerToMemberTypeInfo(const MemberPointerType * Ty)4154e5dd7070Spatrick ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
4155e5dd7070Spatrick   QualType PointeeTy = Ty->getPointeeType();
4156e5dd7070Spatrick 
4157e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p7:
4158e5dd7070Spatrick   //   __flags is a flag word describing the cv-qualification and other
4159e5dd7070Spatrick   //   attributes of the type pointed to.
4160e5dd7070Spatrick   unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);
4161e5dd7070Spatrick 
4162e5dd7070Spatrick   const RecordType *ClassType = cast<RecordType>(Ty->getClass());
4163e5dd7070Spatrick   if (IsIncompleteClassType(ClassType))
4164e5dd7070Spatrick     Flags |= PTI_ContainingClassIncomplete;
4165e5dd7070Spatrick 
4166e5dd7070Spatrick   llvm::Type *UnsignedIntLTy =
4167e5dd7070Spatrick     CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
4168e5dd7070Spatrick   Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4169e5dd7070Spatrick 
4170e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p7:
4171e5dd7070Spatrick   //   __pointee is a pointer to the std::type_info derivation for the
4172e5dd7070Spatrick   //   unqualified type being pointed to.
4173e5dd7070Spatrick   llvm::Constant *PointeeTypeInfo =
4174e5dd7070Spatrick       ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(PointeeTy);
4175e5dd7070Spatrick   Fields.push_back(PointeeTypeInfo);
4176e5dd7070Spatrick 
4177e5dd7070Spatrick   // Itanium C++ ABI 2.9.5p9:
4178e5dd7070Spatrick   //   __context is a pointer to an abi::__class_type_info corresponding to the
4179e5dd7070Spatrick   //   class type containing the member pointed to
4180e5dd7070Spatrick   //   (e.g., the "A" in "int A::*").
4181e5dd7070Spatrick   Fields.push_back(
4182e5dd7070Spatrick       ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(QualType(ClassType, 0)));
4183e5dd7070Spatrick }
4184e5dd7070Spatrick 
getAddrOfRTTIDescriptor(QualType Ty)4185e5dd7070Spatrick llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
4186e5dd7070Spatrick   return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4187e5dd7070Spatrick }
4188e5dd7070Spatrick 
EmitFundamentalRTTIDescriptors(const CXXRecordDecl * RD)4189e5dd7070Spatrick void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(const CXXRecordDecl *RD) {
4190e5dd7070Spatrick   // Types added here must also be added to TypeInfoIsInStandardLibrary.
4191e5dd7070Spatrick   QualType FundamentalTypes[] = {
4192e5dd7070Spatrick       getContext().VoidTy,             getContext().NullPtrTy,
4193e5dd7070Spatrick       getContext().BoolTy,             getContext().WCharTy,
4194e5dd7070Spatrick       getContext().CharTy,             getContext().UnsignedCharTy,
4195e5dd7070Spatrick       getContext().SignedCharTy,       getContext().ShortTy,
4196e5dd7070Spatrick       getContext().UnsignedShortTy,    getContext().IntTy,
4197e5dd7070Spatrick       getContext().UnsignedIntTy,      getContext().LongTy,
4198e5dd7070Spatrick       getContext().UnsignedLongTy,     getContext().LongLongTy,
4199e5dd7070Spatrick       getContext().UnsignedLongLongTy, getContext().Int128Ty,
4200e5dd7070Spatrick       getContext().UnsignedInt128Ty,   getContext().HalfTy,
4201e5dd7070Spatrick       getContext().FloatTy,            getContext().DoubleTy,
4202e5dd7070Spatrick       getContext().LongDoubleTy,       getContext().Float128Ty,
4203e5dd7070Spatrick       getContext().Char8Ty,            getContext().Char16Ty,
4204e5dd7070Spatrick       getContext().Char32Ty
4205e5dd7070Spatrick   };
4206e5dd7070Spatrick   llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4207*12c85518Srobert       RD->hasAttr<DLLExportAttr>() || CGM.shouldMapVisibilityToDLLExport(RD)
4208e5dd7070Spatrick           ? llvm::GlobalValue::DLLExportStorageClass
4209e5dd7070Spatrick           : llvm::GlobalValue::DefaultStorageClass;
4210e5dd7070Spatrick   llvm::GlobalValue::VisibilityTypes Visibility =
4211e5dd7070Spatrick       CodeGenModule::GetLLVMVisibility(RD->getVisibility());
4212e5dd7070Spatrick   for (const QualType &FundamentalType : FundamentalTypes) {
4213e5dd7070Spatrick     QualType PointerType = getContext().getPointerType(FundamentalType);
4214e5dd7070Spatrick     QualType PointerTypeConst = getContext().getPointerType(
4215e5dd7070Spatrick         FundamentalType.withConst());
4216e5dd7070Spatrick     for (QualType Type : {FundamentalType, PointerType, PointerTypeConst})
4217e5dd7070Spatrick       ItaniumRTTIBuilder(*this).BuildTypeInfo(
4218e5dd7070Spatrick           Type, llvm::GlobalValue::ExternalLinkage,
4219e5dd7070Spatrick           Visibility, DLLStorageClass);
4220e5dd7070Spatrick   }
4221e5dd7070Spatrick }
4222e5dd7070Spatrick 
4223e5dd7070Spatrick /// What sort of uniqueness rules should we use for the RTTI for the
4224e5dd7070Spatrick /// given type?
classifyRTTIUniqueness(QualType CanTy,llvm::GlobalValue::LinkageTypes Linkage) const4225e5dd7070Spatrick ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4226e5dd7070Spatrick     QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage) const {
4227e5dd7070Spatrick   if (shouldRTTIBeUnique())
4228e5dd7070Spatrick     return RUK_Unique;
4229e5dd7070Spatrick 
4230e5dd7070Spatrick   // It's only necessary for linkonce_odr or weak_odr linkage.
4231e5dd7070Spatrick   if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4232e5dd7070Spatrick       Linkage != llvm::GlobalValue::WeakODRLinkage)
4233e5dd7070Spatrick     return RUK_Unique;
4234e5dd7070Spatrick 
4235e5dd7070Spatrick   // It's only necessary with default visibility.
4236e5dd7070Spatrick   if (CanTy->getVisibility() != DefaultVisibility)
4237e5dd7070Spatrick     return RUK_Unique;
4238e5dd7070Spatrick 
4239e5dd7070Spatrick   // If we're not required to publish this symbol, hide it.
4240e5dd7070Spatrick   if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4241e5dd7070Spatrick     return RUK_NonUniqueHidden;
4242e5dd7070Spatrick 
4243e5dd7070Spatrick   // If we're required to publish this symbol, as we might be under an
4244e5dd7070Spatrick   // explicit instantiation, leave it with default visibility but
4245e5dd7070Spatrick   // enable string-comparisons.
4246e5dd7070Spatrick   assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
4247e5dd7070Spatrick   return RUK_NonUniqueVisible;
4248e5dd7070Spatrick }
4249e5dd7070Spatrick 
4250e5dd7070Spatrick // Find out how to codegen the complete destructor and constructor
4251e5dd7070Spatrick namespace {
4252e5dd7070Spatrick enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4253e5dd7070Spatrick }
getCodegenToUse(CodeGenModule & CGM,const CXXMethodDecl * MD)4254e5dd7070Spatrick static StructorCodegen getCodegenToUse(CodeGenModule &CGM,
4255e5dd7070Spatrick                                        const CXXMethodDecl *MD) {
4256e5dd7070Spatrick   if (!CGM.getCodeGenOpts().CXXCtorDtorAliases)
4257e5dd7070Spatrick     return StructorCodegen::Emit;
4258e5dd7070Spatrick 
4259e5dd7070Spatrick   // The complete and base structors are not equivalent if there are any virtual
4260e5dd7070Spatrick   // bases, so emit separate functions.
4261e5dd7070Spatrick   if (MD->getParent()->getNumVBases())
4262e5dd7070Spatrick     return StructorCodegen::Emit;
4263e5dd7070Spatrick 
4264e5dd7070Spatrick   GlobalDecl AliasDecl;
4265e5dd7070Spatrick   if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4266e5dd7070Spatrick     AliasDecl = GlobalDecl(DD, Dtor_Complete);
4267e5dd7070Spatrick   } else {
4268e5dd7070Spatrick     const auto *CD = cast<CXXConstructorDecl>(MD);
4269e5dd7070Spatrick     AliasDecl = GlobalDecl(CD, Ctor_Complete);
4270e5dd7070Spatrick   }
4271e5dd7070Spatrick   llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl);
4272e5dd7070Spatrick 
4273e5dd7070Spatrick   if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
4274e5dd7070Spatrick     return StructorCodegen::RAUW;
4275e5dd7070Spatrick 
4276e5dd7070Spatrick   // FIXME: Should we allow available_externally aliases?
4277e5dd7070Spatrick   if (!llvm::GlobalAlias::isValidLinkage(Linkage))
4278e5dd7070Spatrick     return StructorCodegen::RAUW;
4279e5dd7070Spatrick 
4280e5dd7070Spatrick   if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
4281e5dd7070Spatrick     // Only ELF and wasm support COMDATs with arbitrary names (C5/D5).
4282e5dd7070Spatrick     if (CGM.getTarget().getTriple().isOSBinFormatELF() ||
4283e5dd7070Spatrick         CGM.getTarget().getTriple().isOSBinFormatWasm())
4284e5dd7070Spatrick       return StructorCodegen::COMDAT;
4285e5dd7070Spatrick     return StructorCodegen::Emit;
4286e5dd7070Spatrick   }
4287e5dd7070Spatrick 
4288e5dd7070Spatrick   return StructorCodegen::Alias;
4289e5dd7070Spatrick }
4290e5dd7070Spatrick 
emitConstructorDestructorAlias(CodeGenModule & CGM,GlobalDecl AliasDecl,GlobalDecl TargetDecl)4291e5dd7070Spatrick static void emitConstructorDestructorAlias(CodeGenModule &CGM,
4292e5dd7070Spatrick                                            GlobalDecl AliasDecl,
4293e5dd7070Spatrick                                            GlobalDecl TargetDecl) {
4294e5dd7070Spatrick   llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl);
4295e5dd7070Spatrick 
4296e5dd7070Spatrick   StringRef MangledName = CGM.getMangledName(AliasDecl);
4297e5dd7070Spatrick   llvm::GlobalValue *Entry = CGM.GetGlobalValue(MangledName);
4298e5dd7070Spatrick   if (Entry && !Entry->isDeclaration())
4299e5dd7070Spatrick     return;
4300e5dd7070Spatrick 
4301e5dd7070Spatrick   auto *Aliasee = cast<llvm::GlobalValue>(CGM.GetAddrOfGlobal(TargetDecl));
4302e5dd7070Spatrick 
4303e5dd7070Spatrick   // Create the alias with no name.
4304e5dd7070Spatrick   auto *Alias = llvm::GlobalAlias::create(Linkage, "", Aliasee);
4305e5dd7070Spatrick 
4306e5dd7070Spatrick   // Constructors and destructors are always unnamed_addr.
4307e5dd7070Spatrick   Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4308e5dd7070Spatrick 
4309e5dd7070Spatrick   // Switch any previous uses to the alias.
4310e5dd7070Spatrick   if (Entry) {
4311e5dd7070Spatrick     assert(Entry->getType() == Aliasee->getType() &&
4312e5dd7070Spatrick            "declaration exists with different type");
4313e5dd7070Spatrick     Alias->takeName(Entry);
4314e5dd7070Spatrick     Entry->replaceAllUsesWith(Alias);
4315e5dd7070Spatrick     Entry->eraseFromParent();
4316e5dd7070Spatrick   } else {
4317e5dd7070Spatrick     Alias->setName(MangledName);
4318e5dd7070Spatrick   }
4319e5dd7070Spatrick 
4320e5dd7070Spatrick   // Finally, set up the alias with its proper name and attributes.
4321e5dd7070Spatrick   CGM.SetCommonAttributes(AliasDecl, Alias);
4322e5dd7070Spatrick }
4323e5dd7070Spatrick 
emitCXXStructor(GlobalDecl GD)4324e5dd7070Spatrick void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
4325e5dd7070Spatrick   auto *MD = cast<CXXMethodDecl>(GD.getDecl());
4326e5dd7070Spatrick   auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4327e5dd7070Spatrick   const CXXDestructorDecl *DD = CD ? nullptr : cast<CXXDestructorDecl>(MD);
4328e5dd7070Spatrick 
4329e5dd7070Spatrick   StructorCodegen CGType = getCodegenToUse(CGM, MD);
4330e5dd7070Spatrick 
4331e5dd7070Spatrick   if (CD ? GD.getCtorType() == Ctor_Complete
4332e5dd7070Spatrick          : GD.getDtorType() == Dtor_Complete) {
4333e5dd7070Spatrick     GlobalDecl BaseDecl;
4334e5dd7070Spatrick     if (CD)
4335e5dd7070Spatrick       BaseDecl = GD.getWithCtorType(Ctor_Base);
4336e5dd7070Spatrick     else
4337e5dd7070Spatrick       BaseDecl = GD.getWithDtorType(Dtor_Base);
4338e5dd7070Spatrick 
4339e5dd7070Spatrick     if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4340e5dd7070Spatrick       emitConstructorDestructorAlias(CGM, GD, BaseDecl);
4341e5dd7070Spatrick       return;
4342e5dd7070Spatrick     }
4343e5dd7070Spatrick 
4344e5dd7070Spatrick     if (CGType == StructorCodegen::RAUW) {
4345e5dd7070Spatrick       StringRef MangledName = CGM.getMangledName(GD);
4346e5dd7070Spatrick       auto *Aliasee = CGM.GetAddrOfGlobal(BaseDecl);
4347e5dd7070Spatrick       CGM.addReplacement(MangledName, Aliasee);
4348e5dd7070Spatrick       return;
4349e5dd7070Spatrick     }
4350e5dd7070Spatrick   }
4351e5dd7070Spatrick 
4352e5dd7070Spatrick   // The base destructor is equivalent to the base destructor of its
4353e5dd7070Spatrick   // base class if there is exactly one non-virtual base class with a
4354e5dd7070Spatrick   // non-trivial destructor, there are no fields with a non-trivial
4355e5dd7070Spatrick   // destructor, and the body of the destructor is trivial.
4356e5dd7070Spatrick   if (DD && GD.getDtorType() == Dtor_Base &&
4357e5dd7070Spatrick       CGType != StructorCodegen::COMDAT &&
4358e5dd7070Spatrick       !CGM.TryEmitBaseDestructorAsAlias(DD))
4359e5dd7070Spatrick     return;
4360e5dd7070Spatrick 
4361e5dd7070Spatrick   // FIXME: The deleting destructor is equivalent to the selected operator
4362e5dd7070Spatrick   // delete if:
4363e5dd7070Spatrick   //  * either the delete is a destroying operator delete or the destructor
4364e5dd7070Spatrick   //    would be trivial if it weren't virtual,
4365e5dd7070Spatrick   //  * the conversion from the 'this' parameter to the first parameter of the
4366e5dd7070Spatrick   //    destructor is equivalent to a bitcast,
4367e5dd7070Spatrick   //  * the destructor does not have an implicit "this" return, and
4368e5dd7070Spatrick   //  * the operator delete has the same calling convention and IR function type
4369e5dd7070Spatrick   //    as the destructor.
4370e5dd7070Spatrick   // In such cases we should try to emit the deleting dtor as an alias to the
4371e5dd7070Spatrick   // selected 'operator delete'.
4372e5dd7070Spatrick 
4373e5dd7070Spatrick   llvm::Function *Fn = CGM.codegenCXXStructor(GD);
4374e5dd7070Spatrick 
4375e5dd7070Spatrick   if (CGType == StructorCodegen::COMDAT) {
4376e5dd7070Spatrick     SmallString<256> Buffer;
4377e5dd7070Spatrick     llvm::raw_svector_ostream Out(Buffer);
4378e5dd7070Spatrick     if (DD)
4379e5dd7070Spatrick       getMangleContext().mangleCXXDtorComdat(DD, Out);
4380e5dd7070Spatrick     else
4381e5dd7070Spatrick       getMangleContext().mangleCXXCtorComdat(CD, Out);
4382e5dd7070Spatrick     llvm::Comdat *C = CGM.getModule().getOrInsertComdat(Out.str());
4383e5dd7070Spatrick     Fn->setComdat(C);
4384e5dd7070Spatrick   } else {
4385e5dd7070Spatrick     CGM.maybeSetTrivialComdat(*MD, *Fn);
4386e5dd7070Spatrick   }
4387e5dd7070Spatrick }
4388e5dd7070Spatrick 
getBeginCatchFn(CodeGenModule & CGM)4389e5dd7070Spatrick static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM) {
4390e5dd7070Spatrick   // void *__cxa_begin_catch(void*);
4391e5dd7070Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(
4392e5dd7070Spatrick       CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false);
4393e5dd7070Spatrick 
4394e5dd7070Spatrick   return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
4395e5dd7070Spatrick }
4396e5dd7070Spatrick 
getEndCatchFn(CodeGenModule & CGM)4397e5dd7070Spatrick static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) {
4398e5dd7070Spatrick   // void __cxa_end_catch();
4399e5dd7070Spatrick   llvm::FunctionType *FTy =
4400e5dd7070Spatrick       llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
4401e5dd7070Spatrick 
4402e5dd7070Spatrick   return CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
4403e5dd7070Spatrick }
4404e5dd7070Spatrick 
getGetExceptionPtrFn(CodeGenModule & CGM)4405e5dd7070Spatrick static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM) {
4406e5dd7070Spatrick   // void *__cxa_get_exception_ptr(void*);
4407e5dd7070Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(
4408e5dd7070Spatrick       CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false);
4409e5dd7070Spatrick 
4410e5dd7070Spatrick   return CGM.CreateRuntimeFunction(FTy, "__cxa_get_exception_ptr");
4411e5dd7070Spatrick }
4412e5dd7070Spatrick 
4413e5dd7070Spatrick namespace {
4414e5dd7070Spatrick   /// A cleanup to call __cxa_end_catch.  In many cases, the caught
4415e5dd7070Spatrick   /// exception type lets us state definitively that the thrown exception
4416e5dd7070Spatrick   /// type does not have a destructor.  In particular:
4417e5dd7070Spatrick   ///   - Catch-alls tell us nothing, so we have to conservatively
4418e5dd7070Spatrick   ///     assume that the thrown exception might have a destructor.
4419e5dd7070Spatrick   ///   - Catches by reference behave according to their base types.
4420e5dd7070Spatrick   ///   - Catches of non-record types will only trigger for exceptions
4421e5dd7070Spatrick   ///     of non-record types, which never have destructors.
4422e5dd7070Spatrick   ///   - Catches of record types can trigger for arbitrary subclasses
4423e5dd7070Spatrick   ///     of the caught type, so we have to assume the actual thrown
4424e5dd7070Spatrick   ///     exception type might have a throwing destructor, even if the
4425e5dd7070Spatrick   ///     caught type's destructor is trivial or nothrow.
4426e5dd7070Spatrick   struct CallEndCatch final : EHScopeStack::Cleanup {
CallEndCatch__anon449188eb0911::CallEndCatch4427e5dd7070Spatrick     CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}
4428e5dd7070Spatrick     bool MightThrow;
4429e5dd7070Spatrick 
Emit__anon449188eb0911::CallEndCatch4430e5dd7070Spatrick     void Emit(CodeGenFunction &CGF, Flags flags) override {
4431e5dd7070Spatrick       if (!MightThrow) {
4432e5dd7070Spatrick         CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM));
4433e5dd7070Spatrick         return;
4434e5dd7070Spatrick       }
4435e5dd7070Spatrick 
4436e5dd7070Spatrick       CGF.EmitRuntimeCallOrInvoke(getEndCatchFn(CGF.CGM));
4437e5dd7070Spatrick     }
4438e5dd7070Spatrick   };
4439e5dd7070Spatrick }
4440e5dd7070Spatrick 
4441e5dd7070Spatrick /// Emits a call to __cxa_begin_catch and enters a cleanup to call
4442e5dd7070Spatrick /// __cxa_end_catch.
4443e5dd7070Spatrick ///
4444e5dd7070Spatrick /// \param EndMightThrow - true if __cxa_end_catch might throw
CallBeginCatch(CodeGenFunction & CGF,llvm::Value * Exn,bool EndMightThrow)4445e5dd7070Spatrick static llvm::Value *CallBeginCatch(CodeGenFunction &CGF,
4446e5dd7070Spatrick                                    llvm::Value *Exn,
4447e5dd7070Spatrick                                    bool EndMightThrow) {
4448e5dd7070Spatrick   llvm::CallInst *call =
4449e5dd7070Spatrick     CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn);
4450e5dd7070Spatrick 
4451e5dd7070Spatrick   CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow);
4452e5dd7070Spatrick 
4453e5dd7070Spatrick   return call;
4454e5dd7070Spatrick }
4455e5dd7070Spatrick 
4456e5dd7070Spatrick /// A "special initializer" callback for initializing a catch
4457e5dd7070Spatrick /// parameter during catch initialization.
InitCatchParam(CodeGenFunction & CGF,const VarDecl & CatchParam,Address ParamAddr,SourceLocation Loc)4458e5dd7070Spatrick static void InitCatchParam(CodeGenFunction &CGF,
4459e5dd7070Spatrick                            const VarDecl &CatchParam,
4460e5dd7070Spatrick                            Address ParamAddr,
4461e5dd7070Spatrick                            SourceLocation Loc) {
4462e5dd7070Spatrick   // Load the exception from where the landing pad saved it.
4463e5dd7070Spatrick   llvm::Value *Exn = CGF.getExceptionFromSlot();
4464e5dd7070Spatrick 
4465e5dd7070Spatrick   CanQualType CatchType =
4466e5dd7070Spatrick     CGF.CGM.getContext().getCanonicalType(CatchParam.getType());
4467e5dd7070Spatrick   llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType);
4468e5dd7070Spatrick 
4469e5dd7070Spatrick   // If we're catching by reference, we can just cast the object
4470e5dd7070Spatrick   // pointer to the appropriate pointer.
4471e5dd7070Spatrick   if (isa<ReferenceType>(CatchType)) {
4472e5dd7070Spatrick     QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
4473e5dd7070Spatrick     bool EndCatchMightThrow = CaughtType->isRecordType();
4474e5dd7070Spatrick 
4475e5dd7070Spatrick     // __cxa_begin_catch returns the adjusted object pointer.
4476e5dd7070Spatrick     llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4477e5dd7070Spatrick 
4478e5dd7070Spatrick     // We have no way to tell the personality function that we're
4479e5dd7070Spatrick     // catching by reference, so if we're catching a pointer,
4480e5dd7070Spatrick     // __cxa_begin_catch will actually return that pointer by value.
4481e5dd7070Spatrick     if (const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4482e5dd7070Spatrick       QualType PointeeType = PT->getPointeeType();
4483e5dd7070Spatrick 
4484e5dd7070Spatrick       // When catching by reference, generally we should just ignore
4485e5dd7070Spatrick       // this by-value pointer and use the exception object instead.
4486e5dd7070Spatrick       if (!PointeeType->isRecordType()) {
4487e5dd7070Spatrick 
4488e5dd7070Spatrick         // Exn points to the struct _Unwind_Exception header, which
4489e5dd7070Spatrick         // we have to skip past in order to reach the exception data.
4490e5dd7070Spatrick         unsigned HeaderSize =
4491e5dd7070Spatrick           CGF.CGM.getTargetCodeGenInfo().getSizeOfUnwindException();
4492a9ac8606Spatrick         AdjustedExn =
4493a9ac8606Spatrick             CGF.Builder.CreateConstGEP1_32(CGF.Int8Ty, Exn, HeaderSize);
4494e5dd7070Spatrick 
4495e5dd7070Spatrick       // However, if we're catching a pointer-to-record type that won't
4496e5dd7070Spatrick       // work, because the personality function might have adjusted
4497e5dd7070Spatrick       // the pointer.  There's actually no way for us to fully satisfy
4498e5dd7070Spatrick       // the language/ABI contract here:  we can't use Exn because it
4499e5dd7070Spatrick       // might have the wrong adjustment, but we can't use the by-value
4500e5dd7070Spatrick       // pointer because it's off by a level of abstraction.
4501e5dd7070Spatrick       //
4502e5dd7070Spatrick       // The current solution is to dump the adjusted pointer into an
4503e5dd7070Spatrick       // alloca, which breaks language semantics (because changing the
4504e5dd7070Spatrick       // pointer doesn't change the exception) but at least works.
4505e5dd7070Spatrick       // The better solution would be to filter out non-exact matches
4506e5dd7070Spatrick       // and rethrow them, but this is tricky because the rethrow
4507e5dd7070Spatrick       // really needs to be catchable by other sites at this landing
4508e5dd7070Spatrick       // pad.  The best solution is to fix the personality function.
4509e5dd7070Spatrick       } else {
4510e5dd7070Spatrick         // Pull the pointer for the reference type off.
4511*12c85518Srobert         llvm::Type *PtrTy = CGF.ConvertTypeForMem(CaughtType);
4512e5dd7070Spatrick 
4513e5dd7070Spatrick         // Create the temporary and write the adjusted pointer into it.
4514e5dd7070Spatrick         Address ExnPtrTmp =
4515e5dd7070Spatrick           CGF.CreateTempAlloca(PtrTy, CGF.getPointerAlign(), "exn.byref.tmp");
4516e5dd7070Spatrick         llvm::Value *Casted = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
4517e5dd7070Spatrick         CGF.Builder.CreateStore(Casted, ExnPtrTmp);
4518e5dd7070Spatrick 
4519e5dd7070Spatrick         // Bind the reference to the temporary.
4520e5dd7070Spatrick         AdjustedExn = ExnPtrTmp.getPointer();
4521e5dd7070Spatrick       }
4522e5dd7070Spatrick     }
4523e5dd7070Spatrick 
4524e5dd7070Spatrick     llvm::Value *ExnCast =
4525e5dd7070Spatrick       CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref");
4526e5dd7070Spatrick     CGF.Builder.CreateStore(ExnCast, ParamAddr);
4527e5dd7070Spatrick     return;
4528e5dd7070Spatrick   }
4529e5dd7070Spatrick 
4530e5dd7070Spatrick   // Scalars and complexes.
4531e5dd7070Spatrick   TypeEvaluationKind TEK = CGF.getEvaluationKind(CatchType);
4532e5dd7070Spatrick   if (TEK != TEK_Aggregate) {
4533e5dd7070Spatrick     llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false);
4534e5dd7070Spatrick 
4535e5dd7070Spatrick     // If the catch type is a pointer type, __cxa_begin_catch returns
4536e5dd7070Spatrick     // the pointer by value.
4537e5dd7070Spatrick     if (CatchType->hasPointerRepresentation()) {
4538e5dd7070Spatrick       llvm::Value *CastExn =
4539e5dd7070Spatrick         CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted");
4540e5dd7070Spatrick 
4541e5dd7070Spatrick       switch (CatchType.getQualifiers().getObjCLifetime()) {
4542e5dd7070Spatrick       case Qualifiers::OCL_Strong:
4543e5dd7070Spatrick         CastExn = CGF.EmitARCRetainNonBlock(CastExn);
4544*12c85518Srobert         [[fallthrough]];
4545e5dd7070Spatrick 
4546e5dd7070Spatrick       case Qualifiers::OCL_None:
4547e5dd7070Spatrick       case Qualifiers::OCL_ExplicitNone:
4548e5dd7070Spatrick       case Qualifiers::OCL_Autoreleasing:
4549e5dd7070Spatrick         CGF.Builder.CreateStore(CastExn, ParamAddr);
4550e5dd7070Spatrick         return;
4551e5dd7070Spatrick 
4552e5dd7070Spatrick       case Qualifiers::OCL_Weak:
4553e5dd7070Spatrick         CGF.EmitARCInitWeak(ParamAddr, CastExn);
4554e5dd7070Spatrick         return;
4555e5dd7070Spatrick       }
4556e5dd7070Spatrick       llvm_unreachable("bad ownership qualifier!");
4557e5dd7070Spatrick     }
4558e5dd7070Spatrick 
4559e5dd7070Spatrick     // Otherwise, it returns a pointer into the exception object.
4560e5dd7070Spatrick 
4561e5dd7070Spatrick     llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
4562e5dd7070Spatrick     llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
4563e5dd7070Spatrick 
4564e5dd7070Spatrick     LValue srcLV = CGF.MakeNaturalAlignAddrLValue(Cast, CatchType);
4565e5dd7070Spatrick     LValue destLV = CGF.MakeAddrLValue(ParamAddr, CatchType);
4566e5dd7070Spatrick     switch (TEK) {
4567e5dd7070Spatrick     case TEK_Complex:
4568e5dd7070Spatrick       CGF.EmitStoreOfComplex(CGF.EmitLoadOfComplex(srcLV, Loc), destLV,
4569e5dd7070Spatrick                              /*init*/ true);
4570e5dd7070Spatrick       return;
4571e5dd7070Spatrick     case TEK_Scalar: {
4572e5dd7070Spatrick       llvm::Value *ExnLoad = CGF.EmitLoadOfScalar(srcLV, Loc);
4573e5dd7070Spatrick       CGF.EmitStoreOfScalar(ExnLoad, destLV, /*init*/ true);
4574e5dd7070Spatrick       return;
4575e5dd7070Spatrick     }
4576e5dd7070Spatrick     case TEK_Aggregate:
4577e5dd7070Spatrick       llvm_unreachable("evaluation kind filtered out!");
4578e5dd7070Spatrick     }
4579e5dd7070Spatrick     llvm_unreachable("bad evaluation kind");
4580e5dd7070Spatrick   }
4581e5dd7070Spatrick 
4582e5dd7070Spatrick   assert(isa<RecordType>(CatchType) && "unexpected catch type!");
4583e5dd7070Spatrick   auto catchRD = CatchType->getAsCXXRecordDecl();
4584e5dd7070Spatrick   CharUnits caughtExnAlignment = CGF.CGM.getClassPointerAlignment(catchRD);
4585e5dd7070Spatrick 
4586e5dd7070Spatrick   llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
4587e5dd7070Spatrick 
4588e5dd7070Spatrick   // Check for a copy expression.  If we don't have a copy expression,
4589e5dd7070Spatrick   // that means a trivial copy is okay.
4590e5dd7070Spatrick   const Expr *copyExpr = CatchParam.getInit();
4591e5dd7070Spatrick   if (!copyExpr) {
4592e5dd7070Spatrick     llvm::Value *rawAdjustedExn = CallBeginCatch(CGF, Exn, true);
4593e5dd7070Spatrick     Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4594*12c85518Srobert                         LLVMCatchTy, caughtExnAlignment);
4595e5dd7070Spatrick     LValue Dest = CGF.MakeAddrLValue(ParamAddr, CatchType);
4596e5dd7070Spatrick     LValue Src = CGF.MakeAddrLValue(adjustedExn, CatchType);
4597e5dd7070Spatrick     CGF.EmitAggregateCopy(Dest, Src, CatchType, AggValueSlot::DoesNotOverlap);
4598e5dd7070Spatrick     return;
4599e5dd7070Spatrick   }
4600e5dd7070Spatrick 
4601e5dd7070Spatrick   // We have to call __cxa_get_exception_ptr to get the adjusted
4602e5dd7070Spatrick   // pointer before copying.
4603e5dd7070Spatrick   llvm::CallInst *rawAdjustedExn =
4604e5dd7070Spatrick     CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM), Exn);
4605e5dd7070Spatrick 
4606e5dd7070Spatrick   // Cast that to the appropriate type.
4607e5dd7070Spatrick   Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4608*12c85518Srobert                       LLVMCatchTy, caughtExnAlignment);
4609e5dd7070Spatrick 
4610e5dd7070Spatrick   // The copy expression is defined in terms of an OpaqueValueExpr.
4611e5dd7070Spatrick   // Find it and map it to the adjusted expression.
4612e5dd7070Spatrick   CodeGenFunction::OpaqueValueMapping
4613e5dd7070Spatrick     opaque(CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr),
4614e5dd7070Spatrick            CGF.MakeAddrLValue(adjustedExn, CatchParam.getType()));
4615e5dd7070Spatrick 
4616e5dd7070Spatrick   // Call the copy ctor in a terminate scope.
4617e5dd7070Spatrick   CGF.EHStack.pushTerminate();
4618e5dd7070Spatrick 
4619e5dd7070Spatrick   // Perform the copy construction.
4620e5dd7070Spatrick   CGF.EmitAggExpr(copyExpr,
4621e5dd7070Spatrick                   AggValueSlot::forAddr(ParamAddr, Qualifiers(),
4622e5dd7070Spatrick                                         AggValueSlot::IsNotDestructed,
4623e5dd7070Spatrick                                         AggValueSlot::DoesNotNeedGCBarriers,
4624e5dd7070Spatrick                                         AggValueSlot::IsNotAliased,
4625e5dd7070Spatrick                                         AggValueSlot::DoesNotOverlap));
4626e5dd7070Spatrick 
4627e5dd7070Spatrick   // Leave the terminate scope.
4628e5dd7070Spatrick   CGF.EHStack.popTerminate();
4629e5dd7070Spatrick 
4630e5dd7070Spatrick   // Undo the opaque value mapping.
4631e5dd7070Spatrick   opaque.pop();
4632e5dd7070Spatrick 
4633e5dd7070Spatrick   // Finally we can call __cxa_begin_catch.
4634e5dd7070Spatrick   CallBeginCatch(CGF, Exn, true);
4635e5dd7070Spatrick }
4636e5dd7070Spatrick 
4637e5dd7070Spatrick /// Begins a catch statement by initializing the catch variable and
4638e5dd7070Spatrick /// calling __cxa_begin_catch.
emitBeginCatch(CodeGenFunction & CGF,const CXXCatchStmt * S)4639e5dd7070Spatrick void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
4640e5dd7070Spatrick                                    const CXXCatchStmt *S) {
4641e5dd7070Spatrick   // We have to be very careful with the ordering of cleanups here:
4642e5dd7070Spatrick   //   C++ [except.throw]p4:
4643e5dd7070Spatrick   //     The destruction [of the exception temporary] occurs
4644e5dd7070Spatrick   //     immediately after the destruction of the object declared in
4645e5dd7070Spatrick   //     the exception-declaration in the handler.
4646e5dd7070Spatrick   //
4647e5dd7070Spatrick   // So the precise ordering is:
4648e5dd7070Spatrick   //   1.  Construct catch variable.
4649e5dd7070Spatrick   //   2.  __cxa_begin_catch
4650e5dd7070Spatrick   //   3.  Enter __cxa_end_catch cleanup
4651e5dd7070Spatrick   //   4.  Enter dtor cleanup
4652e5dd7070Spatrick   //
4653e5dd7070Spatrick   // We do this by using a slightly abnormal initialization process.
4654e5dd7070Spatrick   // Delegation sequence:
4655e5dd7070Spatrick   //   - ExitCXXTryStmt opens a RunCleanupsScope
4656e5dd7070Spatrick   //     - EmitAutoVarAlloca creates the variable and debug info
4657e5dd7070Spatrick   //       - InitCatchParam initializes the variable from the exception
4658e5dd7070Spatrick   //       - CallBeginCatch calls __cxa_begin_catch
4659e5dd7070Spatrick   //       - CallBeginCatch enters the __cxa_end_catch cleanup
4660e5dd7070Spatrick   //     - EmitAutoVarCleanups enters the variable destructor cleanup
4661e5dd7070Spatrick   //   - EmitCXXTryStmt emits the code for the catch body
4662e5dd7070Spatrick   //   - EmitCXXTryStmt close the RunCleanupsScope
4663e5dd7070Spatrick 
4664e5dd7070Spatrick   VarDecl *CatchParam = S->getExceptionDecl();
4665e5dd7070Spatrick   if (!CatchParam) {
4666e5dd7070Spatrick     llvm::Value *Exn = CGF.getExceptionFromSlot();
4667e5dd7070Spatrick     CallBeginCatch(CGF, Exn, true);
4668e5dd7070Spatrick     return;
4669e5dd7070Spatrick   }
4670e5dd7070Spatrick 
4671e5dd7070Spatrick   // Emit the local.
4672e5dd7070Spatrick   CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam);
4673e5dd7070Spatrick   InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF), S->getBeginLoc());
4674e5dd7070Spatrick   CGF.EmitAutoVarCleanups(var);
4675e5dd7070Spatrick }
4676e5dd7070Spatrick 
4677e5dd7070Spatrick /// Get or define the following function:
4678e5dd7070Spatrick ///   void @__clang_call_terminate(i8* %exn) nounwind noreturn
4679e5dd7070Spatrick /// This code is used only in C++.
getClangCallTerminateFn(CodeGenModule & CGM)4680e5dd7070Spatrick static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM) {
4681*12c85518Srobert   ASTContext &C = CGM.getContext();
4682*12c85518Srobert   const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
4683*12c85518Srobert       C.VoidTy, {C.getPointerType(C.CharTy)});
4684*12c85518Srobert   llvm::FunctionType *fnTy = CGM.getTypes().GetFunctionType(FI);
4685e5dd7070Spatrick   llvm::FunctionCallee fnRef = CGM.CreateRuntimeFunction(
4686e5dd7070Spatrick       fnTy, "__clang_call_terminate", llvm::AttributeList(), /*Local=*/true);
4687e5dd7070Spatrick   llvm::Function *fn =
4688e5dd7070Spatrick       cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
4689e5dd7070Spatrick   if (fn->empty()) {
4690*12c85518Srobert     CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, fn, /*IsThunk=*/false);
4691e5dd7070Spatrick     fn->setDoesNotThrow();
4692e5dd7070Spatrick     fn->setDoesNotReturn();
4693e5dd7070Spatrick 
4694e5dd7070Spatrick     // What we really want is to massively penalize inlining without
4695e5dd7070Spatrick     // forbidding it completely.  The difference between that and
4696e5dd7070Spatrick     // 'noinline' is negligible.
4697e5dd7070Spatrick     fn->addFnAttr(llvm::Attribute::NoInline);
4698e5dd7070Spatrick 
4699e5dd7070Spatrick     // Allow this function to be shared across translation units, but
4700e5dd7070Spatrick     // we don't want it to turn into an exported symbol.
4701e5dd7070Spatrick     fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
4702e5dd7070Spatrick     fn->setVisibility(llvm::Function::HiddenVisibility);
4703e5dd7070Spatrick     if (CGM.supportsCOMDAT())
4704e5dd7070Spatrick       fn->setComdat(CGM.getModule().getOrInsertComdat(fn->getName()));
4705e5dd7070Spatrick 
4706e5dd7070Spatrick     // Set up the function.
4707e5dd7070Spatrick     llvm::BasicBlock *entry =
4708e5dd7070Spatrick         llvm::BasicBlock::Create(CGM.getLLVMContext(), "", fn);
4709e5dd7070Spatrick     CGBuilderTy builder(CGM, entry);
4710e5dd7070Spatrick 
4711e5dd7070Spatrick     // Pull the exception pointer out of the parameter list.
4712e5dd7070Spatrick     llvm::Value *exn = &*fn->arg_begin();
4713e5dd7070Spatrick 
4714e5dd7070Spatrick     // Call __cxa_begin_catch(exn).
4715e5dd7070Spatrick     llvm::CallInst *catchCall = builder.CreateCall(getBeginCatchFn(CGM), exn);
4716e5dd7070Spatrick     catchCall->setDoesNotThrow();
4717e5dd7070Spatrick     catchCall->setCallingConv(CGM.getRuntimeCC());
4718e5dd7070Spatrick 
4719e5dd7070Spatrick     // Call std::terminate().
4720e5dd7070Spatrick     llvm::CallInst *termCall = builder.CreateCall(CGM.getTerminateFn());
4721e5dd7070Spatrick     termCall->setDoesNotThrow();
4722e5dd7070Spatrick     termCall->setDoesNotReturn();
4723e5dd7070Spatrick     termCall->setCallingConv(CGM.getRuntimeCC());
4724e5dd7070Spatrick 
4725e5dd7070Spatrick     // std::terminate cannot return.
4726e5dd7070Spatrick     builder.CreateUnreachable();
4727e5dd7070Spatrick   }
4728e5dd7070Spatrick   return fnRef;
4729e5dd7070Spatrick }
4730e5dd7070Spatrick 
4731e5dd7070Spatrick llvm::CallInst *
emitTerminateForUnexpectedException(CodeGenFunction & CGF,llvm::Value * Exn)4732e5dd7070Spatrick ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
4733e5dd7070Spatrick                                                    llvm::Value *Exn) {
4734e5dd7070Spatrick   // In C++, we want to call __cxa_begin_catch() before terminating.
4735e5dd7070Spatrick   if (Exn) {
4736e5dd7070Spatrick     assert(CGF.CGM.getLangOpts().CPlusPlus);
4737e5dd7070Spatrick     return CGF.EmitNounwindRuntimeCall(getClangCallTerminateFn(CGF.CGM), Exn);
4738e5dd7070Spatrick   }
4739e5dd7070Spatrick   return CGF.EmitNounwindRuntimeCall(CGF.CGM.getTerminateFn());
4740e5dd7070Spatrick }
4741e5dd7070Spatrick 
4742e5dd7070Spatrick std::pair<llvm::Value *, const CXXRecordDecl *>
LoadVTablePtr(CodeGenFunction & CGF,Address This,const CXXRecordDecl * RD)4743e5dd7070Spatrick ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
4744e5dd7070Spatrick                              const CXXRecordDecl *RD) {
4745e5dd7070Spatrick   return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
4746e5dd7070Spatrick }
4747e5dd7070Spatrick 
emitBeginCatch(CodeGenFunction & CGF,const CXXCatchStmt * C)4748e5dd7070Spatrick void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,
4749e5dd7070Spatrick                                        const CXXCatchStmt *C) {
4750e5dd7070Spatrick   if (CGF.getTarget().hasFeature("exception-handling"))
4751e5dd7070Spatrick     CGF.EHStack.pushCleanup<CatchRetScope>(
4752e5dd7070Spatrick         NormalCleanup, cast<llvm::CatchPadInst>(CGF.CurrentFuncletPad));
4753e5dd7070Spatrick   ItaniumCXXABI::emitBeginCatch(CGF, C);
4754e5dd7070Spatrick }
4755ec727ea7Spatrick 
4756a9ac8606Spatrick llvm::CallInst *
emitTerminateForUnexpectedException(CodeGenFunction & CGF,llvm::Value * Exn)4757a9ac8606Spatrick WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
4758a9ac8606Spatrick                                                        llvm::Value *Exn) {
4759a9ac8606Spatrick   // Itanium ABI calls __clang_call_terminate(), which __cxa_begin_catch() on
4760a9ac8606Spatrick   // the violating exception to mark it handled, but it is currently hard to do
4761a9ac8606Spatrick   // with wasm EH instruction structure with catch/catch_all, we just call
4762a9ac8606Spatrick   // std::terminate and ignore the violating exception as in CGCXXABI.
4763a9ac8606Spatrick   // TODO Consider code transformation that makes calling __clang_call_terminate
4764a9ac8606Spatrick   // possible.
4765a9ac8606Spatrick   return CGCXXABI::emitTerminateForUnexpectedException(CGF, Exn);
4766a9ac8606Spatrick }
4767a9ac8606Spatrick 
4768ec727ea7Spatrick /// Register a global destructor as best as we know how.
registerGlobalDtor(CodeGenFunction & CGF,const VarDecl & D,llvm::FunctionCallee Dtor,llvm::Constant * Addr)4769ec727ea7Spatrick void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
4770a9ac8606Spatrick                                   llvm::FunctionCallee Dtor,
4771a9ac8606Spatrick                                   llvm::Constant *Addr) {
4772a9ac8606Spatrick   if (D.getTLSKind() != VarDecl::TLS_None) {
4773a9ac8606Spatrick     // atexit routine expects "int(*)(int,...)"
4774a9ac8606Spatrick     llvm::FunctionType *FTy =
4775a9ac8606Spatrick         llvm::FunctionType::get(CGM.IntTy, CGM.IntTy, true);
4776a9ac8606Spatrick     llvm::PointerType *FpTy = FTy->getPointerTo();
4777a9ac8606Spatrick 
4778a9ac8606Spatrick     // extern "C" int __pt_atexit_np(int flags, int(*)(int,...), ...);
4779a9ac8606Spatrick     llvm::FunctionType *AtExitTy =
4780a9ac8606Spatrick         llvm::FunctionType::get(CGM.IntTy, {CGM.IntTy, FpTy}, true);
4781a9ac8606Spatrick 
4782a9ac8606Spatrick     // Fetch the actual function.
4783a9ac8606Spatrick     llvm::FunctionCallee AtExit =
4784a9ac8606Spatrick         CGM.CreateRuntimeFunction(AtExitTy, "__pt_atexit_np");
4785ec727ea7Spatrick 
4786ec727ea7Spatrick     // Create __dtor function for the var decl.
4787a9ac8606Spatrick     llvm::Function *DtorStub = CGF.createTLSAtExitStub(D, Dtor, Addr, AtExit);
4788ec727ea7Spatrick 
4789ec727ea7Spatrick     // Register above __dtor with atexit().
4790a9ac8606Spatrick     // First param is flags and must be 0, second param is function ptr
4791a9ac8606Spatrick     llvm::Value *NV = llvm::Constant::getNullValue(CGM.IntTy);
4792a9ac8606Spatrick     CGF.EmitNounwindRuntimeCall(AtExit, {NV, DtorStub});
4793a9ac8606Spatrick 
4794a9ac8606Spatrick     // Cannot unregister TLS __dtor so done
4795a9ac8606Spatrick     return;
4796a9ac8606Spatrick   }
4797a9ac8606Spatrick 
4798a9ac8606Spatrick   // Create __dtor function for the var decl.
4799a9ac8606Spatrick   llvm::Function *DtorStub = CGF.createAtExitStub(D, Dtor, Addr);
4800a9ac8606Spatrick 
4801a9ac8606Spatrick   // Register above __dtor with atexit().
4802a9ac8606Spatrick   CGF.registerGlobalDtorWithAtExit(DtorStub);
4803ec727ea7Spatrick 
4804ec727ea7Spatrick   // Emit __finalize function to unregister __dtor and (as appropriate) call
4805ec727ea7Spatrick   // __dtor.
4806a9ac8606Spatrick   emitCXXStermFinalizer(D, DtorStub, Addr);
4807ec727ea7Spatrick }
4808ec727ea7Spatrick 
emitCXXStermFinalizer(const VarDecl & D,llvm::Function * dtorStub,llvm::Constant * addr)4809ec727ea7Spatrick void XLCXXABI::emitCXXStermFinalizer(const VarDecl &D, llvm::Function *dtorStub,
4810ec727ea7Spatrick                                      llvm::Constant *addr) {
4811ec727ea7Spatrick   llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, false);
4812ec727ea7Spatrick   SmallString<256> FnName;
4813ec727ea7Spatrick   {
4814ec727ea7Spatrick     llvm::raw_svector_ostream Out(FnName);
4815ec727ea7Spatrick     getMangleContext().mangleDynamicStermFinalizer(&D, Out);
4816ec727ea7Spatrick   }
4817ec727ea7Spatrick 
4818ec727ea7Spatrick   // Create the finalization action associated with a variable.
4819ec727ea7Spatrick   const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
4820ec727ea7Spatrick   llvm::Function *StermFinalizer = CGM.CreateGlobalInitOrCleanUpFunction(
4821ec727ea7Spatrick       FTy, FnName.str(), FI, D.getLocation());
4822ec727ea7Spatrick 
4823ec727ea7Spatrick   CodeGenFunction CGF(CGM);
4824ec727ea7Spatrick 
4825ec727ea7Spatrick   CGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, StermFinalizer, FI,
4826a9ac8606Spatrick                     FunctionArgList(), D.getLocation(),
4827a9ac8606Spatrick                     D.getInit()->getExprLoc());
4828ec727ea7Spatrick 
4829ec727ea7Spatrick   // The unatexit subroutine unregisters __dtor functions that were previously
4830ec727ea7Spatrick   // registered by the atexit subroutine. If the referenced function is found,
4831ec727ea7Spatrick   // the unatexit returns a value of 0, meaning that the cleanup is still
4832ec727ea7Spatrick   // pending (and we should call the __dtor function).
4833ec727ea7Spatrick   llvm::Value *V = CGF.unregisterGlobalDtorWithUnAtExit(dtorStub);
4834ec727ea7Spatrick 
4835ec727ea7Spatrick   llvm::Value *NeedsDestruct = CGF.Builder.CreateIsNull(V, "needs_destruct");
4836ec727ea7Spatrick 
4837ec727ea7Spatrick   llvm::BasicBlock *DestructCallBlock = CGF.createBasicBlock("destruct.call");
4838ec727ea7Spatrick   llvm::BasicBlock *EndBlock = CGF.createBasicBlock("destruct.end");
4839ec727ea7Spatrick 
4840ec727ea7Spatrick   // Check if unatexit returns a value of 0. If it does, jump to
4841ec727ea7Spatrick   // DestructCallBlock, otherwise jump to EndBlock directly.
4842ec727ea7Spatrick   CGF.Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
4843ec727ea7Spatrick 
4844ec727ea7Spatrick   CGF.EmitBlock(DestructCallBlock);
4845ec727ea7Spatrick 
4846ec727ea7Spatrick   // Emit the call to dtorStub.
4847ec727ea7Spatrick   llvm::CallInst *CI = CGF.Builder.CreateCall(dtorStub);
4848ec727ea7Spatrick 
4849ec727ea7Spatrick   // Make sure the call and the callee agree on calling convention.
4850ec727ea7Spatrick   CI->setCallingConv(dtorStub->getCallingConv());
4851ec727ea7Spatrick 
4852ec727ea7Spatrick   CGF.EmitBlock(EndBlock);
4853ec727ea7Spatrick 
4854ec727ea7Spatrick   CGF.FinishFunction();
4855ec727ea7Spatrick 
4856a9ac8606Spatrick   if (auto *IPA = D.getAttr<InitPriorityAttr>()) {
4857a9ac8606Spatrick     CGM.AddCXXPrioritizedStermFinalizerEntry(StermFinalizer,
4858a9ac8606Spatrick                                              IPA->getPriority());
4859a9ac8606Spatrick   } else if (isTemplateInstantiation(D.getTemplateSpecializationKind()) ||
4860a9ac8606Spatrick              getContext().GetGVALinkageForVariable(&D) == GVA_DiscardableODR) {
4861a9ac8606Spatrick     // According to C++ [basic.start.init]p2, class template static data
4862a9ac8606Spatrick     // members (i.e., implicitly or explicitly instantiated specializations)
4863a9ac8606Spatrick     // have unordered initialization. As a consequence, we can put them into
4864a9ac8606Spatrick     // their own llvm.global_dtors entry.
4865a9ac8606Spatrick     CGM.AddCXXStermFinalizerToGlobalDtor(StermFinalizer, 65535);
4866a9ac8606Spatrick   } else {
4867ec727ea7Spatrick     CGM.AddCXXStermFinalizerEntry(StermFinalizer);
4868ec727ea7Spatrick   }
4869a9ac8606Spatrick }
4870