34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/GlobalValue.h"
36#include "llvm/IR/Instructions.h"
37#include "llvm/IR/Intrinsics.h"
38#include "llvm/IR/Value.h"
39#include "llvm/Support/ConvertEBCDIC.h"
40#include "llvm/Support/ScopedPrinter.h"
50 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
53 llvm::SmallVector<std::pair<const VarDecl *, llvm::Function *>, 8>
57 bool UseARMMethodPtrABI;
58 bool UseARMGuardVarABI;
59 bool Use32BitVTableOffsetABI;
61 ItaniumMangleContext &getMangleContext() {
66 ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
67 bool UseARMMethodPtrABI =
false,
68 bool UseARMGuardVarABI =
false) :
69 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
70 UseARMGuardVarABI(UseARMGuardVarABI),
71 Use32BitVTableOffsetABI(
false) { }
82 bool isThisCompleteObject(GlobalDecl GD)
const override {
95 llvm_unreachable(
"emitting dtor comdat as function?");
97 llvm_unreachable(
"emitting unified dtor as function?");
99 llvm_unreachable(
"unexpected dtor kind for this ABI");
101 llvm_unreachable(
"bad dtor kind");
113 llvm_unreachable(
"closure ctors in Itanium ABI?");
116 llvm_unreachable(
"emitting ctor comdat as function?");
119 llvm_unreachable(
"emitting unified ctor as function?");
121 llvm_unreachable(
"bad dtor kind");
128 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
130 llvm::Type *ConvertMemberPointerType(
const MemberPointerType *MPT)
override;
133 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
136 llvm::Value *&ThisPtrForCall,
137 llvm::Value *MemFnPtr,
138 const MemberPointerType *MPT)
override;
140 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
const Expr *E,
141 Address Base, llvm::Value *MemPtr,
142 const MemberPointerType *MPT,
143 bool IsInBounds)
override;
145 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
147 llvm::Value *Src)
override;
148 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
149 llvm::Constant *Src)
override;
151 llvm::Constant *EmitNullMemberPointer(
const MemberPointerType *MPT)
override;
153 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
154 llvm::Constant *EmitMemberDataPointer(
const MemberPointerType *MPT,
155 CharUnits offset)
override;
156 llvm::Constant *EmitMemberPointer(
const APValue &MP, QualType MPT)
override;
157 llvm::Constant *BuildMemberPointer(
const CXXMethodDecl *MD,
158 CharUnits ThisAdjustment);
160 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
161 llvm::Value *L, llvm::Value *R,
162 const MemberPointerType *MPT,
163 bool Inequality)
override;
165 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
167 const MemberPointerType *MPT)
override;
169 void emitVirtualObjectDelete(CodeGenFunction &CGF,
const CXXDeleteExpr *DE,
170 Address Ptr, QualType ElementType,
171 const CXXDestructorDecl *Dtor)
override;
173 void emitRethrow(CodeGenFunction &CGF,
bool isNoReturn)
override;
174 void emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E)
override;
176 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
179 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
180 llvm::Value *Exn)
override;
182 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
183 llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty)
override;
185 getAddrOfCXXCatchHandlerType(QualType Ty,
186 QualType CatchHandlerType)
override {
187 return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0};
190 bool shouldTypeidBeNullChecked(QualType SrcRecordTy)
override;
191 void EmitBadTypeidCall(CodeGenFunction &CGF)
override;
192 llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
194 llvm::Type *StdTypeInfoPtrTy)
override;
196 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
197 QualType SrcRecordTy)
override;
203 bool hasUniqueVTablePointer(QualType RecordTy) {
209 if (CGM.getCodeGenOpts().DisableExactDynamicCast ||
210 getContext().getLangOpts().AppleKext)
215 if (!CGM.shouldEmitRTTI())
220 if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))
229 llvm::GlobalValue::DefaultVisibility)
235 return !CGM.mayVTableBeDuplicated(CGM.getVTableLinkage(RD));
238 bool shouldEmitExactDynamicCast(QualType DestRecordTy)
override {
239 return hasUniqueVTablePointer(DestRecordTy);
242 std::optional<ExactDynamicCastInfo>
243 getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
244 QualType DestRecordTy)
override;
246 llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address
Value,
247 QualType SrcRecordTy, QualType DestTy,
248 QualType DestRecordTy,
249 llvm::BasicBlock *CastEnd)
override;
252 QualType SrcRecordTy, QualType DestTy,
253 QualType DestRecordTy,
254 const ExactDynamicCastInfo &CastInfo,
255 llvm::BasicBlock *CastSuccess,
256 llvm::BasicBlock *CastFail)
override;
259 QualType SrcRecordTy)
override;
261 bool EmitBadCastCall(CodeGenFunction &CGF)
override;
264 GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
265 const CXXRecordDecl *ClassDecl,
266 const CXXRecordDecl *BaseClassDecl)
override;
268 void EmitCXXConstructors(
const CXXConstructorDecl *D)
override;
270 AddedStructorArgCounts
271 buildStructorSignature(GlobalDecl GD,
272 SmallVectorImpl<CanQualType> &ArgTys)
override;
274 bool useThunkForDtorVariant(
const CXXDestructorDecl *Dtor,
282 void EmitCXXDestructors(
const CXXDestructorDecl *D)
override;
284 void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
285 FunctionArgList &Params)
override;
287 void EmitInstanceFunctionProlog(CodeGenFunction &CGF)
override;
289 AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
290 const CXXConstructorDecl *D,
296 const CXXDestructorDecl *DD,
301 void EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
304 QualType ThisTy)
override;
306 void emitVTableDefinitions(CodeGenVTables &CGVT,
307 const CXXRecordDecl *RD)
override;
309 bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
310 CodeGenFunction::VPtr Vptr)
override;
312 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
317 getVTableAddressPoint(BaseSubobject Base,
318 const CXXRecordDecl *VTableClass)
override;
320 llvm::Value *getVTableAddressPointInStructor(
321 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
322 BaseSubobject Base,
const CXXRecordDecl *NearestVBase)
override;
324 llvm::Value *getVTableAddressPointInStructorWithVTT(
325 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
326 BaseSubobject Base,
const CXXRecordDecl *NearestVBase);
328 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
329 CharUnits VPtrOffset)
override;
331 CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
332 Address This, llvm::Type *Ty,
333 SourceLocation Loc)
override;
336 EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
338 DeleteOrMemberCallExpr E,
339 llvm::CallBase **CallOrInvoke)
override;
341 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
343 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
344 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
346 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable, GlobalDecl GD,
347 bool ReturnAdjustment)
override {
350 if (ForVTable && !Thunk->hasLocalLinkage())
351 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
352 CGM.setGVProperties(Thunk, GD);
355 bool exportThunk()
override {
return true; }
357 llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
358 const CXXRecordDecl *UnadjustedThisClass,
359 const ThunkInfo &TI)
override;
362 const CXXRecordDecl *UnadjustedRetClass,
363 const ReturnAdjustment &RA)
override;
365 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
366 FunctionArgList &Args)
const override {
367 assert(!Args.empty() &&
"expected the arglist to not be empty!");
368 return Args.size() - 1;
371 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
372 StringRef GetDeletedVirtualCallName()
override
373 {
return "__cxa_deleted_virtual"; }
375 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
376 Address InitializeArrayCookie(CodeGenFunction &CGF,
378 llvm::Value *NumElements,
379 const CXXNewExpr *
expr,
380 QualType ElementType)
override;
381 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
383 CharUnits cookieSize)
override;
385 void EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
386 llvm::GlobalVariable *DeclPtr,
387 bool PerformInit)
override;
388 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
389 llvm::FunctionCallee dtor,
390 llvm::Constant *addr)
override;
392 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
394 void EmitThreadLocalInitFuncs(
396 ArrayRef<const VarDecl *> CXXThreadLocals,
397 ArrayRef<llvm::Function *> CXXThreadLocalInits,
398 ArrayRef<const VarDecl *> CXXThreadLocalInitVars)
override;
400 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
401 return !isEmittedWithConstantInitializer(VD) ||
402 mayNeedDestruction(VD);
404 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
const VarDecl *VD,
405 QualType LValType)
override;
407 bool NeedsVTTParameter(GlobalDecl GD)
override;
410 getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
417 virtual bool shouldRTTIBeUnique()
const {
return true; }
421 enum RTTIUniquenessKind {
439 classifyRTTIUniqueness(QualType CanTy,
440 llvm::GlobalValue::LinkageTypes
Linkage)
const;
441 friend class ItaniumRTTIBuilder;
443 void emitCXXStructor(GlobalDecl GD)
override;
445 std::pair<llvm::Value *, const CXXRecordDecl *>
446 LoadVTablePtr(CodeGenFunction &CGF, Address This,
447 const CXXRecordDecl *RD)
override;
451 getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
453 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
454 const auto &VtableLayout =
455 CGM.getItaniumVTableContext().getVTableLayout(RD);
457 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
459 if (!VtableComponent.isUsedFunctionPointerKind())
462 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
463 const FunctionDecl *FD =
Method->getDefinition();
464 const bool IsInlined =
469 StringRef Name = CGM.getMangledName(
470 VtableComponent.getGlobalDecl(
false));
471 auto *Entry = CGM.GetGlobalValue(Name);
477 if (!Entry || Entry->isDeclaration())
483 bool isVTableHidden(
const CXXRecordDecl *RD)
const {
484 const auto &VtableLayout =
485 CGM.getItaniumVTableContext().getVTableLayout(RD);
487 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
488 if (VtableComponent.isRTTIKind()) {
489 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
490 if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
492 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
493 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
494 if (
Method->getVisibility() == Visibility::HiddenVisibility &&
503class ARMCXXABI :
public ItaniumCXXABI {
505 ARMCXXABI(CodeGen::CodeGenModule &CGM) :
506 ItaniumCXXABI(CGM,
true,
509 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
511 void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,
512 QualType ResTy)
override;
514 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
515 Address InitializeArrayCookie(CodeGenFunction &CGF,
517 llvm::Value *NumElements,
518 const CXXNewExpr *
expr,
519 QualType ElementType)
override;
520 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr,
521 CharUnits cookieSize)
override;
524class AppleARM64CXXABI :
public ARMCXXABI {
526 AppleARM64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {
527 Use32BitVTableOffsetABI =
true;
531 bool shouldRTTIBeUnique()
const override {
return false; }
534class FuchsiaCXXABI final :
public ItaniumCXXABI {
536 explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM)
537 : ItaniumCXXABI(CGM) {}
540 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
543class WebAssemblyCXXABI final :
public ItaniumCXXABI {
545 explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM)
546 : ItaniumCXXABI(CGM,
true,
548 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
550 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
551 llvm::Value *Exn)
override;
554 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
555 bool canCallMismatchedFunctionType()
const override {
return false; }
558class XLCXXABI final :
public ItaniumCXXABI {
560 explicit XLCXXABI(CodeGen::CodeGenModule &CGM)
561 : ItaniumCXXABI(CGM) {}
563 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
564 llvm::FunctionCallee dtor,
565 llvm::Constant *addr)
override;
567 bool useSinitAndSterm()
const override {
return true; }
570 void emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
571 llvm::Constant *addr);
579 case TargetCXXABI::GenericARM:
580 case TargetCXXABI::iOS:
581 case TargetCXXABI::WatchOS:
582 return new ARMCXXABI(CGM);
584 case TargetCXXABI::AppleARM64:
585 return new AppleARM64CXXABI(CGM);
587 case TargetCXXABI::Fuchsia:
588 return new FuchsiaCXXABI(CGM);
593 case TargetCXXABI::GenericAArch64:
594 return new ItaniumCXXABI(CGM,
true,
597 case TargetCXXABI::GenericMIPS:
598 return new ItaniumCXXABI(CGM,
true);
600 case TargetCXXABI::WebAssembly:
601 return new WebAssemblyCXXABI(CGM);
603 case TargetCXXABI::XL:
604 return new XLCXXABI(CGM);
606 case TargetCXXABI::GenericItanium:
607 return new ItaniumCXXABI(CGM);
609 case TargetCXXABI::Microsoft:
610 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
612 llvm_unreachable(
"bad ABI kind");
618 return CGM.PtrDiffTy;
619 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
642CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
644 llvm::Value *&ThisPtrForCall,
652 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
659 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
662 llvm::Value *Adj = RawAdj;
663 if (UseARMMethodPtrABI)
664 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
669 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(),
This, Adj);
670 ThisPtrForCall =
This;
673 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
677 llvm::Value *IsVirtual;
678 if (UseARMMethodPtrABI)
679 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
681 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
682 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
683 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
701 llvm::Value *VTableOffset = FnAsInt;
702 if (!UseARMMethodPtrABI)
703 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
704 if (Use32BitVTableOffsetABI) {
705 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
706 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
711 llvm::Constant *CheckSourceLocation;
712 llvm::Constant *CheckTypeDesc;
713 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
714 CGM.HasHiddenLTOVisibility(RD);
716 if (ShouldEmitCFICheck) {
717 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
718 if (BinOp->isPtrMemOp() &&
721 ->hasPointeeToCFIUncheckedCalleeFunctionType())
722 ShouldEmitCFICheck =
false;
726 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
727 CGM.HasHiddenLTOVisibility(RD);
731 bool ShouldEmitWPDInfo =
732 (CGM.getCodeGenOpts().WholeProgramVTables &&
734 !CGM.AlwaysHasLTOVisibilityPublic(RD)) ||
735 CGM.getCodeGenOpts().DevirtualizeSpeculatively;
736 llvm::Value *VirtualFn =
nullptr;
739 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
740 auto CheckHandler = SanitizerHandler::CFICheckFail;
741 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
743 llvm::Value *TypeId =
nullptr;
744 llvm::Value *CheckResult =
nullptr;
746 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
750 CGM.CreateMetadataIdentifierForVirtualMemPtrType(QualType(MPT, 0));
754 if (ShouldEmitVFEInfo) {
755 llvm::Value *VFPAddr =
756 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
763 llvm::Value *CheckedLoad = Builder.CreateCall(
764 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
765 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
766 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
767 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
771 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
772 llvm::Value *VFPAddr =
773 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
774 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
775 ? llvm::Intrinsic::type_test
776 : llvm::Intrinsic::public_type_test;
779 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
782 if (CGM.getLangOpts().RelativeCXXABIVTables) {
783 VirtualFn = CGF.
Builder.CreateCall(
784 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
785 {VTableOffset->getType()}),
786 {VTable, VTableOffset});
788 llvm::Value *VFPAddr =
795 assert(VirtualFn &&
"Virtual fuction pointer not created!");
796 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
798 "Check result required but not created!");
800 if (ShouldEmitCFICheck) {
804 llvm::Constant *StaticData[] = {
810 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
813 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
814 CGM.getLLVMContext(),
815 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
816 llvm::Value *ValidVtable = Builder.CreateCall(
817 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
818 CGF.
EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,
819 StaticData, {VTable, ValidVtable});
822 FnVirtual = Builder.GetInsertBlock();
831 llvm::Value *NonVirtualFn =
832 Builder.CreateIntToPtr(FnAsInt, CGF.
DefaultPtrTy,
"memptr.nonvirtualfn");
835 if (ShouldEmitCFICheck) {
838 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
839 auto CheckHandler = SanitizerHandler::CFICheckFail;
840 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
842 llvm::Constant *StaticData[] = {
848 llvm::Value *Bit = Builder.getFalse();
849 for (
const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {
850 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
853 Base->getCanonicalDecl()));
854 llvm::Value *TypeId =
857 llvm::Value *TypeTest =
858 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
859 {NonVirtualFn, TypeId});
860 Bit = Builder.CreateOr(Bit, TypeTest);
863 CGF.
EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,
864 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
866 FnNonVirtual = Builder.GetInsertBlock();
872 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
DefaultPtrTy, 2);
873 CalleePtr->addIncoming(VirtualFn, FnVirtual);
874 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
876 CGPointerAuthInfo PointerAuth;
878 if (
const auto &Schema =
879 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
880 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
881 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
883 const auto &AuthInfo =
884 CGM.getMemberFunctionPointerAuthInfo(QualType(MPT, 0));
885 assert(Schema.getKey() == AuthInfo.getKey() &&
886 "Keys for virtual and non-virtual member functions must match");
887 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
888 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
889 PointerAuth = CGPointerAuthInfo(
890 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
891 Schema.authenticatesNullValues(), DiscriminatorPHI);
894 CGCallee
Callee(FPT, CalleePtr, PointerAuth);
900llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
901 CodeGenFunction &CGF,
const Expr *E, Address Base, llvm::Value *MemPtr,
902 const MemberPointerType *MPT,
bool IsInBounds) {
903 assert(MemPtr->getType() == CGM.PtrDiffTy);
905 CGBuilderTy &Builder = CGF.
Builder;
908 llvm::Value *BaseAddr =
Base.emitRawPointer(CGF);
909 return Builder.CreateGEP(CGF.
Int8Ty, BaseAddr, MemPtr,
"memptr.offset",
910 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
911 : llvm::GEPNoWrapFlags::none());
918 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
923 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
924 CPA->getAddrDiscriminator()->isNullValue() &&
926 "unexpected key or discriminators");
929 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
957ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
964 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
965 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
968 CGBuilderTy &Builder = CGF.
Builder;
969 QualType DstType = E->
getType();
972 if (
const auto &NewAuthInfo =
973 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
976 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
977 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
978 llvm::Type *OrigTy = MemFnPtr->getType();
980 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
985 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
986 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
987 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
988 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
989 llvm::Value *IsVirtualOffset =
990 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
991 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
994 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
995 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
999 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
1000 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
1001 ResignBB = Builder.GetInsertBlock();
1004 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
1005 NewSrc->addIncoming(src, StartBB);
1006 NewSrc->addIncoming(ResignedVal, ResignBB);
1012 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1014 llvm::Constant *adj = getMemberPointerAdjustment(E);
1015 if (!adj)
return src;
1017 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1019 const MemberPointerType *destTy =
1026 if (isDerivedToBase)
1027 dst = Builder.CreateNSWSub(src, adj,
"adj");
1029 dst = Builder.CreateNSWAdd(src, adj,
"adj");
1032 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
1033 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
1034 return Builder.CreateSelect(isNull, src, dst);
1038 if (UseARMMethodPtrABI) {
1041 adj = llvm::ConstantInt::get(adj->getType(), offset);
1044 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1045 llvm::Value *dstAdj;
1046 if (isDerivedToBase)
1047 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1049 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1051 return Builder.CreateInsertValue(src, dstAdj, 1);
1054static llvm::Constant *
1059 "member function pointers expected");
1060 if (DestType == SrcType)
1066 if (!NewAuthInfo && !CurAuthInfo)
1069 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1070 if (MemFnPtr->getNumOperands() == 0) {
1078 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1079 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1083ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
1084 llvm::Constant *src) {
1085 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
1086 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
1089 QualType DstType = E->
getType();
1096 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1099 llvm::Constant *adj = getMemberPointerAdjustment(E);
1100 if (!adj)
return src;
1102 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1104 const MemberPointerType *destTy =
1111 if (src->isAllOnesValue())
return src;
1113 if (isDerivedToBase)
1114 return llvm::ConstantExpr::getNSWSub(src, adj);
1116 return llvm::ConstantExpr::getNSWAdd(src, adj);
1120 if (UseARMMethodPtrABI) {
1123 adj = llvm::ConstantInt::get(adj->getType(), offset);
1126 llvm::Constant *srcAdj = src->getAggregateElement(1);
1127 llvm::Constant *dstAdj;
1128 if (isDerivedToBase)
1129 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1131 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1133 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1134 assert(res !=
nullptr &&
"Folding must succeed");
1139ItaniumCXXABI::EmitNullMemberPointer(
const MemberPointerType *MPT) {
1143 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1145 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1146 llvm::Constant *Values[2] = {
Zero,
Zero };
1147 return llvm::ConstantStruct::getAnon(Values);
1151ItaniumCXXABI::EmitMemberDataPointer(
const MemberPointerType *MPT,
1156 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1160ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1164llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1165 CharUnits ThisAdjustment) {
1166 assert(MD->
isInstance() &&
"Member function must not be static!");
1168 CodeGenTypes &Types = CGM.getTypes();
1171 llvm::Constant *MemPtr[2];
1173 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1175 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1177 VTableOffset = Index * 4;
1179 const ASTContext &Context = getContext();
1182 VTableOffset = Index * PointerWidth.
getQuantity();
1185 if (UseARMMethodPtrABI) {
1207 const auto &Schema =
1208 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1210 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1211 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1213 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1216 MemPtr[1] = llvm::ConstantInt::get(
1217 CGM.PtrDiffTy, 2 * ThisAdjustment.
getQuantity() + !Schema);
1223 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1224 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1228 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
1239 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1241 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1242 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1243 (UseARMMethodPtrABI ? 2 : 1) *
1247 return llvm::ConstantStruct::getAnon(MemPtr);
1250llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1252 const MemberPointerType *MPT = MPType->
castAs<MemberPointerType>();
1255 return EmitNullMemberPointer(MPT);
1257 CharUnits ThisAdjustment = getContext().getMemberPointerPathAdjustment(MP);
1259 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1260 llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment);
1261 QualType SrcType = getContext().getMemberPointerType(
1266 getContext().recordMemberDataPointerEvaluation(MPD);
1267 CharUnits FieldOffset =
1268 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1269 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
1277ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
1280 const MemberPointerType *MPT,
1282 CGBuilderTy &Builder = CGF.
Builder;
1284 llvm::ICmpInst::Predicate Eq;
1285 llvm::Instruction::BinaryOps
And,
Or;
1287 Eq = llvm::ICmpInst::ICMP_NE;
1288 And = llvm::Instruction::Or;
1289 Or = llvm::Instruction::And;
1291 Eq = llvm::ICmpInst::ICMP_EQ;
1292 And = llvm::Instruction::And;
1293 Or = llvm::Instruction::Or;
1299 return Builder.CreateICmp(Eq, L, R);
1311 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1312 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1316 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1321 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1322 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr,
Zero,
"cmp.ptr.null");
1326 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1327 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1328 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1332 if (UseARMMethodPtrABI) {
1333 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1336 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1337 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1338 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1,
Zero,
1340 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1344 llvm::Value *
Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1346 Inequality ?
"memptr.ne" :
"memptr.eq");
1351ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
1352 llvm::Value *MemPtr,
1353 const MemberPointerType *MPT) {
1354 CGBuilderTy &Builder = CGF.
Builder;
1358 assert(MemPtr->getType() == CGM.PtrDiffTy);
1359 llvm::Value *NegativeOne =
1360 llvm::Constant::getAllOnesValue(MemPtr->getType());
1361 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1365 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1367 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1368 llvm::Value *
Result = Builder.CreateICmpNE(Ptr,
Zero,
"memptr.tobool");
1372 if (UseARMMethodPtrABI) {
1373 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1374 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1375 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1376 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit,
Zero,
1377 "memptr.isvirtual");
1384bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI)
const {
1385 const CXXRecordDecl *RD = FI.
getReturnType()->getAsCXXRecordDecl();
1392 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1393 LangAS SRetAS = CGM.getTargetCodeGenInfo().getSRetAddrSpace(RD);
1394 unsigned AS = CGM.getContext().getTargetAddressSpace(SRetAS);
1404bool ItaniumCXXABI::isZeroInitializable(
const MemberPointerType *MPT) {
1410void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
1411 const CXXDeleteExpr *DE,
1413 QualType ElementType,
1414 const CXXDestructorDecl *Dtor) {
1416 if (UseGlobalDelete) {
1425 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1426 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1444 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
1447 if (UseGlobalDelete)
1451void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF,
bool isNoReturn) {
1454 llvm::FunctionType *FTy =
1455 llvm::FunctionType::get(CGM.VoidTy,
false);
1457 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1468 llvm::FunctionType *FTy =
1479 llvm::FunctionType *FTy =
1480 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1485void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E) {
1488 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1489 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1493 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1500 llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1505 llvm::Constant *
Dtor =
nullptr;
1511 const ASTContext &Ctx = getContext();
1513 FunctionProtoType::ExtProtoInfo());
1515 CXXDestructorDecl *DtorD =
Record->getDestructor();
1517 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1519 if (!Dtor)
Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1521 llvm::Value *args[] = { ExceptionPtr, TypeInfo,
Dtor };
1533 llvm::Type *PtrDiffTy =
1536 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1538 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1542 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1543 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1544 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1545 llvm::AttributeList Attrs = llvm::AttributeList::get(
1546 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1553 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1570 unsigned NumPublicPaths = 0;
1583 if (PathElement.Base->isVirtual())
1586 if (NumPublicPaths > 1)
1590 const ASTRecordLayout &L = Context.getASTRecordLayout(PathElement.Class);
1592 PathElement.Base->getType()->getAsCXXRecordDecl());
1597 if (NumPublicPaths == 0)
1601 if (NumPublicPaths > 1)
1611 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1616bool ItaniumCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
1620void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1623 Call->setDoesNotReturn();
1624 CGF.
Builder.CreateUnreachable();
1627llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
1628 QualType SrcRecordTy,
1630 llvm::Type *StdTypeInfoPtrTy) {
1635 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1638 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1639 {Value, llvm::ConstantInt::getSigned(CGM.Int32Ty, -4)});
1643 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1649bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1650 QualType SrcRecordTy) {
1654llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1655 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1656 QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1657 llvm::Type *PtrDiffLTy =
1660 llvm::Value *SrcRTTI =
1662 llvm::Value *DestRTTI =
1668 llvm::Value *OffsetHint = llvm::ConstantInt::getSigned(
1674 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1680 llvm::Value *Vtable =
1682 CodeGenFunction::VTableAuthMode::MustTrap);
1687 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1693 llvm::BasicBlock *BadCastBlock =
1700 EmitBadCastCall(CGF);
1706std::optional<CGCXXABI::ExactDynamicCastInfo>
1707ItaniumCXXABI::getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
1708 QualType DestRecordTy) {
1709 assert(shouldEmitExactDynamicCast(DestRecordTy));
1711 ASTContext &Context = getContext();
1716 CXXBasePaths Paths(
true,
true,
1722 std::optional<CharUnits> Offset;
1723 for (
const CXXBasePath &Path : Paths) {
1728 CharUnits PathOffset;
1729 for (
const CXXBasePathElement &PathElement : Path) {
1731 const CXXRecordDecl *
Base =
1732 PathElement.Base->getType()->getAsCXXRecordDecl();
1733 if (PathElement.Base->isVirtual()) {
1739 const ASTRecordLayout &L =
1746 Offset = PathOffset;
1747 else if (Offset != PathOffset) {
1749 return ExactDynamicCastInfo{
true,
1754 return std::nullopt;
1755 return ExactDynamicCastInfo{
false, *Offset};
1758llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1759 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1760 QualType DestTy, QualType DestRecordTy,
1761 const ExactDynamicCastInfo &ExactCastInfo, llvm::BasicBlock *CastSuccess,
1762 llvm::BasicBlock *CastFail) {
1765 auto AuthenticateVTable = [&](
Address ThisAddr,
const CXXRecordDecl *
Decl) {
1769 CodeGenFunction::VTableAuthMode::MustTrap);
1772 bool PerformPostCastAuthentication =
false;
1773 llvm::Value *VTable =
nullptr;
1774 if (ExactCastInfo.RequiresCastToPrimaryBase) {
1779 llvm::Value *PrimaryBase =
1786 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1787 CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip,
1788 false,
false,
nullptr);
1791 if (PerformPostCastAuthentication)
1794 VTable = CGF.
GetVTablePtr(ThisAddr, CGM.GlobalsInt8PtrTy, SrcDecl);
1798 llvm::Constant *ExpectedVTable = getVTableAddressPoint(
1799 BaseSubobject(SrcDecl, ExactCastInfo.Offset), DestDecl);
1800 llvm::Value *
Success = CGF.
Builder.CreateICmpEQ(VTable, ExpectedVTable);
1803 if (!ExactCastInfo.Offset.isZero()) {
1805 llvm::Constant *OffsetConstant =
1806 llvm::ConstantInt::get(CGF.
PtrDiffTy, -Offset);
1809 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1812 if (PerformPostCastAuthentication) {
1815 llvm::BasicBlock *NonNullBlock = CGF.
Builder.GetInsertBlock();
1816 llvm::BasicBlock *PostCastAuthSuccess =
1818 llvm::BasicBlock *PostCastAuthComplete =
1821 PostCastAuthComplete);
1825 AuthenticateVTable(AdjustedThisAddr, DestDecl);
1828 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(AdjustedThisPtr->getType(), 2);
1829 PHI->addIncoming(AdjustedThisPtr, PostCastAuthSuccess);
1830 llvm::Value *NullValue =
1831 llvm::Constant::getNullValue(AdjustedThisPtr->getType());
1832 PHI->addIncoming(NullValue, NonNullBlock);
1833 AdjustedThisPtr = PHI;
1836 return AdjustedThisPtr;
1839llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
1841 QualType SrcRecordTy) {
1843 llvm::Value *OffsetToTop;
1844 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1846 llvm::Value *VTable =
1851 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1855 llvm::Type *PtrDiffLTy =
1859 llvm::Value *VTable =
1864 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1873bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1876 Call->setDoesNotReturn();
1877 CGF.
Builder.CreateUnreachable();
1882ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
1884 const CXXRecordDecl *ClassDecl,
1885 const CXXRecordDecl *BaseClassDecl) {
1886 llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1887 CharUnits VBaseOffsetOffset =
1888 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1890 llvm::Value *VBaseOffsetPtr =
1891 CGF.
Builder.CreateConstGEP1_64(
1893 "vbase.offset.ptr");
1895 llvm::Value *VBaseOffset;
1896 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1902 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1907void ItaniumCXXABI::EmitCXXConstructors(
const CXXConstructorDecl *D) {
1909 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1913 CGM.EmitGlobal(GlobalDecl(D,
Ctor_Base));
1923CGCXXABI::AddedStructorArgCounts
1924ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
1925 SmallVectorImpl<CanQualType> &ArgTys) {
1926 ASTContext &Context = getContext();
1935 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1937 ArgTys.insert(ArgTys.begin() + 1,
1939 return AddedStructorArgCounts::prefix(1);
1941 return AddedStructorArgCounts{};
1944void ItaniumCXXABI::EmitCXXDestructors(
const CXXDestructorDecl *D) {
1947 CGM.EmitGlobal(GlobalDecl(D,
Dtor_Base));
1960void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1962 FunctionArgList &Params) {
1967 if (NeedsVTTParameter(CGF.
CurGD)) {
1968 ASTContext &Context = getContext();
1971 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1976 T, ImplicitParamKind::CXXVTT);
1977 Params.insert(Params.begin() + 1, VTTDecl);
1978 getStructorImplicitParamDecl(CGF) = VTTDecl;
1982void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1989 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1992 if (getStructorImplicitParamDecl(CGF)) {
2005 if (HasThisReturn(CGF.
CurGD))
2009CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
2012 if (!NeedsVTTParameter(GlobalDecl(D,
Type)))
2013 return AddedStructorArgs{};
2020 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
2021 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
2022 QualType VTTTy = getContext().getPointerType(Q);
2023 return AddedStructorArgs::prefix({{VTT, VTTTy}});
2026llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
2029 GlobalDecl GD(DD,
Type);
2033void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
2034 const CXXDestructorDecl *DD,
2038 GlobalDecl GD(DD,
Type);
2041 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
2044 if (getContext().getLangOpts().AppleKext &&
2051 ThisTy, VTT, VTTTy,
nullptr);
2055template <
typename T>
2058 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2071 llvm::GlobalVariable *VTable,
2073 if (VTable->getDLLStorageClass() !=
2074 llvm::GlobalVariable::DefaultStorageClass ||
2080 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2082 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2085void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
2086 const CXXRecordDecl *RD) {
2087 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());
2088 if (VTable->hasInitializer())
2091 ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
2093 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2094 llvm::Constant *RTTI =
2095 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getCanonicalTagType(RD));
2098 ConstantInitBuilder builder(CGM);
2099 auto components = builder.beginStruct();
2101 llvm::GlobalValue::isLocalLinkage(
Linkage));
2102 components.finishAndSetAsInitializer(VTable);
2110 if (CGM.mayVTableBeDuplicated(VTable->getLinkage()))
2111 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2113 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2114 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2116 if (CGM.getTarget().hasPS4DLLImportExport())
2120 CGM.setGVProperties(VTable, RD);
2131 EmitFundamentalRTTIDescriptors(RD);
2139 if (!VTable->isDeclarationForLinker() ||
2140 CGM.getCodeGenOpts().WholeProgramVTables ||
2141 CGM.getCodeGenOpts().DevirtualizeSpeculatively) {
2142 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2146 if (VTable->isDeclarationForLinker()) {
2147 assert(CGM.getCodeGenOpts().WholeProgramVTables ||
2148 CGM.getCodeGenOpts().DevirtualizeSpeculatively);
2149 CGM.addCompilerUsedGlobal(VTable);
2153 if (CGM.getLangOpts().RelativeCXXABIVTables) {
2155 if (!VTable->isDSOLocal())
2160 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
2161 DI->emitVTableSymbol(VTable, RD);
2164bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2165 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
2168 return NeedsVTTParameter(CGF.
CurGD);
2171llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2172 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2173 const CXXRecordDecl *NearestVBase) {
2175 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2176 NeedsVTTParameter(CGF.
CurGD)) {
2177 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
2180 return getVTableAddressPoint(Base, VTableClass);
2184ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
2185 const CXXRecordDecl *VTableClass) {
2186 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());
2190 const VTableLayout &Layout =
2191 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2192 VTableLayout::AddressPointLocation AddressPoint =
2194 llvm::Value *Indices[] = {
2195 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2196 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2202 unsigned ComponentSize =
2203 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2204 unsigned VTableSize =
2207 llvm::ConstantRange InRange(
2208 llvm::APInt(32, (
int)-Offset,
true),
2209 llvm::APInt(32, (
int)(VTableSize - Offset),
true));
2210 return llvm::ConstantExpr::getGetElementPtr(
2211 VTable->getValueType(), VTable, Indices,
true, InRange);
2214llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2215 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2216 const CXXRecordDecl *NearestVBase) {
2217 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2218 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2222 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
2226 if (VirtualPointerIndex)
2228 VirtualPointerIndex);
2235 if (
auto PointerAuth = CGM.getVTablePointerAuthInfo(&CGF, VTableClass, VTT,
2242llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2243 CharUnits VPtrOffset) {
2244 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2246 llvm::GlobalVariable *&VTable = VTables[RD];
2251 CGM.addDeferredVTable(RD);
2253 SmallString<256> Name;
2254 llvm::raw_svector_ostream
Out(Name);
2255 getMangleContext().mangleCXXVTable(RD, Out);
2257 const VTableLayout &VTLayout =
2258 CGM.getItaniumVTableContext().getVTableLayout(RD);
2259 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2264 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2266 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2267 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2268 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2269 if (!CGM.shouldEmitRTTI())
2270 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2272 if (CGM.getTarget().hasPS4DLLImportExport())
2275 CGM.setGVProperties(VTable, RD);
2279CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
2283 SourceLocation Loc) {
2284 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2286 llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
2292 if (CGM.getLangOpts().OpenMPIsTargetDevice) {
2293 auto *NewPtrTy = CGM.VoidPtrTy;
2294 llvm::Type *RtlFnArgs[] = {NewPtrTy};
2295 llvm::FunctionCallee DeviceRtlFn = CGM.CreateRuntimeFunction(
2296 llvm::FunctionType::get(NewPtrTy, RtlFnArgs,
false),
2297 "__llvm_omp_indirect_call_lookup");
2298 auto *BackupTy = VTable->getType();
2306 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2307 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2308 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2310 llvm::Type *ComponentTy = CGM.getVTables().getVTableComponentType();
2312 VTableIndex * CGM.getDataLayout().getTypeSizeInBits(ComponentTy) / 8;
2320 llvm::Value *VFuncLoad;
2321 if (CGM.getLangOpts().RelativeCXXABIVTables) {
2322 VFuncLoad = CGF.
Builder.CreateCall(
2323 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2324 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, ByteOffset)});
2326 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2327 PtrTy, VTable, VTableIndex,
"vfn");
2338 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2339 CGM.getCodeGenOpts().StrictVTablePointers) {
2340 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2341 VFuncLoadInstr->setMetadata(
2342 llvm::LLVMContext::MD_invariant_load,
2343 llvm::MDNode::get(CGM.getLLVMContext(),
2344 llvm::ArrayRef<llvm::Metadata *>()));
2350 CGPointerAuthInfo PointerAuth;
2352 assert(VTableSlotPtr &&
"virtual function pointer not set");
2353 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2356 CGCallee
Callee(GD, VFunc, PointerAuth);
2360llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2361 CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
CXXDtorType DtorType,
2362 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
2363 auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
2364 auto *D = dyn_cast<const CXXDeleteExpr *>(E);
2365 assert((CE !=
nullptr) ^ (D !=
nullptr));
2366 assert(CE ==
nullptr || CE->arguments().empty());
2369 GlobalDecl GD(Dtor, DtorType);
2370 const CGFunctionInfo *FInfo =
2371 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2377 ThisTy = CE->getObjectType();
2379 ThisTy = D->getDestroyedType();
2383 nullptr, QualType(),
nullptr, CallOrInvoke);
2387void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2388 CodeGenVTables &VTables = CGM.getVTables();
2393bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2394 const CXXRecordDecl *RD)
const {
2397 if (CGM.getLangOpts().AppleKext)
2402 if (isVTableHidden(RD))
2405 if (CGM.getCodeGenOpts().ForceEmitVTables)
2422 if (hasAnyUnusedVirtualInlineFunction(RD))
2430 for (
const auto &B : RD->
bases()) {
2431 auto *BRD = B.getType()->getAsCXXRecordDecl();
2432 assert(BRD &&
"no class for base specifier");
2433 if (B.isVirtual() || !BRD->isDynamicClass())
2435 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2443bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2444 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2452 for (
const auto &B : RD->
vbases()) {
2453 auto *BRD = B.getType()->getAsCXXRecordDecl();
2454 assert(BRD &&
"no class for base specifier");
2455 if (!BRD->isDynamicClass())
2457 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2466 int64_t NonVirtualAdjustment,
2467 int64_t VirtualAdjustment,
2468 bool IsReturnAdjustment) {
2469 if (!NonVirtualAdjustment && !VirtualAdjustment)
2475 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2481 llvm::Value *ResultPtr;
2482 if (VirtualAdjustment) {
2483 llvm::Value *VTablePtr =
2486 llvm::Value *Offset;
2487 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2488 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2495 llvm::Type *PtrDiffTy =
2504 V.emitRawPointer(CGF), Offset);
2506 ResultPtr =
V.emitRawPointer(CGF);
2511 if (NonVirtualAdjustment && IsReturnAdjustment) {
2512 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2513 NonVirtualAdjustment);
2520ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This,
2521 const CXXRecordDecl *UnadjustedClass,
2522 const ThunkInfo &TI) {
2529ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
2530 const CXXRecordDecl *UnadjustedClass,
2531 const ReturnAdjustment &RA) {
2537void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
2538 RValue RV, QualType ResultType) {
2540 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2545 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2550CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2554 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2557Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2559 llvm::Value *NumElements,
2560 const CXXNewExpr *
expr,
2561 QualType ElementType) {
2562 assert(requiresArrayCookie(
expr));
2566 ASTContext &Ctx = getContext();
2570 CharUnits CookieSize =
2572 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2576 CharUnits CookieOffset = CookieSize - SizeSize;
2577 if (!CookieOffset.
isZero())
2585 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2586 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2587 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2589 SI->setNoSanitizeMetadata();
2590 llvm::FunctionType *FTy =
2591 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2592 llvm::FunctionCallee F =
2593 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2602llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2604 CharUnits cookieSize) {
2606 Address numElementsPtr = allocPtr;
2607 CharUnits numElementsOffset = cookieSize - CGF.
getSizeSize();
2608 if (!numElementsOffset.
isZero())
2614 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2621 llvm::FunctionType *FTy =
2623 llvm::FunctionCallee F =
2624 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2628CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2638 CGM.getContext().getTypeAlignInChars(elementType));
2641Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2643 llvm::Value *numElements,
2644 const CXXNewExpr *
expr,
2645 QualType elementType) {
2646 assert(requiresArrayCookie(
expr));
2653 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2654 getContext().getTypeSizeInChars(elementType).getQuantity());
2663 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2667llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2669 CharUnits cookieSize) {
2682 llvm::PointerType *GuardPtrTy) {
2684 llvm::FunctionType *FTy =
2688 FTy,
"__cxa_guard_acquire",
2690 llvm::AttributeList::FunctionIndex,
2691 llvm::Attribute::NoUnwind));
2695 llvm::PointerType *GuardPtrTy) {
2697 llvm::FunctionType *FTy =
2698 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2700 FTy,
"__cxa_guard_release",
2702 llvm::AttributeList::FunctionIndex,
2703 llvm::Attribute::NoUnwind));
2707 llvm::PointerType *GuardPtrTy) {
2709 llvm::FunctionType *FTy =
2710 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2712 FTy,
"__cxa_guard_abort",
2714 llvm::AttributeList::FunctionIndex,
2715 llvm::Attribute::NoUnwind));
2719 struct CallGuardAbort final : EHScopeStack::Cleanup {
2720 llvm::GlobalVariable *Guard;
2721 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2723 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2732void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
2734 llvm::GlobalVariable *var,
2735 bool shouldPerformInit) {
2736 CGBuilderTy &Builder = CGF.
Builder;
2740 bool NonTemplateInline =
2747 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2753 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2755 llvm::IntegerType *guardTy;
2756 CharUnits guardAlignment;
2757 if (useInt8GuardVariable) {
2763 if (UseARMGuardVarABI) {
2772 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2778 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2781 SmallString<256> guardName;
2783 llvm::raw_svector_ostream
out(guardName);
2784 getMangleContext().mangleStaticGuardVariable(&D,
out);
2790 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2791 false,
var->getLinkage(),
2792 llvm::ConstantInt::get(guardTy, 0),
2794 guard->setDSOLocal(
var->isDSOLocal());
2795 guard->setVisibility(
var->getVisibility());
2796 guard->setDLLStorageClass(
var->getDLLStorageClass());
2798 guard->setThreadLocalMode(
var->getThreadLocalMode());
2799 guard->setAlignment(guardAlignment.
getAsAlign());
2804 llvm::Comdat *
C =
var->getComdat();
2806 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2807 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2808 guard->setComdat(
C);
2809 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2810 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2813 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2816 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2841 if (!threadsafe || MaxInlineWidthInBits) {
2843 llvm::LoadInst *LI =
2853 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2876 (UseARMGuardVarABI && !useInt8GuardVariable)
2877 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2879 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2885 CodeGenFunction::GuardKind::VariableGuard, &D);
2913 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2914 InitBlock, EndBlock);
2924 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2942 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2951 llvm::FunctionCallee dtor,
2952 llvm::Constant *addr,
bool TLS) {
2954 "unexpected call to emitGlobalDtorWithCXAAtExit");
2956 "__cxa_atexit is disabled");
2957 const char *Name =
"__cxa_atexit";
2960 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2968 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2969 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2973 llvm::Constant *handle =
2976 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2979 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2980 llvm::FunctionType *atexitTy =
2981 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2985 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2986 fn->setDoesNotThrow();
2992 Context.getFunctionType(Context.VoidTy, {Context.VoidPtrTy}, EPI);
2993 llvm::Value *dtorCallee = dtor.getCallee();
2997 if (dtorCallee->getType()->getPointerAddressSpace() != AddrAS)
3005 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
3007 llvm::Value *args[] = {dtorCallee, addr, handle};
3015 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3019 return GlobalInitOrCleanupFn;
3022void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
3023 for (
const auto &I : DtorsUsingAtExit) {
3024 int Priority = I.first;
3025 std::string GlobalCleanupFnName =
3026 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
3028 llvm::Function *GlobalCleanupFn =
3031 CodeGenFunction CGF(*
this);
3032 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalCleanupFn,
3033 getTypes().arrangeNullaryFunction(), FunctionArgList(),
3034 SourceLocation(), SourceLocation());
3038 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
3042 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3043 auto itv = Dtors.rbegin();
3044 while (itv != Dtors.rend()) {
3045 llvm::Function *
Dtor = *itv;
3050 llvm::Value *NeedsDestruct =
3053 llvm::BasicBlock *DestructCallBlock =
3056 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
3059 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
3064 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
3066 CI->setCallingConv(
Dtor->getCallingConv());
3074 AddGlobalDtor(GlobalCleanupFn, Priority);
3078void CodeGenModule::registerGlobalDtorsWithAtExit() {
3079 for (
const auto &I : DtorsUsingAtExit) {
3080 int Priority = I.first;
3081 std::string GlobalInitFnName =
3082 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
3083 llvm::Function *GlobalInitFn =
3086 CodeGenFunction CGF(*
this);
3087 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalInitFn,
3088 getTypes().arrangeNullaryFunction(), FunctionArgList(),
3089 SourceLocation(), SourceLocation());
3097 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3098 for (
auto *Dtor : Dtors) {
3101 if (getCodeGenOpts().CXAAtExit) {
3111 AddGlobalCtor(GlobalInitFn, Priority);
3114 if (getCXXABI().useSinitAndSterm())
3115 unregisterGlobalDtorsWithUnAtExit();
3119void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
3120 llvm::FunctionCallee dtor,
3121 llvm::Constant *addr) {
3126 if (CGM.getLangOpts().HLSL)
3127 return CGM.AddCXXDtorEntry(dtor, addr);
3141 if (CGM.getCodeGenOpts().CXAAtExit || D.
getTLSKind())
3146 if (CGM.getLangOpts().AppleKext) {
3148 return CGM.AddCXXDtorEntry(dtor, addr);
3156 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3166static llvm::GlobalValue::LinkageTypes
3168 llvm::GlobalValue::LinkageTypes VarLinkage =
3172 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3177 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3178 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3180 return llvm::GlobalValue::WeakODRLinkage;
3184ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3187 SmallString<256> WrapperName;
3189 llvm::raw_svector_ostream
Out(WrapperName);
3190 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3195 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3198 QualType RetQT = VD->
getType();
3202 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3203 getContext().getPointerType(RetQT), FunctionArgList());
3205 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3206 llvm::Function *Wrapper =
3208 WrapperName.str(), &CGM.getModule());
3210 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3211 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3213 CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper,
false);
3216 if (!Wrapper->hasLocalLinkage())
3218 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3219 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3221 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
3224 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3225 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3228 ThreadWrappers.push_back({VD, Wrapper});
3232void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3233 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
3234 ArrayRef<llvm::Function *> CXXThreadLocalInits,
3235 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
3236 llvm::Function *InitFunc =
nullptr;
3240 llvm::SmallVector<llvm::Function *, 8> OrderedInits;
3241 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3242 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3245 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3246 CXXThreadLocalInits[I];
3248 OrderedInits.push_back(CXXThreadLocalInits[I]);
3251 if (!OrderedInits.empty()) {
3253 llvm::FunctionType *FTy =
3254 llvm::FunctionType::get(CGM.
VoidTy,
false);
3259 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3261 llvm::GlobalVariable::InternalLinkage,
3262 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3263 Guard->setThreadLocal(
true);
3267 Guard->setAlignment(GuardAlign.
getAsAlign());
3269 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(
3270 InitFunc, OrderedInits, ConstantAddress(Guard, CGM.
Int8Ty, GuardAlign));
3273 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3274 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3280 for (
const VarDecl *VD : CXXThreadLocals) {
3284 getOrCreateThreadLocalWrapper(VD, GV);
3289 for (
auto VDAndWrapper : ThreadWrappers) {
3290 const VarDecl *VD = VDAndWrapper.first;
3291 llvm::GlobalVariable *Var =
3293 llvm::Function *Wrapper = VDAndWrapper.second;
3300 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3306 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3307 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3313 SmallString<256> InitFnName;
3315 llvm::raw_svector_ostream
Out(InitFnName);
3316 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3319 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3324 llvm::GlobalValue *
Init =
nullptr;
3325 bool InitIsInitFunc =
false;
3326 bool HasConstantInitialization =
false;
3327 if (!usesThreadWrapperFunction(VD)) {
3328 HasConstantInitialization =
true;
3330 InitIsInitFunc =
true;
3331 llvm::Function *InitFuncToUse = InitFunc;
3335 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3342 Init = llvm::Function::Create(InitFnTy,
3343 llvm::GlobalVariable::ExternalWeakLinkage,
3351 Init->setVisibility(Var->getVisibility());
3353 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3354 Init->setDSOLocal(Var->isDSOLocal());
3357 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3365 isEmittedWithConstantInitializer(VD,
true) &&
3366 !mayNeedDestruction(VD)) {
3371 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3373 llvm::Function *
Func = llvm::Function::Create(
3374 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3380 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3381 CGBuilderTy Builder(CGM, Entry);
3382 Builder.CreateRetVoid();
3385 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3386 CGBuilderTy Builder(CGM, Entry);
3387 if (HasConstantInitialization) {
3389 }
else if (InitIsInitFunc) {
3391 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3393 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3394 llvm::Function *
Fn =
3396 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3407 Builder.CreateCall(InitFnTy,
Init);
3410 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3411 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3412 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3413 Builder.CreateCondBr(Have, InitBB, ExitBB);
3415 Builder.SetInsertPoint(InitBB);
3416 Builder.CreateCall(InitFnTy,
Init);
3417 Builder.CreateBr(ExitBB);
3419 Builder.SetInsertPoint(ExitBB);
3424 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3428 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3430 Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());
3432 Builder.CreateRet(Val);
3436LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
3438 QualType LValType) {
3440 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3442 llvm::CallInst *CallVal =
3444 CallVal->setCallingConv(Wrapper->getCallingConv());
3458bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
3477ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3478 SmallString<256> MethodName;
3479 llvm::raw_svector_ostream
Out(MethodName);
3480 getMangleContext().mangleCXXName(MD, Out);
3481 MethodName +=
"_vfpthunk_";
3482 StringRef ThunkName = MethodName.str();
3483 llvm::Function *ThunkFn;
3484 if ((ThunkFn = cast_or_null<llvm::Function>(
3485 CGM.
getModule().getNamedValue(ThunkName))))
3490 llvm::GlobalValue::LinkageTypes
Linkage =
3492 : llvm::GlobalValue::InternalLinkage;
3495 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3496 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
3497 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3503 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3504 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3505 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3508 CodeGenFunction CGF(CGM);
3509 CGF.
CurGD = GlobalDecl(MD);
3513 FunctionArgList FunctionArgs;
3517 FunctionArgs, MD->
getLocation(), SourceLocation());
3522 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3523 setCXXABIThisValue(CGF, ThisVal);
3525 CallArgList CallArgs;
3526 for (
const VarDecl *VD : FunctionArgs)
3529 const FunctionProtoType *FPT = MD->
getType()->
getAs<FunctionProtoType>();
3531 const CGFunctionInfo &CallInfo =
3534 getThisAddress(CGF), ThunkTy);
3535 llvm::CallBase *CallOrInvoke;
3536 CGF.
EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke,
3537 true, SourceLocation(),
true);
3539 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3540 if (
Call->getType()->isVoidTy())
3553class ItaniumRTTIBuilder {
3555 llvm::LLVMContext &VMContext;
3556 const ItaniumCXXABI &
CXXABI;
3559 SmallVector<llvm::Constant *, 16> Fields;
3562 llvm::GlobalVariable *
3563 GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3567 llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
3570 void BuildVTablePointer(
const Type *Ty, llvm::Constant *StorageAddress);
3574 void BuildSIClassTypeInfo(
const CXXRecordDecl *RD);
3579 void BuildVMIClassTypeInfo(
const CXXRecordDecl *RD);
3583 void BuildPointerTypeInfo(QualType PointeeTy);
3587 void BuildObjCObjectTypeInfo(
const ObjCObjectType *Ty);
3591 void BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty);
3594 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3595 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3609 PTI_Incomplete = 0x8,
3613 PTI_ContainingClassIncomplete = 0x10,
3619 PTI_Noexcept = 0x40,
3625 VMI_NonDiamondRepeat = 0x1,
3628 VMI_DiamondShaped = 0x2
3642 llvm::Constant *BuildTypeInfo(QualType Ty);
3645 llvm::Constant *BuildTypeInfo(
3647 llvm::GlobalVariable::LinkageTypes
Linkage,
3648 llvm::GlobalValue::VisibilityTypes
Visibility,
3649 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3653llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3654 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage) {
3655 SmallString<256> Name;
3656 llvm::raw_svector_ostream
Out(Name);
3662 llvm::Constant *
Init;
3665 SmallString<256> DualEncodedName;
3666 llvm::ConverterEBCDIC::convertToEBCDIC(Name.substr(4), DualEncodedName);
3667 DualEncodedName +=
'\0';
3668 DualEncodedName += Name.substr(4);
3669 Init = llvm::ConstantDataArray::getString(VMContext, DualEncodedName);
3671 Init = llvm::ConstantDataArray::getString(VMContext, Name.substr(4));
3678 GV->setInitializer(
Init);
3684ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
3686 SmallString<256> Name;
3687 llvm::raw_svector_ostream
Out(Name);
3691 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3698 GV =
new llvm::GlobalVariable(
3700 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3707 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3734 case BuiltinType::Void:
3735 case BuiltinType::NullPtr:
3736 case BuiltinType::Bool:
3737 case BuiltinType::WChar_S:
3738 case BuiltinType::WChar_U:
3739 case BuiltinType::Char_U:
3740 case BuiltinType::Char_S:
3741 case BuiltinType::UChar:
3742 case BuiltinType::SChar:
3743 case BuiltinType::Short:
3744 case BuiltinType::UShort:
3745 case BuiltinType::Int:
3746 case BuiltinType::UInt:
3747 case BuiltinType::Long:
3748 case BuiltinType::ULong:
3749 case BuiltinType::LongLong:
3750 case BuiltinType::ULongLong:
3751 case BuiltinType::Half:
3752 case BuiltinType::Float:
3753 case BuiltinType::Double:
3754 case BuiltinType::LongDouble:
3755 case BuiltinType::Float16:
3756 case BuiltinType::Float128:
3757 case BuiltinType::Ibm128:
3758 case BuiltinType::Char8:
3759 case BuiltinType::Char16:
3760 case BuiltinType::Char32:
3761 case BuiltinType::Int128:
3762 case BuiltinType::UInt128:
3765#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3766 case BuiltinType::Id:
3767#include "clang/Basic/OpenCLImageTypes.def"
3768#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3769 case BuiltinType::Id:
3770#include "clang/Basic/OpenCLExtensionTypes.def"
3771 case BuiltinType::OCLSampler:
3772 case BuiltinType::OCLEvent:
3773 case BuiltinType::OCLClkEvent:
3774 case BuiltinType::OCLQueue:
3775 case BuiltinType::OCLReserveID:
3776#define SVE_TYPE(Name, Id, SingletonId) \
3777 case BuiltinType::Id:
3778#include "clang/Basic/AArch64ACLETypes.def"
3779#define PPC_VECTOR_TYPE(Name, Id, Size) \
3780 case BuiltinType::Id:
3781#include "clang/Basic/PPCTypes.def"
3782#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3783#include "clang/Basic/RISCVVTypes.def"
3784#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3785#include "clang/Basic/WebAssemblyReferenceTypes.def"
3786#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
3787#include "clang/Basic/AMDGPUTypes.def"
3788#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3789#include "clang/Basic/HLSLIntangibleTypes.def"
3790#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3791#include "clang/Basic/SPIRVTypes.def"
3792 case BuiltinType::ShortAccum:
3793 case BuiltinType::Accum:
3794 case BuiltinType::LongAccum:
3795 case BuiltinType::UShortAccum:
3796 case BuiltinType::UAccum:
3797 case BuiltinType::ULongAccum:
3798 case BuiltinType::ShortFract:
3799 case BuiltinType::Fract:
3800 case BuiltinType::LongFract:
3801 case BuiltinType::UShortFract:
3802 case BuiltinType::UFract:
3803 case BuiltinType::ULongFract:
3804 case BuiltinType::SatShortAccum:
3805 case BuiltinType::SatAccum:
3806 case BuiltinType::SatLongAccum:
3807 case BuiltinType::SatUShortAccum:
3808 case BuiltinType::SatUAccum:
3809 case BuiltinType::SatULongAccum:
3810 case BuiltinType::SatShortFract:
3811 case BuiltinType::SatFract:
3812 case BuiltinType::SatLongFract:
3813 case BuiltinType::SatUShortFract:
3814 case BuiltinType::SatUFract:
3815 case BuiltinType::SatULongFract:
3816 case BuiltinType::BFloat16:
3819 case BuiltinType::Dependent:
3820#define BUILTIN_TYPE(Id, SingletonId)
3821#define PLACEHOLDER_TYPE(Id, SingletonId) \
3822 case BuiltinType::Id:
3823#include "clang/AST/BuiltinTypes.def"
3824 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3826 case BuiltinType::ObjCId:
3827 case BuiltinType::ObjCClass:
3828 case BuiltinType::ObjCSel:
3829 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3832 llvm_unreachable(
"Invalid BuiltinType Kind!");
3837 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3855 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3860 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3876 if (!Context.getLangOpts().RTTI)
return false;
3878 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3891 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3901 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3914 return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
3929 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3934 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3938 dyn_cast<MemberPointerType>(Ty)) {
3940 if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
3961 if (
Base->isVirtual())
3969 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
3970 if (!BaseDecl->isEmpty() &&
3977void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty,
3978 llvm::Constant *StorageAddress) {
3980 static const char *
const ClassTypeInfo =
3981 "_ZTVN10__cxxabiv117__class_type_infoE";
3983 static const char *
const SIClassTypeInfo =
3984 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3986 static const char *
const VMIClassTypeInfo =
3987 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3989 const char *VTableName =
nullptr;
3992#define TYPE(Class, Base)
3993#define ABSTRACT_TYPE(Class, Base)
3994#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3995#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3996#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3997#include "clang/AST/TypeNodes.inc"
3998 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4000 case Type::LValueReference:
4001 case Type::RValueReference:
4002 llvm_unreachable(
"References shouldn't get here");
4005 case Type::DeducedTemplateSpecialization:
4006 llvm_unreachable(
"Undeduced type shouldn't get here");
4009 llvm_unreachable(
"Pipe types shouldn't get here");
4011 case Type::ArrayParameter:
4012 llvm_unreachable(
"Array Parameter types should not get here.");
4016 case Type::OverflowBehavior:
4019 case Type::ExtVector:
4020 case Type::ConstantMatrix:
4024 case Type::BlockPointer:
4026 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
4029 case Type::ConstantArray:
4030 case Type::IncompleteArray:
4031 case Type::VariableArray:
4033 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
4036 case Type::FunctionNoProto:
4037 case Type::FunctionProto:
4039 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
4044 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
4047 case Type::Record: {
4049 ->getDefinitionOrSelf();
4052 VTableName = ClassTypeInfo;
4054 VTableName = SIClassTypeInfo;
4056 VTableName = VMIClassTypeInfo;
4062 case Type::ObjCObject:
4068 VTableName = ClassTypeInfo;
4075 case Type::ObjCInterface:
4077 VTableName = SIClassTypeInfo;
4079 VTableName = ClassTypeInfo;
4083 case Type::ObjCObjectPointer:
4086 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
4089 case Type::MemberPointer:
4091 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
4094 case Type::HLSLAttributedResource:
4095 case Type::HLSLInlineSpirv:
4096 llvm_unreachable(
"HLSL doesn't support virtual functions");
4099 llvm::Constant *VTable =
nullptr;
4103 VTable = CGM.
getModule().getNamedAlias(VTableName);
4106 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
4111 llvm::Type *PtrDiffTy =
4118 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
4119 VTable = llvm::ConstantExpr::getInBoundsPtrAdd(VTable, Eight);
4121 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
4122 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
4126 if (
const auto &Schema =
4130 Schema.isAddressDiscriminated() ? StorageAddress :
nullptr,
4131 GlobalDecl(), QualType(Ty, 0));
4133 Fields.push_back(VTable);
4150 return llvm::GlobalValue::InternalLinkage;
4154 llvm_unreachable(
"Linkage hasn't been computed!");
4159 return llvm::GlobalValue::InternalLinkage;
4167 return llvm::GlobalValue::LinkOnceODRLinkage;
4169 if (
const RecordType *
Record = dyn_cast<RecordType>(Ty)) {
4173 return llvm::GlobalValue::WeakODRLinkage;
4174 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4175 if (RD->
hasAttr<DLLImportAttr>() &&
4177 return llvm::GlobalValue::ExternalLinkage;
4184 return llvm::GlobalValue::LinkOnceODRLinkage;
4187 llvm_unreachable(
"Invalid linkage!");
4190llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) {
4195 SmallString<256> Name;
4196 llvm::raw_svector_ostream
Out(Name);
4199 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4200 if (OldGV && !OldGV->isDeclaration()) {
4201 assert(!OldGV->hasAvailableExternallyLinkage() &&
4202 "available_externally typeinfos not yet implemented");
4210 return GetAddrOfExternalRTTIDescriptor(Ty);
4217 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4218 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4220 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
4222 ItaniumCXXABI::RUK_NonUniqueHidden)
4223 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
4227 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4228 llvm::GlobalValue::DefaultStorageClass;
4230 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4231 RD->
hasAttr<DLLExportAttr>()) ||
4233 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4234 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
4235 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4237 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass);
4240llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4242 llvm::GlobalVariable::LinkageTypes
Linkage,
4243 llvm::GlobalValue::VisibilityTypes
Visibility,
4244 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4245 SmallString<256> Name;
4246 llvm::raw_svector_ostream
Out(Name);
4249 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4251 llvm::GlobalVariable *GV =
4260 llvm::Constant *TypeNameField;
4264 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4266 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4269 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4270 llvm::Constant *flag =
4271 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
4272 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4278 Fields.push_back(TypeNameField);
4281#define TYPE(Class, Base)
4282#define ABSTRACT_TYPE(Class, Base)
4283#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4284#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4285#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4286#include "clang/AST/TypeNodes.inc"
4287 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4292 case Type::ExtVector:
4293 case Type::ConstantMatrix:
4295 case Type::BlockPointer:
4300 case Type::LValueReference:
4301 case Type::RValueReference:
4302 llvm_unreachable(
"References shouldn't get here");
4305 case Type::DeducedTemplateSpecialization:
4306 llvm_unreachable(
"Undeduced type shouldn't get here");
4314 case Type::ConstantArray:
4315 case Type::IncompleteArray:
4316 case Type::VariableArray:
4317 case Type::ArrayParameter:
4322 case Type::FunctionNoProto:
4323 case Type::FunctionProto:
4333 case Type::Record: {
4335 ->getDefinitionOrSelf();
4342 BuildSIClassTypeInfo(RD);
4344 BuildVMIClassTypeInfo(RD);
4349 case Type::ObjCObject:
4350 case Type::ObjCInterface:
4354 case Type::ObjCObjectPointer:
4362 case Type::MemberPointer:
4370 case Type::OverflowBehavior:
4373 case Type::HLSLAttributedResource:
4374 case Type::HLSLInlineSpirv:
4375 llvm_unreachable(
"HLSL doesn't support RTTI");
4378 GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));
4381 auto GVDLLStorageClass = DLLStorageClass;
4383 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
4384 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
4387 if (RD->
hasAttr<DLLExportAttr>() ||
4389 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
4395 GV->takeName(OldGV);
4396 OldGV->replaceAllUsesWith(GV);
4397 OldGV->eraseFromParent();
4401 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4428 TypeName->setDLLStorageClass(DLLStorageClass);
4429 GV->setDLLStorageClass(GVDLLStorageClass);
4439void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4441 const Type *
T = OT->getBaseType().getTypePtr();
4449 ObjCInterfaceDecl *Super =
Class->getSuperClass();
4457 llvm::Constant *BaseTypeInfo =
4458 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4459 Fields.push_back(BaseTypeInfo);
4464void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4468 llvm::Constant *BaseTypeInfo =
4470 Fields.push_back(BaseTypeInfo);
4477 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
4478 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
4490 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
4491 if (
Base->isVirtual()) {
4493 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4496 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4498 if (Bases.NonVirtualBases.count(BaseDecl))
4499 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4503 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4506 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4508 if (Bases.VirtualBases.count(BaseDecl))
4509 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4514 for (
const auto &I : BaseDecl->bases())
4525 for (
const auto &I : RD->
bases())
4534void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4535 llvm::Type *UnsignedIntLTy =
4543 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4548 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4581 llvm::Type *OffsetFlagsLTy =
4584 for (
const auto &Base : RD->
bases()) {
4586 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4588 auto *BaseDecl =
Base.getType()->castAsCXXRecordDecl();
4596 if (
Base.isVirtual())
4608 if (
Base.isVirtual())
4609 OffsetFlags |= BCTI_Virtual;
4611 OffsetFlags |= BCTI_Public;
4613 Fields.push_back(llvm::ConstantInt::getSigned(OffsetFlagsLTy, OffsetFlags));
4622 if (
Type.isConstQualified())
4623 Flags |= ItaniumRTTIBuilder::PTI_Const;
4624 if (
Type.isVolatileQualified())
4625 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4626 if (
Type.isRestrictQualified())
4627 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4634 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4637 if (Proto->isNothrow()) {
4638 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4648void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
4654 llvm::Type *UnsignedIntLTy =
4656 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4661 llvm::Constant *PointeeTypeInfo =
4662 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4663 Fields.push_back(PointeeTypeInfo);
4669ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty) {
4679 Flags |= PTI_ContainingClassIncomplete;
4681 llvm::Type *UnsignedIntLTy =
4683 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4688 llvm::Constant *PointeeTypeInfo =
4689 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4690 Fields.push_back(PointeeTypeInfo);
4697 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
T));
4700llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
4701 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4704void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4706 QualType FundamentalTypes[] = {
4707 getContext().VoidTy, getContext().NullPtrTy,
4708 getContext().BoolTy, getContext().WCharTy,
4709 getContext().CharTy, getContext().UnsignedCharTy,
4710 getContext().SignedCharTy, getContext().ShortTy,
4711 getContext().UnsignedShortTy, getContext().IntTy,
4712 getContext().UnsignedIntTy, getContext().LongTy,
4713 getContext().UnsignedLongTy, getContext().LongLongTy,
4714 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4715 getContext().UnsignedInt128Ty, getContext().HalfTy,
4716 getContext().FloatTy, getContext().DoubleTy,
4717 getContext().LongDoubleTy, getContext().Float128Ty,
4718 getContext().Char8Ty, getContext().Char16Ty,
4719 getContext().Char32Ty
4721 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4723 ? llvm::GlobalValue::DLLExportStorageClass
4724 : llvm::GlobalValue::DefaultStorageClass;
4725 llvm::GlobalValue::VisibilityTypes
Visibility =
4727 for (
const QualType &FundamentalType : FundamentalTypes) {
4728 QualType PointerType = getContext().getPointerType(FundamentalType);
4729 QualType PointerTypeConst = getContext().getPointerType(
4730 FundamentalType.withConst());
4731 for (QualType
Type : {FundamentalType, PointerType, PointerTypeConst})
4732 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4733 Type, llvm::GlobalValue::ExternalLinkage,
4740ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4741 QualType CanTy, llvm::GlobalValue::LinkageTypes
Linkage)
const {
4742 if (shouldRTTIBeUnique())
4746 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4747 Linkage != llvm::GlobalValue::WeakODRLinkage)
4755 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4756 return RUK_NonUniqueHidden;
4761 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4762 return RUK_NonUniqueVisible;
4767enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4772 return StructorCodegen::Emit;
4777 return StructorCodegen::Emit;
4780 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4788 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4789 return StructorCodegen::RAUW;
4792 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4793 return StructorCodegen::RAUW;
4795 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4799 return StructorCodegen::COMDAT;
4800 return StructorCodegen::Emit;
4803 return StructorCodegen::Alias;
4813 if (Entry && !Entry->isDeclaration())
4819 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4822 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4826 assert(Entry->getType() == Aliasee->getType() &&
4827 "declaration exists with different type");
4828 Alias->takeName(Entry);
4829 Entry->replaceAllUsesWith(Alias);
4830 Entry->eraseFromParent();
4832 Alias->setName(MangledName);
4839void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
4841 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4848 GlobalDecl BaseDecl;
4854 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4859 if (CGType == StructorCodegen::RAUW) {
4872 CGType != StructorCodegen::COMDAT &&
4890 if (CGType == StructorCodegen::COMDAT) {
4891 SmallString<256> Buffer;
4892 llvm::raw_svector_ostream
Out(Buffer);
4894 getMangleContext().mangleCXXDtorComdat(DD, Out);
4896 getMangleContext().mangleCXXCtorComdat(CD, Out);
4897 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(
Out.str());
4906 llvm::FunctionType *FTy = llvm::FunctionType::get(
4914 llvm::FunctionType *FTy =
4915 llvm::FunctionType::get(CGM.
VoidTy,
false);
4922 llvm::FunctionType *FTy = llvm::FunctionType::get(
4941 struct CallEndCatch final : EHScopeStack::Cleanup {
4942 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4945 void Emit(CodeGenFunction &CGF, Flags flags)
override {
4964 bool EndMightThrow) {
4965 llvm::CallInst *call =
4968 CGF.
EHStack.pushCleanup<CallEndCatch>(
4970 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4995 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
5000 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
5009 unsigned HeaderSize =
5012 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
5035 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
5043 llvm::Value *ExnCast =
5044 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
5056 if (CatchType->hasPointerRepresentation()) {
5057 llvm::Value *CastExn =
5058 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
5075 llvm_unreachable(
"bad ownership qualifier!");
5093 llvm_unreachable(
"evaluation kind filtered out!");
5095 llvm_unreachable(
"bad evaluation kind");
5099 auto catchRD = CatchType->getAsCXXRecordDecl();
5109 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5110 LLVMCatchTy, caughtExnAlignment);
5119 llvm::CallInst *rawAdjustedExn =
5123 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5124 LLVMCatchTy, caughtExnAlignment);
5155void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5156 const CXXCatchStmt *S) {
5203 C.VoidTy, {C.getPointerType(C.CharTy)});
5206 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5207 llvm::Function *fn =
5212 fn->setDoesNotThrow();
5213 fn->setDoesNotReturn();
5218 fn->addFnAttr(llvm::Attribute::NoInline);
5222 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5223 fn->setVisibility(llvm::Function::HiddenVisibility);
5225 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5228 llvm::BasicBlock *entry =
5233 llvm::Value *exn = &*fn->arg_begin();
5236 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5237 catchCall->setDoesNotThrow();
5241 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5242 termCall->setDoesNotThrow();
5243 termCall->setDoesNotReturn();
5247 builder.CreateUnreachable();
5253ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5263std::pair<llvm::Value *, const CXXRecordDecl *>
5264ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
5265 const CXXRecordDecl *RD) {
5270ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5271 const CXXMethodDecl *origMD =
5275 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5281void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5282 const CXXCatchStmt *
C) {
5284 CGF.
EHStack.pushCleanup<CatchRetScope>(
5286 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5290WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5307void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
5308 llvm::FunctionCallee Dtor,
5309 llvm::Constant *
Addr) {
5314 llvm::FunctionType *AtExitTy =
5315 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5318 llvm::FunctionCallee
AtExit =
5326 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5334 llvm::Function *DtorStub =
5342 emitCXXStermFinalizer(D, DtorStub,
Addr);
5345void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
5346 llvm::Constant *addr) {
5347 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5348 SmallString<256> FnName;
5350 llvm::raw_svector_ostream
Out(FnName);
5351 getMangleContext().mangleDynamicStermFinalizer(&D, Out);
5359 CodeGenFunction CGF(CGM);
5373 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5378 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5383 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5386 CI->setCallingConv(dtorStub->getCallingConv());
5392 if (
auto *IPA = D.
getAttr<InitPriorityAttr>()) {
5394 IPA->getPriority());
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static CharUnits computeOffsetHint(ASTContext &astContext, const CXXRecordDecl *src, const CXXRecordDecl *dst)
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, QualType ty)
Return the linkage that the type info and type info name constants should have for the given type.
static mlir::Value 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::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, clang::ASTContext &astCtx)
static bool isThreadWrapperReplaceable(clang::ASTContext &astCtx)
llvm::MachO::Record Record
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D)
Determine what kind of template specialization the given declaration is.
static QualType getPointeeType(const MemRegion *R)
#define CXXABI(Name, Str)
C Language Family Type Representation.
a trap message and trap category.
const ValueDecl * getMemberPointerDecl() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
This class is used for builtin types like 'int'.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a C++ struct/union/class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
const Expr * getSubExpr() const
static CanQual< Type > CreateUnsafe(QualType Other)
Qualifiers getQualifiers() const
Retrieve all qualifiers.
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
std::string SymbolPartition
The name of the partition that symbols are assigned to, specified with -fsymbol-partition (see https:...
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
unsigned getAddressSpace() const
Return the address space that this address resides in.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
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...
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.
Represents an element in a path from a derived class to a base class.
const CXXRecordDecl * NearestVBase
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
llvm::PointerType * GlobalsVoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * CharTy
char
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * SizeTy
llvm::PointerType * 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.