33#include "llvm/IR/DataLayout.h" 
   34#include "llvm/IR/GlobalValue.h" 
   35#include "llvm/IR/Instructions.h" 
   36#include "llvm/IR/Intrinsics.h" 
   37#include "llvm/IR/Value.h" 
   38#include "llvm/Support/ScopedPrinter.h" 
   48  llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
 
   51  llvm::SmallVector<std::pair<const VarDecl *, llvm::Function *>, 8>
 
   55  bool UseARMMethodPtrABI;
 
   56  bool UseARMGuardVarABI;
 
   57  bool Use32BitVTableOffsetABI;
 
   59  ItaniumMangleContext &getMangleContext() {
 
   64  ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
 
   65                bool UseARMMethodPtrABI = 
false,
 
   66                bool UseARMGuardVarABI = 
false) :
 
   67    CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
 
   68    UseARMGuardVarABI(UseARMGuardVarABI),
 
   69    Use32BitVTableOffsetABI(
false) { }
 
   80  bool isThisCompleteObject(GlobalDecl GD)
 const override {
 
   93        llvm_unreachable(
"emitting dtor comdat as function?");
 
   95        llvm_unreachable(
"emitting unified dtor as function?");
 
   97      llvm_unreachable(
"bad dtor kind");
 
  109        llvm_unreachable(
"closure ctors in Itanium ABI?");
 
  112        llvm_unreachable(
"emitting ctor comdat as function?");
 
  115        llvm_unreachable(
"emitting unified ctor as function?");
 
  117      llvm_unreachable(
"bad dtor kind");
 
  124  bool isZeroInitializable(
const MemberPointerType *MPT) 
override;
 
  126  llvm::Type *ConvertMemberPointerType(
const MemberPointerType *MPT) 
override;
 
  129    EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
 
  132                                    llvm::Value *&ThisPtrForCall,
 
  133                                    llvm::Value *MemFnPtr,
 
  134                                    const MemberPointerType *MPT) 
override;
 
  136  llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF, 
const Expr *E,
 
  137                                            Address Base, llvm::Value *MemPtr,
 
  138                                            const MemberPointerType *MPT,
 
  139                                            bool IsInBounds) 
override;
 
  141  llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
 
  143                                           llvm::Value *Src) 
override;
 
  144  llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
 
  145                                              llvm::Constant *Src) 
override;
 
  147  llvm::Constant *EmitNullMemberPointer(
const MemberPointerType *MPT) 
override;
 
  149  llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD) 
override;
 
  150  llvm::Constant *EmitMemberDataPointer(
const MemberPointerType *MPT,
 
  151                                        CharUnits offset) 
override;
 
  152  llvm::Constant *EmitMemberPointer(
const APValue &MP, QualType MPT) 
override;
 
  153  llvm::Constant *BuildMemberPointer(
const CXXMethodDecl *MD,
 
  154                                     CharUnits ThisAdjustment);
 
  156  llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
 
  157                                           llvm::Value *L, llvm::Value *R,
 
  158                                           const MemberPointerType *MPT,
 
  159                                           bool Inequality) 
override;
 
  161  llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
 
  163                                         const MemberPointerType *MPT) 
override;
 
  165  void emitVirtualObjectDelete(CodeGenFunction &CGF, 
const CXXDeleteExpr *DE,
 
  166                               Address Ptr, QualType ElementType,
 
  167                               const CXXDestructorDecl *Dtor) 
override;
 
  169  void emitRethrow(CodeGenFunction &CGF, 
bool isNoReturn) 
override;
 
  170  void emitThrow(CodeGenFunction &CGF, 
const CXXThrowExpr *E) 
override;
 
  172  void emitBeginCatch(CodeGenFunction &CGF, 
const CXXCatchStmt *
C) 
override;
 
  175  emitTerminateForUnexpectedException(CodeGenFunction &CGF,
 
  176                                      llvm::Value *Exn) 
override;
 
  178  void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
 
  179  llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) 
override;
 
  181  getAddrOfCXXCatchHandlerType(QualType Ty,
 
  182                               QualType CatchHandlerType)
 override {
 
  183    return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0};
 
  186  bool shouldTypeidBeNullChecked(QualType SrcRecordTy) 
override;
 
  187  void EmitBadTypeidCall(CodeGenFunction &CGF) 
override;
 
  188  llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
 
  190                          llvm::Type *StdTypeInfoPtrTy) 
override;
 
  192  bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
 
  193                                          QualType SrcRecordTy) 
override;
 
  199  bool hasUniqueVTablePointer(QualType RecordTy) {
 
  204    if (!CGM.getCodeGenOpts().AssumeUniqueVTables ||
 
  205        getContext().getLangOpts().AppleKext)
 
  210    if (!CGM.shouldEmitRTTI())
 
  215    if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))
 
  224        llvm::GlobalValue::DefaultVisibility)
 
  230  bool shouldEmitExactDynamicCast(QualType DestRecordTy)
 override {
 
  231    return hasUniqueVTablePointer(DestRecordTy);
 
  234  std::optional<ExactDynamicCastInfo>
 
  235  getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
 
  236                          QualType DestRecordTy) 
override;
 
  238  llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address 
Value,
 
  239                                   QualType SrcRecordTy, QualType DestTy,
 
  240                                   QualType DestRecordTy,
 
  241                                   llvm::BasicBlock *CastEnd) 
override;
 
  244                                    QualType SrcRecordTy, QualType DestTy,
 
  245                                    QualType DestRecordTy,
 
  246                                    const ExactDynamicCastInfo &CastInfo,
 
  247                                    llvm::BasicBlock *CastSuccess,
 
  248                                    llvm::BasicBlock *CastFail) 
override;
 
  251                                     QualType SrcRecordTy) 
override;
 
  253  bool EmitBadCastCall(CodeGenFunction &CGF) 
override;
 
  256    GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
 
  257                              const CXXRecordDecl *ClassDecl,
 
  258                              const CXXRecordDecl *BaseClassDecl) 
override;
 
  260  void EmitCXXConstructors(
const CXXConstructorDecl *D) 
override;
 
  262  AddedStructorArgCounts
 
  263  buildStructorSignature(GlobalDecl GD,
 
  264                         SmallVectorImpl<CanQualType> &ArgTys) 
override;
 
  266  bool useThunkForDtorVariant(
const CXXDestructorDecl *Dtor,
 
  274  void EmitCXXDestructors(
const CXXDestructorDecl *D) 
override;
 
  276  void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
 
  277                                 FunctionArgList &Params) 
override;
 
  279  void EmitInstanceFunctionProlog(CodeGenFunction &CGF) 
override;
 
  281  AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
 
  282                                               const CXXConstructorDecl *D,
 
  288                                             const CXXDestructorDecl *DD,
 
  293  void EmitDestructorCall(CodeGenFunction &CGF, 
const CXXDestructorDecl *DD,
 
  296                          QualType ThisTy) 
override;
 
  298  void emitVTableDefinitions(CodeGenVTables &CGVT,
 
  299                             const CXXRecordDecl *RD) 
override;
 
  301  bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
 
  302                                           CodeGenFunction::VPtr Vptr) 
override;
 
  304  bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
 override {
 
  309  getVTableAddressPoint(BaseSubobject Base,
 
  310                        const CXXRecordDecl *VTableClass) 
override;
 
  312  llvm::Value *getVTableAddressPointInStructor(
 
  313      CodeGenFunction &CGF, 
const CXXRecordDecl *VTableClass,
 
  314      BaseSubobject Base, 
const CXXRecordDecl *NearestVBase) 
override;
 
  316  llvm::Value *getVTableAddressPointInStructorWithVTT(
 
  317      CodeGenFunction &CGF, 
const CXXRecordDecl *VTableClass,
 
  318      BaseSubobject Base, 
const CXXRecordDecl *NearestVBase);
 
  320  llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
 
  321                                        CharUnits VPtrOffset) 
override;
 
  323  CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
 
  324                                     Address This, llvm::Type *Ty,
 
  325                                     SourceLocation Loc) 
override;
 
  328  EmitVirtualDestructorCall(CodeGenFunction &CGF, 
const CXXDestructorDecl *Dtor,
 
  330                            DeleteOrMemberCallExpr E,
 
  331                            llvm::CallBase **CallOrInvoke) 
override;
 
  333  void emitVirtualInheritanceTables(
const CXXRecordDecl *RD) 
override;
 
  335  bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD) 
const override;
 
  336  bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD) 
const;
 
  338  void setThunkLinkage(llvm::Function *Thunk, 
bool ForVTable, GlobalDecl GD,
 
  339                       bool ReturnAdjustment)
 override {
 
  342    if (ForVTable && !Thunk->hasLocalLinkage())
 
  343      Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
 
  344    CGM.setGVProperties(Thunk, GD);
 
  347  bool exportThunk()
 override { 
return true; }
 
  349  llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
 
  350                                     const CXXRecordDecl *UnadjustedThisClass,
 
  351                                     const ThunkInfo &TI) 
override;
 
  353  llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
 
  354                                       const CXXRecordDecl *UnadjustedRetClass,
 
  355                                       const ReturnAdjustment &RA) 
override;
 
  357  size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
 
  358                              FunctionArgList &Args)
 const override {
 
  359    assert(!Args.empty() && 
"expected the arglist to not be empty!");
 
  360    return Args.size() - 1;
 
  363  StringRef GetPureVirtualCallName()
 override { 
return "__cxa_pure_virtual"; }
 
  364  StringRef GetDeletedVirtualCallName()
 override 
  365    { 
return "__cxa_deleted_virtual"; }
 
  367  CharUnits getArrayCookieSizeImpl(QualType elementType) 
override;
 
  368  Address InitializeArrayCookie(CodeGenFunction &CGF,
 
  370                                llvm::Value *NumElements,
 
  371                                const CXXNewExpr *
expr,
 
  372                                QualType ElementType) 
override;
 
  373  llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
 
  375                                   CharUnits cookieSize) 
override;
 
  377  void EmitGuardedInit(CodeGenFunction &CGF, 
const VarDecl &D,
 
  378                       llvm::GlobalVariable *DeclPtr,
 
  379                       bool PerformInit) 
override;
 
  380  void registerGlobalDtor(CodeGenFunction &CGF, 
const VarDecl &D,
 
  381                          llvm::FunctionCallee dtor,
 
  382                          llvm::Constant *addr) 
override;
 
  384  llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
 
  386  void EmitThreadLocalInitFuncs(
 
  388      ArrayRef<const VarDecl *> CXXThreadLocals,
 
  389      ArrayRef<llvm::Function *> CXXThreadLocalInits,
 
  390      ArrayRef<const VarDecl *> CXXThreadLocalInitVars) 
override;
 
  392  bool usesThreadWrapperFunction(
const VarDecl *VD)
 const override {
 
  393    return !isEmittedWithConstantInitializer(VD) ||
 
  394           mayNeedDestruction(VD);
 
  396  LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, 
const VarDecl *VD,
 
  397                                      QualType LValType) 
override;
 
  399  bool NeedsVTTParameter(GlobalDecl GD) 
override;
 
  402  getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
 
  409  virtual bool shouldRTTIBeUnique()
 const { 
return true; }
 
  413  enum RTTIUniquenessKind {
 
  431  classifyRTTIUniqueness(QualType CanTy,
 
  432                         llvm::GlobalValue::LinkageTypes 
Linkage) 
const;
 
  433  friend class ItaniumRTTIBuilder;
 
  435  void emitCXXStructor(GlobalDecl GD) 
override;
 
  437  std::pair<llvm::Value *, const CXXRecordDecl *>
 
  438  LoadVTablePtr(CodeGenFunction &CGF, Address This,
 
  439                const CXXRecordDecl *RD) 
override;
 
  443   getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
 
  445   bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
 const {
 
  446     const auto &VtableLayout =
 
  447         CGM.getItaniumVTableContext().getVTableLayout(RD);
 
  449     for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
 
  451       if (!VtableComponent.isUsedFunctionPointerKind())
 
  454       const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
 
  455       const FunctionDecl *FD = 
Method->getDefinition();
 
  456       const bool IsInlined =
 
  461       StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
 
  462       auto *Entry = CGM.GetGlobalValue(Name);
 
  468       if (!Entry || Entry->isDeclaration())
 
  474  bool isVTableHidden(
const CXXRecordDecl *RD)
 const {
 
  475    const auto &VtableLayout =
 
  476            CGM.getItaniumVTableContext().getVTableLayout(RD);
 
  478    for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
 
  479      if (VtableComponent.isRTTIKind()) {
 
  480        const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
 
  481        if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
 
  483      } 
else if (VtableComponent.isUsedFunctionPointerKind()) {
 
  484        const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
 
  485        if (
Method->getVisibility() == Visibility::HiddenVisibility &&
 
  494class ARMCXXABI : 
public ItaniumCXXABI {
 
  496  ARMCXXABI(CodeGen::CodeGenModule &CGM) :
 
  497    ItaniumCXXABI(CGM, 
true,
 
  500  bool constructorsAndDestructorsReturnThis()
 const override { 
return true; }
 
  502  void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,
 
  503                           QualType ResTy) 
override;
 
  505  CharUnits getArrayCookieSizeImpl(QualType elementType) 
override;
 
  506  Address InitializeArrayCookie(CodeGenFunction &CGF,
 
  508                                llvm::Value *NumElements,
 
  509                                const CXXNewExpr *
expr,
 
  510                                QualType ElementType) 
override;
 
  511  llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr,
 
  512                                   CharUnits cookieSize) 
override;
 
  515class AppleARM64CXXABI : 
public ARMCXXABI {
 
  517  AppleARM64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {
 
  518    Use32BitVTableOffsetABI = 
true;
 
  522  bool shouldRTTIBeUnique()
 const override { 
return false; }
 
  525class FuchsiaCXXABI final : 
public ItaniumCXXABI {
 
  527  explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM)
 
  528      : ItaniumCXXABI(CGM) {}
 
  531  bool constructorsAndDestructorsReturnThis()
 const override { 
return true; }
 
  534class WebAssemblyCXXABI final : 
public ItaniumCXXABI {
 
  536  explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM)
 
  537      : ItaniumCXXABI(CGM, 
true,
 
  539  void emitBeginCatch(CodeGenFunction &CGF, 
const CXXCatchStmt *
C) 
override;
 
  541  emitTerminateForUnexpectedException(CodeGenFunction &CGF,
 
  542                                      llvm::Value *Exn) 
override;
 
  545  bool constructorsAndDestructorsReturnThis()
 const override { 
return true; }
 
  546  bool canCallMismatchedFunctionType()
 const override { 
return false; }
 
  549class XLCXXABI final : 
public ItaniumCXXABI {
 
  551  explicit XLCXXABI(CodeGen::CodeGenModule &CGM)
 
  552      : ItaniumCXXABI(CGM) {}
 
  554  void registerGlobalDtor(CodeGenFunction &CGF, 
const VarDecl &D,
 
  555                          llvm::FunctionCallee dtor,
 
  556                          llvm::Constant *addr) 
override;
 
  558  bool useSinitAndSterm()
 const override { 
return true; }
 
  561  void emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
 
  562                             llvm::Constant *addr);
 
  570  case TargetCXXABI::GenericARM:
 
  571  case TargetCXXABI::iOS:
 
  572  case TargetCXXABI::WatchOS:
 
  573    return new ARMCXXABI(CGM);
 
  575  case TargetCXXABI::AppleARM64:
 
  576    return new AppleARM64CXXABI(CGM);
 
  578  case TargetCXXABI::Fuchsia:
 
  579    return new FuchsiaCXXABI(CGM);
 
  584  case TargetCXXABI::GenericAArch64:
 
  585    return new ItaniumCXXABI(CGM, 
true,
 
  588  case TargetCXXABI::GenericMIPS:
 
  589    return new ItaniumCXXABI(CGM, 
true);
 
  591  case TargetCXXABI::WebAssembly:
 
  592    return new WebAssemblyCXXABI(CGM);
 
  594  case TargetCXXABI::XL:
 
  595    return new XLCXXABI(CGM);
 
  597  case TargetCXXABI::GenericItanium:
 
  598    return new ItaniumCXXABI(CGM);
 
  600  case TargetCXXABI::Microsoft:
 
  601    llvm_unreachable(
"Microsoft ABI is not Itanium-based");
 
  603  llvm_unreachable(
"bad ABI kind");
 
 
  609    return CGM.PtrDiffTy;
 
  610  return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
 
  633CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
 
  635    llvm::Value *&ThisPtrForCall,
 
  643  llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
 
  650  llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1, 
"memptr.adj");
 
  653  llvm::Value *Adj = RawAdj;
 
  654  if (UseARMMethodPtrABI)
 
  655    Adj = Builder.CreateAShr(Adj, ptrdiff_1, 
"memptr.adj.shifted");
 
  660  This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(), 
This, Adj);
 
  661  ThisPtrForCall = 
This;
 
  664  llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0, 
"memptr.ptr");
 
  668  llvm::Value *IsVirtual;
 
  669  if (UseARMMethodPtrABI)
 
  670    IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
 
  672    IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
 
  673  IsVirtual = Builder.CreateIsNotNull(IsVirtual, 
"memptr.isvirtual");
 
  674  Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
 
  692  llvm::Value *VTableOffset = FnAsInt;
 
  693  if (!UseARMMethodPtrABI)
 
  694    VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
 
  695  if (Use32BitVTableOffsetABI) {
 
  696    VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
 
  697    VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
 
  702  llvm::Constant *CheckSourceLocation;
 
  703  llvm::Constant *CheckTypeDesc;
 
  704  bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
 
  705                            CGM.HasHiddenLTOVisibility(RD);
 
  707  if (ShouldEmitCFICheck) {
 
  708    if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
 
  709      if (BinOp->isPtrMemOp() &&
 
  712              ->hasPointeeToToCFIUncheckedCalleeFunctionType())
 
  713        ShouldEmitCFICheck = 
false;
 
  717  bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
 
  718                           CGM.HasHiddenLTOVisibility(RD);
 
  719  bool ShouldEmitWPDInfo =
 
  720      CGM.getCodeGenOpts().WholeProgramVTables &&
 
  722      !CGM.AlwaysHasLTOVisibilityPublic(RD);
 
  723  llvm::Value *VirtualFn = 
nullptr;
 
  726    auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
 
  727    auto CheckHandler = SanitizerHandler::CFICheckFail;
 
  728    SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
 
  730    llvm::Value *TypeId = 
nullptr;
 
  731    llvm::Value *CheckResult = 
nullptr;
 
  733    if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
 
  737          CGM.CreateMetadataIdentifierForVirtualMemPtrType(QualType(MPT, 0));
 
  741    if (ShouldEmitVFEInfo) {
 
  742      llvm::Value *VFPAddr =
 
  743          Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
 
  750      llvm::Value *CheckedLoad = Builder.CreateCall(
 
  751          CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
 
  752          {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
 
  753      CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
 
  754      VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
 
  758      if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
 
  759        llvm::Value *VFPAddr =
 
  760            Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
 
  761        llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
 
  762                                      ? llvm::Intrinsic::type_test
 
  763                                      : llvm::Intrinsic::public_type_test;
 
  766            Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
 
  769      if (CGM.getItaniumVTableContext().isRelativeLayout()) {
 
  770        VirtualFn = CGF.
Builder.CreateCall(
 
  771            CGM.getIntrinsic(llvm::Intrinsic::load_relative,
 
  772                             {VTableOffset->getType()}),
 
  773            {VTable, VTableOffset});
 
  775        llvm::Value *VFPAddr =
 
  782    assert(VirtualFn && 
"Virtual fuction pointer not created!");
 
  783    assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
 
  785           "Check result required but not created!");
 
  787    if (ShouldEmitCFICheck) {
 
  791      llvm::Constant *StaticData[] = {
 
  797      if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
 
  800        llvm::Value *AllVtables = llvm::MetadataAsValue::get(
 
  801            CGM.getLLVMContext(),
 
  802            llvm::MDString::get(CGM.getLLVMContext(), 
"all-vtables"));
 
  803        llvm::Value *ValidVtable = Builder.CreateCall(
 
  804            CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
 
  805        CGF.
EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,
 
  806                      StaticData, {VTable, ValidVtable});
 
  809      FnVirtual = Builder.GetInsertBlock();
 
  818  llvm::Value *NonVirtualFn =
 
  819      Builder.CreateIntToPtr(FnAsInt, CGF.
DefaultPtrTy, 
"memptr.nonvirtualfn");
 
  822  if (ShouldEmitCFICheck) {
 
  825      auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
 
  826      auto CheckHandler = SanitizerHandler::CFICheckFail;
 
  827      SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
 
  829      llvm::Constant *StaticData[] = {
 
  835      llvm::Value *Bit = Builder.getFalse();
 
  836      for (
const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {
 
  837        llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
 
  840                                              Base->getCanonicalDecl()));
 
  841        llvm::Value *TypeId =
 
  844        llvm::Value *TypeTest =
 
  845            Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
 
  846                               {NonVirtualFn, TypeId});
 
  847        Bit = Builder.CreateOr(Bit, TypeTest);
 
  850      CGF.
EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,
 
  851                    {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
 
  853      FnNonVirtual = Builder.GetInsertBlock();
 
  859  llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
DefaultPtrTy, 2);
 
  860  CalleePtr->addIncoming(VirtualFn, FnVirtual);
 
  861  CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
 
  863  CGPointerAuthInfo PointerAuth;
 
  865  if (
const auto &Schema =
 
  866          CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
 
  867    llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
 
  868    DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
 
  870    const auto &AuthInfo =
 
  871        CGM.getMemberFunctionPointerAuthInfo(QualType(MPT, 0));
 
  872    assert(Schema.getKey() == AuthInfo.getKey() &&
 
  873           "Keys for virtual and non-virtual member functions must match");
 
  874    auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
 
  875    DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
 
  876    PointerAuth = CGPointerAuthInfo(
 
  877        Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
 
  878        Schema.authenticatesNullValues(), DiscriminatorPHI);
 
  881  CGCallee 
Callee(FPT, CalleePtr, PointerAuth);
 
  887llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
 
  888    CodeGenFunction &CGF, 
const Expr *E, Address Base, llvm::Value *MemPtr,
 
  889    const MemberPointerType *MPT, 
bool IsInBounds) {
 
  890  assert(MemPtr->getType() == CGM.PtrDiffTy);
 
  892  CGBuilderTy &Builder = CGF.
Builder;
 
  895  llvm::Value *BaseAddr = 
Base.emitRawPointer(CGF);
 
  896  return Builder.CreateGEP(CGF.
Int8Ty, BaseAddr, MemPtr, 
"memptr.offset",
 
  897                           IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
 
  898                                      : llvm::GEPNoWrapFlags::none());
 
  905  const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
 
  910  assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
 
  911         CPA->getAddrDiscriminator()->isZeroValue() &&
 
  913         "unexpected key or discriminators");
 
  916      CPA->getPointer(), NewAuthInfo.
getKey(), 
nullptr,
 
 
  944ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
 
  951  assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
 
  952         E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
 
  955  CGBuilderTy &Builder = CGF.
Builder;
 
  956  QualType DstType = E->
getType();
 
  959    if (
const auto &NewAuthInfo =
 
  960            CGM.getMemberFunctionPointerAuthInfo(DstType)) {
 
  963      const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
 
  964      llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0, 
"memptr.ptr");
 
  965      llvm::Type *OrigTy = MemFnPtr->getType();
 
  967      llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
 
  972      assert(UseARMMethodPtrABI && 
"ARM ABI expected");
 
  973      llvm::Value *Adj = Builder.CreateExtractValue(src, 1, 
"memptr.adj");
 
  974      llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
 
  975      llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
 
  976      llvm::Value *IsVirtualOffset =
 
  977          Builder.CreateIsNotNull(AndVal, 
"is.virtual.offset");
 
  978      Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
 
  981      llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
 
  982      MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
 
  986      MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
 
  987      llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
 
  988      ResignBB = Builder.GetInsertBlock();
 
  991      llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
 
  992      NewSrc->addIncoming(src, StartBB);
 
  993      NewSrc->addIncoming(ResignedVal, ResignBB);
 
  999  if (E->
getCastKind() == CK_ReinterpretMemberPointer) 
return src;
 
 1001  llvm::Constant *adj = getMemberPointerAdjustment(E);
 
 1002  if (!adj) 
return src;
 
 1004  bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
 
 1006  const MemberPointerType *destTy =
 
 1013    if (isDerivedToBase)
 
 1014      dst = Builder.CreateNSWSub(src, adj, 
"adj");
 
 1016      dst = Builder.CreateNSWAdd(src, adj, 
"adj");
 
 1019    llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
 
 1020    llvm::Value *isNull = Builder.CreateICmpEQ(src, null, 
"memptr.isnull");
 
 1021    return Builder.CreateSelect(isNull, src, dst);
 
 1025  if (UseARMMethodPtrABI) {
 
 1028    adj = llvm::ConstantInt::get(adj->getType(), offset);
 
 1031  llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1, 
"src.adj");
 
 1032  llvm::Value *dstAdj;
 
 1033  if (isDerivedToBase)
 
 1034    dstAdj = Builder.CreateNSWSub(srcAdj, adj, 
"adj");
 
 1036    dstAdj = Builder.CreateNSWAdd(srcAdj, adj, 
"adj");
 
 1038  return Builder.CreateInsertValue(src, dstAdj, 1);
 
 1041static llvm::Constant *
 
 1046         "member function pointers expected");
 
 1047  if (DestType == SrcType)
 
 1053  if (!NewAuthInfo && !CurAuthInfo)
 
 1056  llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
 
 1057  if (MemFnPtr->getNumOperands() == 0) {
 
 1065  ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
 
 1066  return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
 
 
 1070ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
 
 1071                                           llvm::Constant *src) {
 
 1072  assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
 
 1073         E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
 
 1076  QualType DstType = E->
getType();
 
 1083  if (E->
getCastKind() == CK_ReinterpretMemberPointer) 
return src;
 
 1086  llvm::Constant *adj = getMemberPointerAdjustment(E);
 
 1087  if (!adj) 
return src;
 
 1089  bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
 
 1091  const MemberPointerType *destTy =
 
 1098    if (src->isAllOnesValue()) 
return src;
 
 1100    if (isDerivedToBase)
 
 1101      return llvm::ConstantExpr::getNSWSub(src, adj);
 
 1103      return llvm::ConstantExpr::getNSWAdd(src, adj);
 
 1107  if (UseARMMethodPtrABI) {
 
 1110    adj = llvm::ConstantInt::get(adj->getType(), offset);
 
 1113  llvm::Constant *srcAdj = src->getAggregateElement(1);
 
 1114  llvm::Constant *dstAdj;
 
 1115  if (isDerivedToBase)
 
 1116    dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
 
 1118    dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
 
 1120  llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
 
 1121  assert(res != 
nullptr && 
"Folding must succeed");
 
 1126ItaniumCXXABI::EmitNullMemberPointer(
const MemberPointerType *MPT) {
 
 1130    return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL, 
true);
 
 1132  llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
 
 1133  llvm::Constant *Values[2] = { 
Zero, 
Zero };
 
 1134  return llvm::ConstantStruct::getAnon(Values);
 
 1138ItaniumCXXABI::EmitMemberDataPointer(
const MemberPointerType *MPT,
 
 1143  return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
 
 1147ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
 
 1151llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
 
 1152                                                  CharUnits ThisAdjustment) {
 
 1153  assert(MD->
isInstance() && 
"Member function must not be static!");
 
 1155  CodeGenTypes &Types = CGM.getTypes();
 
 1158  llvm::Constant *MemPtr[2];
 
 1160    uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
 
 1162    if (CGM.getItaniumVTableContext().isRelativeLayout()) {
 
 1164      VTableOffset = Index * 4;
 
 1166      const ASTContext &Context = getContext();
 
 1169      VTableOffset = Index * PointerWidth.
getQuantity();
 
 1172    if (UseARMMethodPtrABI) {
 
 1194      const auto &Schema =
 
 1195          CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
 
 1197        MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
 
 1198            getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
 
 1200        MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
 
 1203      MemPtr[1] = llvm::ConstantInt::get(
 
 1204          CGM.PtrDiffTy, 2 * ThisAdjustment.
getQuantity() + !Schema);
 
 1210      MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
 
 1211      MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
 
 1215    const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
 
 1226    llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
 
 1228    MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
 
 1229    MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
 
 1230                                       (UseARMMethodPtrABI ? 2 : 1) *
 
 1234  return llvm::ConstantStruct::getAnon(MemPtr);
 
 1237llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
 
 1239  const MemberPointerType *MPT = MPType->
castAs<MemberPointerType>();
 
 1242    return EmitNullMemberPointer(MPT);
 
 1244  CharUnits ThisAdjustment = getContext().getMemberPointerPathAdjustment(MP);
 
 1246  if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
 
 1247    llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment);
 
 1248    QualType SrcType = getContext().getMemberPointerType(
 
 1253  CharUnits FieldOffset =
 
 1254    getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
 
 1255  return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
 
 1263ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
 
 1266                                           const MemberPointerType *MPT,
 
 1268  CGBuilderTy &Builder = CGF.
Builder;
 
 1270  llvm::ICmpInst::Predicate Eq;
 
 1271  llvm::Instruction::BinaryOps 
And, 
Or;
 
 1273    Eq = llvm::ICmpInst::ICMP_NE;
 
 1274    And = llvm::Instruction::Or;
 
 1275    Or = llvm::Instruction::And;
 
 1277    Eq = llvm::ICmpInst::ICMP_EQ;
 
 1278    And = llvm::Instruction::And;
 
 1279    Or = llvm::Instruction::Or;
 
 1285    return Builder.CreateICmp(Eq, L, R);
 
 1297  llvm::Value *LPtr = Builder.CreateExtractValue(L, 0, 
"lhs.memptr.ptr");
 
 1298  llvm::Value *RPtr = Builder.CreateExtractValue(R, 0, 
"rhs.memptr.ptr");
 
 1302  llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr, 
"cmp.ptr");
 
 1307  llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
 
 1308  llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, 
Zero, 
"cmp.ptr.null");
 
 1312  llvm::Value *LAdj = Builder.CreateExtractValue(L, 1, 
"lhs.memptr.adj");
 
 1313  llvm::Value *RAdj = Builder.CreateExtractValue(R, 1, 
"rhs.memptr.adj");
 
 1314  llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj, 
"cmp.adj");
 
 1318  if (UseARMMethodPtrABI) {
 
 1319    llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
 
 1322    llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj, 
"or.adj");
 
 1323    llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
 
 1324    llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, 
Zero,
 
 1326    EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
 
 1330  llvm::Value *
Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
 
 1332                               Inequality ? 
"memptr.ne" : 
"memptr.eq");
 
 1337ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
 
 1338                                          llvm::Value *MemPtr,
 
 1339                                          const MemberPointerType *MPT) {
 
 1340  CGBuilderTy &Builder = CGF.
Builder;
 
 1344    assert(MemPtr->getType() == CGM.PtrDiffTy);
 
 1345    llvm::Value *NegativeOne =
 
 1346      llvm::Constant::getAllOnesValue(MemPtr->getType());
 
 1347    return Builder.CreateICmpNE(MemPtr, NegativeOne, 
"memptr.tobool");
 
 1351  llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0, 
"memptr.ptr");
 
 1353  llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
 
 1354  llvm::Value *
Result = Builder.CreateICmpNE(Ptr, 
Zero, 
"memptr.tobool");
 
 1358  if (UseARMMethodPtrABI) {
 
 1359    llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
 
 1360    llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1, 
"memptr.adj");
 
 1361    llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One, 
"memptr.virtualbit");
 
 1362    llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, 
Zero,
 
 1363                                                  "memptr.isvirtual");
 
 1370bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI)
 const {
 
 1371  const CXXRecordDecl *RD = FI.
getReturnType()->getAsCXXRecordDecl();
 
 1377    auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
 
 1379        Align, CGM.getDataLayout().getAllocaAddrSpace(),
 
 1388bool ItaniumCXXABI::isZeroInitializable(
const MemberPointerType *MPT) {
 
 1394void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
 
 1395                                            const CXXDeleteExpr *DE,
 
 1397                                            QualType ElementType,
 
 1398                                            const CXXDestructorDecl *Dtor) {
 
 1400  if (UseGlobalDelete) {
 
 1409    llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
 
 1410        CGF.
IntPtrTy, VTable, -2, 
"complete-offset.ptr");
 
 1428  EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
 
 1431  if (UseGlobalDelete)
 
 1435void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF, 
bool isNoReturn) {
 
 1438  llvm::FunctionType *FTy =
 
 1439    llvm::FunctionType::get(CGM.VoidTy, 
false);
 
 1441  llvm::FunctionCallee 
Fn = CGM.CreateRuntimeFunction(FTy, 
"__cxa_rethrow");
 
 1452  llvm::FunctionType *FTy =
 
 
 1463  llvm::FunctionType *FTy =
 
 1464    llvm::FunctionType::get(CGM.
VoidTy, Args, 
false);
 
 
 1469void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, 
const CXXThrowExpr *E) {
 
 1472  llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
 
 1473  uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
 
 1477      AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize), 
"exception");
 
 1481      E->
getSubExpr(), Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));
 
 1484  llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
 
 1489  llvm::Constant *Dtor = 
nullptr;
 
 1495    const ASTContext &Ctx = getContext();
 
 1497                                          FunctionProtoType::ExtProtoInfo());
 
 1499    CXXDestructorDecl *DtorD = 
Record->getDestructor();
 
 1500    Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD, 
Dtor_Complete));
 
 1501    Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
 
 1503  if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
 
 1505  llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
 
 1517  llvm::Type *PtrDiffTy =
 
 1520  llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
 
 1522  llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, 
false);
 
 1526  FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
 
 1527  FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
 
 1528  FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
 
 1529  llvm::AttributeList Attrs = llvm::AttributeList::get(
 
 1530      CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
 
 
 1537  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy, 
false);
 
 
 1554  unsigned NumPublicPaths = 0;
 
 1567      if (PathElement.Base->isVirtual())
 
 1570      if (NumPublicPaths > 1) 
 
 1574      const ASTRecordLayout &L = Context.getASTRecordLayout(PathElement.Class);
 
 1576          PathElement.Base->getType()->getAsCXXRecordDecl());
 
 1581  if (NumPublicPaths == 0)
 
 1585  if (NumPublicPaths > 1)
 
 
 1595  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy, 
false);
 
 
 1600bool ItaniumCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
 
 1604void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
 
 1607  Call->setDoesNotReturn();
 
 1608  CGF.
Builder.CreateUnreachable();
 
 1611llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
 
 1612                                       QualType SrcRecordTy,
 
 1614                                       llvm::Type *StdTypeInfoPtrTy) {
 
 1619  if (CGM.getItaniumVTableContext().isRelativeLayout()) {
 
 1622        CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
 
 1623        {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});
 
 1627        CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy, 
Value, -1ULL);
 
 1633bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
 
 1634                                                       QualType SrcRecordTy) {
 
 1638llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
 
 1639    CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
 
 1640    QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
 
 1641  llvm::Type *PtrDiffLTy =
 
 1644  llvm::Value *SrcRTTI =
 
 1646  llvm::Value *DestRTTI =
 
 1652  llvm::Value *OffsetHint = llvm::ConstantInt::get(
 
 1658  if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
 
 1664    llvm::Value *Vtable =
 
 1666                         CodeGenFunction::VTableAuthMode::MustTrap);
 
 1671  llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
 
 1677    llvm::BasicBlock *BadCastBlock =
 
 1684    EmitBadCastCall(CGF);
 
 1690std::optional<CGCXXABI::ExactDynamicCastInfo>
 
 1691ItaniumCXXABI::getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
 
 1692                                       QualType DestRecordTy) {
 
 1693  assert(shouldEmitExactDynamicCast(DestRecordTy));
 
 1695  ASTContext &Context = getContext();
 
 1700  CXXBasePaths Paths(
true, 
true,
 
 1706  std::optional<CharUnits> Offset;
 
 1707  for (
const CXXBasePath &Path : Paths) {
 
 1712    CharUnits PathOffset;
 
 1713    for (
const CXXBasePathElement &PathElement : Path) {
 
 1715      const CXXRecordDecl *
Base =
 
 1716          PathElement.Base->getType()->getAsCXXRecordDecl();
 
 1717      if (PathElement.Base->isVirtual()) {
 
 1723        const ASTRecordLayout &L =
 
 1730      Offset = PathOffset;
 
 1731    else if (Offset != PathOffset) {
 
 1733      return ExactDynamicCastInfo{
true,
 
 1738    return std::nullopt;
 
 1739  return ExactDynamicCastInfo{
false, *Offset};
 
 1742llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
 
 1743    CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
 
 1744    QualType DestTy, QualType DestRecordTy,
 
 1745    const ExactDynamicCastInfo &ExactCastInfo, llvm::BasicBlock *CastSuccess,
 
 1746    llvm::BasicBlock *CastFail) {
 
 1749  auto AuthenticateVTable = [&](Address ThisAddr, 
const CXXRecordDecl *
Decl) {
 
 1753                           CodeGenFunction::VTableAuthMode::MustTrap);
 
 1756  bool PerformPostCastAuthentication = 
false;
 
 1757  llvm::Value *VTable = 
nullptr;
 
 1758  if (ExactCastInfo.RequiresCastToPrimaryBase) {
 
 1763    llvm::Value *PrimaryBase =
 
 1770    PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
 
 1771    CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip,
 
 1772                                        false, 
false, 
nullptr);
 
 1775    if (PerformPostCastAuthentication)
 
 1782  llvm::Constant *ExpectedVTable = getVTableAddressPoint(
 
 1783      BaseSubobject(SrcDecl, ExactCastInfo.Offset), DestDecl);
 
 1784  llvm::Value *
Success = CGF.
Builder.CreateICmpEQ(VTable, ExpectedVTable);
 
 1787  if (!ExactCastInfo.Offset.isZero()) {
 
 1789    llvm::Constant *OffsetConstant =
 
 1790        llvm::ConstantInt::get(CGF.
PtrDiffTy, -Offset);
 
 1793    PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
 
 1796  if (PerformPostCastAuthentication) {
 
 1799    llvm::BasicBlock *NonNullBlock = CGF.
Builder.GetInsertBlock();
 
 1800    llvm::BasicBlock *PostCastAuthSuccess =
 
 1802    llvm::BasicBlock *PostCastAuthComplete =
 
 1805                             PostCastAuthComplete);
 
 1807    Address AdjustedThisAddr =
 
 1809    AuthenticateVTable(AdjustedThisAddr, DestDecl);
 
 1812    llvm::PHINode *PHI = CGF.
Builder.CreatePHI(AdjustedThisPtr->getType(), 2);
 
 1813    PHI->addIncoming(AdjustedThisPtr, PostCastAuthSuccess);
 
 1814    llvm::Value *NullValue =
 
 1815        llvm::Constant::getNullValue(AdjustedThisPtr->getType());
 
 1816    PHI->addIncoming(NullValue, NonNullBlock);
 
 1817    AdjustedThisPtr = PHI;
 
 1820  return AdjustedThisPtr;
 
 1823llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
 
 1825                                                  QualType SrcRecordTy) {
 
 1827  llvm::Value *OffsetToTop;
 
 1828  if (CGM.getItaniumVTableContext().isRelativeLayout()) {
 
 1830    llvm::Value *VTable =
 
 1835        CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
 
 1839    llvm::Type *PtrDiffLTy =
 
 1843    llvm::Value *VTable =
 
 1848        CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
 
 1857bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
 
 1860  Call->setDoesNotReturn();
 
 1861  CGF.
Builder.CreateUnreachable();
 
 1866ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
 
 1868                                         const CXXRecordDecl *ClassDecl,
 
 1869                                         const CXXRecordDecl *BaseClassDecl) {
 
 1870  llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
 
 1871  CharUnits VBaseOffsetOffset =
 
 1872      CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
 
 1874  llvm::Value *VBaseOffsetPtr =
 
 1875    CGF.
Builder.CreateConstGEP1_64(
 
 1877        "vbase.offset.ptr");
 
 1879  llvm::Value *VBaseOffset;
 
 1880  if (CGM.getItaniumVTableContext().isRelativeLayout()) {
 
 1886        CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(), 
"vbase.offset");
 
 1891void ItaniumCXXABI::EmitCXXConstructors(
const CXXConstructorDecl *D) {
 
 1893  assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
 
 1897  CGM.EmitGlobal(GlobalDecl(D, 
Ctor_Base));
 
 1907CGCXXABI::AddedStructorArgCounts
 
 1908ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
 
 1909                                      SmallVectorImpl<CanQualType> &ArgTys) {
 
 1910  ASTContext &Context = getContext();
 
 1919    LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
 
 1921    ArgTys.insert(ArgTys.begin() + 1,
 
 1923    return AddedStructorArgCounts::prefix(1);
 
 1925  return AddedStructorArgCounts{};
 
 1928void ItaniumCXXABI::EmitCXXDestructors(
const CXXDestructorDecl *D) {
 
 1931  CGM.EmitGlobal(GlobalDecl(D, 
Dtor_Base));
 
 1944void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
 
 1946                                              FunctionArgList &Params) {
 
 1951  if (NeedsVTTParameter(CGF.
CurGD)) {
 
 1952    ASTContext &Context = getContext();
 
 1955    LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
 
 1960        T, ImplicitParamKind::CXXVTT);
 
 1961    Params.insert(Params.begin() + 1, VTTDecl);
 
 1962    getStructorImplicitParamDecl(CGF) = VTTDecl;
 
 1966void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
 
 1973  setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
 
 1976  if (getStructorImplicitParamDecl(CGF)) {
 
 1989  if (HasThisReturn(CGF.
CurGD))
 
 1993CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
 
 1996  if (!NeedsVTTParameter(GlobalDecl(D, 
Type)))
 
 1997    return AddedStructorArgs{};
 
 2004  LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
 
 2005  QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
 
 2006  QualType VTTTy = getContext().getPointerType(Q);
 
 2007  return AddedStructorArgs::prefix({{VTT, VTTTy}});
 
 2010llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
 
 2013  GlobalDecl GD(DD, 
Type);
 
 2017void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
 
 2018                                       const CXXDestructorDecl *DD,
 
 2022  GlobalDecl GD(DD, 
Type);
 
 2025  QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
 
 2028  if (getContext().getLangOpts().AppleKext &&
 
 2035                            ThisTy, VTT, VTTTy, 
nullptr);
 
 2039template <
typename T>
 
 2042    if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
 
 
 2055                                              llvm::GlobalVariable *VTable,
 
 2057  if (VTable->getDLLStorageClass() !=
 
 2058          llvm::GlobalVariable::DefaultStorageClass ||
 
 2064      VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
 
 2066    VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
 
 
 2069void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
 
 2070                                          const CXXRecordDecl *RD) {
 
 2071  llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());
 
 2072  if (VTable->hasInitializer())
 
 2075  ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
 
 2077  llvm::GlobalVariable::LinkageTypes 
Linkage = CGM.getVTableLinkage(RD);
 
 2078  llvm::Constant *RTTI =
 
 2079      CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getCanonicalTagType(RD));
 
 2082  ConstantInitBuilder builder(CGM);
 
 2083  auto components = builder.beginStruct();
 
 2085                               llvm::GlobalValue::isLocalLinkage(
Linkage));
 
 2086  components.finishAndSetAsInitializer(VTable);
 
 2091  if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
 
 2092    VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
 
 2094  if (CGM.getTarget().hasPS4DLLImportExport())
 
 2098  CGM.setGVProperties(VTable, RD);
 
 2109    EmitFundamentalRTTIDescriptors(RD);
 
 2116  if (!VTable->isDeclarationForLinker() ||
 
 2117      CGM.getCodeGenOpts().WholeProgramVTables) {
 
 2118    CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
 
 2122    if (VTable->isDeclarationForLinker()) {
 
 2123      assert(CGM.getCodeGenOpts().WholeProgramVTables);
 
 2124      CGM.addCompilerUsedGlobal(VTable);
 
 2130    if (!VTable->isDSOLocal())
 
 2135  if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
 
 2136    DI->emitVTableSymbol(VTable, RD);
 
 2139bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
 
 2140    CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
 
 2143  return NeedsVTTParameter(CGF.
CurGD);
 
 2146llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
 
 2147    CodeGenFunction &CGF, 
const CXXRecordDecl *VTableClass, BaseSubobject Base,
 
 2148    const CXXRecordDecl *NearestVBase) {
 
 2150  if ((
Base.getBase()->getNumVBases() || NearestVBase != 
nullptr) &&
 
 2151      NeedsVTTParameter(CGF.
CurGD)) {
 
 2152    return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
 
 2155  return getVTableAddressPoint(Base, VTableClass);
 
 2159ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
 
 2160                                     const CXXRecordDecl *VTableClass) {
 
 2161  llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());
 
 2165  const VTableLayout &Layout =
 
 2166      CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
 
 2167  VTableLayout::AddressPointLocation AddressPoint =
 
 2169  llvm::Value *Indices[] = {
 
 2170    llvm::ConstantInt::get(CGM.Int32Ty, 0),
 
 2171    llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
 
 2177  unsigned ComponentSize =
 
 2178      CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
 
 2179  unsigned VTableSize =
 
 2182  llvm::ConstantRange InRange(
 
 2183      llvm::APInt(32, (
int)-Offset, 
true),
 
 2184      llvm::APInt(32, (
int)(VTableSize - Offset), 
true));
 
 2185  return llvm::ConstantExpr::getGetElementPtr(
 
 2186      VTable->getValueType(), VTable, Indices, 
true, InRange);
 
 2189llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
 
 2190    CodeGenFunction &CGF, 
const CXXRecordDecl *VTableClass, BaseSubobject Base,
 
 2191    const CXXRecordDecl *NearestVBase) {
 
 2192  assert((
Base.getBase()->getNumVBases() || NearestVBase != 
nullptr) &&
 
 2193         NeedsVTTParameter(CGF.
CurGD) && 
"This class doesn't have VTT");
 
 2197      CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
 
 2201  if (VirtualPointerIndex)
 
 2203                                                 VirtualPointerIndex);
 
 2220llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
 
 2221                                                     CharUnits VPtrOffset) {
 
 2222  assert(VPtrOffset.
isZero() && 
"Itanium ABI only supports zero vptr offsets");
 
 2224  llvm::GlobalVariable *&VTable = VTables[RD];
 
 2229  CGM.addDeferredVTable(RD);
 
 2231  SmallString<256> Name;
 
 2232  llvm::raw_svector_ostream 
Out(Name);
 
 2233  getMangleContext().mangleCXXVTable(RD, Out);
 
 2235  const VTableLayout &VTLayout =
 
 2236      CGM.getItaniumVTableContext().getVTableLayout(RD);
 
 2237  llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
 
 2242  unsigned PAlign = CGM.getVtableGlobalVarAlignment();
 
 2244  VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
 
 2245      Name, VTableType, llvm::GlobalValue::ExternalLinkage,
 
 2246      getContext().toCharUnitsFromBits(PAlign).getAsAlign());
 
 2247  VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
 2249  if (CGM.getTarget().hasPS4DLLImportExport())
 
 2252  CGM.setGVProperties(VTable, RD);
 
 2256CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
 
 2260                                                  SourceLocation Loc) {
 
 2261  llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
 
 2263  llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
 
 2265  uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
 
 2266  llvm::Value *VFunc, *VTableSlotPtr = 
nullptr;
 
 2267  auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
 
 2269  llvm::Type *ComponentTy = CGM.getVTables().getVTableComponentType();
 
 2271      VTableIndex * CGM.getDataLayout().getTypeSizeInBits(ComponentTy) / 8;
 
 2279    llvm::Value *VFuncLoad;
 
 2280    if (CGM.getItaniumVTableContext().isRelativeLayout()) {
 
 2281      VFuncLoad = CGF.
Builder.CreateCall(
 
 2282          CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
 
 2283          {VTable, llvm::ConstantInt::get(CGM.Int32Ty, ByteOffset)});
 
 2285      VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
 
 2286          PtrTy, VTable, VTableIndex, 
"vfn");
 
 2297    if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
 
 2298        CGM.getCodeGenOpts().StrictVTablePointers) {
 
 2299      if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
 
 2300        VFuncLoadInstr->setMetadata(
 
 2301            llvm::LLVMContext::MD_invariant_load,
 
 2302            llvm::MDNode::get(CGM.getLLVMContext(),
 
 2303                              llvm::ArrayRef<llvm::Metadata *>()));
 
 2309  CGPointerAuthInfo PointerAuth;
 
 2311    assert(VTableSlotPtr && 
"virtual function pointer not set");
 
 2312    GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
 
 2315  CGCallee 
Callee(GD, VFunc, PointerAuth);
 
 2319llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
 
 2320    CodeGenFunction &CGF, 
const CXXDestructorDecl *Dtor, 
CXXDtorType DtorType,
 
 2321    Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
 
 2322  auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
 
 2323  auto *D = dyn_cast<const CXXDeleteExpr *>(E);
 
 2324  assert((CE != 
nullptr) ^ (D != 
nullptr));
 
 2325  assert(CE == 
nullptr || CE->arguments().empty());
 
 2328  GlobalDecl GD(Dtor, DtorType);
 
 2329  const CGFunctionInfo *FInfo =
 
 2330      &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
 
 2336    ThisTy = CE->getObjectType();
 
 2338    ThisTy = D->getDestroyedType();
 
 2342                            nullptr, QualType(), 
nullptr, CallOrInvoke);
 
 2346void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
 
 2347  CodeGenVTables &VTables = CGM.getVTables();
 
 2352bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
 
 2353    const CXXRecordDecl *RD)
 const {
 
 2356  if (CGM.getLangOpts().AppleKext)
 
 2361  if (isVTableHidden(RD))
 
 2364  if (CGM.getCodeGenOpts().ForceEmitVTables)
 
 2381  if (hasAnyUnusedVirtualInlineFunction(RD))
 
 2389    for (
const auto &B : RD->
bases()) {
 
 2390      auto *BRD = B.getType()->getAsCXXRecordDecl();
 
 2391      assert(BRD && 
"no class for base specifier");
 
 2392      if (B.isVirtual() || !BRD->isDynamicClass())
 
 2394      if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
 
 2402bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
 const {
 
 2403  if (!canSpeculativelyEmitVTableAsBaseClass(RD))
 
 2411  for (
const auto &B : RD->
vbases()) {
 
 2412    auto *BRD = B.getType()->getAsCXXRecordDecl();
 
 2413    assert(BRD && 
"no class for base specifier");
 
 2414    if (!BRD->isDynamicClass())
 
 2416    if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
 
 2425                                          int64_t NonVirtualAdjustment,
 
 2426                                          int64_t VirtualAdjustment,
 
 2427                                          bool IsReturnAdjustment) {
 
 2428  if (!NonVirtualAdjustment && !VirtualAdjustment)
 
 2434  if (NonVirtualAdjustment && !IsReturnAdjustment) {
 
 2440  llvm::Value *ResultPtr;
 
 2441  if (VirtualAdjustment) {
 
 2442    llvm::Value *VTablePtr =
 
 2445    llvm::Value *Offset;
 
 2446    llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
 
 2447        CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
 
 2454      llvm::Type *PtrDiffTy =
 
 2463                                              V.emitRawPointer(CGF), Offset);
 
 2465    ResultPtr = 
V.emitRawPointer(CGF);
 
 2470  if (NonVirtualAdjustment && IsReturnAdjustment) {
 
 2471    ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
 
 2472                                                       NonVirtualAdjustment);
 
 
 2479ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This,
 
 2480                                     const CXXRecordDecl *UnadjustedClass,
 
 2481                                     const ThunkInfo &TI) {
 
 2488ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
 
 2489                                       const CXXRecordDecl *UnadjustedClass,
 
 2490                                       const ReturnAdjustment &RA) {
 
 2496void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
 
 2497                                    RValue RV, QualType ResultType) {
 
 2499    return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
 
 2504  return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
 
 2509CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
 
 2513                  CGM.getContext().getPreferredTypeAlignInChars(elementType));
 
 2516Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
 
 2518                                             llvm::Value *NumElements,
 
 2519                                             const CXXNewExpr *
expr,
 
 2520                                             QualType ElementType) {
 
 2521  assert(requiresArrayCookie(
expr));
 
 2525  ASTContext &Ctx = getContext();
 
 2529  CharUnits CookieSize =
 
 2531  assert(CookieSize == getArrayCookieSizeImpl(ElementType));
 
 2534  Address CookiePtr = NewPtr;
 
 2535  CharUnits CookieOffset = CookieSize - SizeSize;
 
 2536  if (!CookieOffset.
isZero())
 
 2544  if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
 
 2545      (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
 
 2546       CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
 
 2548    SI->setNoSanitizeMetadata();
 
 2549    llvm::FunctionType *FTy =
 
 2550        llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(), 
false);
 
 2551    llvm::FunctionCallee F =
 
 2552        CGM.CreateRuntimeFunction(FTy, 
"__asan_poison_cxx_array_cookie");
 
 2561llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
 
 2563                                                CharUnits cookieSize) {
 
 2565  Address numElementsPtr = allocPtr;
 
 2566  CharUnits numElementsOffset = cookieSize - CGF.
getSizeSize();
 
 2567  if (!numElementsOffset.
isZero())
 
 2573  if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
 
 2580  llvm::FunctionType *FTy =
 
 2582  llvm::FunctionCallee F =
 
 2583      CGM.CreateRuntimeFunction(FTy, 
"__asan_load_cxx_array_cookie");
 
 2587CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
 
 2597                  CGM.getContext().getTypeAlignInChars(elementType));
 
 2600Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
 
 2602                                         llvm::Value *numElements,
 
 2603                                         const CXXNewExpr *
expr,
 
 2604                                         QualType elementType) {
 
 2605  assert(requiresArrayCookie(
expr));
 
 2608  Address cookie = newPtr;
 
 2612  llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
 
 2613                 getContext().getTypeSizeInChars(elementType).getQuantity());
 
 2622  CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
 
 2626llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
 
 2628                                            CharUnits cookieSize) {
 
 2631  Address numElementsPtr
 
 2641                                              llvm::PointerType *GuardPtrTy) {
 
 2643  llvm::FunctionType *FTy =
 
 2647      FTy, 
"__cxa_guard_acquire",
 
 2649                               llvm::AttributeList::FunctionIndex,
 
 2650                               llvm::Attribute::NoUnwind));
 
 
 2654                                              llvm::PointerType *GuardPtrTy) {
 
 2656  llvm::FunctionType *FTy =
 
 2657    llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy, 
false);
 
 2659      FTy, 
"__cxa_guard_release",
 
 2661                               llvm::AttributeList::FunctionIndex,
 
 2662                               llvm::Attribute::NoUnwind));
 
 
 2666                                            llvm::PointerType *GuardPtrTy) {
 
 2668  llvm::FunctionType *FTy =
 
 2669    llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy, 
false);
 
 2671      FTy, 
"__cxa_guard_abort",
 
 2673                               llvm::AttributeList::FunctionIndex,
 
 2674                               llvm::Attribute::NoUnwind));
 
 
 2678  struct CallGuardAbort final : EHScopeStack::Cleanup {
 
 2679    llvm::GlobalVariable *Guard;
 
 2680    CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
 
 2682    void Emit(CodeGenFunction &CGF, Flags flags)
 override {
 
 2691void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
 
 2693                                    llvm::GlobalVariable *var,
 
 2694                                    bool shouldPerformInit) {
 
 2695  CGBuilderTy &Builder = CGF.
Builder;
 
 2699  bool NonTemplateInline =
 
 2706  bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
 
 2712  bool useInt8GuardVariable = !threadsafe && 
var->hasInternalLinkage();
 
 2714  llvm::IntegerType *guardTy;
 
 2715  CharUnits guardAlignment;
 
 2716  if (useInt8GuardVariable) {
 
 2722    if (UseARMGuardVarABI) {
 
 2731  llvm::PointerType *guardPtrTy = llvm::PointerType::get(
 
 2737  llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
 
 2740    SmallString<256> guardName;
 
 2742      llvm::raw_svector_ostream 
out(guardName);
 
 2743      getMangleContext().mangleStaticGuardVariable(&D, 
out);
 
 2749    guard = 
new llvm::GlobalVariable(CGM.getModule(), guardTy,
 
 2750                                     false, 
var->getLinkage(),
 
 2751                                     llvm::ConstantInt::get(guardTy, 0),
 
 2753    guard->setDSOLocal(
var->isDSOLocal());
 
 2754    guard->setVisibility(
var->getVisibility());
 
 2755    guard->setDLLStorageClass(
var->getDLLStorageClass());
 
 2757    guard->setThreadLocalMode(
var->getThreadLocalMode());
 
 2758    guard->setAlignment(guardAlignment.
getAsAlign());
 
 2763    llvm::Comdat *
C = 
var->getComdat();
 
 2765        (CGM.getTarget().getTriple().isOSBinFormatELF() ||
 
 2766         CGM.getTarget().getTriple().isOSBinFormatWasm())) {
 
 2767      guard->setComdat(
C);
 
 2768    } 
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
 
 2769      guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
 
 2772    CGM.setStaticLocalDeclGuardAddress(&D, guard);
 
 2775  Address guardAddr = Address(guard, guard->getValueType(), guardAlignment);
 
 2800  if (!threadsafe || MaxInlineWidthInBits) {
 
 2802    llvm::LoadInst *LI =
 
 2812      LI->setAtomic(llvm::AtomicOrdering::Acquire);
 
 2835        (UseARMGuardVarABI && !useInt8GuardVariable)
 
 2836            ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
 
 2838    llvm::Value *NeedsInit = Builder.CreateIsNull(
V, 
"guard.uninitialized");
 
 2844                                 CodeGenFunction::GuardKind::VariableGuard, &D);
 
 2872    Builder.CreateCondBr(Builder.CreateIsNotNull(
V, 
"tobool"),
 
 2873                         InitBlock, EndBlock);
 
 2883    Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
 
 2901    Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
 
 2910                                        llvm::FunctionCallee dtor,
 
 2911                                        llvm::Constant *addr, 
bool TLS) {
 
 2913         "unexpected call to emitGlobalDtorWithCXAAtExit");
 
 2915         "__cxa_atexit is disabled");
 
 2916  const char *Name = 
"__cxa_atexit";
 
 2919    Name = 
T.isOSDarwin() ?  
"_tlv_atexit" : 
"__cxa_thread_atexit";
 
 2927  auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
 
 2928  auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
 
 2932  llvm::Constant *handle =
 
 2935  GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
 
 2938  llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
 
 2939  llvm::FunctionType *atexitTy =
 
 2940    llvm::FunctionType::get(CGF.
IntTy, paramTys, 
false);
 
 2944  if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
 
 2945    fn->setDoesNotThrow();
 
 2951      Context.getFunctionType(Context.VoidTy, {Context.VoidPtrTy}, EPI);
 
 2960    addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
 
 2962  llvm::Value *args[] = {dtorCallee, addr, handle};
 
 
 2970  llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy, 
false);
 
 2974  return GlobalInitOrCleanupFn;
 
 
 2977void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
 
 2978  for (
const auto &I : DtorsUsingAtExit) {
 
 2979    int Priority = I.first;
 
 2980    std::string GlobalCleanupFnName =
 
 2981        std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
 
 2983    llvm::Function *GlobalCleanupFn =
 
 2986    CodeGenFunction CGF(*
this);
 
 2987    CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalCleanupFn,
 
 2988                      getTypes().arrangeNullaryFunction(), FunctionArgList(),
 
 2989                      SourceLocation(), SourceLocation());
 
 2993    llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy, 
false);
 
 2997    const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
 
 2998    auto itv = Dtors.rbegin();
 
 2999    while (itv != Dtors.rend()) {
 
 3000      llvm::Function *Dtor = *itv;
 
 3005      llvm::Value *NeedsDestruct =
 
 3008      llvm::BasicBlock *DestructCallBlock =
 
 3011          (itv + 1) != Dtors.rend() ? 
"unatexit.call" : 
"destruct.end");
 
 3014      CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
 
 3019      llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
 
 3021      CI->setCallingConv(Dtor->getCallingConv());
 
 3029    AddGlobalDtor(GlobalCleanupFn, Priority);
 
 3033void CodeGenModule::registerGlobalDtorsWithAtExit() {
 
 3034  for (
const auto &I : DtorsUsingAtExit) {
 
 3035    int Priority = I.first;
 
 3036    std::string GlobalInitFnName =
 
 3037        std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
 
 3038    llvm::Function *GlobalInitFn =
 
 3041    CodeGenFunction CGF(*
this);
 
 3042    CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalInitFn,
 
 3043                      getTypes().arrangeNullaryFunction(), FunctionArgList(),
 
 3044                      SourceLocation(), SourceLocation());
 
 3052    const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
 
 3053    for (
auto *Dtor : Dtors) {
 
 3056      if (getCodeGenOpts().CXAAtExit) {
 
 3066    AddGlobalCtor(GlobalInitFn, Priority);
 
 3069  if (getCXXABI().useSinitAndSterm())
 
 3070    unregisterGlobalDtorsWithUnAtExit();
 
 3074void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, 
const VarDecl &D,
 
 3075                                       llvm::FunctionCallee dtor,
 
 3076                                       llvm::Constant *addr) {
 
 3081  if (CGM.getLangOpts().HLSL)
 
 3082    return CGM.AddCXXDtorEntry(dtor, addr);
 
 3096  if (CGM.getCodeGenOpts().CXAAtExit || D.
getTLSKind())
 
 3101  if (CGM.getLangOpts().AppleKext) {
 
 3103    return CGM.AddCXXDtorEntry(dtor, addr);
 
 3111  assert(!VD->
isStaticLocal() && 
"static local VarDecls don't need wrappers!");
 
 
 3121static llvm::GlobalValue::LinkageTypes
 
 3123  llvm::GlobalValue::LinkageTypes VarLinkage =
 
 3127  if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
 
 3132    if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
 
 3133        !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
 
 3135  return llvm::GlobalValue::WeakODRLinkage;
 
 
 3139ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
 
 3142  SmallString<256> WrapperName;
 
 3144    llvm::raw_svector_ostream 
Out(WrapperName);
 
 3145    getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
 
 3150  if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
 
 3153  QualType RetQT = VD->
getType();
 
 3157  const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
 
 3158      getContext().getPointerType(RetQT), FunctionArgList());
 
 3160  llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
 
 3161  llvm::Function *Wrapper =
 
 3163                             WrapperName.str(), &CGM.getModule());
 
 3165  if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
 
 3166    Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
 
 3168  CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper, 
false);
 
 3171  if (!Wrapper->hasLocalLinkage())
 
 3173        llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
 
 3174        llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
 
 3176      Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
 
 3179    Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
 
 3180    Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
 
 3183  ThreadWrappers.push_back({VD, Wrapper});
 
 3187void ItaniumCXXABI::EmitThreadLocalInitFuncs(
 
 3188    CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
 
 3189    ArrayRef<llvm::Function *> CXXThreadLocalInits,
 
 3190    ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
 
 3191  llvm::Function *InitFunc = 
nullptr;
 
 3195  llvm::SmallVector<llvm::Function *, 8> OrderedInits;
 
 3196  llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
 
 3197  for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
 
 3200      UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
 
 3201          CXXThreadLocalInits[I];
 
 3203      OrderedInits.push_back(CXXThreadLocalInits[I]);
 
 3206  if (!OrderedInits.empty()) {
 
 3208    llvm::FunctionType *FTy =
 
 3209        llvm::FunctionType::get(CGM.
VoidTy, 
false);
 
 3214    llvm::GlobalVariable *Guard = 
new llvm::GlobalVariable(
 
 3216        llvm::GlobalVariable::InternalLinkage,
 
 3217        llvm::ConstantInt::get(CGM.
Int8Ty, 0), 
"__tls_guard");
 
 3218    Guard->setThreadLocal(
true);
 
 3222    Guard->setAlignment(GuardAlign.
getAsAlign());
 
 3224    CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(
 
 3225        InitFunc, OrderedInits, ConstantAddress(Guard, CGM.
Int8Ty, GuardAlign));
 
 3228      InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
 
 3229      InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
 
 3235  for (
const VarDecl *VD : CXXThreadLocals) {
 
 3239      getOrCreateThreadLocalWrapper(VD, GV);
 
 3244  for (
auto VDAndWrapper : ThreadWrappers) {
 
 3245    const VarDecl *VD = VDAndWrapper.first;
 
 3246    llvm::GlobalVariable *Var =
 
 3248    llvm::Function *Wrapper = VDAndWrapper.second;
 
 3255        Wrapper->setLinkage(llvm::Function::ExternalLinkage);
 
 3261      if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
 
 3262        Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
 
 3268    SmallString<256> InitFnName;
 
 3270      llvm::raw_svector_ostream 
Out(InitFnName);
 
 3271      getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
 
 3274    llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy, 
false);
 
 3279    llvm::GlobalValue *
Init = 
nullptr;
 
 3280    bool InitIsInitFunc = 
false;
 
 3281    bool HasConstantInitialization = 
false;
 
 3282    if (!usesThreadWrapperFunction(VD)) {
 
 3283      HasConstantInitialization = 
true;
 
 3285      InitIsInitFunc = 
true;
 
 3286      llvm::Function *InitFuncToUse = InitFunc;
 
 3290        Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
 
 3297      Init = llvm::Function::Create(InitFnTy,
 
 3298                                    llvm::GlobalVariable::ExternalWeakLinkage,
 
 3306      Init->setVisibility(Var->getVisibility());
 
 3308      if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
 
 3309        Init->setDSOLocal(Var->isDSOLocal());
 
 3312    llvm::LLVMContext &Context = CGM.
getModule().getContext();
 
 3320        isEmittedWithConstantInitializer(VD, 
true) &&
 
 3321        !mayNeedDestruction(VD)) {
 
 3326      assert(
Init == 
nullptr && 
"Expected Init to be null.");
 
 3328      llvm::Function *
Func = llvm::Function::Create(
 
 3329          InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
 
 3335      llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, 
"", 
Func);
 
 3336      CGBuilderTy Builder(CGM, Entry);
 
 3337      Builder.CreateRetVoid();
 
 3340    llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context, 
"", Wrapper);
 
 3341    CGBuilderTy Builder(CGM, Entry);
 
 3342    if (HasConstantInitialization) {
 
 3344    } 
else if (InitIsInitFunc) {
 
 3346        llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy, 
Init);
 
 3348          CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
 
 3349          llvm::Function *
Fn =
 
 3351          Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
 
 3362      Builder.CreateCall(InitFnTy, 
Init);
 
 3365      llvm::Value *Have = Builder.CreateIsNotNull(
Init);
 
 3366      llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context, 
"", Wrapper);
 
 3367      llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context, 
"", Wrapper);
 
 3368      Builder.CreateCondBr(Have, InitBB, ExitBB);
 
 3370      Builder.SetInsertPoint(InitBB);
 
 3371      Builder.CreateCall(InitFnTy, 
Init);
 
 3372      Builder.CreateBr(ExitBB);
 
 3374      Builder.SetInsertPoint(ExitBB);
 
 3379    llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
 
 3383      Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
 
 3385    Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());
 
 3387    Builder.CreateRet(Val);
 
 3391LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
 
 3393                                                   QualType LValType) {
 
 3395  llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
 
 3397  llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
 
 3398  CallVal->setCallingConv(Wrapper->getCallingConv());
 
 3412bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
 
 3431ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
 
 3432  SmallString<256> MethodName;
 
 3433  llvm::raw_svector_ostream 
Out(MethodName);
 
 3434  getMangleContext().mangleCXXName(MD, Out);
 
 3435  MethodName += 
"_vfpthunk_";
 
 3436  StringRef ThunkName = MethodName.str();
 
 3437  llvm::Function *ThunkFn;
 
 3438  if ((ThunkFn = cast_or_null<llvm::Function>(
 
 3439           CGM.
getModule().getNamedValue(ThunkName))))
 
 3444  llvm::GlobalValue::LinkageTypes 
Linkage =
 
 3446                                : llvm::GlobalValue::InternalLinkage;
 
 3449  if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
 
 3450    ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
 
 3451  assert(ThunkFn->getName() == ThunkName && 
"name was uniqued!");
 
 3457  ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
 
 3458  ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
 
 3459  ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
 
 3462  CodeGenFunction CGF(CGM);
 
 3463  CGF.
CurGD = GlobalDecl(MD);
 
 3467  FunctionArgList FunctionArgs;
 
 3471                    FunctionArgs, MD->
getLocation(), SourceLocation());
 
 3472  llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
 
 3473  setCXXABIThisValue(CGF, ThisVal);
 
 3475  CallArgList CallArgs;
 
 3476  for (
const VarDecl *VD : FunctionArgs)
 
 3479  const FunctionProtoType *FPT = MD->
getType()->
getAs<FunctionProtoType>();
 
 3481  const CGFunctionInfo &CallInfo =
 
 3484                                         getThisAddress(CGF), ThunkTy);
 
 3485  llvm::CallBase *CallOrInvoke;
 
 3486  CGF.
EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke,
 
 3487               true, SourceLocation(), 
true);
 
 3489  Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
 
 3490  if (
Call->getType()->isVoidTy())
 
 3503class ItaniumRTTIBuilder {
 
 3505  llvm::LLVMContext &VMContext;
 
 3506  const ItaniumCXXABI &
CXXABI;  
 
 3509  SmallVector<llvm::Constant *, 16> Fields;
 
 3512  llvm::GlobalVariable *
 
 3513  GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes 
Linkage);
 
 3517  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
 
 3520  void BuildVTablePointer(
const Type *Ty, llvm::Constant *StorageAddress);
 
 3524  void BuildSIClassTypeInfo(
const CXXRecordDecl *RD);
 
 3529  void BuildVMIClassTypeInfo(
const CXXRecordDecl *RD);
 
 3533  void BuildPointerTypeInfo(QualType PointeeTy);
 
 3537  void BuildObjCObjectTypeInfo(
const ObjCObjectType *Ty);
 
 3541  void BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty);
 
 3544  ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
 
 3545      : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), 
CXXABI(ABI) {}
 
 3559    PTI_Incomplete = 0x8,
 
 3563    PTI_ContainingClassIncomplete = 0x10,
 
 3569    PTI_Noexcept = 0x40,
 
 3575    VMI_NonDiamondRepeat = 0x1,
 
 3578    VMI_DiamondShaped = 0x2
 
 3592  llvm::Constant *BuildTypeInfo(QualType Ty);
 
 3595  llvm::Constant *BuildTypeInfo(
 
 3597      llvm::GlobalVariable::LinkageTypes 
Linkage,
 
 3598      llvm::GlobalValue::VisibilityTypes 
Visibility,
 
 3599      llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
 
 3603llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
 
 3604    QualType Ty, llvm::GlobalVariable::LinkageTypes 
Linkage) {
 
 3605  SmallString<256> Name;
 
 3606  llvm::raw_svector_ostream 
Out(Name);
 
 3612  llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
 
 3619  GV->setInitializer(
Init);
 
 3625ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
 
 3627  SmallString<256> Name;
 
 3628  llvm::raw_svector_ostream 
Out(Name);
 
 3632  llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
 
 3639    GV = 
new llvm::GlobalVariable(
 
 3641        true, llvm::GlobalValue::ExternalLinkage, 
nullptr, Name);
 
 3648        GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
 
 3675    case BuiltinType::Void:
 
 3676    case BuiltinType::NullPtr:
 
 3677    case BuiltinType::Bool:
 
 3678    case BuiltinType::WChar_S:
 
 3679    case BuiltinType::WChar_U:
 
 3680    case BuiltinType::Char_U:
 
 3681    case BuiltinType::Char_S:
 
 3682    case BuiltinType::UChar:
 
 3683    case BuiltinType::SChar:
 
 3684    case BuiltinType::Short:
 
 3685    case BuiltinType::UShort:
 
 3686    case BuiltinType::Int:
 
 3687    case BuiltinType::UInt:
 
 3688    case BuiltinType::Long:
 
 3689    case BuiltinType::ULong:
 
 3690    case BuiltinType::LongLong:
 
 3691    case BuiltinType::ULongLong:
 
 3692    case BuiltinType::Half:
 
 3693    case BuiltinType::Float:
 
 3694    case BuiltinType::Double:
 
 3695    case BuiltinType::LongDouble:
 
 3696    case BuiltinType::Float16:
 
 3697    case BuiltinType::Float128:
 
 3698    case BuiltinType::Ibm128:
 
 3699    case BuiltinType::Char8:
 
 3700    case BuiltinType::Char16:
 
 3701    case BuiltinType::Char32:
 
 3702    case BuiltinType::Int128:
 
 3703    case BuiltinType::UInt128:
 
 3706#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 
 3707    case BuiltinType::Id: 
 3708#include "clang/Basic/OpenCLImageTypes.def" 
 3709#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 
 3710    case BuiltinType::Id: 
 3711#include "clang/Basic/OpenCLExtensionTypes.def" 
 3712    case BuiltinType::OCLSampler:
 
 3713    case BuiltinType::OCLEvent:
 
 3714    case BuiltinType::OCLClkEvent:
 
 3715    case BuiltinType::OCLQueue:
 
 3716    case BuiltinType::OCLReserveID:
 
 3717#define SVE_TYPE(Name, Id, SingletonId) \ 
 3718    case BuiltinType::Id: 
 3719#include "clang/Basic/AArch64ACLETypes.def" 
 3720#define PPC_VECTOR_TYPE(Name, Id, Size) \ 
 3721    case BuiltinType::Id: 
 3722#include "clang/Basic/PPCTypes.def" 
 3723#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id: 
 3724#include "clang/Basic/RISCVVTypes.def" 
 3725#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id: 
 3726#include "clang/Basic/WebAssemblyReferenceTypes.def" 
 3727#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id: 
 3728#include "clang/Basic/AMDGPUTypes.def" 
 3729#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id: 
 3730#include "clang/Basic/HLSLIntangibleTypes.def" 
 3731    case BuiltinType::ShortAccum:
 
 3732    case BuiltinType::Accum:
 
 3733    case BuiltinType::LongAccum:
 
 3734    case BuiltinType::UShortAccum:
 
 3735    case BuiltinType::UAccum:
 
 3736    case BuiltinType::ULongAccum:
 
 3737    case BuiltinType::ShortFract:
 
 3738    case BuiltinType::Fract:
 
 3739    case BuiltinType::LongFract:
 
 3740    case BuiltinType::UShortFract:
 
 3741    case BuiltinType::UFract:
 
 3742    case BuiltinType::ULongFract:
 
 3743    case BuiltinType::SatShortAccum:
 
 3744    case BuiltinType::SatAccum:
 
 3745    case BuiltinType::SatLongAccum:
 
 3746    case BuiltinType::SatUShortAccum:
 
 3747    case BuiltinType::SatUAccum:
 
 3748    case BuiltinType::SatULongAccum:
 
 3749    case BuiltinType::SatShortFract:
 
 3750    case BuiltinType::SatFract:
 
 3751    case BuiltinType::SatLongFract:
 
 3752    case BuiltinType::SatUShortFract:
 
 3753    case BuiltinType::SatUFract:
 
 3754    case BuiltinType::SatULongFract:
 
 3755    case BuiltinType::BFloat16:
 
 3758    case BuiltinType::Dependent:
 
 3759#define BUILTIN_TYPE(Id, SingletonId) 
 3760#define PLACEHOLDER_TYPE(Id, SingletonId) \ 
 3761    case BuiltinType::Id: 
 3762#include "clang/AST/BuiltinTypes.def" 
 3763      llvm_unreachable(
"asking for RRTI for a placeholder type!");
 
 3765    case BuiltinType::ObjCId:
 
 3766    case BuiltinType::ObjCClass:
 
 3767    case BuiltinType::ObjCSel:
 
 3768      llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
 
 3771  llvm_unreachable(
"Invalid BuiltinType Kind!");
 
 
 3776  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
 
 
 3794  if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
 
 3799  if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
 
 
 3815  if (!Context.getLangOpts().RTTI) 
return false;
 
 3817  if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
 
 3830    bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
 
 3840      return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
 
 
 3853  return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
 
 
 3868  if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
 
 3873  if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
 
 3877      dyn_cast<MemberPointerType>(Ty)) {
 
 3879    if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
 
 
 3900  if (
Base->isVirtual())
 
 3908  auto *BaseDecl = 
Base->getType()->castAsCXXRecordDecl();
 
 3909  if (!BaseDecl->isEmpty() &&
 
 
 3916void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty,
 
 3917                                            llvm::Constant *StorageAddress) {
 
 3919  static const char * 
const ClassTypeInfo =
 
 3920    "_ZTVN10__cxxabiv117__class_type_infoE";
 
 3922  static const char * 
const SIClassTypeInfo =
 
 3923    "_ZTVN10__cxxabiv120__si_class_type_infoE";
 
 3925  static const char * 
const VMIClassTypeInfo =
 
 3926    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
 
 3928  const char *VTableName = 
nullptr;
 
 3931#define TYPE(Class, Base) 
 3932#define ABSTRACT_TYPE(Class, Base) 
 3933#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 
 3934#define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 
 3935#define DEPENDENT_TYPE(Class, Base) case Type::Class: 
 3936#include "clang/AST/TypeNodes.inc" 
 3937    llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
 
 3939  case Type::LValueReference:
 
 3940  case Type::RValueReference:
 
 3941    llvm_unreachable(
"References shouldn't get here");
 
 3944  case Type::DeducedTemplateSpecialization:
 
 3945    llvm_unreachable(
"Undeduced type shouldn't get here");
 
 3948    llvm_unreachable(
"Pipe types shouldn't get here");
 
 3950  case Type::ArrayParameter:
 
 3951    llvm_unreachable(
"Array Parameter types should not get here.");
 
 3957  case Type::ExtVector:
 
 3958  case Type::ConstantMatrix:
 
 3962  case Type::BlockPointer:
 
 3964    VTableName = 
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
 
 3967  case Type::ConstantArray:
 
 3968  case Type::IncompleteArray:
 
 3969  case Type::VariableArray:
 
 3971    VTableName = 
"_ZTVN10__cxxabiv117__array_type_infoE";
 
 3974  case Type::FunctionNoProto:
 
 3975  case Type::FunctionProto:
 
 3977    VTableName = 
"_ZTVN10__cxxabiv120__function_type_infoE";
 
 3982    VTableName = 
"_ZTVN10__cxxabiv116__enum_type_infoE";
 
 3985  case Type::Record: {
 
 3987                         ->getDefinitionOrSelf();
 
 3990      VTableName = ClassTypeInfo;
 
 3992      VTableName = SIClassTypeInfo;
 
 3994      VTableName = VMIClassTypeInfo;
 
 4000  case Type::ObjCObject:
 
 4006      VTableName = ClassTypeInfo;
 
 4013  case Type::ObjCInterface:
 
 4015      VTableName = SIClassTypeInfo;
 
 4017      VTableName = ClassTypeInfo;
 
 4021  case Type::ObjCObjectPointer:
 
 4024    VTableName = 
"_ZTVN10__cxxabiv119__pointer_type_infoE";
 
 4027  case Type::MemberPointer:
 
 4029    VTableName = 
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
 
 4032  case Type::HLSLAttributedResource:
 
 4033  case Type::HLSLInlineSpirv:
 
 4034    llvm_unreachable(
"HLSL doesn't support virtual functions");
 
 4037  llvm::Constant *VTable = 
nullptr;
 
 4041    VTable = CGM.
getModule().getNamedAlias(VTableName);
 
 4044    VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
 
 4049  llvm::Type *PtrDiffTy =
 
 4056    llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
 
 4058        llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8Ty, VTable, Eight);
 
 4060    llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
 
 4061    VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
 
 4065  if (
const auto &Schema =
 
 4069        Schema.isAddressDiscriminated() ? StorageAddress : 
nullptr,
 
 4070        GlobalDecl(), QualType(Ty, 0));
 
 4072  Fields.push_back(VTable);
 
 4089    return llvm::GlobalValue::InternalLinkage;
 
 4093    llvm_unreachable(
"Linkage hasn't been computed!");
 
 4098    return llvm::GlobalValue::InternalLinkage;
 
 4106      return llvm::GlobalValue::LinkOnceODRLinkage;
 
 4108    if (
const RecordType *
Record = dyn_cast<RecordType>(Ty)) {
 
 4112        return llvm::GlobalValue::WeakODRLinkage;
 
 4113      if (CGM.
getTriple().isWindowsItaniumEnvironment())
 
 4114        if (RD->
hasAttr<DLLImportAttr>() &&
 
 4116          return llvm::GlobalValue::ExternalLinkage;
 
 4123    return llvm::GlobalValue::LinkOnceODRLinkage;
 
 4126  llvm_unreachable(
"Invalid linkage!");
 
 
 4129llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) {
 
 4134  SmallString<256> Name;
 
 4135  llvm::raw_svector_ostream 
Out(Name);
 
 4138  llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
 
 4139  if (OldGV && !OldGV->isDeclaration()) {
 
 4140    assert(!OldGV->hasAvailableExternallyLinkage() &&
 
 4141           "available_externally typeinfos not yet implemented");
 
 4149    return GetAddrOfExternalRTTIDescriptor(Ty);
 
 4156  llvm::GlobalValue::VisibilityTypes llvmVisibility;
 
 4157  if (llvm::GlobalValue::isLocalLinkage(
Linkage))
 
 4159    llvmVisibility = llvm::GlobalValue::DefaultVisibility;
 
 4161           ItaniumCXXABI::RUK_NonUniqueHidden)
 
 4162    llvmVisibility = llvm::GlobalValue::HiddenVisibility;
 
 4166  llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
 
 4167      llvm::GlobalValue::DefaultStorageClass;
 
 4169    if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
 
 4170         RD->
hasAttr<DLLExportAttr>()) ||
 
 4172         !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
 
 4173         llvmVisibility == llvm::GlobalValue::DefaultVisibility))
 
 4174      DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
 
 4176  return BuildTypeInfo(Ty, 
Linkage, llvmVisibility, DLLStorageClass);
 
 4179llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
 
 4181      llvm::GlobalVariable::LinkageTypes 
Linkage,
 
 4182      llvm::GlobalValue::VisibilityTypes 
Visibility,
 
 4183      llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
 
 4184  SmallString<256> Name;
 
 4185  llvm::raw_svector_ostream 
Out(Name);
 
 4188  llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
 
 4190  llvm::GlobalVariable *GV =
 
 4199  llvm::Constant *TypeNameField;
 
 4203  ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
 
 4205  if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
 
 4208    TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
 
 4209    llvm::Constant *flag =
 
 4210        llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
 
 4211    TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
 
 4217  Fields.push_back(TypeNameField);
 
 4220#define TYPE(Class, Base) 
 4221#define ABSTRACT_TYPE(Class, Base) 
 4222#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 
 4223#define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 
 4224#define DEPENDENT_TYPE(Class, Base) case Type::Class: 
 4225#include "clang/AST/TypeNodes.inc" 
 4226    llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
 
 4231  case Type::ExtVector:
 
 4232  case Type::ConstantMatrix:
 
 4234  case Type::BlockPointer:
 
 4239  case Type::LValueReference:
 
 4240  case Type::RValueReference:
 
 4241    llvm_unreachable(
"References shouldn't get here");
 
 4244  case Type::DeducedTemplateSpecialization:
 
 4245    llvm_unreachable(
"Undeduced type shouldn't get here");
 
 4253  case Type::ConstantArray:
 
 4254  case Type::IncompleteArray:
 
 4255  case Type::VariableArray:
 
 4256  case Type::ArrayParameter:
 
 4261  case Type::FunctionNoProto:
 
 4262  case Type::FunctionProto:
 
 4272  case Type::Record: {
 
 4274                         ->getDefinitionOrSelf();
 
 4281      BuildSIClassTypeInfo(RD);
 
 4283      BuildVMIClassTypeInfo(RD);
 
 4288  case Type::ObjCObject:
 
 4289  case Type::ObjCInterface:
 
 4293  case Type::ObjCObjectPointer:
 
 4301  case Type::MemberPointer:
 
 4309  case Type::HLSLAttributedResource:
 
 4310  case Type::HLSLInlineSpirv:
 
 4311    llvm_unreachable(
"HLSL doesn't support RTTI");
 
 4314  GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));
 
 4317  auto GVDLLStorageClass = DLLStorageClass;
 
 4319      GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
 
 4320    if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
 
 4323      if (RD->
hasAttr<DLLExportAttr>() ||
 
 4325        GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
 
 4331    GV->takeName(OldGV);
 
 4332    OldGV->replaceAllUsesWith(GV);
 
 4333    OldGV->eraseFromParent();
 
 4337    GV->setComdat(M.getOrInsertComdat(GV->getName()));
 
 4364  TypeName->setDLLStorageClass(DLLStorageClass);
 
 4365  GV->setDLLStorageClass(GVDLLStorageClass);
 
 4375void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
 
 4377  const Type *
T = OT->getBaseType().getTypePtr();
 
 4385  ObjCInterfaceDecl *Super = 
Class->getSuperClass();
 
 4393  llvm::Constant *BaseTypeInfo =
 
 4394      ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
 
 4395  Fields.push_back(BaseTypeInfo);
 
 4400void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
 
 4404  llvm::Constant *BaseTypeInfo =
 
 4406  Fields.push_back(BaseTypeInfo);
 
 4413    llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
 
 4414    llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
 
 4426  auto *BaseDecl = 
Base->getType()->castAsCXXRecordDecl();
 
 4427  if (
Base->isVirtual()) {
 
 4429    if (!Bases.VirtualBases.insert(BaseDecl).second) {
 
 4432      Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
 
 4434      if (Bases.NonVirtualBases.count(BaseDecl))
 
 4435        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
 
 4439    if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
 
 4442      Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
 
 4444      if (Bases.VirtualBases.count(BaseDecl))
 
 4445        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
 
 4450  for (
const auto &I : BaseDecl->bases())
 
 
 4461  for (
const auto &I : RD->
bases())
 
 
 4470void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
 
 4471  llvm::Type *UnsignedIntLTy =
 
 4479  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
 
 4484  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
 
 4517  llvm::Type *OffsetFlagsLTy =
 
 4520  for (
const auto &Base : RD->
bases()) {
 
 4522    Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
 
 4524    auto *BaseDecl = 
Base.getType()->castAsCXXRecordDecl();
 
 4532    if (
Base.isVirtual())
 
 4544    if (
Base.isVirtual())
 
 4545      OffsetFlags |= BCTI_Virtual;
 
 4547      OffsetFlags |= BCTI_Public;
 
 4549    Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
 
 4558  if (
Type.isConstQualified())
 
 4559    Flags |= ItaniumRTTIBuilder::PTI_Const;
 
 4560  if (
Type.isVolatileQualified())
 
 4561    Flags |= ItaniumRTTIBuilder::PTI_Volatile;
 
 4562  if (
Type.isRestrictQualified())
 
 4563    Flags |= ItaniumRTTIBuilder::PTI_Restrict;
 
 4570    Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
 
 4573    if (Proto->isNothrow()) {
 
 4574      Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
 
 
 4584void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
 
 4590  llvm::Type *UnsignedIntLTy =
 
 4592  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
 
 4597  llvm::Constant *PointeeTypeInfo =
 
 4598      ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
 
 4599  Fields.push_back(PointeeTypeInfo);
 
 4605ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty) {
 
 4615    Flags |= PTI_ContainingClassIncomplete;
 
 4617  llvm::Type *UnsignedIntLTy =
 
 4619  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
 
 4624  llvm::Constant *PointeeTypeInfo =
 
 4625      ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
 
 4626  Fields.push_back(PointeeTypeInfo);
 
 4633  Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
T));
 
 4636llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
 
 4637  return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
 
 4640void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
 
 4642  QualType FundamentalTypes[] = {
 
 4643      getContext().VoidTy,             getContext().NullPtrTy,
 
 4644      getContext().BoolTy,             getContext().WCharTy,
 
 4645      getContext().CharTy,             getContext().UnsignedCharTy,
 
 4646      getContext().SignedCharTy,       getContext().ShortTy,
 
 4647      getContext().UnsignedShortTy,    getContext().IntTy,
 
 4648      getContext().UnsignedIntTy,      getContext().LongTy,
 
 4649      getContext().UnsignedLongTy,     getContext().LongLongTy,
 
 4650      getContext().UnsignedLongLongTy, getContext().Int128Ty,
 
 4651      getContext().UnsignedInt128Ty,   getContext().HalfTy,
 
 4652      getContext().FloatTy,            getContext().DoubleTy,
 
 4653      getContext().LongDoubleTy,       getContext().Float128Ty,
 
 4654      getContext().Char8Ty,            getContext().Char16Ty,
 
 4655      getContext().Char32Ty
 
 4657  llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
 
 4659          ? llvm::GlobalValue::DLLExportStorageClass
 
 4660          : llvm::GlobalValue::DefaultStorageClass;
 
 4661  llvm::GlobalValue::VisibilityTypes 
Visibility =
 
 4663  for (
const QualType &FundamentalType : FundamentalTypes) {
 
 4664    QualType PointerType = getContext().getPointerType(FundamentalType);
 
 4665    QualType PointerTypeConst = getContext().getPointerType(
 
 4666        FundamentalType.withConst());
 
 4667    for (QualType 
Type : {FundamentalType, PointerType, PointerTypeConst})
 
 4668      ItaniumRTTIBuilder(*this).BuildTypeInfo(
 
 4669          Type, llvm::GlobalValue::ExternalLinkage,
 
 4676ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
 
 4677    QualType CanTy, llvm::GlobalValue::LinkageTypes 
Linkage)
 const {
 
 4678  if (shouldRTTIBeUnique())
 
 4682  if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
 
 4683      Linkage != llvm::GlobalValue::WeakODRLinkage)
 
 4691  if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
 
 4692    return RUK_NonUniqueHidden;
 
 4697  assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
 
 4698  return RUK_NonUniqueVisible;
 
 4703enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
 
 4708    return StructorCodegen::Emit;
 
 4713    return StructorCodegen::Emit;
 
 4716  if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
 
 4724  if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
 
 4725    return StructorCodegen::RAUW;
 
 4728  if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
 
 4729    return StructorCodegen::RAUW;
 
 4731  if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
 
 4735      return StructorCodegen::COMDAT;
 
 4736    return StructorCodegen::Emit;
 
 4739  return StructorCodegen::Alias;
 
 
 4749  if (Entry && !Entry->isDeclaration())
 
 4755  auto *Alias = llvm::GlobalAlias::create(
Linkage, 
"", Aliasee);
 
 4758  Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
 4762    assert(Entry->getType() == Aliasee->getType() &&
 
 4763           "declaration exists with different type");
 
 4764    Alias->takeName(Entry);
 
 4765    Entry->replaceAllUsesWith(Alias);
 
 4766    Entry->eraseFromParent();
 
 4768    Alias->setName(MangledName);
 
 
 4775void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
 
 4777  auto *CD = dyn_cast<CXXConstructorDecl>(MD);
 
 4784    GlobalDecl BaseDecl;
 
 4790    if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
 
 4795    if (CGType == StructorCodegen::RAUW) {
 
 4808      CGType != StructorCodegen::COMDAT &&
 
 4826  if (CGType == StructorCodegen::COMDAT) {
 
 4827    SmallString<256> Buffer;
 
 4828    llvm::raw_svector_ostream 
Out(Buffer);
 
 4830      getMangleContext().mangleCXXDtorComdat(DD, Out);
 
 4832      getMangleContext().mangleCXXCtorComdat(CD, Out);
 
 4833    llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(
Out.str());
 
 4842  llvm::FunctionType *FTy = llvm::FunctionType::get(
 
 
 4850  llvm::FunctionType *FTy =
 
 4851      llvm::FunctionType::get(CGM.
VoidTy, 
false);
 
 
 4858  llvm::FunctionType *FTy = llvm::FunctionType::get(
 
 
 4877  struct CallEndCatch final : EHScopeStack::Cleanup {
 
 4878    CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
 
 4881    void Emit(CodeGenFunction &CGF, Flags flags)
 override {
 
 4900                                   bool EndMightThrow) {
 
 4901  llvm::CallInst *call =
 
 4904  CGF.
EHStack.pushCleanup<CallEndCatch>(
 
 4906      EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
 
 
 4931    llvm::Value *AdjustedExn = 
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
 
 4936    if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
 
 4945        unsigned HeaderSize =
 
 4948            CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
 
 4971        llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
 
 4979    llvm::Value *ExnCast =
 
 4980      CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, 
"exn.byref");
 
 4992    if (CatchType->hasPointerRepresentation()) {
 
 4993      llvm::Value *CastExn =
 
 4994        CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, 
"exn.casted");
 
 5011      llvm_unreachable(
"bad ownership qualifier!");
 
 5029      llvm_unreachable(
"evaluation kind filtered out!");
 
 5031    llvm_unreachable(
"bad evaluation kind");
 
 5035  auto catchRD = CatchType->getAsCXXRecordDecl();
 
 5045    Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
 
 5046                        LLVMCatchTy, caughtExnAlignment);
 
 5055  llvm::CallInst *rawAdjustedExn =
 
 5059  Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
 
 5060                      LLVMCatchTy, caughtExnAlignment);
 
 
 5091void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
 
 5092                                   const CXXCatchStmt *S) {
 
 5139      C.VoidTy, {C.getPointerType(C.CharTy)});
 
 5142      fnTy, 
"__clang_call_terminate", llvm::AttributeList(), 
true);
 
 5143  llvm::Function *fn =
 
 5148    fn->setDoesNotThrow();
 
 5149    fn->setDoesNotReturn();
 
 5154    fn->addFnAttr(llvm::Attribute::NoInline);
 
 5158    fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
 
 5159    fn->setVisibility(llvm::Function::HiddenVisibility);
 
 5161      fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
 
 5164    llvm::BasicBlock *entry =
 
 5169    llvm::Value *exn = &*fn->arg_begin();
 
 5172    llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
 
 5173    catchCall->setDoesNotThrow();
 
 5177    llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
 
 5178    termCall->setDoesNotThrow();
 
 5179    termCall->setDoesNotReturn();
 
 5183    builder.CreateUnreachable();
 
 
 5189ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
 
 5199std::pair<llvm::Value *, const CXXRecordDecl *>
 
 5200ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
 
 5201                             const CXXRecordDecl *RD) {
 
 5206ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
 
 5207  const CXXMethodDecl *origMD =
 
 5211  llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
 
 5217void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,
 
 5218                                       const CXXCatchStmt *
C) {
 
 5220    CGF.
EHStack.pushCleanup<CatchRetScope>(
 
 5222  ItaniumCXXABI::emitBeginCatch(CGF, 
C);
 
 5226WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
 
 5243void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF, 
const VarDecl &D,
 
 5244                                  llvm::FunctionCallee Dtor,
 
 5245                                  llvm::Constant *
Addr) {
 
 5250    llvm::FunctionType *AtExitTy =
 
 5251        llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy}, 
true);
 
 5254    llvm::FunctionCallee 
AtExit =
 
 5262    llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
 
 5270  llvm::Function *DtorStub =
 
 5278  emitCXXStermFinalizer(D, DtorStub, 
Addr);
 
 5281void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
 
 5282                                     llvm::Constant *addr) {
 
 5283  llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy, 
false);
 
 5284  SmallString<256> FnName;
 
 5286    llvm::raw_svector_ostream 
Out(FnName);
 
 5287    getMangleContext().mangleDynamicStermFinalizer(&D, Out);
 
 5295  CodeGenFunction CGF(CGM);
 
 5309  llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
 
 5314  CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
 
 5319  llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
 
 5322  CI->setCallingConv(dtorStub->getCallingConv());
 
 5328  if (
auto *IPA = D.
getAttr<InitPriorityAttr>()) {
 
 5330                                             IPA->getPriority());
 
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static CharUnits computeOffsetHint(ASTContext &astContext, const CXXRecordDecl *src, const CXXRecordDecl *dst)
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, QualType ty)
Return the linkage that the type info and type info name constants should have for the given type.
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void @__clang_call_terminate(i8* exn) nounwind noreturn This co...
static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD)
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF)
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::FunctionCallee dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM)
static llvm::Constant * pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType, QualType SrcType, CodeGenModule &CGM)
static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static llvm::Value * performTypeAdjustment(CodeGenFunction &CGF, Address InitialPtr, const CXXRecordDecl *UnadjustedClass, int64_t NonVirtualAdjustment, int64_t VirtualAdjustment, bool IsReturnAdjustment)
static llvm::Function * createGlobalInitOrCleanupFn(CodeGen::CodeGenModule &CGM, StringRef FnName)
static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM)
static bool IsStandardLibraryRTTIDescriptor(QualType Ty)
IsStandardLibraryRTTIDescriptor - Returns whether the type information for the given type exists in t...
static llvm::Value * CallBeginCatch(CodeGenFunction &CGF, llvm::Value *Exn, bool EndMightThrow)
Emits a call to __cxa_begin_catch and enters a cleanup to call __cxa_end_catch.
static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static bool isThreadWrapperReplaceable(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
static void InitCatchParam(CodeGenFunction &CGF, const VarDecl &CatchParam, Address ParamAddr, SourceLocation Loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty)
TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type info for that type is de...
static bool CanUseSingleInheritance(const CXXRecordDecl *RD)
static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM)
static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
Get the appropriate linkage for the wrapper function.
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void setVTableSelectiveDLLImportExport(CodeGenModule &CGM, llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static bool ContainsIncompleteClassType(QualType Ty)
ContainsIncompleteClassType - Returns whether the given type contains an incomplete class type.
static llvm::Constant * pointerAuthResignConstant(llvm::Value *Ptr, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, CodeGenModule &CGM)
static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM)
static void dtorTy(Block *, std::byte *Ptr, const Descriptor *)
llvm::MachO::Record Record
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D)
Determine what kind of template specialization the given declaration is.
static QualType getPointeeType(const MemRegion *R)
#define CXXABI(Name, Str)
C Language Family Type Representation.
a trap message and trap category.
const ValueDecl * getMemberPointerDecl() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
This class is used for builtin types like 'int'.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a C++ struct/union/class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
const Expr * getSubExpr() const
static CanQual< Type > CreateUnsafe(QualType Other)
Qualifiers getQualifiers() const
Retrieve all qualifiers.
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
std::string SymbolPartition
The name of the partition that symbols are assigned to, specified with -fsymbol-partition (see https:...
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
unsigned getAddressSpace() const
Return the address space that this address resides in.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ... produce name = getelementptr inbounds addr, i64 index where i64 is actually the t...
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual llvm::CallInst * emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn)
MangleContext & getMangleContext()
Gets the mangle context.
All available information about a concrete callee.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
llvm::Value * getDiscriminator() const
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass, VTableAuthMode AuthMode=VTableAuthMode::Authenticate)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
llvm::Function * createTLSAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr, llvm::FunctionCallee &AtExit)
Create a stub function, suitable for being passed to __pt_atexit_np, which passes the given address t...
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitARCInitWeak(Address addr, llvm::Value *value)
i8* @objc_initWeak(i8** addr, i8* value) Returns value.
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
llvm::Type * ConvertType(QualType T)
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void EmitAnyExprToExn(const Expr *E, Address Addr)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
const TargetInfo & getTarget() const
CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, const CXXRecordDecl *RD)
BuildVirtualCall - This routine makes indirect vtable call for call to virtual destructors.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, llvm::BasicBlock *InitBlock, llvm::BasicBlock *NoInitBlock, GuardKind Kind, const VarDecl *D)
Emit a branch to select whether or not to perform guarded initialization.
CGDebugInfo * getDebugInfo()
LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source=AlignmentSource::Type)
Same as MakeAddrLValue above except that the pointer is known to be unsigned.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Emit the concrete pointer authentication informaton for the given authentication schema.
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
llvm::Value * unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub)
Call unatexit() with function dtorStub.
llvm::Value * emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void registerGlobalDtorWithLLVM(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Registers the dtor using 'llvm.global_dtors' for platforms that do not support an 'atexit()' function...
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
llvm::Type * ConvertTypeForMem(QualType T)
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Instruction * CurrentFuncletPad
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::LLVMContext & getLLVMContext()
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
This class organizes the cross-function state that is used while generating LLVM code.
void AddCXXPrioritizedStermFinalizerEntry(llvm::Function *StermFinalizer, int Priority)
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
void AddCXXStermFinalizerToGlobalDtor(llvm::Function *StermFinalizer, int Priority)
Add an sterm finalizer to its own llvm.global_dtors entry.
llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const
Get LLVM TLS mode from CodeGenOptions.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenVTables & getVTables()
void AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn)
Add an sterm finalizer to the C++ global cleanup function.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
llvm::Constant * getFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return the ABI-correct function pointer value for a reference to the given function.
CGPointerAuthInfo getMemberFunctionPointerAuthInfo(QualType FT)
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const
const TargetInfo & getTarget() const
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD)
Returns LLVM linkage for a declarator.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V)
llvm::Constant * getMemberFunctionPointer(const FunctionDecl *FD, llvm::Type *Ty=nullptr)
llvm::Function * codegenCXXStructor(GlobalDecl GD)
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const llvm::Triple & getTriple() const
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD)
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, const CXXRecordDecl *Class, CharUnits ExpectedTargetAlign)
Given a class pointer with an actual known alignment, and the expected alignment of an object at a dy...
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
ItaniumVTableContext & getItaniumVTableContext()
ASTContext & getContext() const
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
bool supportsCOMDAT() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, llvm::Align Alignment)
Will return a global variable of the given type.
llvm::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
llvm::LLVMContext & getLLVMContext()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void addReplacement(StringRef Name, llvm::Constant *C)
llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Sign a constant pointer using the given scheme, producing a constant with the same IR type.
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Function * CreateGlobalInitOrCleanUpFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false, llvm::GlobalVariable::LinkageTypes Linkage=llvm::GlobalVariable::InternalLinkage)
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
const CodeGenOptions & getCodeGenOpts() const
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i....
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)
Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
llvm::GlobalVariable * GetAddrOfVTT(const CXXRecordDecl *RD)
GetAddrOfVTT - Get the address of the VTT for the given record decl.
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
void GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable, llvm::StringRef AliasNameRef)
Generate a public facing alias for the vtable and make the vtable either hidden or private.
bool isVTableExternal(const CXXRecordDecl *RD)
At this point in the translation unit, does it appear that can we rely on the vtable being defined el...
void RemoveHwasanMetadata(llvm::GlobalValue *GV) const
Specify a global should not be instrumented with hwasan.
void EmitVTTDefinition(llvm::GlobalVariable *VTT, llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD)
EmitVTTDefinition - Emit the definition of the given vtable.
void pushTerminate()
Push a terminate handler on the stack.
void popTerminate()
Pops a terminate handler off the stack.
static RValue get(llvm::Value *V)
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
decl_range noload_decls() const
noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...
SourceLocation getLocation() const
DeclContext * getDeclContext()
bool shouldEmitInExternalSource() const
Whether the definition of the declaration should be emitted in external sources.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
Represents a prototype with parameter type info, e.g.
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
CXXCtorType getCtorType() const
GlobalDecl getCanonicalDecl() const
GlobalDecl getWithDtorType(CXXDtorType Type)
CXXDtorType getDtorType() const
const Decl * getDecl() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
bool isRelativeLayout() const
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
GlobalDecl findOriginalMethod(GlobalDecl GD)
Return the method that added the v-table slot that will be used to call the given method.
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
bool isExternallyVisible() const
static const OpaqueValueExpr * findInCopyConstruct(const Expr *expr)
Given an expression which invokes a copy constructor — i.e.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
Encodes a location in the source.
SourceLocation getBeginLoc() const LLVM_READONLY
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getMaxAtomicInlineWidth() const
Return the maximum width lock-free atomic operation which can be inlined given the supported features...
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool hasPS4DLLImportExport() const
uint64_t getPointerAlign(LangAS AddrSpace) const
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Visibility getVisibility() const
Determine the visibility of this type.
bool isMemberFunctionPointerType() const
Linkage getLinkage() const
Determine the linkage of this type.
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
AddressPointLocation getAddressPoint(BaseSubobject Base) const
size_t getVTableSize(size_t i) const
Represents a variable declaration or definition.
TLSKind getTLSKind() const
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isInline() const
Whether this variable is (C++1z) inline.
const Expr * getInit() const
@ TLS_Dynamic
TLS with a dynamic initializer.
@ TLS_None
Not a TLS variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
CGCXXABI * CreateItaniumCXXABI(CodeGenModule &CGM)
Creates an Itanium-family ABI.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
constexpr Variable var(Literal L)
Returns the variable of L.
bool This(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
@ Ctor_Comdat
The COMDAT used for ctors.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
@ Success
Annotation was successful.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ VisibleNone
No linkage according to the standard, but is visible from other translation units because of types de...
@ None
No linkage, which means that the entity is unique and can only be referred to from within its scope.
@ UniqueExternal
External linkage within a unique namespace.
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.
const FunctionProtoType * T
CXXDtorType
C++ destructor types.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
bool isDiscardableGVALinkage(GVALinkage L)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ EST_None
no exception specification
Visibility
Describes the different kinds of visibility that a declaration may have.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
const half4 dst(half4 Src0, half4 Src1)
Represents an element in a path from a derived class to a base class.
const CXXRecordDecl * NearestVBase
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
llvm::PointerType * GlobalsVoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * CharTy
char
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * SizeTy
llvm::PointerType * VoidPtrPtrTy
llvm::PointerType * GlobalsInt8PtrTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
CharUnits getSizeSize() const
CharUnits getSizeAlign() const
llvm::PointerType * Int8PtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
llvm::PointerType * DefaultPtrTy
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
Extra information about a function prototype.
PointerAuthSchema CXXVTTVTablePointers
The ABI for C++ virtual table pointers as installed in a VTT.
PointerAuthSchema CXXTypeInfoVTablePointer
TypeInfo has external ABI requirements and is emitted without actually having parsed the libcxx defin...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@103031170252120233124322035264172076254313213024 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@106065375072164260365214033034320247050276346205 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.