10b57cec5SDimitry Andric //===----- CGCXXABI.h - Interface to C++ ABIs -------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This provides an abstract class for C++ code generation. Concrete subclasses 100b57cec5SDimitry Andric // of this implement code generation for specific C++ ABIs. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CGCXXABI_H 150b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CGCXXABI_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "CodeGenFunction.h" 180b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 195ffd83dbSDimitry Andric #include "clang/CodeGen/CodeGenABITypes.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric class Constant; 230b57cec5SDimitry Andric class Type; 240b57cec5SDimitry Andric class Value; 250b57cec5SDimitry Andric class CallInst; 260b57cec5SDimitry Andric } 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace clang { 290b57cec5SDimitry Andric class CastExpr; 300b57cec5SDimitry Andric class CXXConstructorDecl; 310b57cec5SDimitry Andric class CXXDestructorDecl; 320b57cec5SDimitry Andric class CXXMethodDecl; 330b57cec5SDimitry Andric class CXXRecordDecl; 340b57cec5SDimitry Andric class MangleContext; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric namespace CodeGen { 370b57cec5SDimitry Andric class CGCallee; 380b57cec5SDimitry Andric class CodeGenFunction; 390b57cec5SDimitry Andric class CodeGenModule; 400b57cec5SDimitry Andric struct CatchTypeInfo; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric /// Implements C++ ABI-specific code generation functions. 430b57cec5SDimitry Andric class CGCXXABI { 44972a253aSDimitry Andric friend class CodeGenModule; 45972a253aSDimitry Andric 460b57cec5SDimitry Andric protected: 470b57cec5SDimitry Andric CodeGenModule &CGM; 480b57cec5SDimitry Andric std::unique_ptr<MangleContext> MangleCtx; 490b57cec5SDimitry Andric CGCXXABI(CodeGenModule & CGM)500b57cec5SDimitry Andric CGCXXABI(CodeGenModule &CGM) 510b57cec5SDimitry Andric : CGM(CGM), MangleCtx(CGM.getContext().createMangleContext()) {} 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric protected: getThisDecl(CodeGenFunction & CGF)540b57cec5SDimitry Andric ImplicitParamDecl *getThisDecl(CodeGenFunction &CGF) { 550b57cec5SDimitry Andric return CGF.CXXABIThisDecl; 560b57cec5SDimitry Andric } getThisValue(CodeGenFunction & CGF)570b57cec5SDimitry Andric llvm::Value *getThisValue(CodeGenFunction &CGF) { 580b57cec5SDimitry Andric return CGF.CXXABIThisValue; 590b57cec5SDimitry Andric } getThisAddress(CodeGenFunction & CGF)600b57cec5SDimitry Andric Address getThisAddress(CodeGenFunction &CGF) { 6181ad6265SDimitry Andric return Address( 6281ad6265SDimitry Andric CGF.CXXABIThisValue, 6381ad6265SDimitry Andric CGF.ConvertTypeForMem(CGF.CXXABIThisDecl->getType()->getPointeeType()), 6481ad6265SDimitry Andric CGF.CXXABIThisAlignment); 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric /// Issue a diagnostic about unsupported features in the ABI. 680b57cec5SDimitry Andric void ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric /// Get a null value for unsupported member pointers. 710b57cec5SDimitry Andric llvm::Constant *GetBogusMemberPointer(QualType T); 720b57cec5SDimitry Andric getStructorImplicitParamDecl(CodeGenFunction & CGF)730b57cec5SDimitry Andric ImplicitParamDecl *&getStructorImplicitParamDecl(CodeGenFunction &CGF) { 740b57cec5SDimitry Andric return CGF.CXXStructorImplicitParamDecl; 750b57cec5SDimitry Andric } getStructorImplicitParamValue(CodeGenFunction & CGF)760b57cec5SDimitry Andric llvm::Value *&getStructorImplicitParamValue(CodeGenFunction &CGF) { 770b57cec5SDimitry Andric return CGF.CXXStructorImplicitParamValue; 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /// Loads the incoming C++ this pointer as it was passed by the caller. 810b57cec5SDimitry Andric llvm::Value *loadIncomingCXXThis(CodeGenFunction &CGF); 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric void setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr); 840b57cec5SDimitry Andric getContext()850b57cec5SDimitry Andric ASTContext &getContext() const { return CGM.getContext(); } 860b57cec5SDimitry Andric 8704eeddc0SDimitry Andric bool mayNeedDestruction(const VarDecl *VD) const; 8804eeddc0SDimitry Andric 8904eeddc0SDimitry Andric /// Determine whether we will definitely emit this variable with a constant 9004eeddc0SDimitry Andric /// initializer, either because the language semantics demand it or because 9104eeddc0SDimitry Andric /// we know that the initializer is a constant. 9204eeddc0SDimitry Andric // For weak definitions, any initializer available in the current translation 9304eeddc0SDimitry Andric // is not necessarily reflective of the initializer used; such initializers 9404eeddc0SDimitry Andric // are ignored unless if InspectInitForWeakDef is true. 9504eeddc0SDimitry Andric bool 9604eeddc0SDimitry Andric isEmittedWithConstantInitializer(const VarDecl *VD, 9704eeddc0SDimitry Andric bool InspectInitForWeakDef = false) const; 9804eeddc0SDimitry Andric 990b57cec5SDimitry Andric virtual bool requiresArrayCookie(const CXXDeleteExpr *E, QualType eltType); 1000b57cec5SDimitry Andric virtual bool requiresArrayCookie(const CXXNewExpr *E); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric /// Determine whether there's something special about the rules of 1030b57cec5SDimitry Andric /// the ABI tell us that 'this' is a complete object within the 1040b57cec5SDimitry Andric /// given function. Obvious common logic like being defined on a 1050b57cec5SDimitry Andric /// final class will have been taken care of by the caller. 1060b57cec5SDimitry Andric virtual bool isThisCompleteObject(GlobalDecl GD) const = 0; 1070b57cec5SDimitry Andric constructorsAndDestructorsReturnThis()108bdd1243dSDimitry Andric virtual bool constructorsAndDestructorsReturnThis() const { 109bdd1243dSDimitry Andric return CGM.getCodeGenOpts().CtorDtorReturnThis; 110bdd1243dSDimitry Andric } 111bdd1243dSDimitry Andric 1120b57cec5SDimitry Andric public: 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric virtual ~CGCXXABI(); 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric /// Gets the mangle context. getMangleContext()1170b57cec5SDimitry Andric MangleContext &getMangleContext() { 1180b57cec5SDimitry Andric return *MangleCtx; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric /// Returns true if the given constructor or destructor is one of the 1220b57cec5SDimitry Andric /// kinds that the ABI says returns 'this' (only applies when called 1230b57cec5SDimitry Andric /// non-virtually for destructors). 1240b57cec5SDimitry Andric /// 1250b57cec5SDimitry Andric /// There currently is no way to indicate if a destructor returns 'this' 1260b57cec5SDimitry Andric /// when called virtually, and code generation does not support the case. HasThisReturn(GlobalDecl GD)127bdd1243dSDimitry Andric virtual bool HasThisReturn(GlobalDecl GD) const { 128bdd1243dSDimitry Andric if (isa<CXXConstructorDecl>(GD.getDecl()) || 129bdd1243dSDimitry Andric (isa<CXXDestructorDecl>(GD.getDecl()) && 130bdd1243dSDimitry Andric GD.getDtorType() != Dtor_Deleting)) 131bdd1243dSDimitry Andric return constructorsAndDestructorsReturnThis(); 132bdd1243dSDimitry Andric return false; 133bdd1243dSDimitry Andric } 1340b57cec5SDimitry Andric hasMostDerivedReturn(GlobalDecl GD)1350b57cec5SDimitry Andric virtual bool hasMostDerivedReturn(GlobalDecl GD) const { return false; } 1360b57cec5SDimitry Andric useSinitAndSterm()1375ffd83dbSDimitry Andric virtual bool useSinitAndSterm() const { return false; } 1385ffd83dbSDimitry Andric 1390b57cec5SDimitry Andric /// Returns true if the target allows calling a function through a pointer 1400b57cec5SDimitry Andric /// with a different signature than the actual function (or equivalently, 1410b57cec5SDimitry Andric /// bitcasting a function or function pointer to a different function type). 1420b57cec5SDimitry Andric /// In principle in the most general case this could depend on the target, the 1430b57cec5SDimitry Andric /// calling convention, and the actual types of the arguments and return 1440b57cec5SDimitry Andric /// value. Here it just means whether the signature mismatch could *ever* be 1450b57cec5SDimitry Andric /// allowed; in other words, does the target do strict checking of signatures 1460b57cec5SDimitry Andric /// for all calls. canCallMismatchedFunctionType()1470b57cec5SDimitry Andric virtual bool canCallMismatchedFunctionType() const { return true; } 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric /// If the C++ ABI requires the given type be returned in a particular way, 1500b57cec5SDimitry Andric /// this method sets RetAI and returns true. 1510b57cec5SDimitry Andric virtual bool classifyReturnType(CGFunctionInfo &FI) const = 0; 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric /// Specify how one should pass an argument of a record type. 1540b57cec5SDimitry Andric enum RecordArgABI { 1550b57cec5SDimitry Andric /// Pass it using the normal C aggregate rules for the ABI, potentially 1560b57cec5SDimitry Andric /// introducing extra copies and passing some or all of it in registers. 1570b57cec5SDimitry Andric RAA_Default = 0, 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric /// Pass it on the stack using its defined layout. The argument must be 1600b57cec5SDimitry Andric /// evaluated directly into the correct stack position in the arguments area, 1610b57cec5SDimitry Andric /// and the call machinery must not move it or introduce extra copies. 1620b57cec5SDimitry Andric RAA_DirectInMemory, 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric /// Pass it as a pointer to temporary memory. 1650b57cec5SDimitry Andric RAA_Indirect 1660b57cec5SDimitry Andric }; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric /// Returns how an argument of the given record type should be passed. 1690b57cec5SDimitry Andric virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const = 0; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric /// Returns true if the implicit 'sret' parameter comes after the implicit 1720b57cec5SDimitry Andric /// 'this' parameter of C++ instance methods. isSRetParameterAfterThis()1730b57cec5SDimitry Andric virtual bool isSRetParameterAfterThis() const { return false; } 1740b57cec5SDimitry Andric 175e8d8bef9SDimitry Andric /// Returns true if the ABI permits the argument to be a homogeneous 176e8d8bef9SDimitry Andric /// aggregate. 177e8d8bef9SDimitry Andric virtual bool isPermittedToBeHomogeneousAggregate(const CXXRecordDecl * RD)178e8d8bef9SDimitry Andric isPermittedToBeHomogeneousAggregate(const CXXRecordDecl *RD) const { 179e8d8bef9SDimitry Andric return true; 180e8d8bef9SDimitry Andric }; 181e8d8bef9SDimitry Andric 1820b57cec5SDimitry Andric /// Find the LLVM type used to represent the given member pointer 1830b57cec5SDimitry Andric /// type. 1840b57cec5SDimitry Andric virtual llvm::Type * 1850b57cec5SDimitry Andric ConvertMemberPointerType(const MemberPointerType *MPT); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric /// Load a member function from an object and a member function 1880b57cec5SDimitry Andric /// pointer. Apply the this-adjustment and set 'This' to the 1890b57cec5SDimitry Andric /// adjusted value. 1900b57cec5SDimitry Andric virtual CGCallee EmitLoadOfMemberFunctionPointer( 1910b57cec5SDimitry Andric CodeGenFunction &CGF, const Expr *E, Address This, 1920b57cec5SDimitry Andric llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr, 1930b57cec5SDimitry Andric const MemberPointerType *MPT); 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric /// Calculate an l-value from an object and a data member pointer. 1960b57cec5SDimitry Andric virtual llvm::Value * 1970b57cec5SDimitry Andric EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, 1980b57cec5SDimitry Andric Address Base, llvm::Value *MemPtr, 1990b57cec5SDimitry Andric const MemberPointerType *MPT); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric /// Perform a derived-to-base, base-to-derived, or bitcast member 2020b57cec5SDimitry Andric /// pointer conversion. 2030b57cec5SDimitry Andric virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF, 2040b57cec5SDimitry Andric const CastExpr *E, 2050b57cec5SDimitry Andric llvm::Value *Src); 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric /// Perform a derived-to-base, base-to-derived, or bitcast member 2080b57cec5SDimitry Andric /// pointer conversion on a constant value. 2090b57cec5SDimitry Andric virtual llvm::Constant *EmitMemberPointerConversion(const CastExpr *E, 2100b57cec5SDimitry Andric llvm::Constant *Src); 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric /// Return true if the given member pointer can be zero-initialized 2130b57cec5SDimitry Andric /// (in the C++ sense) with an LLVM zeroinitializer. 2140b57cec5SDimitry Andric virtual bool isZeroInitializable(const MemberPointerType *MPT); 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric /// Return whether or not a member pointers type is convertible to an IR type. isMemberPointerConvertible(const MemberPointerType * MPT)2170b57cec5SDimitry Andric virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const { 2180b57cec5SDimitry Andric return true; 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric /// Create a null member pointer of the given type. 2220b57cec5SDimitry Andric virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT); 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric /// Create a member pointer for the given method. 2250b57cec5SDimitry Andric virtual llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD); 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric /// Create a member pointer for the given field. 2280b57cec5SDimitry Andric virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT, 2290b57cec5SDimitry Andric CharUnits offset); 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric /// Create a member pointer for the given member pointer constant. 2320b57cec5SDimitry Andric virtual llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT); 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric /// Emit a comparison between two member pointers. Returns an i1. 2350b57cec5SDimitry Andric virtual llvm::Value * 2360b57cec5SDimitry Andric EmitMemberPointerComparison(CodeGenFunction &CGF, 2370b57cec5SDimitry Andric llvm::Value *L, 2380b57cec5SDimitry Andric llvm::Value *R, 2390b57cec5SDimitry Andric const MemberPointerType *MPT, 2400b57cec5SDimitry Andric bool Inequality); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric /// Determine if a member pointer is non-null. Returns an i1. 2430b57cec5SDimitry Andric virtual llvm::Value * 2440b57cec5SDimitry Andric EmitMemberPointerIsNotNull(CodeGenFunction &CGF, 2450b57cec5SDimitry Andric llvm::Value *MemPtr, 2460b57cec5SDimitry Andric const MemberPointerType *MPT); 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric protected: 2490b57cec5SDimitry Andric /// A utility method for computing the offset required for the given 2500b57cec5SDimitry Andric /// base-to-derived or derived-to-base member-pointer conversion. 2510b57cec5SDimitry Andric /// Does not handle virtual conversions (in case we ever fully 2520b57cec5SDimitry Andric /// support an ABI that allows this). Returns null if no adjustment 2530b57cec5SDimitry Andric /// is required. 2540b57cec5SDimitry Andric llvm::Constant *getMemberPointerAdjustment(const CastExpr *E); 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric public: 2570b57cec5SDimitry Andric virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, 2580b57cec5SDimitry Andric const CXXDeleteExpr *DE, 2590b57cec5SDimitry Andric Address Ptr, QualType ElementType, 2600b57cec5SDimitry Andric const CXXDestructorDecl *Dtor) = 0; 2610b57cec5SDimitry Andric virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) = 0; 2620b57cec5SDimitry Andric virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) = 0; getThrowInfo(QualType T)2630b57cec5SDimitry Andric virtual llvm::GlobalVariable *getThrowInfo(QualType T) { return nullptr; } 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric /// Determine whether it's possible to emit a vtable for \p RD, even 2660b57cec5SDimitry Andric /// though we do not know that the vtable has been marked as used by semantic 2670b57cec5SDimitry Andric /// analysis. 2680b57cec5SDimitry Andric virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const = 0; 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) = 0; 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric virtual llvm::CallInst * 2730b57cec5SDimitry Andric emitTerminateForUnexpectedException(CodeGenFunction &CGF, 2740b57cec5SDimitry Andric llvm::Value *Exn); 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0; 2770b57cec5SDimitry Andric virtual CatchTypeInfo 2780b57cec5SDimitry Andric getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) = 0; 2790b57cec5SDimitry Andric virtual CatchTypeInfo getCatchAllTypeInfo(); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric virtual bool shouldTypeidBeNullChecked(bool IsDeref, 2820b57cec5SDimitry Andric QualType SrcRecordTy) = 0; 2830b57cec5SDimitry Andric virtual void EmitBadTypeidCall(CodeGenFunction &CGF) = 0; 2840b57cec5SDimitry Andric virtual llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, 2850b57cec5SDimitry Andric Address ThisPtr, 2860b57cec5SDimitry Andric llvm::Type *StdTypeInfoPtrTy) = 0; 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, 2890b57cec5SDimitry Andric QualType SrcRecordTy) = 0; 29006c3fb27SDimitry Andric virtual bool shouldEmitExactDynamicCast(QualType DestRecordTy) = 0; 2910b57cec5SDimitry Andric 29206c3fb27SDimitry Andric virtual llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address Value, 2930b57cec5SDimitry Andric QualType SrcRecordTy, 29406c3fb27SDimitry Andric QualType DestTy, 29506c3fb27SDimitry Andric QualType DestRecordTy, 29606c3fb27SDimitry Andric llvm::BasicBlock *CastEnd) = 0; 29706c3fb27SDimitry Andric 29806c3fb27SDimitry Andric virtual llvm::Value *emitDynamicCastToVoid(CodeGenFunction &CGF, 29906c3fb27SDimitry Andric Address Value, 30006c3fb27SDimitry Andric QualType SrcRecordTy) = 0; 30106c3fb27SDimitry Andric 30206c3fb27SDimitry Andric /// Emit a dynamic_cast from SrcRecordTy to DestRecordTy. The cast fails if 30306c3fb27SDimitry Andric /// the dynamic type of Value is not exactly DestRecordTy. 30406c3fb27SDimitry Andric virtual llvm::Value *emitExactDynamicCast(CodeGenFunction &CGF, Address Value, 30506c3fb27SDimitry Andric QualType SrcRecordTy, 30606c3fb27SDimitry Andric QualType DestTy, 30706c3fb27SDimitry Andric QualType DestRecordTy, 30806c3fb27SDimitry Andric llvm::BasicBlock *CastSuccess, 30906c3fb27SDimitry Andric llvm::BasicBlock *CastFail) = 0; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric virtual bool EmitBadCastCall(CodeGenFunction &CGF) = 0; 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric virtual llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF, 3140b57cec5SDimitry Andric Address This, 3150b57cec5SDimitry Andric const CXXRecordDecl *ClassDecl, 3160b57cec5SDimitry Andric const CXXRecordDecl *BaseClassDecl) = 0; 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric virtual llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, 3190b57cec5SDimitry Andric const CXXRecordDecl *RD); 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric /// Emit the code to initialize hidden members required 3220b57cec5SDimitry Andric /// to handle virtual inheritance, if needed by the ABI. 3230b57cec5SDimitry Andric virtual void initializeHiddenVirtualInheritanceMembers(CodeGenFunction & CGF,const CXXRecordDecl * RD)3240b57cec5SDimitry Andric initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, 3250b57cec5SDimitry Andric const CXXRecordDecl *RD) {} 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric /// Emit constructor variants required by this ABI. 3280b57cec5SDimitry Andric virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0; 3290b57cec5SDimitry Andric 3305ffd83dbSDimitry Andric /// Additional implicit arguments to add to the beginning (Prefix) and end 3315ffd83dbSDimitry Andric /// (Suffix) of a constructor / destructor arg list. 3320b57cec5SDimitry Andric /// 3335ffd83dbSDimitry Andric /// Note that Prefix should actually be inserted *after* the first existing 3345ffd83dbSDimitry Andric /// arg; `this` arguments always come first. 3350b57cec5SDimitry Andric struct AddedStructorArgs { 3365ffd83dbSDimitry Andric struct Arg { 3375ffd83dbSDimitry Andric llvm::Value *Value; 3385ffd83dbSDimitry Andric QualType Type; 3395ffd83dbSDimitry Andric }; 3405ffd83dbSDimitry Andric SmallVector<Arg, 1> Prefix; 3415ffd83dbSDimitry Andric SmallVector<Arg, 1> Suffix; 3425ffd83dbSDimitry Andric AddedStructorArgs() = default; AddedStructorArgsAddedStructorArgs3435ffd83dbSDimitry Andric AddedStructorArgs(SmallVector<Arg, 1> P, SmallVector<Arg, 1> S) 3445ffd83dbSDimitry Andric : Prefix(std::move(P)), Suffix(std::move(S)) {} prefixAddedStructorArgs3455ffd83dbSDimitry Andric static AddedStructorArgs prefix(SmallVector<Arg, 1> Args) { 3465ffd83dbSDimitry Andric return {std::move(Args), {}}; 3475ffd83dbSDimitry Andric } suffixAddedStructorArgs3485ffd83dbSDimitry Andric static AddedStructorArgs suffix(SmallVector<Arg, 1> Args) { 3495ffd83dbSDimitry Andric return {{}, std::move(Args)}; 3505ffd83dbSDimitry Andric } 3515ffd83dbSDimitry Andric }; 3525ffd83dbSDimitry Andric 3535ffd83dbSDimitry Andric /// Similar to AddedStructorArgs, but only notes the number of additional 3545ffd83dbSDimitry Andric /// arguments. 3555ffd83dbSDimitry Andric struct AddedStructorArgCounts { 3560b57cec5SDimitry Andric unsigned Prefix = 0; 3570b57cec5SDimitry Andric unsigned Suffix = 0; 3585ffd83dbSDimitry Andric AddedStructorArgCounts() = default; AddedStructorArgCountsAddedStructorArgCounts3595ffd83dbSDimitry Andric AddedStructorArgCounts(unsigned P, unsigned S) : Prefix(P), Suffix(S) {} prefixAddedStructorArgCounts3605ffd83dbSDimitry Andric static AddedStructorArgCounts prefix(unsigned N) { return {N, 0}; } suffixAddedStructorArgCounts3615ffd83dbSDimitry Andric static AddedStructorArgCounts suffix(unsigned N) { return {0, N}; } 3620b57cec5SDimitry Andric }; 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric /// Build the signature of the given constructor or destructor variant by 3650b57cec5SDimitry Andric /// adding any required parameters. For convenience, ArgTys has been 3660b57cec5SDimitry Andric /// initialized with the type of 'this'. 3675ffd83dbSDimitry Andric virtual AddedStructorArgCounts 3680b57cec5SDimitry Andric buildStructorSignature(GlobalDecl GD, 3690b57cec5SDimitry Andric SmallVectorImpl<CanQualType> &ArgTys) = 0; 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric /// Returns true if the given destructor type should be emitted as a linkonce 3720b57cec5SDimitry Andric /// delegating thunk, regardless of whether the dtor is defined in this TU or 3730b57cec5SDimitry Andric /// not. 3740b57cec5SDimitry Andric virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, 3750b57cec5SDimitry Andric CXXDtorType DT) const = 0; 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric virtual void setCXXDestructorDLLStorage(llvm::GlobalValue *GV, 3780b57cec5SDimitry Andric const CXXDestructorDecl *Dtor, 3790b57cec5SDimitry Andric CXXDtorType DT) const; 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric virtual llvm::GlobalValue::LinkageTypes 3820b57cec5SDimitry Andric getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor, 3830b57cec5SDimitry Andric CXXDtorType DT) const; 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric /// Emit destructor variants required by this ABI. 3860b57cec5SDimitry Andric virtual void EmitCXXDestructors(const CXXDestructorDecl *D) = 0; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric /// Get the type of the implicit "this" parameter used by a method. May return 3890b57cec5SDimitry Andric /// zero if no specific type is applicable, e.g. if the ABI expects the "this" 3900b57cec5SDimitry Andric /// parameter to point to some artificial offset in a complete object due to 3910b57cec5SDimitry Andric /// vbases being reordered. getThisArgumentTypeForMethod(GlobalDecl GD)3921ac55f4cSDimitry Andric virtual const CXXRecordDecl *getThisArgumentTypeForMethod(GlobalDecl GD) { 3931ac55f4cSDimitry Andric return cast<CXXMethodDecl>(GD.getDecl())->getParent(); 3940b57cec5SDimitry Andric } 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric /// Perform ABI-specific "this" argument adjustment required prior to 3970b57cec5SDimitry Andric /// a call of a virtual function. 3980b57cec5SDimitry Andric /// The "VirtualCall" argument is true iff the call itself is virtual. 3990b57cec5SDimitry Andric virtual Address adjustThisArgumentForVirtualFunctionCall(CodeGenFunction & CGF,GlobalDecl GD,Address This,bool VirtualCall)4000b57cec5SDimitry Andric adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD, 4010b57cec5SDimitry Andric Address This, bool VirtualCall) { 4020b57cec5SDimitry Andric return This; 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric /// Build a parameter variable suitable for 'this'. 4060b57cec5SDimitry Andric void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params); 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric /// Insert any ABI-specific implicit parameters into the parameter list for a 4090b57cec5SDimitry Andric /// function. This generally involves extra data for constructors and 4100b57cec5SDimitry Andric /// destructors. 4110b57cec5SDimitry Andric /// 4120b57cec5SDimitry Andric /// ABIs may also choose to override the return type, which has been 4130b57cec5SDimitry Andric /// initialized with the type of 'this' if HasThisReturn(CGF.CurGD) is true or 4140b57cec5SDimitry Andric /// the formal return type of the function otherwise. 4150b57cec5SDimitry Andric virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, 4160b57cec5SDimitry Andric FunctionArgList &Params) = 0; 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric /// Get the ABI-specific "this" parameter adjustment to apply in the prologue 4190b57cec5SDimitry Andric /// of a virtual function. getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)4200b57cec5SDimitry Andric virtual CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) { 4210b57cec5SDimitry Andric return CharUnits::Zero(); 4220b57cec5SDimitry Andric } 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric /// Emit the ABI-specific prolog for the function. 4250b57cec5SDimitry Andric virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0; 4260b57cec5SDimitry Andric 4275ffd83dbSDimitry Andric virtual AddedStructorArgs 4285ffd83dbSDimitry Andric getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, 4295ffd83dbSDimitry Andric CXXCtorType Type, bool ForVirtualBase, 4305ffd83dbSDimitry Andric bool Delegating) = 0; 4315ffd83dbSDimitry Andric 4320b57cec5SDimitry Andric /// Add any ABI-specific implicit arguments needed to call a constructor. 4330b57cec5SDimitry Andric /// 4340b57cec5SDimitry Andric /// \return The number of arguments added at the beginning and end of the 4350b57cec5SDimitry Andric /// call, which is typically zero or one. 4365ffd83dbSDimitry Andric AddedStructorArgCounts 4370b57cec5SDimitry Andric addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, 4380b57cec5SDimitry Andric CXXCtorType Type, bool ForVirtualBase, 4395ffd83dbSDimitry Andric bool Delegating, CallArgList &Args); 4405ffd83dbSDimitry Andric 4415ffd83dbSDimitry Andric /// Get the implicit (second) parameter that comes after the "this" pointer, 4425ffd83dbSDimitry Andric /// or nullptr if there is isn't one. 4435ffd83dbSDimitry Andric virtual llvm::Value * 4445ffd83dbSDimitry Andric getCXXDestructorImplicitParam(CodeGenFunction &CGF, 4455ffd83dbSDimitry Andric const CXXDestructorDecl *DD, CXXDtorType Type, 4465ffd83dbSDimitry Andric bool ForVirtualBase, bool Delegating) = 0; 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric /// Emit the destructor call. 4490b57cec5SDimitry Andric virtual void EmitDestructorCall(CodeGenFunction &CGF, 4500b57cec5SDimitry Andric const CXXDestructorDecl *DD, CXXDtorType Type, 4510b57cec5SDimitry Andric bool ForVirtualBase, bool Delegating, 4520b57cec5SDimitry Andric Address This, QualType ThisTy) = 0; 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric /// Emits the VTable definitions required for the given record type. 4550b57cec5SDimitry Andric virtual void emitVTableDefinitions(CodeGenVTables &CGVT, 4560b57cec5SDimitry Andric const CXXRecordDecl *RD) = 0; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric /// Checks if ABI requires extra virtual offset for vtable field. 4590b57cec5SDimitry Andric virtual bool 4600b57cec5SDimitry Andric isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, 4610b57cec5SDimitry Andric CodeGenFunction::VPtr Vptr) = 0; 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric /// Checks if ABI requires to initialize vptrs for given dynamic class. 4640b57cec5SDimitry Andric virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) = 0; 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric /// Get the address point of the vtable for the given base subobject. 4670b57cec5SDimitry Andric virtual llvm::Constant * 4680b57cec5SDimitry Andric getVTableAddressPoint(BaseSubobject Base, 4690b57cec5SDimitry Andric const CXXRecordDecl *VTableClass) = 0; 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric /// Get the address point of the vtable for the given base subobject while 4720b57cec5SDimitry Andric /// building a constructor or a destructor. 4730b57cec5SDimitry Andric virtual llvm::Value * 4740b57cec5SDimitry Andric getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, 4750b57cec5SDimitry Andric BaseSubobject Base, 4760b57cec5SDimitry Andric const CXXRecordDecl *NearestVBase) = 0; 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric /// Get the address point of the vtable for the given base subobject while 4790b57cec5SDimitry Andric /// building a constexpr. 4800b57cec5SDimitry Andric virtual llvm::Constant * 4810b57cec5SDimitry Andric getVTableAddressPointForConstExpr(BaseSubobject Base, 4820b57cec5SDimitry Andric const CXXRecordDecl *VTableClass) = 0; 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric /// Get the address of the vtable for the given record decl which should be 4850b57cec5SDimitry Andric /// used for the vptr at the given offset in RD. 4860b57cec5SDimitry Andric virtual llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD, 4870b57cec5SDimitry Andric CharUnits VPtrOffset) = 0; 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric /// Build a virtual function pointer in the ABI-specific way. 4900b57cec5SDimitry Andric virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, 4910b57cec5SDimitry Andric GlobalDecl GD, Address This, 4920b57cec5SDimitry Andric llvm::Type *Ty, 4930b57cec5SDimitry Andric SourceLocation Loc) = 0; 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric using DeleteOrMemberCallExpr = 4960b57cec5SDimitry Andric llvm::PointerUnion<const CXXDeleteExpr *, const CXXMemberCallExpr *>; 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric /// Emit the ABI-specific virtual destructor call. 4990b57cec5SDimitry Andric virtual llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF, 5000b57cec5SDimitry Andric const CXXDestructorDecl *Dtor, 5010b57cec5SDimitry Andric CXXDtorType DtorType, 5020b57cec5SDimitry Andric Address This, 5030b57cec5SDimitry Andric DeleteOrMemberCallExpr E) = 0; 5040b57cec5SDimitry Andric adjustCallArgsForDestructorThunk(CodeGenFunction & CGF,GlobalDecl GD,CallArgList & CallArgs)5050b57cec5SDimitry Andric virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, 5060b57cec5SDimitry Andric GlobalDecl GD, 5070b57cec5SDimitry Andric CallArgList &CallArgs) {} 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andric /// Emit any tables needed to implement virtual inheritance. For Itanium, 5100b57cec5SDimitry Andric /// this emits virtual table tables. For the MSVC++ ABI, this emits virtual 5110b57cec5SDimitry Andric /// base tables. 5120b57cec5SDimitry Andric virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0; 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric virtual bool exportThunk() = 0; 5150b57cec5SDimitry Andric virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, 5160b57cec5SDimitry Andric GlobalDecl GD, bool ReturnAdjustment) = 0; 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric virtual llvm::Value *performThisAdjustment(CodeGenFunction &CGF, 5190b57cec5SDimitry Andric Address This, 5200b57cec5SDimitry Andric const ThisAdjustment &TA) = 0; 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric virtual llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, 5230b57cec5SDimitry Andric Address Ret, 5240b57cec5SDimitry Andric const ReturnAdjustment &RA) = 0; 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric virtual void EmitReturnFromThunk(CodeGenFunction &CGF, 5270b57cec5SDimitry Andric RValue RV, QualType ResultType); 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, 5300b57cec5SDimitry Andric FunctionArgList &Args) const = 0; 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric /// Gets the offsets of all the virtual base pointers in a given class. 5330b57cec5SDimitry Andric virtual std::vector<CharUnits> getVBPtrOffsets(const CXXRecordDecl *RD); 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric /// Gets the pure virtual member call function. 5360b57cec5SDimitry Andric virtual StringRef GetPureVirtualCallName() = 0; 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric /// Gets the deleted virtual member call name. 5390b57cec5SDimitry Andric virtual StringRef GetDeletedVirtualCallName() = 0; 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric /**************************** Array cookies ******************************/ 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric /// Returns the extra size required in order to store the array 5440b57cec5SDimitry Andric /// cookie for the given new-expression. May return 0 to indicate that no 5450b57cec5SDimitry Andric /// array cookie is required. 5460b57cec5SDimitry Andric /// 5470b57cec5SDimitry Andric /// Several cases are filtered out before this method is called: 5480b57cec5SDimitry Andric /// - non-array allocations never need a cookie 5490b57cec5SDimitry Andric /// - calls to \::operator new(size_t, void*) never need a cookie 5500b57cec5SDimitry Andric /// 5510b57cec5SDimitry Andric /// \param expr - the new-expression being allocated. 5520b57cec5SDimitry Andric virtual CharUnits GetArrayCookieSize(const CXXNewExpr *expr); 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric /// Initialize the array cookie for the given allocation. 5550b57cec5SDimitry Andric /// 5560b57cec5SDimitry Andric /// \param NewPtr - a char* which is the presumed-non-null 5570b57cec5SDimitry Andric /// return value of the allocation function 5580b57cec5SDimitry Andric /// \param NumElements - the computed number of elements, 5590b57cec5SDimitry Andric /// potentially collapsed from the multidimensional array case; 5600b57cec5SDimitry Andric /// always a size_t 5610b57cec5SDimitry Andric /// \param ElementType - the base element allocated type, 5620b57cec5SDimitry Andric /// i.e. the allocated type after stripping all array types 5630b57cec5SDimitry Andric virtual Address InitializeArrayCookie(CodeGenFunction &CGF, 5640b57cec5SDimitry Andric Address NewPtr, 5650b57cec5SDimitry Andric llvm::Value *NumElements, 5660b57cec5SDimitry Andric const CXXNewExpr *expr, 5670b57cec5SDimitry Andric QualType ElementType); 5680b57cec5SDimitry Andric 5690b57cec5SDimitry Andric /// Reads the array cookie associated with the given pointer, 5700b57cec5SDimitry Andric /// if it has one. 5710b57cec5SDimitry Andric /// 5720b57cec5SDimitry Andric /// \param Ptr - a pointer to the first element in the array 5730b57cec5SDimitry Andric /// \param ElementType - the base element type of elements of the array 5740b57cec5SDimitry Andric /// \param NumElements - an out parameter which will be initialized 5750b57cec5SDimitry Andric /// with the number of elements allocated, or zero if there is no 5760b57cec5SDimitry Andric /// cookie 5770b57cec5SDimitry Andric /// \param AllocPtr - an out parameter which will be initialized 5780b57cec5SDimitry Andric /// with a char* pointing to the address returned by the allocation 5790b57cec5SDimitry Andric /// function 5800b57cec5SDimitry Andric /// \param CookieSize - an out parameter which will be initialized 5810b57cec5SDimitry Andric /// with the size of the cookie, or zero if there is no cookie 5820b57cec5SDimitry Andric virtual void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr, 5830b57cec5SDimitry Andric const CXXDeleteExpr *expr, 5840b57cec5SDimitry Andric QualType ElementType, llvm::Value *&NumElements, 5850b57cec5SDimitry Andric llvm::Value *&AllocPtr, CharUnits &CookieSize); 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric /// Return whether the given global decl needs a VTT parameter. 5880b57cec5SDimitry Andric virtual bool NeedsVTTParameter(GlobalDecl GD); 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric protected: 5910b57cec5SDimitry Andric /// Returns the extra size required in order to store the array 5920b57cec5SDimitry Andric /// cookie for the given type. Assumes that an array cookie is 5930b57cec5SDimitry Andric /// required. 5940b57cec5SDimitry Andric virtual CharUnits getArrayCookieSizeImpl(QualType elementType); 5950b57cec5SDimitry Andric 5960b57cec5SDimitry Andric /// Reads the array cookie for an allocation which is known to have one. 5970b57cec5SDimitry Andric /// This is called by the standard implementation of ReadArrayCookie. 5980b57cec5SDimitry Andric /// 5990b57cec5SDimitry Andric /// \param ptr - a pointer to the allocation made for an array, as a char* 6000b57cec5SDimitry Andric /// \param cookieSize - the computed cookie size of an array 6010b57cec5SDimitry Andric /// 6020b57cec5SDimitry Andric /// Other parameters are as above. 6030b57cec5SDimitry Andric /// 6040b57cec5SDimitry Andric /// \return a size_t 6050b57cec5SDimitry Andric virtual llvm::Value *readArrayCookieImpl(CodeGenFunction &IGF, Address ptr, 6060b57cec5SDimitry Andric CharUnits cookieSize); 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric public: 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric /*************************** Static local guards ****************************/ 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric /// Emits the guarded initializer and destructor setup for the given 6130b57cec5SDimitry Andric /// variable, given that it couldn't be emitted as a constant. 6140b57cec5SDimitry Andric /// If \p PerformInit is false, the initialization has been folded to a 6150b57cec5SDimitry Andric /// constant and should not be performed. 6160b57cec5SDimitry Andric /// 6170b57cec5SDimitry Andric /// The variable may be: 6180b57cec5SDimitry Andric /// - a static local variable 6190b57cec5SDimitry Andric /// - a static data member of a class template instantiation 6200b57cec5SDimitry Andric virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, 6210b57cec5SDimitry Andric llvm::GlobalVariable *DeclPtr, 6220b57cec5SDimitry Andric bool PerformInit) = 0; 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric /// Emit code to force the execution of a destructor during global 6250b57cec5SDimitry Andric /// teardown. The default implementation of this uses atexit. 6260b57cec5SDimitry Andric /// 6270b57cec5SDimitry Andric /// \param Dtor - a function taking a single pointer argument 6280b57cec5SDimitry Andric /// \param Addr - a pointer to pass to the destructor function. 6290b57cec5SDimitry Andric virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, 6300b57cec5SDimitry Andric llvm::FunctionCallee Dtor, 6310b57cec5SDimitry Andric llvm::Constant *Addr) = 0; 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric /*************************** thread_local initialization ********************/ 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric /// Emits ABI-required functions necessary to initialize thread_local 6360b57cec5SDimitry Andric /// variables in this translation unit. 6370b57cec5SDimitry Andric /// 6380b57cec5SDimitry Andric /// \param CXXThreadLocals - The thread_local declarations in this translation 6390b57cec5SDimitry Andric /// unit. 6400b57cec5SDimitry Andric /// \param CXXThreadLocalInits - If this translation unit contains any 6410b57cec5SDimitry Andric /// non-constant initialization or non-trivial destruction for 6420b57cec5SDimitry Andric /// thread_local variables, a list of functions to perform the 6430b57cec5SDimitry Andric /// initialization. 6440b57cec5SDimitry Andric virtual void EmitThreadLocalInitFuncs( 6450b57cec5SDimitry Andric CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals, 6460b57cec5SDimitry Andric ArrayRef<llvm::Function *> CXXThreadLocalInits, 6470b57cec5SDimitry Andric ArrayRef<const VarDecl *> CXXThreadLocalInitVars) = 0; 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric // Determine if references to thread_local global variables can be made 6500b57cec5SDimitry Andric // directly or require access through a thread wrapper function. 651a7dea167SDimitry Andric virtual bool usesThreadWrapperFunction(const VarDecl *VD) const = 0; 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric /// Emit a reference to a non-local thread_local variable (including 6540b57cec5SDimitry Andric /// triggering the initialization of all thread_local variables in its 6550b57cec5SDimitry Andric /// translation unit). 6560b57cec5SDimitry Andric virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, 6570b57cec5SDimitry Andric const VarDecl *VD, 6580b57cec5SDimitry Andric QualType LValType) = 0; 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric /// Emit a single constructor/destructor with the given type from a C++ 6610b57cec5SDimitry Andric /// constructor Decl. 6620b57cec5SDimitry Andric virtual void emitCXXStructor(GlobalDecl GD) = 0; 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric /// Load a vtable from This, an object of polymorphic type RD, or from one of 6650b57cec5SDimitry Andric /// its virtual bases if it does not have its own vtable. Returns the vtable 6660b57cec5SDimitry Andric /// and the class from which the vtable was loaded. 6670b57cec5SDimitry Andric virtual std::pair<llvm::Value *, const CXXRecordDecl *> 6680b57cec5SDimitry Andric LoadVTablePtr(CodeGenFunction &CGF, Address This, 6690b57cec5SDimitry Andric const CXXRecordDecl *RD) = 0; 6700b57cec5SDimitry Andric }; 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric // Create an instance of a C++ ABI class: 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric /// Creates an Itanium-family ABI. 6750b57cec5SDimitry Andric CGCXXABI *CreateItaniumCXXABI(CodeGenModule &CGM); 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric /// Creates a Microsoft-family ABI. 6780b57cec5SDimitry Andric CGCXXABI *CreateMicrosoftCXXABI(CodeGenModule &CGM); 6790b57cec5SDimitry Andric 6800b57cec5SDimitry Andric struct CatchRetScope final : EHScopeStack::Cleanup { 6810b57cec5SDimitry Andric llvm::CatchPadInst *CPI; 6820b57cec5SDimitry Andric CatchRetScopefinal6830b57cec5SDimitry Andric CatchRetScope(llvm::CatchPadInst *CPI) : CPI(CPI) {} 6840b57cec5SDimitry Andric Emitfinal6850b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override { 6860b57cec5SDimitry Andric llvm::BasicBlock *BB = CGF.createBasicBlock("catchret.dest"); 6870b57cec5SDimitry Andric CGF.Builder.CreateCatchRet(CPI, BB); 6880b57cec5SDimitry Andric CGF.EmitBlock(BB); 6890b57cec5SDimitry Andric } 6900b57cec5SDimitry Andric }; 6910b57cec5SDimitry Andric } 6920b57cec5SDimitry Andric } 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric #endif 695