//===----- 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 FieldDecl;
class MangleContext;

namespace CodeGen {
class CGCallee;
class CodeGenFunction;
class CodeGenModule;
struct CatchTypeInfo;

/// Implements C++ ABI-specific code generation functions.
class CGCXXABI {
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.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(); }

  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;

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 { 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(const CXXMethodDecl *MD) {
    return MD->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
