123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684 |
- //===----- CGCXXABI.h - Interface to C++ ABIs -------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This provides an abstract class for C++ code generation. Concrete subclasses
- // of this implement code generation for specific C++ ABIs.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_LIB_CODEGEN_CGCXXABI_H
- #define LLVM_CLANG_LIB_CODEGEN_CGCXXABI_H
- #include "CodeGenFunction.h"
- #include "clang/Basic/LLVM.h"
- #include "clang/CodeGen/CodeGenABITypes.h"
- namespace llvm {
- class Constant;
- class Type;
- class Value;
- class CallInst;
- }
- namespace clang {
- class CastExpr;
- class CXXConstructorDecl;
- class CXXDestructorDecl;
- class CXXMethodDecl;
- class CXXRecordDecl;
- class MangleContext;
- namespace CodeGen {
- class CGCallee;
- class CodeGenFunction;
- class CodeGenModule;
- struct CatchTypeInfo;
- /// Implements C++ ABI-specific code generation functions.
- class CGCXXABI {
- friend class CodeGenModule;
- protected:
- CodeGenModule &CGM;
- std::unique_ptr<MangleContext> MangleCtx;
- CGCXXABI(CodeGenModule &CGM)
- : CGM(CGM), MangleCtx(CGM.getContext().createMangleContext()) {}
- protected:
- ImplicitParamDecl *getThisDecl(CodeGenFunction &CGF) {
- return CGF.CXXABIThisDecl;
- }
- llvm::Value *getThisValue(CodeGenFunction &CGF) {
- return CGF.CXXABIThisValue;
- }
- Address getThisAddress(CodeGenFunction &CGF) {
- return Address(
- CGF.CXXABIThisValue,
- CGF.ConvertTypeForMem(CGF.CXXABIThisDecl->getType()->getPointeeType()),
- CGF.CXXABIThisAlignment);
- }
- /// Issue a diagnostic about unsupported features in the ABI.
- void ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S);
- /// Get a null value for unsupported member pointers.
- llvm::Constant *GetBogusMemberPointer(QualType T);
- ImplicitParamDecl *&getStructorImplicitParamDecl(CodeGenFunction &CGF) {
- return CGF.CXXStructorImplicitParamDecl;
- }
- llvm::Value *&getStructorImplicitParamValue(CodeGenFunction &CGF) {
- return CGF.CXXStructorImplicitParamValue;
- }
- /// Loads the incoming C++ this pointer as it was passed by the caller.
- llvm::Value *loadIncomingCXXThis(CodeGenFunction &CGF);
- void setCXXABIThisValue(CodeGenFunction &CGF, llvm::Value *ThisPtr);
- ASTContext &getContext() const { return CGM.getContext(); }
- bool mayNeedDestruction(const VarDecl *VD) const;
- /// Determine whether we will definitely emit this variable with a constant
- /// initializer, either because the language semantics demand it or because
- /// we know that the initializer is a constant.
- // For weak definitions, any initializer available in the current translation
- // is not necessarily reflective of the initializer used; such initializers
- // are ignored unless if InspectInitForWeakDef is true.
- bool
- isEmittedWithConstantInitializer(const VarDecl *VD,
- bool InspectInitForWeakDef = false) const;
- virtual bool requiresArrayCookie(const CXXDeleteExpr *E, QualType eltType);
- virtual bool requiresArrayCookie(const CXXNewExpr *E);
- /// Determine whether there's something special about the rules of
- /// the ABI tell us that 'this' is a complete object within the
- /// given function. Obvious common logic like being defined on a
- /// final class will have been taken care of by the caller.
- virtual bool isThisCompleteObject(GlobalDecl GD) const = 0;
- virtual bool constructorsAndDestructorsReturnThis() const {
- return CGM.getCodeGenOpts().CtorDtorReturnThis;
- }
- public:
- virtual ~CGCXXABI();
- /// Gets the mangle context.
- MangleContext &getMangleContext() {
- return *MangleCtx;
- }
- /// Returns true if the given constructor or destructor is one of the
- /// kinds that the ABI says returns 'this' (only applies when called
- /// non-virtually for destructors).
- ///
- /// There currently is no way to indicate if a destructor returns 'this'
- /// when called virtually, and code generation does not support the case.
- virtual bool HasThisReturn(GlobalDecl GD) const {
- if (isa<CXXConstructorDecl>(GD.getDecl()) ||
- (isa<CXXDestructorDecl>(GD.getDecl()) &&
- GD.getDtorType() != Dtor_Deleting))
- return constructorsAndDestructorsReturnThis();
- return false;
- }
- virtual bool hasMostDerivedReturn(GlobalDecl GD) const { return false; }
- virtual bool useSinitAndSterm() const { return false; }
- /// Returns true if the target allows calling a function through a pointer
- /// with a different signature than the actual function (or equivalently,
- /// bitcasting a function or function pointer to a different function type).
- /// In principle in the most general case this could depend on the target, the
- /// calling convention, and the actual types of the arguments and return
- /// value. Here it just means whether the signature mismatch could *ever* be
- /// allowed; in other words, does the target do strict checking of signatures
- /// for all calls.
- virtual bool canCallMismatchedFunctionType() const { return true; }
- /// If the C++ ABI requires the given type be returned in a particular way,
- /// this method sets RetAI and returns true.
- virtual bool classifyReturnType(CGFunctionInfo &FI) const = 0;
- /// Specify how one should pass an argument of a record type.
- enum RecordArgABI {
- /// Pass it using the normal C aggregate rules for the ABI, potentially
- /// introducing extra copies and passing some or all of it in registers.
- RAA_Default = 0,
- /// Pass it on the stack using its defined layout. The argument must be
- /// evaluated directly into the correct stack position in the arguments area,
- /// and the call machinery must not move it or introduce extra copies.
- RAA_DirectInMemory,
- /// Pass it as a pointer to temporary memory.
- RAA_Indirect
- };
- /// Returns how an argument of the given record type should be passed.
- virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const = 0;
- /// Returns true if the implicit 'sret' parameter comes after the implicit
- /// 'this' parameter of C++ instance methods.
- virtual bool isSRetParameterAfterThis() const { return false; }
- /// Returns true if the ABI permits the argument to be a homogeneous
- /// aggregate.
- virtual bool
- isPermittedToBeHomogeneousAggregate(const CXXRecordDecl *RD) const {
- return true;
- };
- /// Find the LLVM type used to represent the given member pointer
- /// type.
- virtual llvm::Type *
- ConvertMemberPointerType(const MemberPointerType *MPT);
- /// Load a member function from an object and a member function
- /// pointer. Apply the this-adjustment and set 'This' to the
- /// adjusted value.
- virtual CGCallee EmitLoadOfMemberFunctionPointer(
- CodeGenFunction &CGF, const Expr *E, Address This,
- llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
- const MemberPointerType *MPT);
- /// Calculate an l-value from an object and a data member pointer.
- virtual llvm::Value *
- EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
- Address Base, llvm::Value *MemPtr,
- const MemberPointerType *MPT);
- /// Perform a derived-to-base, base-to-derived, or bitcast member
- /// pointer conversion.
- virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
- const CastExpr *E,
- llvm::Value *Src);
- /// Perform a derived-to-base, base-to-derived, or bitcast member
- /// pointer conversion on a constant value.
- virtual llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
- llvm::Constant *Src);
- /// Return true if the given member pointer can be zero-initialized
- /// (in the C++ sense) with an LLVM zeroinitializer.
- virtual bool isZeroInitializable(const MemberPointerType *MPT);
- /// Return whether or not a member pointers type is convertible to an IR type.
- virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const {
- return true;
- }
- /// Create a null member pointer of the given type.
- virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
- /// Create a member pointer for the given method.
- virtual llvm::Constant *EmitMemberFunctionPointer(const CXXMethodDecl *MD);
- /// Create a member pointer for the given field.
- virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
- CharUnits offset);
- /// Create a member pointer for the given member pointer constant.
- virtual llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT);
- /// Emit a comparison between two member pointers. Returns an i1.
- virtual llvm::Value *
- EmitMemberPointerComparison(CodeGenFunction &CGF,
- llvm::Value *L,
- llvm::Value *R,
- const MemberPointerType *MPT,
- bool Inequality);
- /// Determine if a member pointer is non-null. Returns an i1.
- virtual llvm::Value *
- EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
- llvm::Value *MemPtr,
- const MemberPointerType *MPT);
- protected:
- /// A utility method for computing the offset required for the given
- /// base-to-derived or derived-to-base member-pointer conversion.
- /// Does not handle virtual conversions (in case we ever fully
- /// support an ABI that allows this). Returns null if no adjustment
- /// is required.
- llvm::Constant *getMemberPointerAdjustment(const CastExpr *E);
- public:
- virtual void emitVirtualObjectDelete(CodeGenFunction &CGF,
- const CXXDeleteExpr *DE,
- Address Ptr, QualType ElementType,
- const CXXDestructorDecl *Dtor) = 0;
- virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn) = 0;
- virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) = 0;
- virtual llvm::GlobalVariable *getThrowInfo(QualType T) { return nullptr; }
- /// Determine whether it's possible to emit a vtable for \p RD, even
- /// though we do not know that the vtable has been marked as used by semantic
- /// analysis.
- virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const = 0;
- virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C) = 0;
- virtual llvm::CallInst *
- emitTerminateForUnexpectedException(CodeGenFunction &CGF,
- llvm::Value *Exn);
- virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0;
- virtual CatchTypeInfo
- getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType) = 0;
- virtual CatchTypeInfo getCatchAllTypeInfo();
- virtual bool shouldTypeidBeNullChecked(bool IsDeref,
- QualType SrcRecordTy) = 0;
- virtual void EmitBadTypeidCall(CodeGenFunction &CGF) = 0;
- virtual llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
- Address ThisPtr,
- llvm::Type *StdTypeInfoPtrTy) = 0;
- virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
- QualType SrcRecordTy) = 0;
- virtual llvm::Value *
- EmitDynamicCastCall(CodeGenFunction &CGF, Address Value,
- QualType SrcRecordTy, QualType DestTy,
- QualType DestRecordTy, llvm::BasicBlock *CastEnd) = 0;
- virtual llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF,
- Address Value,
- QualType SrcRecordTy,
- QualType DestTy) = 0;
- virtual bool EmitBadCastCall(CodeGenFunction &CGF) = 0;
- virtual llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
- Address This,
- const CXXRecordDecl *ClassDecl,
- const CXXRecordDecl *BaseClassDecl) = 0;
- virtual llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
- const CXXRecordDecl *RD);
- /// Emit the code to initialize hidden members required
- /// to handle virtual inheritance, if needed by the ABI.
- virtual void
- initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF,
- const CXXRecordDecl *RD) {}
- /// Emit constructor variants required by this ABI.
- virtual void EmitCXXConstructors(const CXXConstructorDecl *D) = 0;
- /// Additional implicit arguments to add to the beginning (Prefix) and end
- /// (Suffix) of a constructor / destructor arg list.
- ///
- /// Note that Prefix should actually be inserted *after* the first existing
- /// arg; `this` arguments always come first.
- struct AddedStructorArgs {
- struct Arg {
- llvm::Value *Value;
- QualType Type;
- };
- SmallVector<Arg, 1> Prefix;
- SmallVector<Arg, 1> Suffix;
- AddedStructorArgs() = default;
- AddedStructorArgs(SmallVector<Arg, 1> P, SmallVector<Arg, 1> S)
- : Prefix(std::move(P)), Suffix(std::move(S)) {}
- static AddedStructorArgs prefix(SmallVector<Arg, 1> Args) {
- return {std::move(Args), {}};
- }
- static AddedStructorArgs suffix(SmallVector<Arg, 1> Args) {
- return {{}, std::move(Args)};
- }
- };
- /// Similar to AddedStructorArgs, but only notes the number of additional
- /// arguments.
- struct AddedStructorArgCounts {
- unsigned Prefix = 0;
- unsigned Suffix = 0;
- AddedStructorArgCounts() = default;
- AddedStructorArgCounts(unsigned P, unsigned S) : Prefix(P), Suffix(S) {}
- static AddedStructorArgCounts prefix(unsigned N) { return {N, 0}; }
- static AddedStructorArgCounts suffix(unsigned N) { return {0, N}; }
- };
- /// Build the signature of the given constructor or destructor variant by
- /// adding any required parameters. For convenience, ArgTys has been
- /// initialized with the type of 'this'.
- virtual AddedStructorArgCounts
- buildStructorSignature(GlobalDecl GD,
- SmallVectorImpl<CanQualType> &ArgTys) = 0;
- /// Returns true if the given destructor type should be emitted as a linkonce
- /// delegating thunk, regardless of whether the dtor is defined in this TU or
- /// not.
- virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
- CXXDtorType DT) const = 0;
- virtual void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
- const CXXDestructorDecl *Dtor,
- CXXDtorType DT) const;
- virtual llvm::GlobalValue::LinkageTypes
- getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor,
- CXXDtorType DT) const;
- /// Emit destructor variants required by this ABI.
- virtual void EmitCXXDestructors(const CXXDestructorDecl *D) = 0;
- /// Get the type of the implicit "this" parameter used by a method. May return
- /// zero if no specific type is applicable, e.g. if the ABI expects the "this"
- /// parameter to point to some artificial offset in a complete object due to
- /// vbases being reordered.
- virtual const CXXRecordDecl *getThisArgumentTypeForMethod(GlobalDecl GD) {
- return cast<CXXMethodDecl>(GD.getDecl())->getParent();
- }
- /// Perform ABI-specific "this" argument adjustment required prior to
- /// a call of a virtual function.
- /// The "VirtualCall" argument is true iff the call itself is virtual.
- virtual Address
- adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD,
- Address This, bool VirtualCall) {
- return This;
- }
- /// Build a parameter variable suitable for 'this'.
- void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params);
- /// Insert any ABI-specific implicit parameters into the parameter list for a
- /// function. This generally involves extra data for constructors and
- /// destructors.
- ///
- /// ABIs may also choose to override the return type, which has been
- /// initialized with the type of 'this' if HasThisReturn(CGF.CurGD) is true or
- /// the formal return type of the function otherwise.
- virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
- FunctionArgList &Params) = 0;
- /// Get the ABI-specific "this" parameter adjustment to apply in the prologue
- /// of a virtual function.
- virtual CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
- return CharUnits::Zero();
- }
- /// Emit the ABI-specific prolog for the function.
- virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0;
- virtual AddedStructorArgs
- getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
- CXXCtorType Type, bool ForVirtualBase,
- bool Delegating) = 0;
- /// Add any ABI-specific implicit arguments needed to call a constructor.
- ///
- /// \return The number of arguments added at the beginning and end of the
- /// call, which is typically zero or one.
- AddedStructorArgCounts
- addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
- CXXCtorType Type, bool ForVirtualBase,
- bool Delegating, CallArgList &Args);
- /// Get the implicit (second) parameter that comes after the "this" pointer,
- /// or nullptr if there is isn't one.
- virtual llvm::Value *
- getCXXDestructorImplicitParam(CodeGenFunction &CGF,
- const CXXDestructorDecl *DD, CXXDtorType Type,
- bool ForVirtualBase, bool Delegating) = 0;
- /// Emit the destructor call.
- virtual void EmitDestructorCall(CodeGenFunction &CGF,
- const CXXDestructorDecl *DD, CXXDtorType Type,
- bool ForVirtualBase, bool Delegating,
- Address This, QualType ThisTy) = 0;
- /// Emits the VTable definitions required for the given record type.
- virtual void emitVTableDefinitions(CodeGenVTables &CGVT,
- const CXXRecordDecl *RD) = 0;
- /// Checks if ABI requires extra virtual offset for vtable field.
- virtual bool
- isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
- CodeGenFunction::VPtr Vptr) = 0;
- /// Checks if ABI requires to initialize vptrs for given dynamic class.
- virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass) = 0;
- /// Get the address point of the vtable for the given base subobject.
- virtual llvm::Constant *
- getVTableAddressPoint(BaseSubobject Base,
- const CXXRecordDecl *VTableClass) = 0;
- /// Get the address point of the vtable for the given base subobject while
- /// building a constructor or a destructor.
- virtual llvm::Value *
- getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD,
- BaseSubobject Base,
- const CXXRecordDecl *NearestVBase) = 0;
- /// Get the address point of the vtable for the given base subobject while
- /// building a constexpr.
- virtual llvm::Constant *
- getVTableAddressPointForConstExpr(BaseSubobject Base,
- const CXXRecordDecl *VTableClass) = 0;
- /// Get the address of the vtable for the given record decl which should be
- /// used for the vptr at the given offset in RD.
- virtual llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
- CharUnits VPtrOffset) = 0;
- /// Build a virtual function pointer in the ABI-specific way.
- virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF,
- GlobalDecl GD, Address This,
- llvm::Type *Ty,
- SourceLocation Loc) = 0;
- using DeleteOrMemberCallExpr =
- llvm::PointerUnion<const CXXDeleteExpr *, const CXXMemberCallExpr *>;
- /// Emit the ABI-specific virtual destructor call.
- virtual llvm::Value *EmitVirtualDestructorCall(CodeGenFunction &CGF,
- const CXXDestructorDecl *Dtor,
- CXXDtorType DtorType,
- Address This,
- DeleteOrMemberCallExpr E) = 0;
- virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF,
- GlobalDecl GD,
- CallArgList &CallArgs) {}
- /// Emit any tables needed to implement virtual inheritance. For Itanium,
- /// this emits virtual table tables. For the MSVC++ ABI, this emits virtual
- /// base tables.
- virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0;
- virtual bool exportThunk() = 0;
- virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
- GlobalDecl GD, bool ReturnAdjustment) = 0;
- virtual llvm::Value *performThisAdjustment(CodeGenFunction &CGF,
- Address This,
- const ThisAdjustment &TA) = 0;
- virtual llvm::Value *performReturnAdjustment(CodeGenFunction &CGF,
- Address Ret,
- const ReturnAdjustment &RA) = 0;
- virtual void EmitReturnFromThunk(CodeGenFunction &CGF,
- RValue RV, QualType ResultType);
- virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *,
- FunctionArgList &Args) const = 0;
- /// Gets the offsets of all the virtual base pointers in a given class.
- virtual std::vector<CharUnits> getVBPtrOffsets(const CXXRecordDecl *RD);
- /// Gets the pure virtual member call function.
- virtual StringRef GetPureVirtualCallName() = 0;
- /// Gets the deleted virtual member call name.
- virtual StringRef GetDeletedVirtualCallName() = 0;
- /**************************** Array cookies ******************************/
- /// Returns the extra size required in order to store the array
- /// cookie for the given new-expression. May return 0 to indicate that no
- /// array cookie is required.
- ///
- /// Several cases are filtered out before this method is called:
- /// - non-array allocations never need a cookie
- /// - calls to \::operator new(size_t, void*) never need a cookie
- ///
- /// \param expr - the new-expression being allocated.
- virtual CharUnits GetArrayCookieSize(const CXXNewExpr *expr);
- /// Initialize the array cookie for the given allocation.
- ///
- /// \param NewPtr - a char* which is the presumed-non-null
- /// return value of the allocation function
- /// \param NumElements - the computed number of elements,
- /// potentially collapsed from the multidimensional array case;
- /// always a size_t
- /// \param ElementType - the base element allocated type,
- /// i.e. the allocated type after stripping all array types
- virtual Address InitializeArrayCookie(CodeGenFunction &CGF,
- Address NewPtr,
- llvm::Value *NumElements,
- const CXXNewExpr *expr,
- QualType ElementType);
- /// Reads the array cookie associated with the given pointer,
- /// if it has one.
- ///
- /// \param Ptr - a pointer to the first element in the array
- /// \param ElementType - the base element type of elements of the array
- /// \param NumElements - an out parameter which will be initialized
- /// with the number of elements allocated, or zero if there is no
- /// cookie
- /// \param AllocPtr - an out parameter which will be initialized
- /// with a char* pointing to the address returned by the allocation
- /// function
- /// \param CookieSize - an out parameter which will be initialized
- /// with the size of the cookie, or zero if there is no cookie
- virtual void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr,
- const CXXDeleteExpr *expr,
- QualType ElementType, llvm::Value *&NumElements,
- llvm::Value *&AllocPtr, CharUnits &CookieSize);
- /// Return whether the given global decl needs a VTT parameter.
- virtual bool NeedsVTTParameter(GlobalDecl GD);
- protected:
- /// Returns the extra size required in order to store the array
- /// cookie for the given type. Assumes that an array cookie is
- /// required.
- virtual CharUnits getArrayCookieSizeImpl(QualType elementType);
- /// Reads the array cookie for an allocation which is known to have one.
- /// This is called by the standard implementation of ReadArrayCookie.
- ///
- /// \param ptr - a pointer to the allocation made for an array, as a char*
- /// \param cookieSize - the computed cookie size of an array
- ///
- /// Other parameters are as above.
- ///
- /// \return a size_t
- virtual llvm::Value *readArrayCookieImpl(CodeGenFunction &IGF, Address ptr,
- CharUnits cookieSize);
- public:
- /*************************** Static local guards ****************************/
- /// Emits the guarded initializer and destructor setup for the given
- /// variable, given that it couldn't be emitted as a constant.
- /// If \p PerformInit is false, the initialization has been folded to a
- /// constant and should not be performed.
- ///
- /// The variable may be:
- /// - a static local variable
- /// - a static data member of a class template instantiation
- virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
- llvm::GlobalVariable *DeclPtr,
- bool PerformInit) = 0;
- /// Emit code to force the execution of a destructor during global
- /// teardown. The default implementation of this uses atexit.
- ///
- /// \param Dtor - a function taking a single pointer argument
- /// \param Addr - a pointer to pass to the destructor function.
- virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
- llvm::FunctionCallee Dtor,
- llvm::Constant *Addr) = 0;
- /*************************** thread_local initialization ********************/
- /// Emits ABI-required functions necessary to initialize thread_local
- /// variables in this translation unit.
- ///
- /// \param CXXThreadLocals - The thread_local declarations in this translation
- /// unit.
- /// \param CXXThreadLocalInits - If this translation unit contains any
- /// non-constant initialization or non-trivial destruction for
- /// thread_local variables, a list of functions to perform the
- /// initialization.
- virtual void EmitThreadLocalInitFuncs(
- CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
- ArrayRef<llvm::Function *> CXXThreadLocalInits,
- ArrayRef<const VarDecl *> CXXThreadLocalInitVars) = 0;
- // Determine if references to thread_local global variables can be made
- // directly or require access through a thread wrapper function.
- virtual bool usesThreadWrapperFunction(const VarDecl *VD) const = 0;
- /// Emit a reference to a non-local thread_local variable (including
- /// triggering the initialization of all thread_local variables in its
- /// translation unit).
- virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
- const VarDecl *VD,
- QualType LValType) = 0;
- /// Emit a single constructor/destructor with the given type from a C++
- /// constructor Decl.
- virtual void emitCXXStructor(GlobalDecl GD) = 0;
- /// Load a vtable from This, an object of polymorphic type RD, or from one of
- /// its virtual bases if it does not have its own vtable. Returns the vtable
- /// and the class from which the vtable was loaded.
- virtual std::pair<llvm::Value *, const CXXRecordDecl *>
- LoadVTablePtr(CodeGenFunction &CGF, Address This,
- const CXXRecordDecl *RD) = 0;
- };
- // Create an instance of a C++ ABI class:
- /// Creates an Itanium-family ABI.
- CGCXXABI *CreateItaniumCXXABI(CodeGenModule &CGM);
- /// Creates a Microsoft-family ABI.
- CGCXXABI *CreateMicrosoftCXXABI(CodeGenModule &CGM);
- struct CatchRetScope final : EHScopeStack::Cleanup {
- llvm::CatchPadInst *CPI;
- CatchRetScope(llvm::CatchPadInst *CPI) : CPI(CPI) {}
- void Emit(CodeGenFunction &CGF, Flags flags) override {
- llvm::BasicBlock *BB = CGF.createBasicBlock("catchret.dest");
- CGF.Builder.CreateCatchRet(CPI, BB);
- CGF.EmitBlock(BB);
- }
- };
- }
- }
- #endif
|