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) {}
3560 PTI_Incomplete = 0x8,
3564 PTI_ContainingClassIncomplete = 0x10,
3570 PTI_Noexcept = 0x40,
3576 VMI_NonDiamondRepeat = 0x1,
3579 VMI_DiamondShaped = 0x2
3593 llvm::Constant *BuildTypeInfo(QualType Ty);
3597 llvm::Constant *BuildTypeInfo(
3598 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage,
3599 llvm::GlobalValue::VisibilityTypes
Visibility,
3600 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass,
3601 llvm::GlobalValue::VisibilityTypes TypeInfoVisibility,
3602 llvm::GlobalValue::DLLStorageClassTypes TypeInfoDLLStorageClass);
3606llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3607 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage) {
3608 SmallString<256> Name;
3609 llvm::raw_svector_ostream
Out(Name);
3615 llvm::Constant *
Init;
3618 SmallString<256> DualEncodedName;
3619 llvm::ConverterEBCDIC::convertToEBCDIC(Name.substr(4), DualEncodedName);
3620 DualEncodedName +=
'\0';
3621 DualEncodedName += Name.substr(4);
3622 Init = llvm::ConstantDataArray::getString(VMContext, DualEncodedName);
3624 Init = llvm::ConstantDataArray::getString(VMContext, Name.substr(4));
3631 GV->setInitializer(
Init);
3637ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
3639 SmallString<256> Name;
3640 llvm::raw_svector_ostream
Out(Name);
3644 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3651 GV =
new llvm::GlobalVariable(
3653 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3660 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3687 case BuiltinType::Void:
3688 case BuiltinType::NullPtr:
3689 case BuiltinType::Bool:
3690 case BuiltinType::WChar_S:
3691 case BuiltinType::WChar_U:
3692 case BuiltinType::Char_U:
3693 case BuiltinType::Char_S:
3694 case BuiltinType::UChar:
3695 case BuiltinType::SChar:
3696 case BuiltinType::Short:
3697 case BuiltinType::UShort:
3698 case BuiltinType::Int:
3699 case BuiltinType::UInt:
3700 case BuiltinType::Long:
3701 case BuiltinType::ULong:
3702 case BuiltinType::LongLong:
3703 case BuiltinType::ULongLong:
3704 case BuiltinType::Half:
3705 case BuiltinType::Float:
3706 case BuiltinType::Double:
3707 case BuiltinType::LongDouble:
3708 case BuiltinType::Float16:
3709 case BuiltinType::Float128:
3710 case BuiltinType::Ibm128:
3711 case BuiltinType::Char8:
3712 case BuiltinType::Char16:
3713 case BuiltinType::Char32:
3714 case BuiltinType::Int128:
3715 case BuiltinType::UInt128:
3718#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3719 case BuiltinType::Id:
3720#include "clang/Basic/OpenCLImageTypes.def"
3721#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3722 case BuiltinType::Id:
3723#include "clang/Basic/OpenCLExtensionTypes.def"
3724 case BuiltinType::OCLSampler:
3725 case BuiltinType::OCLEvent:
3726 case BuiltinType::OCLClkEvent:
3727 case BuiltinType::OCLQueue:
3728 case BuiltinType::OCLReserveID:
3729#define SVE_TYPE(Name, Id, SingletonId) \
3730 case BuiltinType::Id:
3731#include "clang/Basic/AArch64ACLETypes.def"
3732#define PPC_VECTOR_TYPE(Name, Id, Size) \
3733 case BuiltinType::Id:
3734#include "clang/Basic/PPCTypes.def"
3735#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3736#include "clang/Basic/RISCVVTypes.def"
3737#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3738#include "clang/Basic/WebAssemblyReferenceTypes.def"
3739#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
3740#include "clang/Basic/AMDGPUTypes.def"
3741#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3742#include "clang/Basic/HLSLIntangibleTypes.def"
3743#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3744#include "clang/Basic/SPIRVTypes.def"
3745 case BuiltinType::ShortAccum:
3746 case BuiltinType::Accum:
3747 case BuiltinType::LongAccum:
3748 case BuiltinType::UShortAccum:
3749 case BuiltinType::UAccum:
3750 case BuiltinType::ULongAccum:
3751 case BuiltinType::ShortFract:
3752 case BuiltinType::Fract:
3753 case BuiltinType::LongFract:
3754 case BuiltinType::UShortFract:
3755 case BuiltinType::UFract:
3756 case BuiltinType::ULongFract:
3757 case BuiltinType::SatShortAccum:
3758 case BuiltinType::SatAccum:
3759 case BuiltinType::SatLongAccum:
3760 case BuiltinType::SatUShortAccum:
3761 case BuiltinType::SatUAccum:
3762 case BuiltinType::SatULongAccum:
3763 case BuiltinType::SatShortFract:
3764 case BuiltinType::SatFract:
3765 case BuiltinType::SatLongFract:
3766 case BuiltinType::SatUShortFract:
3767 case BuiltinType::SatUFract:
3768 case BuiltinType::SatULongFract:
3769 case BuiltinType::BFloat16:
3772 case BuiltinType::Dependent:
3773#define BUILTIN_TYPE(Id, SingletonId)
3774#define PLACEHOLDER_TYPE(Id, SingletonId) \
3775 case BuiltinType::Id:
3776#include "clang/AST/BuiltinTypes.def"
3777 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3779 case BuiltinType::ObjCId:
3780 case BuiltinType::ObjCClass:
3781 case BuiltinType::ObjCSel:
3782 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3785 llvm_unreachable(
"Invalid BuiltinType Kind!");
3790 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3808 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3813 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3829 if (!Context.getLangOpts().RTTI)
return false;
3831 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3844 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3854 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3867 return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
3882 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3887 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3891 dyn_cast<MemberPointerType>(Ty)) {
3893 if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
3914 if (
Base->isVirtual())
3922 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
3923 if (!BaseDecl->isEmpty() &&
3930void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty,
3931 llvm::Constant *StorageAddress) {
3933 static const char *
const ClassTypeInfo =
3934 "_ZTVN10__cxxabiv117__class_type_infoE";
3936 static const char *
const SIClassTypeInfo =
3937 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3939 static const char *
const VMIClassTypeInfo =
3940 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3942 const char *VTableName =
nullptr;
3945#define TYPE(Class, Base)
3946#define ABSTRACT_TYPE(Class, Base)
3947#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3948#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3949#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3950#include "clang/AST/TypeNodes.inc"
3951 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3953 case Type::LValueReference:
3954 case Type::RValueReference:
3955 llvm_unreachable(
"References shouldn't get here");
3958 case Type::DeducedTemplateSpecialization:
3959 llvm_unreachable(
"Undeduced type shouldn't get here");
3962 llvm_unreachable(
"Pipe types shouldn't get here");
3964 case Type::ArrayParameter:
3965 llvm_unreachable(
"Array Parameter types should not get here.");
3969 case Type::OverflowBehavior:
3972 case Type::ExtVector:
3973 case Type::ConstantMatrix:
3977 case Type::BlockPointer:
3979 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3982 case Type::ConstantArray:
3983 case Type::IncompleteArray:
3984 case Type::VariableArray:
3986 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3989 case Type::FunctionNoProto:
3990 case Type::FunctionProto:
3992 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3997 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
4000 case Type::Record: {
4002 ->getDefinitionOrSelf();
4005 VTableName = ClassTypeInfo;
4007 VTableName = SIClassTypeInfo;
4009 VTableName = VMIClassTypeInfo;
4015 case Type::ObjCObject:
4021 VTableName = ClassTypeInfo;
4028 case Type::ObjCInterface:
4030 VTableName = SIClassTypeInfo;
4032 VTableName = ClassTypeInfo;
4036 case Type::ObjCObjectPointer:
4039 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
4042 case Type::MemberPointer:
4044 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
4047 case Type::HLSLAttributedResource:
4048 case Type::HLSLInlineSpirv:
4049 llvm_unreachable(
"HLSL doesn't support virtual functions");
4052 llvm::Constant *VTable =
nullptr;
4056 VTable = CGM.
getModule().getNamedAlias(VTableName);
4059 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
4064 llvm::Type *PtrDiffTy =
4071 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
4072 VTable = llvm::ConstantExpr::getInBoundsPtrAdd(VTable, Eight);
4074 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
4075 VTable = llvm::ConstantExpr::getGetElementPtr(
4077 llvm::GEPNoWrapFlags::inBounds());
4080 if (
const auto &Schema =
4084 Schema.isAddressDiscriminated() ? StorageAddress :
nullptr,
4085 GlobalDecl(), QualType(Ty, 0));
4087 Fields.push_back(VTable);
4104 return llvm::GlobalValue::InternalLinkage;
4108 llvm_unreachable(
"Linkage hasn't been computed!");
4113 return llvm::GlobalValue::InternalLinkage;
4121 return llvm::GlobalValue::LinkOnceODRLinkage;
4123 if (
const RecordType *
Record = dyn_cast<RecordType>(Ty)) {
4127 return llvm::GlobalValue::WeakODRLinkage;
4128 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4129 if (RD->
hasAttr<DLLImportAttr>() &&
4131 return llvm::GlobalValue::ExternalLinkage;
4138 return llvm::GlobalValue::LinkOnceODRLinkage;
4141 llvm_unreachable(
"Invalid linkage!");
4146static llvm::GlobalValue::VisibilityTypes
4148 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4149 if (DLLStorageClass == llvm::GlobalValue::DLLExportStorageClass &&
4150 Visibility == llvm::GlobalValue::HiddenVisibility)
4151 return llvm::GlobalValue::DefaultVisibility;
4155llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) {
4160 SmallString<256> Name;
4161 llvm::raw_svector_ostream
Out(Name);
4164 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4165 if (OldGV && !OldGV->isDeclaration()) {
4166 assert(!OldGV->hasAvailableExternallyLinkage() &&
4167 "available_externally typeinfos not yet implemented");
4175 return GetAddrOfExternalRTTIDescriptor(Ty);
4182 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4183 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4185 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
4187 ItaniumCXXABI::RUK_NonUniqueHidden)
4188 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
4192 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4193 llvm::GlobalValue::DefaultStorageClass;
4195 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4196 RD->
hasAttr<DLLExportAttr>()) ||
4198 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4199 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
4200 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4205 llvm::GlobalValue::DLLStorageClassTypes TypeInfoDLLStorageClass =
4208 TypeInfoDLLStorageClass != llvm::GlobalValue::DLLExportStorageClass) {
4210 if (RD->
hasAttr<DLLExportAttr>() ||
4212 TypeInfoDLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4215 llvm::GlobalValue::VisibilityTypes TypeInfoVisibility =
4218 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass,
4219 TypeInfoVisibility, TypeInfoDLLStorageClass);
4222llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4223 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage,
4224 llvm::GlobalValue::VisibilityTypes
Visibility,
4225 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass,
4226 llvm::GlobalValue::VisibilityTypes TypeInfoVisibility,
4227 llvm::GlobalValue::DLLStorageClassTypes TypeInfoDLLStorageClass) {
4228 SmallString<256> Name;
4229 llvm::raw_svector_ostream
Out(Name);
4232 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4234 llvm::GlobalVariable *GV =
4243 llvm::Constant *TypeNameField;
4247 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4249 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4252 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4253 llvm::Constant *flag =
4254 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
4255 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4261 Fields.push_back(TypeNameField);
4264#define TYPE(Class, Base)
4265#define ABSTRACT_TYPE(Class, Base)
4266#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4267#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4268#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4269#include "clang/AST/TypeNodes.inc"
4270 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4275 case Type::ExtVector:
4276 case Type::ConstantMatrix:
4278 case Type::BlockPointer:
4283 case Type::LValueReference:
4284 case Type::RValueReference:
4285 llvm_unreachable(
"References shouldn't get here");
4288 case Type::DeducedTemplateSpecialization:
4289 llvm_unreachable(
"Undeduced type shouldn't get here");
4297 case Type::ConstantArray:
4298 case Type::IncompleteArray:
4299 case Type::VariableArray:
4300 case Type::ArrayParameter:
4305 case Type::FunctionNoProto:
4306 case Type::FunctionProto:
4316 case Type::Record: {
4318 ->getDefinitionOrSelf();
4325 BuildSIClassTypeInfo(RD);
4327 BuildVMIClassTypeInfo(RD);
4332 case Type::ObjCObject:
4333 case Type::ObjCInterface:
4337 case Type::ObjCObjectPointer:
4345 case Type::MemberPointer:
4353 case Type::OverflowBehavior:
4356 case Type::HLSLAttributedResource:
4357 case Type::HLSLInlineSpirv:
4358 llvm_unreachable(
"HLSL doesn't support RTTI");
4361 GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));
4365 GV->takeName(OldGV);
4366 OldGV->replaceAllUsesWith(GV);
4367 OldGV->eraseFromParent();
4371 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4395 GV->setVisibility(TypeInfoVisibility);
4398 TypeName->setDLLStorageClass(DLLStorageClass);
4399 GV->setDLLStorageClass(TypeInfoDLLStorageClass);
4409void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4411 const Type *
T = OT->getBaseType().getTypePtr();
4419 ObjCInterfaceDecl *Super =
Class->getSuperClass();
4427 llvm::Constant *BaseTypeInfo =
4428 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4429 Fields.push_back(BaseTypeInfo);
4434void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4438 llvm::Constant *BaseTypeInfo =
4440 Fields.push_back(BaseTypeInfo);
4447 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
4448 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
4460 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
4461 if (
Base->isVirtual()) {
4463 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4466 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4468 if (Bases.NonVirtualBases.count(BaseDecl))
4469 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4473 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4476 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4478 if (Bases.VirtualBases.count(BaseDecl))
4479 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4484 for (
const auto &I : BaseDecl->bases())
4495 for (
const auto &I : RD->
bases())
4504void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4505 llvm::Type *UnsignedIntLTy =
4513 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4518 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4551 llvm::Type *OffsetFlagsLTy =
4554 for (
const auto &Base : RD->
bases()) {
4556 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4558 auto *BaseDecl =
Base.getType()->castAsCXXRecordDecl();
4566 if (
Base.isVirtual())
4578 if (
Base.isVirtual())
4579 OffsetFlags |= BCTI_Virtual;
4581 OffsetFlags |= BCTI_Public;
4583 Fields.push_back(llvm::ConstantInt::getSigned(OffsetFlagsLTy, OffsetFlags));
4592 if (
Type.isConstQualified())
4593 Flags |= ItaniumRTTIBuilder::PTI_Const;
4594 if (
Type.isVolatileQualified())
4595 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4596 if (
Type.isRestrictQualified())
4597 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4604 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4607 if (Proto->isNothrow()) {
4608 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4618void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
4624 llvm::Type *UnsignedIntLTy =
4626 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4631 llvm::Constant *PointeeTypeInfo =
4632 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4633 Fields.push_back(PointeeTypeInfo);
4639ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty) {
4649 Flags |= PTI_ContainingClassIncomplete;
4651 llvm::Type *UnsignedIntLTy =
4653 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4658 llvm::Constant *PointeeTypeInfo =
4659 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4660 Fields.push_back(PointeeTypeInfo);
4667 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
T));
4670llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
4671 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4674void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4676 QualType FundamentalTypes[] = {
4677 getContext().VoidTy, getContext().NullPtrTy,
4678 getContext().BoolTy, getContext().WCharTy,
4679 getContext().CharTy, getContext().UnsignedCharTy,
4680 getContext().SignedCharTy, getContext().ShortTy,
4681 getContext().UnsignedShortTy, getContext().IntTy,
4682 getContext().UnsignedIntTy, getContext().LongTy,
4683 getContext().UnsignedLongTy, getContext().LongLongTy,
4684 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4685 getContext().UnsignedInt128Ty, getContext().HalfTy,
4686 getContext().FloatTy, getContext().DoubleTy,
4687 getContext().LongDoubleTy, getContext().Float128Ty,
4688 getContext().Char8Ty, getContext().Char16Ty,
4689 getContext().Char32Ty
4691 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4693 ? llvm::GlobalValue::DLLExportStorageClass
4694 : llvm::GlobalValue::DefaultStorageClass;
4697 for (
const QualType &FundamentalType : FundamentalTypes) {
4698 QualType PointerType = getContext().getPointerType(FundamentalType);
4699 QualType PointerTypeConst = getContext().getPointerType(
4700 FundamentalType.withConst());
4701 for (QualType
Type : {FundamentalType, PointerType, PointerTypeConst})
4702 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4703 Type, llvm::GlobalValue::ExternalLinkage,
Visibility, DLLStorageClass,
4710ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4711 QualType CanTy, llvm::GlobalValue::LinkageTypes
Linkage)
const {
4712 if (shouldRTTIBeUnique())
4716 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4717 Linkage != llvm::GlobalValue::WeakODRLinkage)
4725 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4726 return RUK_NonUniqueHidden;
4731 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4732 return RUK_NonUniqueVisible;
4737enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4742 return StructorCodegen::Emit;
4747 return StructorCodegen::Emit;
4750 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4758 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4759 return StructorCodegen::RAUW;
4762 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4763 return StructorCodegen::RAUW;
4765 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4769 return StructorCodegen::COMDAT;
4770 return StructorCodegen::Emit;
4773 return StructorCodegen::Alias;
4783 if (Entry && !Entry->isDeclaration())
4789 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4792 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4796 assert(Entry->getType() == Aliasee->getType() &&
4797 "declaration exists with different type");
4798 Alias->takeName(Entry);
4799 Entry->replaceAllUsesWith(Alias);
4800 Entry->eraseFromParent();
4802 Alias->setName(MangledName);
4809void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
4811 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4818 GlobalDecl BaseDecl;
4824 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4829 if (CGType == StructorCodegen::RAUW) {
4842 CGType != StructorCodegen::COMDAT &&
4860 if (CGType == StructorCodegen::COMDAT) {
4861 SmallString<256> Buffer;
4862 llvm::raw_svector_ostream
Out(Buffer);
4864 getMangleContext().mangleCXXDtorComdat(DD, Out);
4866 getMangleContext().mangleCXXCtorComdat(CD, Out);
4867 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(
Out.str());
4876 llvm::FunctionType *FTy = llvm::FunctionType::get(
4884 llvm::FunctionType *FTy =
4885 llvm::FunctionType::get(CGM.
VoidTy,
false);
4892 llvm::FunctionType *FTy = llvm::FunctionType::get(
4911 struct CallEndCatch final : EHScopeStack::Cleanup {
4912 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4915 void Emit(CodeGenFunction &CGF, Flags flags)
override {
4934 bool EndMightThrow) {
4935 llvm::CallInst *call =
4938 CGF.
EHStack.pushCleanup<CallEndCatch>(
4940 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4965 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4970 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4979 unsigned HeaderSize =
4982 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
5005 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
5013 llvm::Value *ExnCast =
5014 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
5026 if (CatchType->hasPointerRepresentation()) {
5027 llvm::Value *CastExn =
5028 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
5045 llvm_unreachable(
"bad ownership qualifier!");
5063 llvm_unreachable(
"evaluation kind filtered out!");
5065 llvm_unreachable(
"bad evaluation kind");
5069 auto catchRD = CatchType->getAsCXXRecordDecl();
5079 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5080 LLVMCatchTy, caughtExnAlignment);
5089 llvm::CallInst *rawAdjustedExn =
5093 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5094 LLVMCatchTy, caughtExnAlignment);
5125void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5126 const CXXCatchStmt *S) {
5173 C.VoidTy, {C.getPointerType(C.CharTy)});
5176 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5177 llvm::Function *fn =
5182 fn->setDoesNotThrow();
5183 fn->setDoesNotReturn();
5188 fn->addFnAttr(llvm::Attribute::NoInline);
5192 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5193 fn->setVisibility(llvm::Function::HiddenVisibility);
5195 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5198 llvm::BasicBlock *entry =
5203 llvm::Value *exn = &*fn->arg_begin();
5206 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5207 catchCall->setDoesNotThrow();
5211 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5212 termCall->setDoesNotThrow();
5213 termCall->setDoesNotReturn();
5217 builder.CreateUnreachable();
5223ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5233std::pair<llvm::Value *, const CXXRecordDecl *>
5234ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
5235 const CXXRecordDecl *RD) {
5240ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5241 const CXXMethodDecl *origMD =
5245 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5251void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5252 const CXXCatchStmt *
C) {
5254 CGF.
EHStack.pushCleanup<CatchRetScope>(
5256 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5260WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5277void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
5278 llvm::FunctionCallee Dtor,
5279 llvm::Constant *
Addr) {
5284 llvm::FunctionType *AtExitTy =
5285 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5288 llvm::FunctionCallee
AtExit =
5296 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5304 llvm::Function *DtorStub =
5312 emitCXXStermFinalizer(D, DtorStub,
Addr);
5315void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
5316 llvm::Constant *addr) {
5317 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5318 SmallString<256> FnName;
5320 llvm::raw_svector_ostream
Out(FnName);
5321 getMangleContext().mangleDynamicStermFinalizer(&D, Out);
5329 CodeGenFunction CGF(CGM);
5343 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5348 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5353 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5356 CI->setCallingConv(dtorStub->getCallingConv());
5362 if (
auto *IPA = D.
getAttr<InitPriorityAttr>()) {
5364 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 unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF)
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::FunctionCallee dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM)
static llvm::Constant * pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType, QualType SrcType, CodeGenModule &CGM)
static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static llvm::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 bool ContainsIncompleteClassType(QualType Ty)
ContainsIncompleteClassType - Returns whether the given type contains an incomplete class type.
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 getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
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
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
std::string SymbolPartition
The name of the partition that symbols are assigned to, specified with -fsymbol-partition (see https:...
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
unsigned getAddressSpace() const
Return the address space that this address resides in.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
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.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Visibility getVisibility() const
Determine the visibility of this type.
bool isMemberFunctionPointerType() const
Linkage getLinkage() const
Determine the linkage of this type.
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
AddressPointLocation getAddressPoint(BaseSubobject Base) const
size_t getVTableSize(size_t i) const
Represents a variable declaration or definition.
TLSKind getTLSKind() const
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isInline() const
Whether this variable is (C++1z) inline.
const Expr * getInit() const
@ TLS_Dynamic
TLS with a dynamic initializer.
@ TLS_None
Not a TLS variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
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].
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
CGCXXABI * CreateItaniumCXXABI(CodeGenModule &CGM)
Creates an Itanium-family ABI.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
constexpr Variable var(Literal L)
Returns the variable of L.
bool This(InterpState &S, CodePtr OpPC)
@ 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)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ EST_None
no exception specification
Visibility
Describes the different kinds of visibility that a declaration may have.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
const 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
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
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.