35#include "llvm/IR/DataLayout.h"
36#include "llvm/IR/GlobalValue.h"
37#include "llvm/IR/Instructions.h"
38#include "llvm/IR/Intrinsics.h"
39#include "llvm/IR/Value.h"
40#include "llvm/Support/ConvertEBCDIC.h"
41#include "llvm/Support/ScopedPrinter.h"
51 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
54 llvm::SmallVector<std::pair<const VarDecl *, llvm::Function *>, 8>
58 bool UseARMMethodPtrABI;
59 bool UseARMGuardVarABI;
60 bool Use32BitVTableOffsetABI;
62 ItaniumMangleContext &getMangleContext() {
67 ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
68 bool UseARMMethodPtrABI =
false,
69 bool UseARMGuardVarABI =
false) :
70 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
71 UseARMGuardVarABI(UseARMGuardVarABI),
72 Use32BitVTableOffsetABI(
false) { }
83 bool isThisCompleteObject(GlobalDecl GD)
const override {
96 llvm_unreachable(
"emitting dtor comdat as function?");
98 llvm_unreachable(
"emitting unified dtor as function?");
100 llvm_unreachable(
"unexpected dtor kind for this ABI");
102 llvm_unreachable(
"bad dtor kind");
114 llvm_unreachable(
"closure ctors in Itanium ABI?");
117 llvm_unreachable(
"emitting ctor comdat as function?");
120 llvm_unreachable(
"emitting unified ctor as function?");
122 llvm_unreachable(
"bad dtor kind");
129 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
131 llvm::Type *ConvertMemberPointerType(
const MemberPointerType *MPT)
override;
134 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
137 llvm::Value *&ThisPtrForCall,
138 llvm::Value *MemFnPtr,
139 const MemberPointerType *MPT)
override;
141 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
const Expr *E,
142 Address Base, llvm::Value *MemPtr,
143 const MemberPointerType *MPT,
144 bool IsInBounds)
override;
146 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
148 llvm::Value *Src)
override;
149 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
150 llvm::Constant *Src)
override;
152 llvm::Constant *EmitNullMemberPointer(
const MemberPointerType *MPT)
override;
154 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
155 llvm::Constant *EmitMemberDataPointer(
const MemberPointerType *MPT,
156 CharUnits offset)
override;
157 llvm::Constant *EmitMemberPointer(
const APValue &MP, QualType MPT)
override;
158 llvm::Constant *BuildMemberPointer(
const CXXMethodDecl *MD,
159 CharUnits ThisAdjustment);
161 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
162 llvm::Value *L, llvm::Value *R,
163 const MemberPointerType *MPT,
164 bool Inequality)
override;
166 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
168 const MemberPointerType *MPT)
override;
170 void emitVirtualObjectDelete(CodeGenFunction &CGF,
const CXXDeleteExpr *DE,
171 Address Ptr, QualType ElementType,
172 const CXXDestructorDecl *Dtor)
override;
174 void emitRethrow(CodeGenFunction &CGF,
bool isNoReturn)
override;
175 void emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E)
override;
177 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
180 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
181 llvm::Value *Exn)
override;
183 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
184 llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty)
override;
186 getAddrOfCXXCatchHandlerType(QualType Ty,
187 QualType CatchHandlerType)
override {
188 return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0};
191 bool shouldTypeidBeNullChecked(QualType SrcRecordTy)
override;
192 void EmitBadTypeidCall(CodeGenFunction &CGF)
override;
193 llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
195 llvm::Type *StdTypeInfoPtrTy)
override;
197 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
198 QualType SrcRecordTy)
override;
204 bool hasUniqueVTablePointer(QualType RecordTy) {
210 if (CGM.getCodeGenOpts().DisableExactDynamicCast ||
211 getContext().getLangOpts().AppleKext)
216 if (!CGM.shouldEmitRTTI())
221 if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))
230 llvm::GlobalValue::DefaultVisibility)
236 return !CGM.mayVTableBeDuplicated(CGM.getVTableLinkage(RD));
239 bool shouldEmitExactDynamicCast(QualType DestRecordTy)
override {
240 return hasUniqueVTablePointer(DestRecordTy);
243 std::optional<ExactDynamicCastInfo>
244 getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
245 QualType DestRecordTy)
override;
247 llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address
Value,
248 QualType SrcRecordTy, QualType DestTy,
249 QualType DestRecordTy,
250 llvm::BasicBlock *CastEnd)
override;
253 QualType SrcRecordTy, QualType DestTy,
254 QualType DestRecordTy,
255 const ExactDynamicCastInfo &CastInfo,
256 llvm::BasicBlock *CastSuccess,
257 llvm::BasicBlock *CastFail)
override;
260 QualType SrcRecordTy)
override;
262 bool EmitBadCastCall(CodeGenFunction &CGF)
override;
265 GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
266 const CXXRecordDecl *ClassDecl,
267 const CXXRecordDecl *BaseClassDecl)
override;
269 void EmitCXXConstructors(
const CXXConstructorDecl *D)
override;
271 AddedStructorArgCounts
272 buildStructorSignature(GlobalDecl GD,
273 SmallVectorImpl<CanQualType> &ArgTys)
override;
275 bool useThunkForDtorVariant(
const CXXDestructorDecl *Dtor,
283 void EmitCXXDestructors(
const CXXDestructorDecl *D)
override;
285 void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
286 FunctionArgList &Params)
override;
288 void EmitInstanceFunctionProlog(CodeGenFunction &CGF)
override;
290 AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
291 const CXXConstructorDecl *D,
297 const CXXDestructorDecl *DD,
302 void EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
305 QualType ThisTy)
override;
307 void emitVTableDefinitions(CodeGenVTables &CGVT,
308 const CXXRecordDecl *RD)
override;
310 bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
311 CodeGenFunction::VPtr Vptr)
override;
313 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
318 getVTableAddressPoint(BaseSubobject Base,
319 const CXXRecordDecl *VTableClass)
override;
321 llvm::Value *getVTableAddressPointInStructor(
322 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
323 BaseSubobject Base,
const CXXRecordDecl *NearestVBase)
override;
325 llvm::Value *getVTableAddressPointInStructorWithVTT(
326 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
327 BaseSubobject Base,
const CXXRecordDecl *NearestVBase);
329 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
330 CharUnits VPtrOffset)
override;
332 CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
333 Address This, llvm::Type *Ty,
334 SourceLocation Loc)
override;
337 EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
339 DeleteOrMemberCallExpr E,
340 llvm::CallBase **CallOrInvoke)
override;
342 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
344 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
345 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
347 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable, GlobalDecl GD,
348 bool ReturnAdjustment)
override {
351 if (ForVTable && !Thunk->hasLocalLinkage())
352 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
353 CGM.setGVProperties(Thunk, GD);
356 bool exportThunk()
override {
return true; }
358 llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
359 const CXXRecordDecl *UnadjustedThisClass,
360 const ThunkInfo &TI)
override;
363 const CXXRecordDecl *UnadjustedRetClass,
364 const ReturnAdjustment &RA)
override;
366 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
367 FunctionArgList &Args)
const override {
368 assert(!Args.empty() &&
"expected the arglist to not be empty!");
369 return Args.size() - 1;
372 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
373 StringRef GetDeletedVirtualCallName()
override
374 {
return "__cxa_deleted_virtual"; }
376 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
377 Address InitializeArrayCookie(CodeGenFunction &CGF,
379 llvm::Value *NumElements,
380 const CXXNewExpr *
expr,
381 QualType ElementType)
override;
382 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
384 CharUnits cookieSize)
override;
386 void EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
387 llvm::GlobalVariable *DeclPtr,
388 bool PerformInit)
override;
389 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
390 llvm::FunctionCallee dtor,
391 llvm::Constant *addr)
override;
393 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
395 void EmitThreadLocalInitFuncs(
397 ArrayRef<const VarDecl *> CXXThreadLocals,
398 ArrayRef<llvm::Function *> CXXThreadLocalInits,
399 ArrayRef<const VarDecl *> CXXThreadLocalInitVars)
override;
401 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
402 return !isEmittedWithConstantInitializer(VD) ||
403 mayNeedDestruction(VD);
405 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
const VarDecl *VD,
406 QualType LValType)
override;
408 bool NeedsVTTParameter(GlobalDecl GD)
override;
411 getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
418 virtual bool shouldRTTIBeUnique()
const {
return true; }
422 enum RTTIUniquenessKind {
440 classifyRTTIUniqueness(QualType CanTy,
441 llvm::GlobalValue::LinkageTypes
Linkage)
const;
442 friend class ItaniumRTTIBuilder;
444 void emitCXXStructor(GlobalDecl GD)
override;
446 std::pair<llvm::Value *, const CXXRecordDecl *>
447 LoadVTablePtr(CodeGenFunction &CGF, Address This,
448 const CXXRecordDecl *RD)
override;
452 getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
454 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
455 const auto &VtableLayout =
456 CGM.getItaniumVTableContext().getVTableLayout(RD);
458 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
460 if (!VtableComponent.isUsedFunctionPointerKind())
463 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
464 const FunctionDecl *FD =
Method->getDefinition();
465 const bool IsInlined =
470 StringRef Name = CGM.getMangledName(
471 VtableComponent.getGlobalDecl(
false));
472 auto *Entry = CGM.GetGlobalValue(Name);
478 if (!Entry || Entry->isDeclaration())
484 bool isVTableHidden(
const CXXRecordDecl *RD)
const {
485 const auto &VtableLayout =
486 CGM.getItaniumVTableContext().getVTableLayout(RD);
488 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
489 if (VtableComponent.isRTTIKind()) {
490 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
491 if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
493 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
494 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
495 if (
Method->getVisibility() == Visibility::HiddenVisibility &&
504class ARMCXXABI :
public ItaniumCXXABI {
506 ARMCXXABI(CodeGen::CodeGenModule &CGM) :
507 ItaniumCXXABI(CGM,
true,
510 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
512 void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,
513 QualType ResTy)
override;
515 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
516 Address InitializeArrayCookie(CodeGenFunction &CGF,
518 llvm::Value *NumElements,
519 const CXXNewExpr *
expr,
520 QualType ElementType)
override;
521 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr,
522 CharUnits cookieSize)
override;
525class AppleARM64CXXABI :
public ARMCXXABI {
527 AppleARM64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {
528 Use32BitVTableOffsetABI =
true;
532 bool shouldRTTIBeUnique()
const override {
return false; }
535class FuchsiaCXXABI final :
public ItaniumCXXABI {
537 explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM)
538 : ItaniumCXXABI(CGM) {}
541 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
544class WebAssemblyCXXABI final :
public ItaniumCXXABI {
546 explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM)
547 : ItaniumCXXABI(CGM,
true,
549 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
551 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
552 llvm::Value *Exn)
override;
555 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
556 bool canCallMismatchedFunctionType()
const override {
return false; }
559class XLCXXABI final :
public ItaniumCXXABI {
561 explicit XLCXXABI(CodeGen::CodeGenModule &CGM)
562 : ItaniumCXXABI(CGM) {}
564 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
565 llvm::FunctionCallee dtor,
566 llvm::Constant *addr)
override;
568 bool useSinitAndSterm()
const override {
return true; }
571 void emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
572 llvm::Constant *addr);
580 case TargetCXXABI::GenericARM:
581 case TargetCXXABI::iOS:
582 case TargetCXXABI::WatchOS:
583 return new ARMCXXABI(CGM);
585 case TargetCXXABI::AppleARM64:
586 return new AppleARM64CXXABI(CGM);
588 case TargetCXXABI::Fuchsia:
589 return new FuchsiaCXXABI(CGM);
594 case TargetCXXABI::GenericAArch64:
595 return new ItaniumCXXABI(CGM,
true,
598 case TargetCXXABI::GenericMIPS:
599 return new ItaniumCXXABI(CGM,
true);
601 case TargetCXXABI::WebAssembly:
602 return new WebAssemblyCXXABI(CGM);
604 case TargetCXXABI::XL:
605 return new XLCXXABI(CGM);
607 case TargetCXXABI::GenericItanium:
608 return new ItaniumCXXABI(CGM);
610 case TargetCXXABI::Microsoft:
611 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
613 llvm_unreachable(
"bad ABI kind");
619 return CGM.PtrDiffTy;
620 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
643CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
645 llvm::Value *&ThisPtrForCall,
653 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
660 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
663 llvm::Value *Adj = RawAdj;
664 if (UseARMMethodPtrABI)
665 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
670 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(),
This, Adj);
671 ThisPtrForCall =
This;
674 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
678 llvm::Value *IsVirtual;
679 if (UseARMMethodPtrABI)
680 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
682 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
683 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
684 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
702 llvm::Value *VTableOffset = FnAsInt;
703 if (!UseARMMethodPtrABI)
704 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
705 if (Use32BitVTableOffsetABI) {
706 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
707 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
712 llvm::Constant *CheckSourceLocation;
713 llvm::Constant *CheckTypeDesc;
714 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
715 CGM.HasHiddenLTOVisibility(RD);
717 if (ShouldEmitCFICheck) {
718 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
719 if (BinOp->isPtrMemOp() &&
722 ->hasPointeeToCFIUncheckedCalleeFunctionType())
723 ShouldEmitCFICheck =
false;
727 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
728 CGM.HasHiddenLTOVisibility(RD);
732 bool ShouldEmitWPDInfo =
733 (CGM.getCodeGenOpts().WholeProgramVTables &&
735 !CGM.AlwaysHasLTOVisibilityPublic(RD)) ||
736 CGM.getCodeGenOpts().DevirtualizeSpeculatively;
737 llvm::Value *VirtualFn =
nullptr;
740 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
741 auto CheckHandler = SanitizerHandler::CFICheckFail;
742 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
744 llvm::Value *TypeId =
nullptr;
745 llvm::Value *CheckResult =
nullptr;
747 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
751 CGM.CreateMetadataIdentifierForVirtualMemPtrType(QualType(MPT, 0));
755 if (ShouldEmitVFEInfo) {
756 llvm::Value *VFPAddr =
757 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
764 llvm::Value *CheckedLoad = Builder.CreateCall(
765 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
766 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
767 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
768 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
772 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
773 llvm::Value *VFPAddr =
774 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
775 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
776 ? llvm::Intrinsic::type_test
777 : llvm::Intrinsic::public_type_test;
780 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
783 if (CGM.getLangOpts().RelativeCXXABIVTables) {
784 VirtualFn = CGF.
Builder.CreateCall(
785 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
786 {VTableOffset->getType()}),
787 {VTable, VTableOffset});
789 llvm::Value *VFPAddr =
796 assert(VirtualFn &&
"Virtual fuction pointer not created!");
797 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
799 "Check result required but not created!");
801 if (ShouldEmitCFICheck) {
805 llvm::Constant *StaticData[] = {
811 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
814 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
815 CGM.getLLVMContext(),
816 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
817 llvm::Value *ValidVtable = Builder.CreateCall(
818 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
819 CGF.
EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,
820 StaticData, {VTable, ValidVtable});
823 FnVirtual = Builder.GetInsertBlock();
832 llvm::Value *NonVirtualFn =
833 Builder.CreateIntToPtr(FnAsInt, CGF.
DefaultPtrTy,
"memptr.nonvirtualfn");
836 if (ShouldEmitCFICheck) {
839 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
840 auto CheckHandler = SanitizerHandler::CFICheckFail;
841 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
843 llvm::Constant *StaticData[] = {
849 llvm::Value *Bit = Builder.getFalse();
850 for (
const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {
851 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
854 Base->getCanonicalDecl()));
855 llvm::Value *TypeId =
858 llvm::Value *TypeTest =
859 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
860 {NonVirtualFn, TypeId});
861 Bit = Builder.CreateOr(Bit, TypeTest);
864 CGF.
EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,
865 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
867 FnNonVirtual = Builder.GetInsertBlock();
873 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
DefaultPtrTy, 2);
874 CalleePtr->addIncoming(VirtualFn, FnVirtual);
875 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
877 CGPointerAuthInfo PointerAuth;
879 if (
const auto &Schema =
880 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
881 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
882 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
884 const auto &AuthInfo =
885 CGM.getMemberFunctionPointerAuthInfo(QualType(MPT, 0));
886 assert(Schema.getKey() == AuthInfo.getKey() &&
887 "Keys for virtual and non-virtual member functions must match");
888 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
889 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
890 PointerAuth = CGPointerAuthInfo(
891 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
892 Schema.authenticatesNullValues(), DiscriminatorPHI);
895 CGCallee
Callee(FPT, CalleePtr, PointerAuth);
901llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
902 CodeGenFunction &CGF,
const Expr *E, Address Base, llvm::Value *MemPtr,
903 const MemberPointerType *MPT,
bool IsInBounds) {
904 assert(MemPtr->getType() == CGM.PtrDiffTy);
906 CGBuilderTy &Builder = CGF.
Builder;
909 llvm::Value *BaseAddr =
Base.emitRawPointer(CGF);
910 return Builder.CreateGEP(CGF.
Int8Ty, BaseAddr, MemPtr,
"memptr.offset",
911 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
912 : llvm::GEPNoWrapFlags::none());
919 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
924 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
925 CPA->getAddrDiscriminator()->isNullValue() &&
927 "unexpected key or discriminators");
930 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
958ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
965 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
966 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
969 CGBuilderTy &Builder = CGF.
Builder;
970 QualType DstType = E->
getType();
973 if (
const auto &NewAuthInfo =
974 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
977 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
978 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
979 llvm::Type *OrigTy = MemFnPtr->getType();
981 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
986 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
987 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
988 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
989 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
990 llvm::Value *IsVirtualOffset =
991 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
992 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
995 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
996 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
1000 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
1001 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
1002 ResignBB = Builder.GetInsertBlock();
1005 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
1006 NewSrc->addIncoming(src, StartBB);
1007 NewSrc->addIncoming(ResignedVal, ResignBB);
1013 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1015 llvm::Constant *adj = getMemberPointerAdjustment(E);
1016 if (!adj)
return src;
1018 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1020 const MemberPointerType *destTy =
1027 if (isDerivedToBase)
1028 dst = Builder.CreateNSWSub(src, adj,
"adj");
1030 dst = Builder.CreateNSWAdd(src, adj,
"adj");
1033 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
1034 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
1035 return Builder.CreateSelect(isNull, src, dst);
1039 if (UseARMMethodPtrABI) {
1042 adj = llvm::ConstantInt::get(adj->getType(), offset);
1045 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1046 llvm::Value *dstAdj;
1047 if (isDerivedToBase)
1048 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1050 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1052 return Builder.CreateInsertValue(src, dstAdj, 1);
1055static llvm::Constant *
1060 "member function pointers expected");
1061 if (DestType == SrcType)
1067 if (!NewAuthInfo && !CurAuthInfo)
1070 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1071 if (MemFnPtr->getNumOperands() == 0) {
1079 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1080 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1084ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
1085 llvm::Constant *src) {
1086 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
1087 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
1090 QualType DstType = E->
getType();
1097 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1100 llvm::Constant *adj = getMemberPointerAdjustment(E);
1101 if (!adj)
return src;
1103 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1105 const MemberPointerType *destTy =
1112 if (src->isAllOnesValue())
return src;
1114 if (isDerivedToBase)
1115 return llvm::ConstantExpr::getNSWSub(src, adj);
1117 return llvm::ConstantExpr::getNSWAdd(src, adj);
1121 if (UseARMMethodPtrABI) {
1124 adj = llvm::ConstantInt::get(adj->getType(), offset);
1127 llvm::Constant *srcAdj = src->getAggregateElement(1);
1128 llvm::Constant *dstAdj;
1129 if (isDerivedToBase)
1130 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1132 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1134 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1135 assert(res !=
nullptr &&
"Folding must succeed");
1140ItaniumCXXABI::EmitNullMemberPointer(
const MemberPointerType *MPT) {
1144 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1146 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1147 llvm::Constant *Values[2] = {
Zero,
Zero };
1148 return llvm::ConstantStruct::getAnon(Values);
1152ItaniumCXXABI::EmitMemberDataPointer(
const MemberPointerType *MPT,
1157 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1161ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1165llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1166 CharUnits ThisAdjustment) {
1167 assert(MD->
isInstance() &&
"Member function must not be static!");
1169 CodeGenTypes &Types = CGM.getTypes();
1172 llvm::Constant *MemPtr[2];
1174 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1176 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1178 VTableOffset = Index * 4;
1180 const ASTContext &Context = getContext();
1183 VTableOffset = Index * PointerWidth.
getQuantity();
1186 if (UseARMMethodPtrABI) {
1208 const auto &Schema =
1209 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1211 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1212 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1214 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1217 MemPtr[1] = llvm::ConstantInt::get(
1218 CGM.PtrDiffTy, 2 * ThisAdjustment.
getQuantity() + !Schema);
1224 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1225 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1229 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
1240 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1242 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1243 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1244 (UseARMMethodPtrABI ? 2 : 1) *
1248 return llvm::ConstantStruct::getAnon(MemPtr);
1251llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1253 const MemberPointerType *MPT = MPType->
castAs<MemberPointerType>();
1256 return EmitNullMemberPointer(MPT);
1258 CharUnits ThisAdjustment = getContext().getMemberPointerPathAdjustment(MP);
1260 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1261 llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment);
1262 QualType SrcType = getContext().getMemberPointerType(
1267 getContext().recordMemberDataPointerEvaluation(MPD);
1268 CharUnits FieldOffset =
1269 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1270 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
1278ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
1281 const MemberPointerType *MPT,
1283 CGBuilderTy &Builder = CGF.
Builder;
1285 llvm::ICmpInst::Predicate Eq;
1286 llvm::Instruction::BinaryOps
And,
Or;
1288 Eq = llvm::ICmpInst::ICMP_NE;
1289 And = llvm::Instruction::Or;
1290 Or = llvm::Instruction::And;
1292 Eq = llvm::ICmpInst::ICMP_EQ;
1293 And = llvm::Instruction::And;
1294 Or = llvm::Instruction::Or;
1300 return Builder.CreateICmp(Eq, L, R);
1312 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1313 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1317 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1322 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1323 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr,
Zero,
"cmp.ptr.null");
1327 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1328 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1329 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1333 if (UseARMMethodPtrABI) {
1334 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1337 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1338 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1339 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1,
Zero,
1341 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1345 llvm::Value *
Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1347 Inequality ?
"memptr.ne" :
"memptr.eq");
1352ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
1353 llvm::Value *MemPtr,
1354 const MemberPointerType *MPT) {
1355 CGBuilderTy &Builder = CGF.
Builder;
1359 assert(MemPtr->getType() == CGM.PtrDiffTy);
1360 llvm::Value *NegativeOne =
1361 llvm::Constant::getAllOnesValue(MemPtr->getType());
1362 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1366 llvm::Value *
Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1368 llvm::Constant *
Zero = llvm::ConstantInt::get(
Ptr->getType(), 0);
1369 llvm::Value *
Result = Builder.CreateICmpNE(Ptr,
Zero,
"memptr.tobool");
1373 if (UseARMMethodPtrABI) {
1374 llvm::Constant *One = llvm::ConstantInt::get(
Ptr->getType(), 1);
1375 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1376 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1377 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit,
Zero,
1378 "memptr.isvirtual");
1385bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI)
const {
1386 const CXXRecordDecl *RD = FI.
getReturnType()->getAsCXXRecordDecl();
1393 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1394 LangAS SRetAS = CGM.getTargetCodeGenInfo().getSRetAddrSpace(RD);
1395 unsigned AS = CGM.getContext().getTargetAddressSpace(SRetAS);
1405bool ItaniumCXXABI::isZeroInitializable(
const MemberPointerType *MPT) {
1411void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
1412 const CXXDeleteExpr *DE,
1414 QualType ElementType,
1415 const CXXDestructorDecl *Dtor) {
1417 if (UseGlobalDelete) {
1422 auto *ClassDecl = ElementType->castAsCXXRecordDecl();
1426 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1427 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1432 llvm::Value *CompletePtr =
Ptr.emitRawPointer(CGF);
1445 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
1448 if (UseGlobalDelete)
1452void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF,
bool isNoReturn) {
1455 llvm::FunctionType *FTy =
1456 llvm::FunctionType::get(CGM.VoidTy,
false);
1458 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1469 llvm::FunctionType *FTy =
1480 llvm::FunctionType *FTy =
1481 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1486void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E) {
1489 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1490 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1494 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1501 llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1506 llvm::Constant *
Dtor =
nullptr;
1512 const ASTContext &Ctx = getContext();
1514 FunctionProtoType::ExtProtoInfo());
1516 CXXDestructorDecl *DtorD =
Record->getDestructor();
1518 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1520 if (!Dtor)
Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1522 llvm::Value *args[] = { ExceptionPtr, TypeInfo,
Dtor };
1534 llvm::Type *PtrDiffTy =
1537 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1539 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1543 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1544 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1545 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1546 llvm::AttributeList Attrs = llvm::AttributeList::get(
1547 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1554 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1560 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1565bool ItaniumCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
1569void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1572 Call->setDoesNotReturn();
1573 CGF.
Builder.CreateUnreachable();
1576llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
1577 QualType SrcRecordTy,
1579 llvm::Type *StdTypeInfoPtrTy) {
1584 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1587 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1588 {Value, llvm::ConstantInt::getSigned(CGM.Int32Ty, -4)});
1592 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1598bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1599 QualType SrcRecordTy) {
1603llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1604 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1605 QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1606 llvm::Type *PtrDiffLTy =
1609 llvm::Value *SrcRTTI =
1611 llvm::Value *DestRTTI =
1617 llvm::Value *OffsetHint = llvm::ConstantInt::getSigned(
1624 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1630 llvm::Value *Vtable =
1632 CodeGenFunction::VTableAuthMode::MustTrap);
1637 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1643 llvm::BasicBlock *BadCastBlock =
1650 EmitBadCastCall(CGF);
1656std::optional<CGCXXABI::ExactDynamicCastInfo>
1657ItaniumCXXABI::getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
1658 QualType DestRecordTy) {
1659 assert(shouldEmitExactDynamicCast(DestRecordTy));
1661 ASTContext &Context = getContext();
1666 CXXBasePaths Paths(
true,
true,
1672 std::optional<CharUnits> Offset;
1673 for (
const CXXBasePath &Path : Paths) {
1678 CharUnits PathOffset;
1679 for (
const CXXBasePathElement &PathElement : Path) {
1681 const CXXRecordDecl *
Base =
1682 PathElement.Base->getType()->getAsCXXRecordDecl();
1683 if (PathElement.Base->isVirtual()) {
1689 const ASTRecordLayout &L =
1696 Offset = PathOffset;
1697 else if (Offset != PathOffset) {
1699 return ExactDynamicCastInfo{
true,
1704 return std::nullopt;
1705 return ExactDynamicCastInfo{
false, *Offset};
1708llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1709 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1710 QualType DestTy, QualType DestRecordTy,
1711 const ExactDynamicCastInfo &ExactCastInfo, llvm::BasicBlock *CastSuccess,
1712 llvm::BasicBlock *CastFail) {
1715 auto AuthenticateVTable = [&](
Address ThisAddr,
const CXXRecordDecl *
Decl) {
1719 CodeGenFunction::VTableAuthMode::MustTrap);
1722 bool PerformPostCastAuthentication =
false;
1723 llvm::Value *VTable =
nullptr;
1724 if (ExactCastInfo.RequiresCastToPrimaryBase) {
1729 llvm::Value *PrimaryBase =
1736 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1737 CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip,
1738 false,
false,
nullptr);
1741 if (PerformPostCastAuthentication)
1744 VTable = CGF.
GetVTablePtr(ThisAddr, CGM.GlobalsInt8PtrTy, SrcDecl);
1748 llvm::Constant *ExpectedVTable = getVTableAddressPoint(
1749 BaseSubobject(SrcDecl, ExactCastInfo.Offset), DestDecl);
1750 llvm::Value *
Success = CGF.
Builder.CreateICmpEQ(VTable, ExpectedVTable);
1753 if (!ExactCastInfo.Offset.isZero()) {
1755 llvm::Constant *OffsetConstant =
1756 llvm::ConstantInt::get(CGF.
PtrDiffTy, -Offset);
1759 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1762 if (PerformPostCastAuthentication) {
1765 llvm::BasicBlock *NonNullBlock = CGF.
Builder.GetInsertBlock();
1766 llvm::BasicBlock *PostCastAuthSuccess =
1768 llvm::BasicBlock *PostCastAuthComplete =
1771 PostCastAuthComplete);
1775 AuthenticateVTable(AdjustedThisAddr, DestDecl);
1778 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(AdjustedThisPtr->getType(), 2);
1779 PHI->addIncoming(AdjustedThisPtr, PostCastAuthSuccess);
1780 llvm::Value *NullValue =
1781 llvm::Constant::getNullValue(AdjustedThisPtr->getType());
1782 PHI->addIncoming(NullValue, NonNullBlock);
1783 AdjustedThisPtr = PHI;
1786 return AdjustedThisPtr;
1789llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
1791 QualType SrcRecordTy) {
1793 llvm::Value *OffsetToTop;
1794 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1796 llvm::Value *VTable =
1801 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1805 llvm::Type *PtrDiffLTy =
1809 llvm::Value *VTable =
1814 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1823bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1826 Call->setDoesNotReturn();
1827 CGF.
Builder.CreateUnreachable();
1832ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
1834 const CXXRecordDecl *ClassDecl,
1835 const CXXRecordDecl *BaseClassDecl) {
1836 llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1837 CharUnits VBaseOffsetOffset =
1838 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1840 llvm::Value *VBaseOffsetPtr =
1841 CGF.
Builder.CreateConstGEP1_64(
1843 "vbase.offset.ptr");
1845 llvm::Value *VBaseOffset;
1846 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1852 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1857void ItaniumCXXABI::EmitCXXConstructors(
const CXXConstructorDecl *D) {
1859 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1863 CGM.EmitGlobal(GlobalDecl(D,
Ctor_Base));
1873CGCXXABI::AddedStructorArgCounts
1874ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
1875 SmallVectorImpl<CanQualType> &ArgTys) {
1876 ASTContext &Context = getContext();
1885 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1887 ArgTys.insert(ArgTys.begin() + 1,
1889 return AddedStructorArgCounts::prefix(1);
1891 return AddedStructorArgCounts{};
1894void ItaniumCXXABI::EmitCXXDestructors(
const CXXDestructorDecl *D) {
1897 CGM.EmitGlobal(GlobalDecl(D,
Dtor_Base));
1910void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1912 FunctionArgList &Params) {
1917 if (NeedsVTTParameter(CGF.
CurGD)) {
1918 ASTContext &Context = getContext();
1921 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1926 T, ImplicitParamKind::CXXVTT);
1927 Params.insert(Params.begin() + 1, VTTDecl);
1928 getStructorImplicitParamDecl(CGF) = VTTDecl;
1932void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1939 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1942 if (getStructorImplicitParamDecl(CGF)) {
1955 if (HasThisReturn(CGF.
CurGD))
1959CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
1962 if (!NeedsVTTParameter(GlobalDecl(D,
Type)))
1963 return AddedStructorArgs{};
1970 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1971 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
1972 QualType VTTTy = getContext().getPointerType(Q);
1973 return AddedStructorArgs::prefix({{VTT, VTTTy}});
1976llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
1979 GlobalDecl GD(DD,
Type);
1983void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
1984 const CXXDestructorDecl *DD,
1988 GlobalDecl GD(DD,
Type);
1991 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1994 if (getContext().getLangOpts().AppleKext &&
2001 ThisTy, VTT, VTTTy,
nullptr);
2005template <
typename T>
2008 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2021 llvm::GlobalVariable *VTable,
2023 if (VTable->getDLLStorageClass() !=
2024 llvm::GlobalVariable::DefaultStorageClass ||
2030 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2032 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2035void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
2036 const CXXRecordDecl *RD) {
2037 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());
2038 if (VTable->hasInitializer())
2041 ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
2043 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2044 llvm::Constant *RTTI =
2045 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getCanonicalTagType(RD));
2048 ConstantInitBuilder builder(CGM);
2049 auto components = builder.beginStruct();
2051 llvm::GlobalValue::isLocalLinkage(
Linkage));
2052 components.finishAndSetAsInitializer(VTable);
2060 if (CGM.mayVTableBeDuplicated(VTable->getLinkage()))
2061 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2063 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2064 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2066 if (CGM.getTarget().hasPS4DLLImportExport())
2070 CGM.setGVProperties(VTable, RD);
2081 EmitFundamentalRTTIDescriptors(RD);
2089 if (!VTable->isDeclarationForLinker() ||
2090 CGM.getCodeGenOpts().WholeProgramVTables ||
2091 CGM.getCodeGenOpts().DevirtualizeSpeculatively) {
2092 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2096 if (VTable->isDeclarationForLinker()) {
2097 assert(CGM.getCodeGenOpts().WholeProgramVTables ||
2098 CGM.getCodeGenOpts().DevirtualizeSpeculatively);
2099 CGM.addCompilerUsedGlobal(VTable);
2103 if (CGM.getLangOpts().RelativeCXXABIVTables) {
2105 if (!VTable->isDSOLocal())
2110 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
2111 DI->emitVTableSymbol(VTable, RD);
2114bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2115 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
2118 return NeedsVTTParameter(CGF.
CurGD);
2121llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2122 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2123 const CXXRecordDecl *NearestVBase) {
2125 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2126 NeedsVTTParameter(CGF.
CurGD)) {
2127 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
2130 return getVTableAddressPoint(Base, VTableClass);
2134ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
2135 const CXXRecordDecl *VTableClass) {
2136 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());
2140 const VTableLayout &Layout =
2141 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2142 VTableLayout::AddressPointLocation AddressPoint =
2144 llvm::Constant *Indices[] = {
2145 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2146 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2152 unsigned ComponentSize =
2153 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2154 unsigned VTableSize =
2157 llvm::ConstantRange InRange(
2158 llvm::APInt(32, (
int)-Offset,
true),
2159 llvm::APInt(32, (
int)(VTableSize - Offset),
true));
2160 return llvm::ConstantExpr::getGetElementPtr(
2161 CGM.getDataLayout(), VTable->getValueType(), VTable, Indices,
2162 llvm::GEPNoWrapFlags::inBounds(), InRange);
2165llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2166 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2167 const CXXRecordDecl *NearestVBase) {
2168 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2169 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2173 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
2177 if (VirtualPointerIndex)
2179 VirtualPointerIndex);
2186 if (
auto PointerAuth = CGM.getVTablePointerAuthInfo(&CGF, VTableClass, VTT,
2193llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2194 CharUnits VPtrOffset) {
2195 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2197 llvm::GlobalVariable *&VTable = VTables[RD];
2202 CGM.addDeferredVTable(RD);
2204 SmallString<256> Name;
2205 llvm::raw_svector_ostream
Out(Name);
2206 getMangleContext().mangleCXXVTable(RD, Out);
2208 const VTableLayout &VTLayout =
2209 CGM.getItaniumVTableContext().getVTableLayout(RD);
2210 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2215 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2217 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2218 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2219 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2220 if (!CGM.shouldEmitRTTI())
2221 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2223 if (CGM.getTarget().hasPS4DLLImportExport())
2226 CGM.setGVProperties(VTable, RD);
2230CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
2234 SourceLocation Loc) {
2235 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2237 llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
2243 if (CGM.getLangOpts().OpenMPIsTargetDevice) {
2244 auto *NewPtrTy = CGM.VoidPtrTy;
2245 llvm::Type *RtlFnArgs[] = {NewPtrTy};
2246 llvm::FunctionCallee DeviceRtlFn = CGM.CreateRuntimeFunction(
2247 llvm::FunctionType::get(NewPtrTy, RtlFnArgs,
false),
2248 "__llvm_omp_indirect_call_lookup");
2249 auto *BackupTy = VTable->getType();
2257 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2258 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2259 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2261 llvm::Type *ComponentTy = CGM.getVTables().getVTableComponentType();
2263 VTableIndex * CGM.getDataLayout().getTypeSizeInBits(ComponentTy) / 8;
2271 llvm::Value *VFuncLoad;
2272 if (CGM.getLangOpts().RelativeCXXABIVTables) {
2273 VFuncLoad = CGF.
Builder.CreateCall(
2274 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2275 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, ByteOffset)});
2277 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2278 PtrTy, VTable, VTableIndex,
"vfn");
2289 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2290 CGM.getCodeGenOpts().StrictVTablePointers) {
2291 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2292 VFuncLoadInstr->setMetadata(
2293 llvm::LLVMContext::MD_invariant_load,
2294 llvm::MDNode::get(CGM.getLLVMContext(),
2295 llvm::ArrayRef<llvm::Metadata *>()));
2301 CGPointerAuthInfo PointerAuth;
2303 assert(VTableSlotPtr &&
"virtual function pointer not set");
2304 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2307 CGCallee
Callee(GD, VFunc, PointerAuth);
2311llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2312 CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
CXXDtorType DtorType,
2313 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
2314 auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
2315 auto *D = dyn_cast<const CXXDeleteExpr *>(E);
2316 assert((CE !=
nullptr) ^ (D !=
nullptr));
2317 assert(CE ==
nullptr || CE->arguments().empty());
2320 GlobalDecl GD(Dtor, DtorType);
2321 const CGFunctionInfo *FInfo =
2322 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2328 ThisTy = CE->getObjectType();
2330 ThisTy = D->getDestroyedType();
2334 nullptr, QualType(),
nullptr, CallOrInvoke);
2338void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2339 CodeGenVTables &VTables = CGM.getVTables();
2344bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2345 const CXXRecordDecl *RD)
const {
2348 if (CGM.getLangOpts().AppleKext)
2353 if (isVTableHidden(RD))
2356 if (CGM.getCodeGenOpts().ForceEmitVTables)
2373 if (hasAnyUnusedVirtualInlineFunction(RD))
2381 for (
const auto &B : RD->
bases()) {
2382 auto *BRD = B.getType()->getAsCXXRecordDecl();
2383 assert(BRD &&
"no class for base specifier");
2384 if (B.isVirtual() || !BRD->isDynamicClass())
2386 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2394bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2395 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2403 for (
const auto &B : RD->
vbases()) {
2404 auto *BRD = B.getType()->getAsCXXRecordDecl();
2405 assert(BRD &&
"no class for base specifier");
2406 if (!BRD->isDynamicClass())
2408 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2417 int64_t NonVirtualAdjustment,
2418 int64_t VirtualAdjustment,
2419 bool IsReturnAdjustment) {
2420 if (!NonVirtualAdjustment && !VirtualAdjustment)
2426 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2432 llvm::Value *ResultPtr;
2433 if (VirtualAdjustment) {
2434 llvm::Value *VTablePtr =
2437 llvm::Value *Offset;
2438 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2439 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2446 llvm::Type *PtrDiffTy =
2455 V.emitRawPointer(CGF), Offset);
2457 ResultPtr =
V.emitRawPointer(CGF);
2462 if (NonVirtualAdjustment && IsReturnAdjustment) {
2463 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2464 NonVirtualAdjustment);
2471ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This,
2472 const CXXRecordDecl *UnadjustedClass,
2473 const ThunkInfo &TI) {
2480ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
2481 const CXXRecordDecl *UnadjustedClass,
2482 const ReturnAdjustment &RA) {
2488void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
2489 RValue RV, QualType ResultType) {
2491 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2496 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2501CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2505 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2508Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2510 llvm::Value *NumElements,
2511 const CXXNewExpr *
expr,
2512 QualType ElementType) {
2513 assert(requiresArrayCookie(
expr));
2517 ASTContext &Ctx = getContext();
2521 CharUnits CookieSize =
2523 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2527 CharUnits CookieOffset = CookieSize - SizeSize;
2528 if (!CookieOffset.
isZero())
2536 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2537 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2538 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2540 SI->setNoSanitizeMetadata();
2541 llvm::FunctionType *FTy =
2542 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2543 llvm::FunctionCallee F =
2544 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2553llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2555 CharUnits cookieSize) {
2557 Address numElementsPtr = allocPtr;
2558 CharUnits numElementsOffset = cookieSize - CGF.
getSizeSize();
2559 if (!numElementsOffset.
isZero())
2565 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2572 llvm::FunctionType *FTy =
2574 llvm::FunctionCallee F =
2575 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2579CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2589 CGM.getContext().getTypeAlignInChars(elementType));
2592Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2594 llvm::Value *numElements,
2595 const CXXNewExpr *
expr,
2596 QualType elementType) {
2597 assert(requiresArrayCookie(
expr));
2604 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2605 getContext().getTypeSizeInChars(elementType).getQuantity());
2614 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2618llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2620 CharUnits cookieSize) {
2633 llvm::PointerType *GuardPtrTy) {
2635 llvm::FunctionType *FTy =
2639 FTy,
"__cxa_guard_acquire",
2641 llvm::AttributeList::FunctionIndex,
2642 llvm::Attribute::NoUnwind));
2646 llvm::PointerType *GuardPtrTy) {
2648 llvm::FunctionType *FTy =
2649 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2651 FTy,
"__cxa_guard_release",
2653 llvm::AttributeList::FunctionIndex,
2654 llvm::Attribute::NoUnwind));
2658 llvm::PointerType *GuardPtrTy) {
2660 llvm::FunctionType *FTy =
2661 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2663 FTy,
"__cxa_guard_abort",
2665 llvm::AttributeList::FunctionIndex,
2666 llvm::Attribute::NoUnwind));
2670 struct CallGuardAbort final : EHScopeStack::Cleanup {
2671 llvm::GlobalVariable *Guard;
2672 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2674 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2683void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
2685 llvm::GlobalVariable *var,
2686 bool shouldPerformInit) {
2687 CGBuilderTy &Builder = CGF.
Builder;
2691 bool NonTemplateInline =
2698 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2704 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2706 llvm::IntegerType *guardTy;
2707 CharUnits guardAlignment;
2708 if (useInt8GuardVariable) {
2714 if (UseARMGuardVarABI) {
2723 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2729 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2732 SmallString<256> guardName;
2734 llvm::raw_svector_ostream
out(guardName);
2735 getMangleContext().mangleStaticGuardVariable(&D,
out);
2741 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2742 false,
var->getLinkage(),
2743 llvm::ConstantInt::get(guardTy, 0),
2745 guard->setDSOLocal(
var->isDSOLocal());
2746 guard->setVisibility(
var->getVisibility());
2747 guard->setDLLStorageClass(
var->getDLLStorageClass());
2749 guard->setThreadLocalMode(
var->getThreadLocalMode());
2750 guard->setAlignment(guardAlignment.
getAsAlign());
2755 llvm::Comdat *
C =
var->getComdat();
2757 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2758 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2759 guard->setComdat(
C);
2760 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2761 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2764 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2767 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2792 if (!threadsafe || MaxInlineWidthInBits) {
2794 llvm::LoadInst *LI =
2804 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2827 (UseARMGuardVarABI && !useInt8GuardVariable)
2828 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2830 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2836 CodeGenFunction::GuardKind::VariableGuard, &D);
2864 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2865 InitBlock, EndBlock);
2875 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2893 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2902 llvm::FunctionCallee dtor,
2903 llvm::Constant *addr,
bool TLS) {
2905 "unexpected call to emitGlobalDtorWithCXAAtExit");
2907 "__cxa_atexit is disabled");
2908 const char *Name =
"__cxa_atexit";
2911 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2919 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2920 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2924 llvm::Constant *handle =
2927 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2930 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2931 llvm::FunctionType *atexitTy =
2932 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2936 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2937 fn->setDoesNotThrow();
2943 Context.getFunctionType(Context.VoidTy, {Context.VoidPtrTy}, EPI);
2944 llvm::Value *dtorCallee = dtor.getCallee();
2948 if (dtorCallee->getType()->getPointerAddressSpace() != AddrAS)
2956 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2958 llvm::Value *args[] = {dtorCallee, addr, handle};
2966 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2970 return GlobalInitOrCleanupFn;
2973void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
2974 for (
const auto &I : DtorsUsingAtExit) {
2975 int Priority = I.first;
2976 std::string GlobalCleanupFnName =
2977 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
2979 llvm::Function *GlobalCleanupFn =
2982 CodeGenFunction CGF(*
this);
2983 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalCleanupFn,
2984 getTypes().arrangeNullaryFunction(), FunctionArgList(),
2985 SourceLocation(), SourceLocation());
2989 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
2993 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2994 auto itv = Dtors.rbegin();
2995 while (itv != Dtors.rend()) {
2996 llvm::Function *
Dtor = *itv;
3001 llvm::Value *NeedsDestruct =
3004 llvm::BasicBlock *DestructCallBlock =
3007 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
3010 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
3015 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
3017 CI->setCallingConv(
Dtor->getCallingConv());
3025 AddGlobalDtor(GlobalCleanupFn, Priority);
3029void CodeGenModule::registerGlobalDtorsWithAtExit() {
3030 for (
const auto &I : DtorsUsingAtExit) {
3031 int Priority = I.first;
3032 std::string GlobalInitFnName =
3033 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
3034 llvm::Function *GlobalInitFn =
3037 CodeGenFunction CGF(*
this);
3038 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalInitFn,
3039 getTypes().arrangeNullaryFunction(), FunctionArgList(),
3040 SourceLocation(), SourceLocation());
3048 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3049 for (
auto *Dtor : Dtors) {
3052 if (getCodeGenOpts().CXAAtExit) {
3062 AddGlobalCtor(GlobalInitFn, Priority);
3065 if (getCXXABI().useSinitAndSterm())
3066 unregisterGlobalDtorsWithUnAtExit();
3070void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
3071 llvm::FunctionCallee dtor,
3072 llvm::Constant *addr) {
3077 if (CGM.getLangOpts().HLSL)
3078 return CGM.AddCXXDtorEntry(dtor, addr);
3092 if (CGM.getCodeGenOpts().CXAAtExit || D.
getTLSKind())
3097 if (CGM.getLangOpts().AppleKext) {
3099 return CGM.AddCXXDtorEntry(dtor, addr);
3107 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3117static llvm::GlobalValue::LinkageTypes
3119 llvm::GlobalValue::LinkageTypes VarLinkage =
3123 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3128 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3129 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3131 return llvm::GlobalValue::WeakODRLinkage;
3135ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3138 SmallString<256> WrapperName;
3140 llvm::raw_svector_ostream
Out(WrapperName);
3141 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3146 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3149 QualType RetQT = VD->
getType();
3153 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3154 getContext().getPointerType(RetQT), FunctionArgList());
3156 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3157 llvm::Function *Wrapper =
3159 WrapperName.str(), &CGM.getModule());
3161 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3162 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3164 CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper,
false);
3167 if (!Wrapper->hasLocalLinkage())
3169 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3170 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3172 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
3175 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3176 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3179 ThreadWrappers.push_back({VD, Wrapper});
3183void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3184 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
3185 ArrayRef<llvm::Function *> CXXThreadLocalInits,
3186 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
3187 llvm::Function *InitFunc =
nullptr;
3191 llvm::SmallVector<llvm::Function *, 8> OrderedInits;
3192 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3193 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3196 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3197 CXXThreadLocalInits[I];
3199 OrderedInits.push_back(CXXThreadLocalInits[I]);
3202 if (!OrderedInits.empty()) {
3204 llvm::FunctionType *FTy =
3205 llvm::FunctionType::get(CGM.
VoidTy,
false);
3210 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3212 llvm::GlobalVariable::InternalLinkage,
3213 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3214 Guard->setThreadLocal(
true);
3218 Guard->setAlignment(GuardAlign.
getAsAlign());
3220 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(
3221 InitFunc, OrderedInits, ConstantAddress(Guard, CGM.
Int8Ty, GuardAlign));
3224 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3225 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3231 for (
const VarDecl *VD : CXXThreadLocals) {
3235 getOrCreateThreadLocalWrapper(VD, GV);
3240 for (
auto VDAndWrapper : ThreadWrappers) {
3241 const VarDecl *VD = VDAndWrapper.first;
3242 llvm::GlobalVariable *Var =
3244 llvm::Function *Wrapper = VDAndWrapper.second;
3251 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3257 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3258 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3264 SmallString<256> InitFnName;
3266 llvm::raw_svector_ostream
Out(InitFnName);
3267 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3270 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3275 llvm::GlobalValue *
Init =
nullptr;
3276 bool InitIsInitFunc =
false;
3277 bool HasConstantInitialization =
false;
3278 if (!usesThreadWrapperFunction(VD)) {
3279 HasConstantInitialization =
true;
3281 InitIsInitFunc =
true;
3282 llvm::Function *InitFuncToUse = InitFunc;
3286 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3293 Init = llvm::Function::Create(InitFnTy,
3294 llvm::GlobalVariable::ExternalWeakLinkage,
3302 Init->setVisibility(Var->getVisibility());
3304 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3305 Init->setDSOLocal(Var->isDSOLocal());
3308 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3316 isEmittedWithConstantInitializer(VD,
true) &&
3317 !mayNeedDestruction(VD)) {
3322 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3324 llvm::Function *
Func = llvm::Function::Create(
3325 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3331 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3332 CGBuilderTy Builder(CGM, Entry);
3333 Builder.CreateRetVoid();
3336 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3337 CGBuilderTy Builder(CGM, Entry);
3338 if (HasConstantInitialization) {
3340 }
else if (InitIsInitFunc) {
3342 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3344 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3345 llvm::Function *
Fn =
3347 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3358 Builder.CreateCall(InitFnTy,
Init);
3361 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3362 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3363 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3364 Builder.CreateCondBr(Have, InitBB, ExitBB);
3366 Builder.SetInsertPoint(InitBB);
3367 Builder.CreateCall(InitFnTy,
Init);
3368 Builder.CreateBr(ExitBB);
3370 Builder.SetInsertPoint(ExitBB);
3375 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3379 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3381 Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());
3383 Builder.CreateRet(Val);
3387LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
3389 QualType LValType) {
3391 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3393 llvm::CallInst *CallVal =
3395 CallVal->setCallingConv(Wrapper->getCallingConv());
3409bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
3428ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3429 SmallString<256> MethodName;
3430 llvm::raw_svector_ostream
Out(MethodName);
3431 getMangleContext().mangleCXXName(MD, Out);
3432 MethodName +=
"_vfpthunk_";
3433 StringRef ThunkName = MethodName.str();
3434 llvm::Function *ThunkFn;
3435 if ((ThunkFn = cast_or_null<llvm::Function>(
3436 CGM.
getModule().getNamedValue(ThunkName))))
3441 llvm::GlobalValue::LinkageTypes
Linkage =
3443 : llvm::GlobalValue::InternalLinkage;
3446 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3447 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
3448 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3454 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3455 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3456 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3459 CodeGenFunction CGF(CGM);
3460 CGF.
CurGD = GlobalDecl(MD);
3464 FunctionArgList FunctionArgs;
3468 FunctionArgs, MD->
getLocation(), SourceLocation());
3473 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3474 setCXXABIThisValue(CGF, ThisVal);
3476 CallArgList CallArgs;
3477 for (
const VarDecl *VD : FunctionArgs)
3480 const FunctionProtoType *FPT = MD->
getType()->
getAs<FunctionProtoType>();
3482 const CGFunctionInfo &CallInfo =
3485 getThisAddress(CGF), ThunkTy);
3486 llvm::CallBase *CallOrInvoke;
3487 CGF.
EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke,
3488 true, SourceLocation(),
true);
3490 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3491 if (
Call->getType()->isVoidTy())
3504class ItaniumRTTIBuilder {
3506 llvm::LLVMContext &VMContext;
3507 const ItaniumCXXABI &
CXXABI;
3510 SmallVector<llvm::Constant *, 16> Fields;
3513 llvm::GlobalVariable *
3514 GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3518 llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
3521 void BuildVTablePointer(
const Type *Ty, llvm::Constant *StorageAddress);
3525 void BuildSIClassTypeInfo(
const CXXRecordDecl *RD);
3530 void BuildVMIClassTypeInfo(
const CXXRecordDecl *RD);
3534 void BuildPointerTypeInfo(QualType PointeeTy);
3538 void BuildObjCObjectTypeInfo(
const ObjCObjectType *Ty);
3542 void BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty);
3545 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3546 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3551 VMI_NonDiamondRepeat = 0x1,
3554 VMI_DiamondShaped = 0x2
3568 llvm::Constant *BuildTypeInfo(QualType Ty);
3572 llvm::Constant *BuildTypeInfo(
3573 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage,
3574 llvm::GlobalValue::VisibilityTypes
Visibility,
3575 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass,
3576 llvm::GlobalValue::VisibilityTypes TypeInfoVisibility,
3577 llvm::GlobalValue::DLLStorageClassTypes TypeInfoDLLStorageClass);
3581llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3582 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage) {
3583 SmallString<256> Name;
3584 llvm::raw_svector_ostream
Out(Name);
3590 llvm::Constant *
Init;
3593 SmallString<256> DualEncodedName;
3594 llvm::ConverterEBCDIC::convertToEBCDIC(Name.substr(4), DualEncodedName);
3595 DualEncodedName +=
'\0';
3596 DualEncodedName += Name.substr(4);
3597 Init = llvm::ConstantDataArray::getString(VMContext, DualEncodedName);
3599 Init = llvm::ConstantDataArray::getString(VMContext, Name.substr(4));
3606 GV->setInitializer(
Init);
3612ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
3614 SmallString<256> Name;
3615 llvm::raw_svector_ostream
Out(Name);
3619 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3626 GV =
new llvm::GlobalVariable(
3628 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3635 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3662 case BuiltinType::Void:
3663 case BuiltinType::NullPtr:
3664 case BuiltinType::Bool:
3665 case BuiltinType::WChar_S:
3666 case BuiltinType::WChar_U:
3667 case BuiltinType::Char_U:
3668 case BuiltinType::Char_S:
3669 case BuiltinType::UChar:
3670 case BuiltinType::SChar:
3671 case BuiltinType::Short:
3672 case BuiltinType::UShort:
3673 case BuiltinType::Int:
3674 case BuiltinType::UInt:
3675 case BuiltinType::Long:
3676 case BuiltinType::ULong:
3677 case BuiltinType::LongLong:
3678 case BuiltinType::ULongLong:
3679 case BuiltinType::Half:
3680 case BuiltinType::Float:
3681 case BuiltinType::Double:
3682 case BuiltinType::LongDouble:
3683 case BuiltinType::Float16:
3684 case BuiltinType::Float128:
3685 case BuiltinType::Ibm128:
3686 case BuiltinType::Char8:
3687 case BuiltinType::Char16:
3688 case BuiltinType::Char32:
3689 case BuiltinType::Int128:
3690 case BuiltinType::UInt128:
3693#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3694 case BuiltinType::Id:
3695#include "clang/Basic/OpenCLImageTypes.def"
3696#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3697 case BuiltinType::Id:
3698#include "clang/Basic/OpenCLExtensionTypes.def"
3699 case BuiltinType::OCLSampler:
3700 case BuiltinType::OCLEvent:
3701 case BuiltinType::OCLClkEvent:
3702 case BuiltinType::OCLQueue:
3703 case BuiltinType::OCLReserveID:
3704#define SVE_TYPE(Name, Id, SingletonId) \
3705 case BuiltinType::Id:
3706#include "clang/Basic/AArch64ACLETypes.def"
3707#define PPC_VECTOR_TYPE(Name, Id, Size) \
3708 case BuiltinType::Id:
3709#include "clang/Basic/PPCTypes.def"
3710#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3711#include "clang/Basic/RISCVVTypes.def"
3712#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3713#include "clang/Basic/WebAssemblyReferenceTypes.def"
3714#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
3715#include "clang/Basic/AMDGPUTypes.def"
3716#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3717#include "clang/Basic/HLSLIntangibleTypes.def"
3718#define HLSL_PACKED_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3719#include "clang/Basic/HLSLPackedTypes.def"
3720#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3721#include "clang/Basic/SPIRVTypes.def"
3722 case BuiltinType::ShortAccum:
3723 case BuiltinType::Accum:
3724 case BuiltinType::LongAccum:
3725 case BuiltinType::UShortAccum:
3726 case BuiltinType::UAccum:
3727 case BuiltinType::ULongAccum:
3728 case BuiltinType::ShortFract:
3729 case BuiltinType::Fract:
3730 case BuiltinType::LongFract:
3731 case BuiltinType::UShortFract:
3732 case BuiltinType::UFract:
3733 case BuiltinType::ULongFract:
3734 case BuiltinType::SatShortAccum:
3735 case BuiltinType::SatAccum:
3736 case BuiltinType::SatLongAccum:
3737 case BuiltinType::SatUShortAccum:
3738 case BuiltinType::SatUAccum:
3739 case BuiltinType::SatULongAccum:
3740 case BuiltinType::SatShortFract:
3741 case BuiltinType::SatFract:
3742 case BuiltinType::SatLongFract:
3743 case BuiltinType::SatUShortFract:
3744 case BuiltinType::SatUFract:
3745 case BuiltinType::SatULongFract:
3746 case BuiltinType::BFloat16:
3747 case BuiltinType::MetaInfo:
3750 case BuiltinType::Dependent:
3751#define BUILTIN_TYPE(Id, SingletonId)
3752#define PLACEHOLDER_TYPE(Id, SingletonId) \
3753 case BuiltinType::Id:
3754#include "clang/AST/BuiltinTypes.def"
3755 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3757 case BuiltinType::ObjCId:
3758 case BuiltinType::ObjCClass:
3759 case BuiltinType::ObjCSel:
3760 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3763 llvm_unreachable(
"Invalid BuiltinType Kind!");
3768 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3786 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3791 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3807 if (!Context.getLangOpts().RTTI)
return false;
3809 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3822 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3832 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3855 if (
Base->isVirtual())
3863 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
3864 if (!BaseDecl->isEmpty() &&
3871void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty,
3872 llvm::Constant *StorageAddress) {
3874 static const char *
const ClassTypeInfo =
3875 "_ZTVN10__cxxabiv117__class_type_infoE";
3877 static const char *
const SIClassTypeInfo =
3878 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3880 static const char *
const VMIClassTypeInfo =
3881 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3883 const char *VTableName =
nullptr;
3886#define TYPE(Class, Base)
3887#define ABSTRACT_TYPE(Class, Base)
3888#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3889#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3890#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3891#include "clang/AST/TypeNodes.inc"
3892 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3894 case Type::LValueReference:
3895 case Type::RValueReference:
3896 llvm_unreachable(
"References shouldn't get here");
3899 case Type::DeducedTemplateSpecialization:
3900 llvm_unreachable(
"Undeduced type shouldn't get here");
3903 llvm_unreachable(
"Pipe types shouldn't get here");
3905 case Type::ArrayParameter:
3906 llvm_unreachable(
"Array Parameter types should not get here.");
3910 case Type::OverflowBehavior:
3913 case Type::ExtVector:
3914 case Type::ConstantMatrix:
3918 case Type::BlockPointer:
3920 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3923 case Type::ConstantArray:
3924 case Type::IncompleteArray:
3925 case Type::VariableArray:
3927 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3930 case Type::FunctionNoProto:
3931 case Type::FunctionProto:
3933 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3938 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3941 case Type::Record: {
3943 ->getDefinitionOrSelf();
3946 VTableName = ClassTypeInfo;
3948 VTableName = SIClassTypeInfo;
3950 VTableName = VMIClassTypeInfo;
3956 case Type::ObjCObject:
3962 VTableName = ClassTypeInfo;
3969 case Type::ObjCInterface:
3971 VTableName = SIClassTypeInfo;
3973 VTableName = ClassTypeInfo;
3977 case Type::ObjCObjectPointer:
3980 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3983 case Type::MemberPointer:
3985 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3988 case Type::HLSLAttributedResource:
3989 case Type::HLSLInlineSpirv:
3990 llvm_unreachable(
"HLSL doesn't support virtual functions");
3993 llvm::Constant *VTable =
nullptr;
3997 VTable = CGM.
getModule().getNamedAlias(VTableName);
4000 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
4005 llvm::Type *PtrDiffTy =
4012 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
4013 VTable = llvm::ConstantExpr::getInBoundsPtrAdd(VTable, Eight);
4015 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
4016 VTable = llvm::ConstantExpr::getGetElementPtr(
4018 llvm::GEPNoWrapFlags::inBounds());
4021 if (
const auto &Schema =
4025 Schema.isAddressDiscriminated() ? StorageAddress :
nullptr,
4026 GlobalDecl(), QualType(Ty, 0));
4028 Fields.push_back(VTable);
4045 return llvm::GlobalValue::InternalLinkage;
4049 llvm_unreachable(
"Linkage hasn't been computed!");
4054 return llvm::GlobalValue::InternalLinkage;
4062 return llvm::GlobalValue::LinkOnceODRLinkage;
4064 if (
const RecordType *
Record = dyn_cast<RecordType>(Ty)) {
4068 return llvm::GlobalValue::WeakODRLinkage;
4069 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4070 if (RD->
hasAttr<DLLImportAttr>() &&
4072 return llvm::GlobalValue::ExternalLinkage;
4079 return llvm::GlobalValue::LinkOnceODRLinkage;
4082 llvm_unreachable(
"Invalid linkage!");
4087static llvm::GlobalValue::VisibilityTypes
4089 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4090 if (DLLStorageClass == llvm::GlobalValue::DLLExportStorageClass &&
4091 Visibility == llvm::GlobalValue::HiddenVisibility)
4092 return llvm::GlobalValue::DefaultVisibility;
4096llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) {
4101 SmallString<256> Name;
4102 llvm::raw_svector_ostream
Out(Name);
4105 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4106 if (OldGV && !OldGV->isDeclaration()) {
4107 assert(!OldGV->hasAvailableExternallyLinkage() &&
4108 "available_externally typeinfos not yet implemented");
4116 return GetAddrOfExternalRTTIDescriptor(Ty);
4123 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4124 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4126 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
4128 ItaniumCXXABI::RUK_NonUniqueHidden)
4129 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
4133 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4134 llvm::GlobalValue::DefaultStorageClass;
4136 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4137 RD->
hasAttr<DLLExportAttr>()) ||
4139 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4140 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
4141 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4146 llvm::GlobalValue::DLLStorageClassTypes TypeInfoDLLStorageClass =
4149 TypeInfoDLLStorageClass != llvm::GlobalValue::DLLExportStorageClass) {
4151 if (RD->
hasAttr<DLLExportAttr>() ||
4153 TypeInfoDLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4156 llvm::GlobalValue::VisibilityTypes TypeInfoVisibility =
4159 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass,
4160 TypeInfoVisibility, TypeInfoDLLStorageClass);
4163llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4164 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage,
4165 llvm::GlobalValue::VisibilityTypes
Visibility,
4166 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass,
4167 llvm::GlobalValue::VisibilityTypes TypeInfoVisibility,
4168 llvm::GlobalValue::DLLStorageClassTypes TypeInfoDLLStorageClass) {
4169 SmallString<256> Name;
4170 llvm::raw_svector_ostream
Out(Name);
4173 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4175 llvm::GlobalVariable *GV =
4184 llvm::Constant *TypeNameField;
4188 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4190 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4193 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4194 llvm::Constant *flag =
4195 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
4196 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4202 Fields.push_back(TypeNameField);
4205#define TYPE(Class, Base)
4206#define ABSTRACT_TYPE(Class, Base)
4207#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4208#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4209#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4210#include "clang/AST/TypeNodes.inc"
4211 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4216 case Type::ExtVector:
4217 case Type::ConstantMatrix:
4219 case Type::BlockPointer:
4224 case Type::LValueReference:
4225 case Type::RValueReference:
4226 llvm_unreachable(
"References shouldn't get here");
4229 case Type::DeducedTemplateSpecialization:
4230 llvm_unreachable(
"Undeduced type shouldn't get here");
4238 case Type::ConstantArray:
4239 case Type::IncompleteArray:
4240 case Type::VariableArray:
4241 case Type::ArrayParameter:
4246 case Type::FunctionNoProto:
4247 case Type::FunctionProto:
4257 case Type::Record: {
4259 ->getDefinitionOrSelf();
4266 BuildSIClassTypeInfo(RD);
4268 BuildVMIClassTypeInfo(RD);
4273 case Type::ObjCObject:
4274 case Type::ObjCInterface:
4278 case Type::ObjCObjectPointer:
4286 case Type::MemberPointer:
4294 case Type::OverflowBehavior:
4297 case Type::HLSLAttributedResource:
4298 case Type::HLSLInlineSpirv:
4299 llvm_unreachable(
"HLSL doesn't support RTTI");
4302 GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));
4306 GV->takeName(OldGV);
4307 OldGV->replaceAllUsesWith(GV);
4308 OldGV->eraseFromParent();
4312 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4336 GV->setVisibility(TypeInfoVisibility);
4339 TypeName->setDLLStorageClass(DLLStorageClass);
4340 GV->setDLLStorageClass(TypeInfoDLLStorageClass);
4350void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4352 const Type *
T = OT->getBaseType().getTypePtr();
4360 ObjCInterfaceDecl *Super =
Class->getSuperClass();
4368 llvm::Constant *BaseTypeInfo =
4369 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4370 Fields.push_back(BaseTypeInfo);
4375void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4379 llvm::Constant *BaseTypeInfo =
4381 Fields.push_back(BaseTypeInfo);
4388 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
4389 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
4401 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
4402 if (
Base->isVirtual()) {
4404 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4407 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4409 if (Bases.NonVirtualBases.count(BaseDecl))
4410 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4414 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4417 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4419 if (Bases.VirtualBases.count(BaseDecl))
4420 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4425 for (
const auto &I : BaseDecl->bases())
4436 for (
const auto &I : RD->
bases())
4445void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4446 llvm::Type *UnsignedIntLTy =
4454 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4459 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4492 llvm::Type *OffsetFlagsLTy =
4495 for (
const auto &Base : RD->
bases()) {
4497 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4499 auto *BaseDecl =
Base.getType()->castAsCXXRecordDecl();
4507 if (
Base.isVirtual())
4519 if (
Base.isVirtual())
4520 OffsetFlags |= BCTI_Virtual;
4522 OffsetFlags |= BCTI_Public;
4524 Fields.push_back(llvm::ConstantInt::getSigned(OffsetFlagsLTy, OffsetFlags));
4530void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
4536 llvm::Type *UnsignedIntLTy =
4538 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4543 llvm::Constant *PointeeTypeInfo =
4544 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4545 Fields.push_back(PointeeTypeInfo);
4551ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty) {
4563 llvm::Type *UnsignedIntLTy =
4565 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4570 llvm::Constant *PointeeTypeInfo =
4571 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4572 Fields.push_back(PointeeTypeInfo);
4579 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
T));
4582llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
4583 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4586void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4588 QualType FundamentalTypes[] = {
4589 getContext().VoidTy, getContext().NullPtrTy,
4590 getContext().BoolTy, getContext().WCharTy,
4591 getContext().CharTy, getContext().UnsignedCharTy,
4592 getContext().SignedCharTy, getContext().ShortTy,
4593 getContext().UnsignedShortTy, getContext().IntTy,
4594 getContext().UnsignedIntTy, getContext().LongTy,
4595 getContext().UnsignedLongTy, getContext().LongLongTy,
4596 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4597 getContext().UnsignedInt128Ty, getContext().HalfTy,
4598 getContext().FloatTy, getContext().DoubleTy,
4599 getContext().LongDoubleTy, getContext().Float128Ty,
4600 getContext().Char8Ty, getContext().Char16Ty,
4601 getContext().Char32Ty
4603 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4605 ? llvm::GlobalValue::DLLExportStorageClass
4606 : llvm::GlobalValue::DefaultStorageClass;
4609 for (
const QualType &FundamentalType : FundamentalTypes) {
4610 QualType PointerType = getContext().getPointerType(FundamentalType);
4611 QualType PointerTypeConst = getContext().getPointerType(
4612 FundamentalType.withConst());
4613 for (QualType
Type : {FundamentalType, PointerType, PointerTypeConst})
4614 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4615 Type, llvm::GlobalValue::ExternalLinkage,
Visibility, DLLStorageClass,
4622ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4623 QualType CanTy, llvm::GlobalValue::LinkageTypes
Linkage)
const {
4624 if (shouldRTTIBeUnique())
4628 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4629 Linkage != llvm::GlobalValue::WeakODRLinkage)
4637 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4638 return RUK_NonUniqueHidden;
4643 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4644 return RUK_NonUniqueVisible;
4649enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4656 llvm::GlobalValue::LinkageTypes
Linkage) {
4660 Linkage != llvm::GlobalValue::AvailableExternallyLinkage;
4666 return StructorCodegen::Emit;
4671 return StructorCodegen::Emit;
4674 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4682 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage) &&
4684 return StructorCodegen::RAUW;
4687 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4688 return StructorCodegen::RAUW;
4690 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4694 return StructorCodegen::COMDAT;
4695 return StructorCodegen::Emit;
4698 return StructorCodegen::Alias;
4708 if (Entry && !Entry->isDeclaration())
4714 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4717 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4721 assert(Entry->getType() == Aliasee->getType() &&
4722 "declaration exists with different type");
4723 Alias->takeName(Entry);
4724 Entry->replaceAllUsesWith(Alias);
4725 Entry->eraseFromParent();
4727 Alias->setName(MangledName);
4734void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
4736 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4743 GlobalDecl BaseDecl;
4749 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4754 if (CGType == StructorCodegen::RAUW) {
4767 CGType != StructorCodegen::COMDAT &&
4785 if (CGType == StructorCodegen::COMDAT) {
4786 SmallString<256> Buffer;
4787 llvm::raw_svector_ostream
Out(Buffer);
4789 getMangleContext().mangleCXXDtorComdat(DD, Out);
4791 getMangleContext().mangleCXXCtorComdat(CD, Out);
4792 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(
Out.str());
4801 llvm::FunctionType *FTy = llvm::FunctionType::get(
4809 llvm::FunctionType *FTy =
4810 llvm::FunctionType::get(CGM.
VoidTy,
false);
4817 llvm::FunctionType *FTy = llvm::FunctionType::get(
4836 struct CallEndCatch final : EHScopeStack::Cleanup {
4837 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4840 void Emit(CodeGenFunction &CGF, Flags flags)
override {
4859 bool EndMightThrow) {
4860 llvm::CallInst *call =
4863 CGF.
EHStack.pushCleanup<CallEndCatch>(
4865 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4890 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4895 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4904 unsigned HeaderSize =
4907 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
4930 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
4938 llvm::Value *ExnCast =
4939 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
4951 if (CatchType->hasPointerRepresentation()) {
4952 llvm::Value *CastExn =
4953 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
4970 llvm_unreachable(
"bad ownership qualifier!");
4988 llvm_unreachable(
"evaluation kind filtered out!");
4990 llvm_unreachable(
"bad evaluation kind");
4994 auto catchRD = CatchType->getAsCXXRecordDecl();
5004 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5005 LLVMCatchTy, caughtExnAlignment);
5014 llvm::CallInst *rawAdjustedExn =
5018 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5019 LLVMCatchTy, caughtExnAlignment);
5050void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5051 const CXXCatchStmt *S) {
5098 C.VoidTy, {C.getPointerType(C.CharTy)});
5101 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5102 llvm::Function *fn =
5107 fn->setDoesNotThrow();
5108 fn->setDoesNotReturn();
5113 fn->addFnAttr(llvm::Attribute::NoInline);
5117 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5118 fn->setVisibility(llvm::Function::HiddenVisibility);
5120 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5123 llvm::BasicBlock *entry =
5128 llvm::Value *exn = &*fn->arg_begin();
5131 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5132 catchCall->setDoesNotThrow();
5136 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5137 termCall->setDoesNotThrow();
5138 termCall->setDoesNotReturn();
5142 builder.CreateUnreachable();
5148ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5158std::pair<llvm::Value *, const CXXRecordDecl *>
5159ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
5160 const CXXRecordDecl *RD) {
5165ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5166 const CXXMethodDecl *origMD =
5170 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5176void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5177 const CXXCatchStmt *
C) {
5179 CGF.
EHStack.pushCleanup<CatchRetScope>(
5181 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5185WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5202void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
5203 llvm::FunctionCallee Dtor,
5204 llvm::Constant *
Addr) {
5209 llvm::FunctionType *AtExitTy =
5210 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5213 llvm::FunctionCallee
AtExit =
5221 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5229 llvm::Function *DtorStub =
5237 emitCXXStermFinalizer(D, DtorStub,
Addr);
5240void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
5241 llvm::Constant *addr) {
5242 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5243 SmallString<256> FnName;
5245 llvm::raw_svector_ostream
Out(FnName);
5246 getMangleContext().mangleDynamicStermFinalizer(&D, Out);
5254 CodeGenFunction CGF(CGM);
5268 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5273 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5278 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5281 CI->setCallingConv(dtorStub->getCallingConv());
5287 if (
auto *IPA = D.
getAttr<InitPriorityAttr>()) {
5289 IPA->getPriority());
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
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 performTypeAdjustment(CIRGenFunction &cgf, Address initialPtr, const CXXRecordDecl *unadjustedClass, int64_t nonVirtualAdjustment, int64_t virtualAdjustment, bool isReturnAdjustment)
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 RValue performReturnAdjustment(CIRGenFunction &cgf, QualType resultType, RValue rv, const ThunkInfo &thunk)
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 bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
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 bool structorSymbolMustBeRetained(CodeGenModule &CGM, const CXXMethodDecl *MD, llvm::GlobalValue::LinkageTypes Linkage)
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::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 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::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 llvm::GlobalValue::VisibilityTypes getRTTIVisibility(llvm::GlobalValue::VisibilityTypes Visibility, llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass)
A dllexported global must not be hidden, so dllexport takes precedence over the visibility implied by...
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 *)
Result
Implement __builtin_bit_cast and related operations.
static cir::GlobalLinkageKind getThreadLocalWrapperLinkage(GlobalOp op, const clang::TargetInfo &targetInfo)
static bool isThreadWrapperReplaceable(const clang::TargetInfo &targetInfo)
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 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
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 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
This is an opaque type for sizes expressed in character units.
bool isZero() const
Test whether the quantity equals zero.
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits 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="")
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, 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::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
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.
CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, llvm::ConstantInt *Discriminator)
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,...
SmallVector< llvm::OperandBundleDef, 1 > getBundlesForFunclet(llvm::Value *Callee)
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::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
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 & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs, const FunctionDecl *ABIInfoFD)
Arrange a call to a C++ method, passing the given arguments.
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 & 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, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
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.
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...
unsigned extractPBaseFlags(const ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
bool containsIncompleteClassType(QualType Ty)
Returns whether the given type contains an incomplete class type.
CharUnits computeOffsetHint(ASTContext &Ctx, const CXXRecordDecl *Src, const CXXRecordDecl *Dst)
Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7].
@ PTI_ContainingClassIncomplete
PTI_ContainingClassIncomplete - Containing class is incomplete.
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.
const EHPersonality & getEHPersonality(CodeGenModule &CGM, const FunctionDecl *FD)
Selects the personality function to use for FD, or for the translation unit as a whole when FD is nul...
@ 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)
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
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...
const FunctionProtoType * T
CXXDtorType
C++ destructor types.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ 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)
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.
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 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 * 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
Extra information about a function prototype.
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.