33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/GlobalValue.h"
35#include "llvm/IR/Instructions.h"
36#include "llvm/IR/Intrinsics.h"
37#include "llvm/IR/Value.h"
38#include "llvm/Support/ConvertEBCDIC.h"
39#include "llvm/Support/ScopedPrinter.h"
49 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
52 llvm::SmallVector<std::pair<const VarDecl *, llvm::Function *>, 8>
56 bool UseARMMethodPtrABI;
57 bool UseARMGuardVarABI;
58 bool Use32BitVTableOffsetABI;
60 ItaniumMangleContext &getMangleContext() {
65 ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
66 bool UseARMMethodPtrABI =
false,
67 bool UseARMGuardVarABI =
false) :
68 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
69 UseARMGuardVarABI(UseARMGuardVarABI),
70 Use32BitVTableOffsetABI(
false) { }
81 bool isThisCompleteObject(GlobalDecl GD)
const override {
94 llvm_unreachable(
"emitting dtor comdat as function?");
96 llvm_unreachable(
"emitting unified dtor as function?");
98 llvm_unreachable(
"unexpected dtor kind for this ABI");
100 llvm_unreachable(
"bad dtor kind");
112 llvm_unreachable(
"closure ctors in Itanium ABI?");
115 llvm_unreachable(
"emitting ctor comdat as function?");
118 llvm_unreachable(
"emitting unified ctor as function?");
120 llvm_unreachable(
"bad dtor kind");
127 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
129 llvm::Type *ConvertMemberPointerType(
const MemberPointerType *MPT)
override;
132 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
135 llvm::Value *&ThisPtrForCall,
136 llvm::Value *MemFnPtr,
137 const MemberPointerType *MPT)
override;
139 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
const Expr *E,
140 Address Base, llvm::Value *MemPtr,
141 const MemberPointerType *MPT,
142 bool IsInBounds)
override;
144 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
146 llvm::Value *Src)
override;
147 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
148 llvm::Constant *Src)
override;
150 llvm::Constant *EmitNullMemberPointer(
const MemberPointerType *MPT)
override;
152 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
153 llvm::Constant *EmitMemberDataPointer(
const MemberPointerType *MPT,
154 CharUnits offset)
override;
155 llvm::Constant *EmitMemberPointer(
const APValue &MP, QualType MPT)
override;
156 llvm::Constant *BuildMemberPointer(
const CXXMethodDecl *MD,
157 CharUnits ThisAdjustment);
159 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
160 llvm::Value *L, llvm::Value *R,
161 const MemberPointerType *MPT,
162 bool Inequality)
override;
164 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
166 const MemberPointerType *MPT)
override;
168 void emitVirtualObjectDelete(CodeGenFunction &CGF,
const CXXDeleteExpr *DE,
169 Address Ptr, QualType ElementType,
170 const CXXDestructorDecl *Dtor)
override;
172 void emitRethrow(CodeGenFunction &CGF,
bool isNoReturn)
override;
173 void emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E)
override;
175 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
178 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
179 llvm::Value *Exn)
override;
181 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
182 llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty)
override;
184 getAddrOfCXXCatchHandlerType(QualType Ty,
185 QualType CatchHandlerType)
override {
186 return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0};
189 bool shouldTypeidBeNullChecked(QualType SrcRecordTy)
override;
190 void EmitBadTypeidCall(CodeGenFunction &CGF)
override;
191 llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
193 llvm::Type *StdTypeInfoPtrTy)
override;
195 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
196 QualType SrcRecordTy)
override;
202 bool hasUniqueVTablePointer(QualType RecordTy) {
208 if (CGM.getCodeGenOpts().DisableExactDynamicCast ||
209 getContext().getLangOpts().AppleKext)
214 if (!CGM.shouldEmitRTTI())
219 if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))
228 llvm::GlobalValue::DefaultVisibility)
234 return !CGM.mayVTableBeDuplicated(CGM.getVTableLinkage(RD));
237 bool shouldEmitExactDynamicCast(QualType DestRecordTy)
override {
238 return hasUniqueVTablePointer(DestRecordTy);
241 std::optional<ExactDynamicCastInfo>
242 getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
243 QualType DestRecordTy)
override;
245 llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address
Value,
246 QualType SrcRecordTy, QualType DestTy,
247 QualType DestRecordTy,
248 llvm::BasicBlock *CastEnd)
override;
251 QualType SrcRecordTy, QualType DestTy,
252 QualType DestRecordTy,
253 const ExactDynamicCastInfo &CastInfo,
254 llvm::BasicBlock *CastSuccess,
255 llvm::BasicBlock *CastFail)
override;
258 QualType SrcRecordTy)
override;
260 bool EmitBadCastCall(CodeGenFunction &CGF)
override;
263 GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
264 const CXXRecordDecl *ClassDecl,
265 const CXXRecordDecl *BaseClassDecl)
override;
267 void EmitCXXConstructors(
const CXXConstructorDecl *D)
override;
269 AddedStructorArgCounts
270 buildStructorSignature(GlobalDecl GD,
271 SmallVectorImpl<CanQualType> &ArgTys)
override;
273 bool useThunkForDtorVariant(
const CXXDestructorDecl *Dtor,
281 void EmitCXXDestructors(
const CXXDestructorDecl *D)
override;
283 void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
284 FunctionArgList &Params)
override;
286 void EmitInstanceFunctionProlog(CodeGenFunction &CGF)
override;
288 AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
289 const CXXConstructorDecl *D,
295 const CXXDestructorDecl *DD,
300 void EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
303 QualType ThisTy)
override;
305 void emitVTableDefinitions(CodeGenVTables &CGVT,
306 const CXXRecordDecl *RD)
override;
308 bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
309 CodeGenFunction::VPtr Vptr)
override;
311 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
316 getVTableAddressPoint(BaseSubobject Base,
317 const CXXRecordDecl *VTableClass)
override;
319 llvm::Value *getVTableAddressPointInStructor(
320 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
321 BaseSubobject Base,
const CXXRecordDecl *NearestVBase)
override;
323 llvm::Value *getVTableAddressPointInStructorWithVTT(
324 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
325 BaseSubobject Base,
const CXXRecordDecl *NearestVBase);
327 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
328 CharUnits VPtrOffset)
override;
330 CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
331 Address This, llvm::Type *Ty,
332 SourceLocation Loc)
override;
335 EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
337 DeleteOrMemberCallExpr E,
338 llvm::CallBase **CallOrInvoke)
override;
340 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
342 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
343 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
345 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable, GlobalDecl GD,
346 bool ReturnAdjustment)
override {
349 if (ForVTable && !Thunk->hasLocalLinkage())
350 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
351 CGM.setGVProperties(Thunk, GD);
354 bool exportThunk()
override {
return true; }
356 llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
357 const CXXRecordDecl *UnadjustedThisClass,
358 const ThunkInfo &TI)
override;
361 const CXXRecordDecl *UnadjustedRetClass,
362 const ReturnAdjustment &RA)
override;
364 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
365 FunctionArgList &Args)
const override {
366 assert(!Args.empty() &&
"expected the arglist to not be empty!");
367 return Args.size() - 1;
370 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
371 StringRef GetDeletedVirtualCallName()
override
372 {
return "__cxa_deleted_virtual"; }
374 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
375 Address InitializeArrayCookie(CodeGenFunction &CGF,
377 llvm::Value *NumElements,
378 const CXXNewExpr *
expr,
379 QualType ElementType)
override;
380 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
382 CharUnits cookieSize)
override;
384 void EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
385 llvm::GlobalVariable *DeclPtr,
386 bool PerformInit)
override;
387 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
388 llvm::FunctionCallee dtor,
389 llvm::Constant *addr)
override;
391 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
393 void EmitThreadLocalInitFuncs(
395 ArrayRef<const VarDecl *> CXXThreadLocals,
396 ArrayRef<llvm::Function *> CXXThreadLocalInits,
397 ArrayRef<const VarDecl *> CXXThreadLocalInitVars)
override;
399 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
400 return !isEmittedWithConstantInitializer(VD) ||
401 mayNeedDestruction(VD);
403 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
const VarDecl *VD,
404 QualType LValType)
override;
406 bool NeedsVTTParameter(GlobalDecl GD)
override;
409 getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
416 virtual bool shouldRTTIBeUnique()
const {
return true; }
420 enum RTTIUniquenessKind {
438 classifyRTTIUniqueness(QualType CanTy,
439 llvm::GlobalValue::LinkageTypes
Linkage)
const;
440 friend class ItaniumRTTIBuilder;
442 void emitCXXStructor(GlobalDecl GD)
override;
444 std::pair<llvm::Value *, const CXXRecordDecl *>
445 LoadVTablePtr(CodeGenFunction &CGF, Address This,
446 const CXXRecordDecl *RD)
override;
450 getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
452 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
453 const auto &VtableLayout =
454 CGM.getItaniumVTableContext().getVTableLayout(RD);
456 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
458 if (!VtableComponent.isUsedFunctionPointerKind())
461 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
462 const FunctionDecl *FD =
Method->getDefinition();
463 const bool IsInlined =
468 StringRef Name = CGM.getMangledName(
469 VtableComponent.getGlobalDecl(
false));
470 auto *Entry = CGM.GetGlobalValue(Name);
476 if (!Entry || Entry->isDeclaration())
482 bool isVTableHidden(
const CXXRecordDecl *RD)
const {
483 const auto &VtableLayout =
484 CGM.getItaniumVTableContext().getVTableLayout(RD);
486 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
487 if (VtableComponent.isRTTIKind()) {
488 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
489 if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
491 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
492 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
493 if (
Method->getVisibility() == Visibility::HiddenVisibility &&
502class ARMCXXABI :
public ItaniumCXXABI {
504 ARMCXXABI(CodeGen::CodeGenModule &CGM) :
505 ItaniumCXXABI(CGM,
true,
508 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
510 void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,
511 QualType ResTy)
override;
513 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
514 Address InitializeArrayCookie(CodeGenFunction &CGF,
516 llvm::Value *NumElements,
517 const CXXNewExpr *
expr,
518 QualType ElementType)
override;
519 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr,
520 CharUnits cookieSize)
override;
523class AppleARM64CXXABI :
public ARMCXXABI {
525 AppleARM64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {
526 Use32BitVTableOffsetABI =
true;
530 bool shouldRTTIBeUnique()
const override {
return false; }
533class FuchsiaCXXABI final :
public ItaniumCXXABI {
535 explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM)
536 : ItaniumCXXABI(CGM) {}
539 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
542class WebAssemblyCXXABI final :
public ItaniumCXXABI {
544 explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM)
545 : ItaniumCXXABI(CGM,
true,
547 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
549 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
550 llvm::Value *Exn)
override;
553 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
554 bool canCallMismatchedFunctionType()
const override {
return false; }
557class XLCXXABI final :
public ItaniumCXXABI {
559 explicit XLCXXABI(CodeGen::CodeGenModule &CGM)
560 : ItaniumCXXABI(CGM) {}
562 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
563 llvm::FunctionCallee dtor,
564 llvm::Constant *addr)
override;
566 bool useSinitAndSterm()
const override {
return true; }
569 void emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
570 llvm::Constant *addr);
578 case TargetCXXABI::GenericARM:
579 case TargetCXXABI::iOS:
580 case TargetCXXABI::WatchOS:
581 return new ARMCXXABI(CGM);
583 case TargetCXXABI::AppleARM64:
584 return new AppleARM64CXXABI(CGM);
586 case TargetCXXABI::Fuchsia:
587 return new FuchsiaCXXABI(CGM);
592 case TargetCXXABI::GenericAArch64:
593 return new ItaniumCXXABI(CGM,
true,
596 case TargetCXXABI::GenericMIPS:
597 return new ItaniumCXXABI(CGM,
true);
599 case TargetCXXABI::WebAssembly:
600 return new WebAssemblyCXXABI(CGM);
602 case TargetCXXABI::XL:
603 return new XLCXXABI(CGM);
605 case TargetCXXABI::GenericItanium:
606 return new ItaniumCXXABI(CGM);
608 case TargetCXXABI::Microsoft:
609 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
611 llvm_unreachable(
"bad ABI kind");
617 return CGM.PtrDiffTy;
618 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
641CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
643 llvm::Value *&ThisPtrForCall,
651 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
658 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
661 llvm::Value *Adj = RawAdj;
662 if (UseARMMethodPtrABI)
663 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
668 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(),
This, Adj);
669 ThisPtrForCall =
This;
672 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
676 llvm::Value *IsVirtual;
677 if (UseARMMethodPtrABI)
678 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
680 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
681 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
682 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
700 llvm::Value *VTableOffset = FnAsInt;
701 if (!UseARMMethodPtrABI)
702 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
703 if (Use32BitVTableOffsetABI) {
704 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
705 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
710 llvm::Constant *CheckSourceLocation;
711 llvm::Constant *CheckTypeDesc;
712 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
713 CGM.HasHiddenLTOVisibility(RD);
715 if (ShouldEmitCFICheck) {
716 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
717 if (BinOp->isPtrMemOp() &&
720 ->hasPointeeToCFIUncheckedCalleeFunctionType())
721 ShouldEmitCFICheck =
false;
725 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
726 CGM.HasHiddenLTOVisibility(RD);
730 bool ShouldEmitWPDInfo =
731 (CGM.getCodeGenOpts().WholeProgramVTables &&
733 !CGM.AlwaysHasLTOVisibilityPublic(RD)) ||
734 CGM.getCodeGenOpts().DevirtualizeSpeculatively;
735 llvm::Value *VirtualFn =
nullptr;
738 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
739 auto CheckHandler = SanitizerHandler::CFICheckFail;
740 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
742 llvm::Value *TypeId =
nullptr;
743 llvm::Value *CheckResult =
nullptr;
745 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
749 CGM.CreateMetadataIdentifierForVirtualMemPtrType(QualType(MPT, 0));
753 if (ShouldEmitVFEInfo) {
754 llvm::Value *VFPAddr =
755 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
762 llvm::Value *CheckedLoad = Builder.CreateCall(
763 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
764 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
765 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
766 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
770 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
771 llvm::Value *VFPAddr =
772 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
773 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
774 ? llvm::Intrinsic::type_test
775 : llvm::Intrinsic::public_type_test;
778 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
781 if (CGM.getLangOpts().RelativeCXXABIVTables) {
782 VirtualFn = CGF.
Builder.CreateCall(
783 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
784 {VTableOffset->getType()}),
785 {VTable, VTableOffset});
787 llvm::Value *VFPAddr =
794 assert(VirtualFn &&
"Virtual fuction pointer not created!");
795 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
797 "Check result required but not created!");
799 if (ShouldEmitCFICheck) {
803 llvm::Constant *StaticData[] = {
809 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
812 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
813 CGM.getLLVMContext(),
814 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
815 llvm::Value *ValidVtable = Builder.CreateCall(
816 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
817 CGF.
EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,
818 StaticData, {VTable, ValidVtable});
821 FnVirtual = Builder.GetInsertBlock();
830 llvm::Value *NonVirtualFn =
831 Builder.CreateIntToPtr(FnAsInt, CGF.
DefaultPtrTy,
"memptr.nonvirtualfn");
834 if (ShouldEmitCFICheck) {
837 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
838 auto CheckHandler = SanitizerHandler::CFICheckFail;
839 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
841 llvm::Constant *StaticData[] = {
847 llvm::Value *Bit = Builder.getFalse();
848 for (
const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {
849 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
852 Base->getCanonicalDecl()));
853 llvm::Value *TypeId =
856 llvm::Value *TypeTest =
857 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
858 {NonVirtualFn, TypeId});
859 Bit = Builder.CreateOr(Bit, TypeTest);
862 CGF.
EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,
863 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
865 FnNonVirtual = Builder.GetInsertBlock();
871 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
DefaultPtrTy, 2);
872 CalleePtr->addIncoming(VirtualFn, FnVirtual);
873 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
875 CGPointerAuthInfo PointerAuth;
877 if (
const auto &Schema =
878 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
879 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
880 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
882 const auto &AuthInfo =
883 CGM.getMemberFunctionPointerAuthInfo(QualType(MPT, 0));
884 assert(Schema.getKey() == AuthInfo.getKey() &&
885 "Keys for virtual and non-virtual member functions must match");
886 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
887 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
888 PointerAuth = CGPointerAuthInfo(
889 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
890 Schema.authenticatesNullValues(), DiscriminatorPHI);
893 CGCallee
Callee(FPT, CalleePtr, PointerAuth);
899llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
900 CodeGenFunction &CGF,
const Expr *E, Address Base, llvm::Value *MemPtr,
901 const MemberPointerType *MPT,
bool IsInBounds) {
902 assert(MemPtr->getType() == CGM.PtrDiffTy);
904 CGBuilderTy &Builder = CGF.
Builder;
907 llvm::Value *BaseAddr =
Base.emitRawPointer(CGF);
908 return Builder.CreateGEP(CGF.
Int8Ty, BaseAddr, MemPtr,
"memptr.offset",
909 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
910 : llvm::GEPNoWrapFlags::none());
917 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
922 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
923 CPA->getAddrDiscriminator()->isNullValue() &&
925 "unexpected key or discriminators");
928 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
956ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
963 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
964 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
967 CGBuilderTy &Builder = CGF.
Builder;
968 QualType DstType = E->
getType();
971 if (
const auto &NewAuthInfo =
972 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
975 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
976 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
977 llvm::Type *OrigTy = MemFnPtr->getType();
979 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
984 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
985 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
986 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
987 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
988 llvm::Value *IsVirtualOffset =
989 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
990 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
993 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
994 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
998 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
999 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
1000 ResignBB = Builder.GetInsertBlock();
1003 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
1004 NewSrc->addIncoming(src, StartBB);
1005 NewSrc->addIncoming(ResignedVal, ResignBB);
1011 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1013 llvm::Constant *adj = getMemberPointerAdjustment(E);
1014 if (!adj)
return src;
1016 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1018 const MemberPointerType *destTy =
1025 if (isDerivedToBase)
1026 dst = Builder.CreateNSWSub(src, adj,
"adj");
1028 dst = Builder.CreateNSWAdd(src, adj,
"adj");
1031 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
1032 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
1033 return Builder.CreateSelect(isNull, src, dst);
1037 if (UseARMMethodPtrABI) {
1040 adj = llvm::ConstantInt::get(adj->getType(), offset);
1043 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1044 llvm::Value *dstAdj;
1045 if (isDerivedToBase)
1046 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1048 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1050 return Builder.CreateInsertValue(src, dstAdj, 1);
1053static llvm::Constant *
1058 "member function pointers expected");
1059 if (DestType == SrcType)
1065 if (!NewAuthInfo && !CurAuthInfo)
1068 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1069 if (MemFnPtr->getNumOperands() == 0) {
1077 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1078 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1082ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
1083 llvm::Constant *src) {
1084 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
1085 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
1088 QualType DstType = E->
getType();
1095 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1098 llvm::Constant *adj = getMemberPointerAdjustment(E);
1099 if (!adj)
return src;
1101 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1103 const MemberPointerType *destTy =
1110 if (src->isAllOnesValue())
return src;
1112 if (isDerivedToBase)
1113 return llvm::ConstantExpr::getNSWSub(src, adj);
1115 return llvm::ConstantExpr::getNSWAdd(src, adj);
1119 if (UseARMMethodPtrABI) {
1122 adj = llvm::ConstantInt::get(adj->getType(), offset);
1125 llvm::Constant *srcAdj = src->getAggregateElement(1);
1126 llvm::Constant *dstAdj;
1127 if (isDerivedToBase)
1128 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1130 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1132 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1133 assert(res !=
nullptr &&
"Folding must succeed");
1138ItaniumCXXABI::EmitNullMemberPointer(
const MemberPointerType *MPT) {
1142 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1144 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1145 llvm::Constant *Values[2] = {
Zero,
Zero };
1146 return llvm::ConstantStruct::getAnon(Values);
1150ItaniumCXXABI::EmitMemberDataPointer(
const MemberPointerType *MPT,
1155 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1159ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1163llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1164 CharUnits ThisAdjustment) {
1165 assert(MD->
isInstance() &&
"Member function must not be static!");
1167 CodeGenTypes &Types = CGM.getTypes();
1170 llvm::Constant *MemPtr[2];
1172 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1174 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1176 VTableOffset = Index * 4;
1178 const ASTContext &Context = getContext();
1181 VTableOffset = Index * PointerWidth.
getQuantity();
1184 if (UseARMMethodPtrABI) {
1206 const auto &Schema =
1207 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1209 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1210 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1212 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1215 MemPtr[1] = llvm::ConstantInt::get(
1216 CGM.PtrDiffTy, 2 * ThisAdjustment.
getQuantity() + !Schema);
1222 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1223 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1227 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
1238 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1240 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1241 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1242 (UseARMMethodPtrABI ? 2 : 1) *
1246 return llvm::ConstantStruct::getAnon(MemPtr);
1249llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1251 const MemberPointerType *MPT = MPType->
castAs<MemberPointerType>();
1254 return EmitNullMemberPointer(MPT);
1256 CharUnits ThisAdjustment = getContext().getMemberPointerPathAdjustment(MP);
1258 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1259 llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment);
1260 QualType SrcType = getContext().getMemberPointerType(
1265 getContext().recordMemberDataPointerEvaluation(MPD);
1266 CharUnits FieldOffset =
1267 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1268 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
1276ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
1279 const MemberPointerType *MPT,
1281 CGBuilderTy &Builder = CGF.
Builder;
1283 llvm::ICmpInst::Predicate Eq;
1284 llvm::Instruction::BinaryOps
And,
Or;
1286 Eq = llvm::ICmpInst::ICMP_NE;
1287 And = llvm::Instruction::Or;
1288 Or = llvm::Instruction::And;
1290 Eq = llvm::ICmpInst::ICMP_EQ;
1291 And = llvm::Instruction::And;
1292 Or = llvm::Instruction::Or;
1298 return Builder.CreateICmp(Eq, L, R);
1310 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1311 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1315 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1320 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1321 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr,
Zero,
"cmp.ptr.null");
1325 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1326 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1327 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1331 if (UseARMMethodPtrABI) {
1332 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1335 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1336 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1337 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1,
Zero,
1339 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1343 llvm::Value *
Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1345 Inequality ?
"memptr.ne" :
"memptr.eq");
1350ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
1351 llvm::Value *MemPtr,
1352 const MemberPointerType *MPT) {
1353 CGBuilderTy &Builder = CGF.
Builder;
1357 assert(MemPtr->getType() == CGM.PtrDiffTy);
1358 llvm::Value *NegativeOne =
1359 llvm::Constant::getAllOnesValue(MemPtr->getType());
1360 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1364 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1366 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1367 llvm::Value *
Result = Builder.CreateICmpNE(Ptr,
Zero,
"memptr.tobool");
1371 if (UseARMMethodPtrABI) {
1372 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1373 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1374 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1375 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit,
Zero,
1376 "memptr.isvirtual");
1383bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI)
const {
1384 const CXXRecordDecl *RD = FI.
getReturnType()->getAsCXXRecordDecl();
1391 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1392 LangAS SRetAS = CGM.getTargetCodeGenInfo().getSRetAddrSpace(RD);
1393 unsigned AS = CGM.getContext().getTargetAddressSpace(SRetAS);
1403bool ItaniumCXXABI::isZeroInitializable(
const MemberPointerType *MPT) {
1409void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
1410 const CXXDeleteExpr *DE,
1412 QualType ElementType,
1413 const CXXDestructorDecl *Dtor) {
1415 if (UseGlobalDelete) {
1424 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1425 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1443 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
1446 if (UseGlobalDelete)
1450void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF,
bool isNoReturn) {
1453 llvm::FunctionType *FTy =
1454 llvm::FunctionType::get(CGM.VoidTy,
false);
1456 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1467 llvm::FunctionType *FTy =
1478 llvm::FunctionType *FTy =
1479 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1484void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E) {
1487 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1488 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1492 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1499 llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1504 llvm::Constant *
Dtor =
nullptr;
1510 const ASTContext &Ctx = getContext();
1512 FunctionProtoType::ExtProtoInfo());
1514 CXXDestructorDecl *DtorD =
Record->getDestructor();
1516 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1518 if (!Dtor)
Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1520 llvm::Value *args[] = { ExceptionPtr, TypeInfo,
Dtor };
1532 llvm::Type *PtrDiffTy =
1535 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1537 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1541 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1542 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1543 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1544 llvm::AttributeList Attrs = llvm::AttributeList::get(
1545 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1552 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1569 unsigned NumPublicPaths = 0;
1582 if (PathElement.Base->isVirtual())
1585 if (NumPublicPaths > 1)
1589 const ASTRecordLayout &L = Context.getASTRecordLayout(PathElement.Class);
1591 PathElement.Base->getType()->getAsCXXRecordDecl());
1596 if (NumPublicPaths == 0)
1600 if (NumPublicPaths > 1)
1610 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1615bool ItaniumCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
1619void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1622 Call->setDoesNotReturn();
1623 CGF.
Builder.CreateUnreachable();
1626llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
1627 QualType SrcRecordTy,
1629 llvm::Type *StdTypeInfoPtrTy) {
1634 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1637 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1638 {Value, llvm::ConstantInt::getSigned(CGM.Int32Ty, -4)});
1642 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1648bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1649 QualType SrcRecordTy) {
1653llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1654 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1655 QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1656 llvm::Type *PtrDiffLTy =
1659 llvm::Value *SrcRTTI =
1661 llvm::Value *DestRTTI =
1667 llvm::Value *OffsetHint = llvm::ConstantInt::getSigned(
1673 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1679 llvm::Value *Vtable =
1681 CodeGenFunction::VTableAuthMode::MustTrap);
1686 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1692 llvm::BasicBlock *BadCastBlock =
1699 EmitBadCastCall(CGF);
1705std::optional<CGCXXABI::ExactDynamicCastInfo>
1706ItaniumCXXABI::getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
1707 QualType DestRecordTy) {
1708 assert(shouldEmitExactDynamicCast(DestRecordTy));
1710 ASTContext &Context = getContext();
1715 CXXBasePaths Paths(
true,
true,
1721 std::optional<CharUnits> Offset;
1722 for (
const CXXBasePath &Path : Paths) {
1727 CharUnits PathOffset;
1728 for (
const CXXBasePathElement &PathElement : Path) {
1730 const CXXRecordDecl *
Base =
1731 PathElement.Base->getType()->getAsCXXRecordDecl();
1732 if (PathElement.Base->isVirtual()) {
1738 const ASTRecordLayout &L =
1745 Offset = PathOffset;
1746 else if (Offset != PathOffset) {
1748 return ExactDynamicCastInfo{
true,
1753 return std::nullopt;
1754 return ExactDynamicCastInfo{
false, *Offset};
1757llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1758 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1759 QualType DestTy, QualType DestRecordTy,
1760 const ExactDynamicCastInfo &ExactCastInfo, llvm::BasicBlock *CastSuccess,
1761 llvm::BasicBlock *CastFail) {
1764 auto AuthenticateVTable = [&](
Address ThisAddr,
const CXXRecordDecl *
Decl) {
1768 CodeGenFunction::VTableAuthMode::MustTrap);
1771 bool PerformPostCastAuthentication =
false;
1772 llvm::Value *VTable =
nullptr;
1773 if (ExactCastInfo.RequiresCastToPrimaryBase) {
1778 llvm::Value *PrimaryBase =
1785 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1786 CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip,
1787 false,
false,
nullptr);
1790 if (PerformPostCastAuthentication)
1797 llvm::Constant *ExpectedVTable = getVTableAddressPoint(
1798 BaseSubobject(SrcDecl, ExactCastInfo.Offset), DestDecl);
1799 llvm::Value *
Success = CGF.
Builder.CreateICmpEQ(VTable, ExpectedVTable);
1802 if (!ExactCastInfo.Offset.isZero()) {
1804 llvm::Constant *OffsetConstant =
1805 llvm::ConstantInt::get(CGF.
PtrDiffTy, -Offset);
1808 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1811 if (PerformPostCastAuthentication) {
1814 llvm::BasicBlock *NonNullBlock = CGF.
Builder.GetInsertBlock();
1815 llvm::BasicBlock *PostCastAuthSuccess =
1817 llvm::BasicBlock *PostCastAuthComplete =
1820 PostCastAuthComplete);
1824 AuthenticateVTable(AdjustedThisAddr, DestDecl);
1827 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(AdjustedThisPtr->getType(), 2);
1828 PHI->addIncoming(AdjustedThisPtr, PostCastAuthSuccess);
1829 llvm::Value *NullValue =
1830 llvm::Constant::getNullValue(AdjustedThisPtr->getType());
1831 PHI->addIncoming(NullValue, NonNullBlock);
1832 AdjustedThisPtr = PHI;
1835 return AdjustedThisPtr;
1838llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
1840 QualType SrcRecordTy) {
1842 llvm::Value *OffsetToTop;
1843 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1845 llvm::Value *VTable =
1850 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1854 llvm::Type *PtrDiffLTy =
1858 llvm::Value *VTable =
1863 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1872bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1875 Call->setDoesNotReturn();
1876 CGF.
Builder.CreateUnreachable();
1881ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
1883 const CXXRecordDecl *ClassDecl,
1884 const CXXRecordDecl *BaseClassDecl) {
1885 llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1886 CharUnits VBaseOffsetOffset =
1887 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1889 llvm::Value *VBaseOffsetPtr =
1890 CGF.
Builder.CreateConstGEP1_64(
1892 "vbase.offset.ptr");
1894 llvm::Value *VBaseOffset;
1895 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1901 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1906void ItaniumCXXABI::EmitCXXConstructors(
const CXXConstructorDecl *D) {
1908 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1912 CGM.EmitGlobal(GlobalDecl(D,
Ctor_Base));
1922CGCXXABI::AddedStructorArgCounts
1923ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
1924 SmallVectorImpl<CanQualType> &ArgTys) {
1925 ASTContext &Context = getContext();
1934 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1936 ArgTys.insert(ArgTys.begin() + 1,
1938 return AddedStructorArgCounts::prefix(1);
1940 return AddedStructorArgCounts{};
1943void ItaniumCXXABI::EmitCXXDestructors(
const CXXDestructorDecl *D) {
1946 CGM.EmitGlobal(GlobalDecl(D,
Dtor_Base));
1959void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1961 FunctionArgList &Params) {
1966 if (NeedsVTTParameter(CGF.
CurGD)) {
1967 ASTContext &Context = getContext();
1970 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1975 T, ImplicitParamKind::CXXVTT);
1976 Params.insert(Params.begin() + 1, VTTDecl);
1977 getStructorImplicitParamDecl(CGF) = VTTDecl;
1981void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1988 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1991 if (getStructorImplicitParamDecl(CGF)) {
2004 if (HasThisReturn(CGF.
CurGD))
2008CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
2011 if (!NeedsVTTParameter(GlobalDecl(D,
Type)))
2012 return AddedStructorArgs{};
2019 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
2020 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
2021 QualType VTTTy = getContext().getPointerType(Q);
2022 return AddedStructorArgs::prefix({{VTT, VTTTy}});
2025llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
2028 GlobalDecl GD(DD,
Type);
2032void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
2033 const CXXDestructorDecl *DD,
2037 GlobalDecl GD(DD,
Type);
2040 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
2043 if (getContext().getLangOpts().AppleKext &&
2050 ThisTy, VTT, VTTTy,
nullptr);
2054template <
typename T>
2057 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2070 llvm::GlobalVariable *VTable,
2072 if (VTable->getDLLStorageClass() !=
2073 llvm::GlobalVariable::DefaultStorageClass ||
2079 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2081 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2084void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
2085 const CXXRecordDecl *RD) {
2086 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());
2087 if (VTable->hasInitializer())
2090 ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
2092 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2093 llvm::Constant *RTTI =
2094 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getCanonicalTagType(RD));
2097 ConstantInitBuilder builder(CGM);
2098 auto components = builder.beginStruct();
2100 llvm::GlobalValue::isLocalLinkage(
Linkage));
2101 components.finishAndSetAsInitializer(VTable);
2109 if (CGM.mayVTableBeDuplicated(VTable->getLinkage()))
2110 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2112 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2113 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2115 if (CGM.getTarget().hasPS4DLLImportExport())
2119 CGM.setGVProperties(VTable, RD);
2130 EmitFundamentalRTTIDescriptors(RD);
2138 if (!VTable->isDeclarationForLinker() ||
2139 CGM.getCodeGenOpts().WholeProgramVTables ||
2140 CGM.getCodeGenOpts().DevirtualizeSpeculatively) {
2141 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2145 if (VTable->isDeclarationForLinker()) {
2146 assert(CGM.getCodeGenOpts().WholeProgramVTables ||
2147 CGM.getCodeGenOpts().DevirtualizeSpeculatively);
2148 CGM.addCompilerUsedGlobal(VTable);
2152 if (CGM.getLangOpts().RelativeCXXABIVTables) {
2154 if (!VTable->isDSOLocal())
2159 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
2160 DI->emitVTableSymbol(VTable, RD);
2163bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2164 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
2167 return NeedsVTTParameter(CGF.
CurGD);
2170llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2171 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2172 const CXXRecordDecl *NearestVBase) {
2174 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2175 NeedsVTTParameter(CGF.
CurGD)) {
2176 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
2179 return getVTableAddressPoint(Base, VTableClass);
2183ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
2184 const CXXRecordDecl *VTableClass) {
2185 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());
2189 const VTableLayout &Layout =
2190 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2191 VTableLayout::AddressPointLocation AddressPoint =
2193 llvm::Value *Indices[] = {
2194 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2195 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2201 unsigned ComponentSize =
2202 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2203 unsigned VTableSize =
2206 llvm::ConstantRange InRange(
2207 llvm::APInt(32, (
int)-Offset,
true),
2208 llvm::APInt(32, (
int)(VTableSize - Offset),
true));
2209 return llvm::ConstantExpr::getGetElementPtr(
2210 VTable->getValueType(), VTable, Indices,
true, InRange);
2213llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2214 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2215 const CXXRecordDecl *NearestVBase) {
2216 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2217 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2221 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
2225 if (VirtualPointerIndex)
2227 VirtualPointerIndex);
2244llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2245 CharUnits VPtrOffset) {
2246 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2248 llvm::GlobalVariable *&VTable = VTables[RD];
2253 CGM.addDeferredVTable(RD);
2255 SmallString<256> Name;
2256 llvm::raw_svector_ostream
Out(Name);
2257 getMangleContext().mangleCXXVTable(RD, Out);
2259 const VTableLayout &VTLayout =
2260 CGM.getItaniumVTableContext().getVTableLayout(RD);
2261 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2266 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2268 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2269 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2270 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2271 if (!CGM.shouldEmitRTTI())
2272 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2274 if (CGM.getTarget().hasPS4DLLImportExport())
2277 CGM.setGVProperties(VTable, RD);
2281CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
2285 SourceLocation Loc) {
2286 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2288 llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
2294 if (CGM.getLangOpts().OpenMPIsTargetDevice) {
2295 auto *NewPtrTy = CGM.VoidPtrTy;
2296 llvm::Type *RtlFnArgs[] = {NewPtrTy};
2297 llvm::FunctionCallee DeviceRtlFn = CGM.CreateRuntimeFunction(
2298 llvm::FunctionType::get(NewPtrTy, RtlFnArgs,
false),
2299 "__llvm_omp_indirect_call_lookup");
2300 auto *BackupTy = VTable->getType();
2308 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2309 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2310 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2312 llvm::Type *ComponentTy = CGM.getVTables().getVTableComponentType();
2314 VTableIndex * CGM.getDataLayout().getTypeSizeInBits(ComponentTy) / 8;
2322 llvm::Value *VFuncLoad;
2323 if (CGM.getLangOpts().RelativeCXXABIVTables) {
2324 VFuncLoad = CGF.
Builder.CreateCall(
2325 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2326 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, ByteOffset)});
2328 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2329 PtrTy, VTable, VTableIndex,
"vfn");
2340 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2341 CGM.getCodeGenOpts().StrictVTablePointers) {
2342 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2343 VFuncLoadInstr->setMetadata(
2344 llvm::LLVMContext::MD_invariant_load,
2345 llvm::MDNode::get(CGM.getLLVMContext(),
2346 llvm::ArrayRef<llvm::Metadata *>()));
2352 CGPointerAuthInfo PointerAuth;
2354 assert(VTableSlotPtr &&
"virtual function pointer not set");
2355 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2358 CGCallee
Callee(GD, VFunc, PointerAuth);
2362llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2363 CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
CXXDtorType DtorType,
2364 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
2365 auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
2366 auto *D = dyn_cast<const CXXDeleteExpr *>(E);
2367 assert((CE !=
nullptr) ^ (D !=
nullptr));
2368 assert(CE ==
nullptr || CE->arguments().empty());
2371 GlobalDecl GD(Dtor, DtorType);
2372 const CGFunctionInfo *FInfo =
2373 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2379 ThisTy = CE->getObjectType();
2381 ThisTy = D->getDestroyedType();
2385 nullptr, QualType(),
nullptr, CallOrInvoke);
2389void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2390 CodeGenVTables &VTables = CGM.getVTables();
2395bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2396 const CXXRecordDecl *RD)
const {
2399 if (CGM.getLangOpts().AppleKext)
2404 if (isVTableHidden(RD))
2407 if (CGM.getCodeGenOpts().ForceEmitVTables)
2424 if (hasAnyUnusedVirtualInlineFunction(RD))
2432 for (
const auto &B : RD->
bases()) {
2433 auto *BRD = B.getType()->getAsCXXRecordDecl();
2434 assert(BRD &&
"no class for base specifier");
2435 if (B.isVirtual() || !BRD->isDynamicClass())
2437 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2445bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2446 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2454 for (
const auto &B : RD->
vbases()) {
2455 auto *BRD = B.getType()->getAsCXXRecordDecl();
2456 assert(BRD &&
"no class for base specifier");
2457 if (!BRD->isDynamicClass())
2459 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2468 int64_t NonVirtualAdjustment,
2469 int64_t VirtualAdjustment,
2470 bool IsReturnAdjustment) {
2471 if (!NonVirtualAdjustment && !VirtualAdjustment)
2477 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2483 llvm::Value *ResultPtr;
2484 if (VirtualAdjustment) {
2485 llvm::Value *VTablePtr =
2488 llvm::Value *Offset;
2489 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2490 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2497 llvm::Type *PtrDiffTy =
2506 V.emitRawPointer(CGF), Offset);
2508 ResultPtr =
V.emitRawPointer(CGF);
2513 if (NonVirtualAdjustment && IsReturnAdjustment) {
2514 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2515 NonVirtualAdjustment);
2522ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This,
2523 const CXXRecordDecl *UnadjustedClass,
2524 const ThunkInfo &TI) {
2531ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
2532 const CXXRecordDecl *UnadjustedClass,
2533 const ReturnAdjustment &RA) {
2539void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
2540 RValue RV, QualType ResultType) {
2542 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2547 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2552CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2556 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2559Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2561 llvm::Value *NumElements,
2562 const CXXNewExpr *
expr,
2563 QualType ElementType) {
2564 assert(requiresArrayCookie(
expr));
2568 ASTContext &Ctx = getContext();
2572 CharUnits CookieSize =
2574 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2578 CharUnits CookieOffset = CookieSize - SizeSize;
2579 if (!CookieOffset.
isZero())
2587 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2588 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2589 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2591 SI->setNoSanitizeMetadata();
2592 llvm::FunctionType *FTy =
2593 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2594 llvm::FunctionCallee F =
2595 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2604llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2606 CharUnits cookieSize) {
2608 Address numElementsPtr = allocPtr;
2609 CharUnits numElementsOffset = cookieSize - CGF.
getSizeSize();
2610 if (!numElementsOffset.
isZero())
2616 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2623 llvm::FunctionType *FTy =
2625 llvm::FunctionCallee F =
2626 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2630CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2640 CGM.getContext().getTypeAlignInChars(elementType));
2643Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2645 llvm::Value *numElements,
2646 const CXXNewExpr *
expr,
2647 QualType elementType) {
2648 assert(requiresArrayCookie(
expr));
2655 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2656 getContext().getTypeSizeInChars(elementType).getQuantity());
2665 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2669llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2671 CharUnits cookieSize) {
2684 llvm::PointerType *GuardPtrTy) {
2686 llvm::FunctionType *FTy =
2690 FTy,
"__cxa_guard_acquire",
2692 llvm::AttributeList::FunctionIndex,
2693 llvm::Attribute::NoUnwind));
2697 llvm::PointerType *GuardPtrTy) {
2699 llvm::FunctionType *FTy =
2700 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2702 FTy,
"__cxa_guard_release",
2704 llvm::AttributeList::FunctionIndex,
2705 llvm::Attribute::NoUnwind));
2709 llvm::PointerType *GuardPtrTy) {
2711 llvm::FunctionType *FTy =
2712 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2714 FTy,
"__cxa_guard_abort",
2716 llvm::AttributeList::FunctionIndex,
2717 llvm::Attribute::NoUnwind));
2721 struct CallGuardAbort final : EHScopeStack::Cleanup {
2722 llvm::GlobalVariable *Guard;
2723 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2725 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2734void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
2736 llvm::GlobalVariable *var,
2737 bool shouldPerformInit) {
2738 CGBuilderTy &Builder = CGF.
Builder;
2742 bool NonTemplateInline =
2749 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2755 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2757 llvm::IntegerType *guardTy;
2758 CharUnits guardAlignment;
2759 if (useInt8GuardVariable) {
2765 if (UseARMGuardVarABI) {
2774 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2780 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2783 SmallString<256> guardName;
2785 llvm::raw_svector_ostream
out(guardName);
2786 getMangleContext().mangleStaticGuardVariable(&D,
out);
2792 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2793 false,
var->getLinkage(),
2794 llvm::ConstantInt::get(guardTy, 0),
2796 guard->setDSOLocal(
var->isDSOLocal());
2797 guard->setVisibility(
var->getVisibility());
2798 guard->setDLLStorageClass(
var->getDLLStorageClass());
2800 guard->setThreadLocalMode(
var->getThreadLocalMode());
2801 guard->setAlignment(guardAlignment.
getAsAlign());
2806 llvm::Comdat *
C =
var->getComdat();
2808 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2809 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2810 guard->setComdat(
C);
2811 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2812 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2815 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2818 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2843 if (!threadsafe || MaxInlineWidthInBits) {
2845 llvm::LoadInst *LI =
2855 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2878 (UseARMGuardVarABI && !useInt8GuardVariable)
2879 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2881 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2887 CodeGenFunction::GuardKind::VariableGuard, &D);
2915 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2916 InitBlock, EndBlock);
2926 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2944 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2953 llvm::FunctionCallee dtor,
2954 llvm::Constant *addr,
bool TLS) {
2956 "unexpected call to emitGlobalDtorWithCXAAtExit");
2958 "__cxa_atexit is disabled");
2959 const char *Name =
"__cxa_atexit";
2962 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2970 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2971 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2975 llvm::Constant *handle =
2978 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2981 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2982 llvm::FunctionType *atexitTy =
2983 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2987 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2988 fn->setDoesNotThrow();
2994 Context.getFunctionType(Context.VoidTy, {Context.VoidPtrTy}, EPI);
2995 llvm::Value *dtorCallee = dtor.getCallee();
2999 if (dtorCallee->getType()->getPointerAddressSpace() != AddrAS)
3007 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
3009 llvm::Value *args[] = {dtorCallee, addr, handle};
3017 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3021 return GlobalInitOrCleanupFn;
3024void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
3025 for (
const auto &I : DtorsUsingAtExit) {
3026 int Priority = I.first;
3027 std::string GlobalCleanupFnName =
3028 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
3030 llvm::Function *GlobalCleanupFn =
3033 CodeGenFunction CGF(*
this);
3034 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalCleanupFn,
3035 getTypes().arrangeNullaryFunction(), FunctionArgList(),
3036 SourceLocation(), SourceLocation());
3040 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
3044 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3045 auto itv = Dtors.rbegin();
3046 while (itv != Dtors.rend()) {
3047 llvm::Function *
Dtor = *itv;
3052 llvm::Value *NeedsDestruct =
3055 llvm::BasicBlock *DestructCallBlock =
3058 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
3061 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
3066 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
3068 CI->setCallingConv(
Dtor->getCallingConv());
3076 AddGlobalDtor(GlobalCleanupFn, Priority);
3080void CodeGenModule::registerGlobalDtorsWithAtExit() {
3081 for (
const auto &I : DtorsUsingAtExit) {
3082 int Priority = I.first;
3083 std::string GlobalInitFnName =
3084 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
3085 llvm::Function *GlobalInitFn =
3088 CodeGenFunction CGF(*
this);
3089 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalInitFn,
3090 getTypes().arrangeNullaryFunction(), FunctionArgList(),
3091 SourceLocation(), SourceLocation());
3099 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3100 for (
auto *Dtor : Dtors) {
3103 if (getCodeGenOpts().CXAAtExit) {
3113 AddGlobalCtor(GlobalInitFn, Priority);
3116 if (getCXXABI().useSinitAndSterm())
3117 unregisterGlobalDtorsWithUnAtExit();
3121void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
3122 llvm::FunctionCallee dtor,
3123 llvm::Constant *addr) {
3128 if (CGM.getLangOpts().HLSL)
3129 return CGM.AddCXXDtorEntry(dtor, addr);
3143 if (CGM.getCodeGenOpts().CXAAtExit || D.
getTLSKind())
3148 if (CGM.getLangOpts().AppleKext) {
3150 return CGM.AddCXXDtorEntry(dtor, addr);
3158 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3168static llvm::GlobalValue::LinkageTypes
3170 llvm::GlobalValue::LinkageTypes VarLinkage =
3174 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3179 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3180 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3182 return llvm::GlobalValue::WeakODRLinkage;
3186ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3189 SmallString<256> WrapperName;
3191 llvm::raw_svector_ostream
Out(WrapperName);
3192 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3197 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3200 QualType RetQT = VD->
getType();
3204 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3205 getContext().getPointerType(RetQT), FunctionArgList());
3207 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3208 llvm::Function *Wrapper =
3210 WrapperName.str(), &CGM.getModule());
3212 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3213 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3215 CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper,
false);
3218 if (!Wrapper->hasLocalLinkage())
3220 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3221 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3223 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
3226 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3227 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3230 ThreadWrappers.push_back({VD, Wrapper});
3234void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3235 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
3236 ArrayRef<llvm::Function *> CXXThreadLocalInits,
3237 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
3238 llvm::Function *InitFunc =
nullptr;
3242 llvm::SmallVector<llvm::Function *, 8> OrderedInits;
3243 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3244 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3247 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3248 CXXThreadLocalInits[I];
3250 OrderedInits.push_back(CXXThreadLocalInits[I]);
3253 if (!OrderedInits.empty()) {
3255 llvm::FunctionType *FTy =
3256 llvm::FunctionType::get(CGM.
VoidTy,
false);
3261 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3263 llvm::GlobalVariable::InternalLinkage,
3264 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3265 Guard->setThreadLocal(
true);
3269 Guard->setAlignment(GuardAlign.
getAsAlign());
3271 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(
3272 InitFunc, OrderedInits, ConstantAddress(Guard, CGM.
Int8Ty, GuardAlign));
3275 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3276 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3282 for (
const VarDecl *VD : CXXThreadLocals) {
3286 getOrCreateThreadLocalWrapper(VD, GV);
3291 for (
auto VDAndWrapper : ThreadWrappers) {
3292 const VarDecl *VD = VDAndWrapper.first;
3293 llvm::GlobalVariable *Var =
3295 llvm::Function *Wrapper = VDAndWrapper.second;
3302 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3308 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3309 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3315 SmallString<256> InitFnName;
3317 llvm::raw_svector_ostream
Out(InitFnName);
3318 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3321 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3326 llvm::GlobalValue *
Init =
nullptr;
3327 bool InitIsInitFunc =
false;
3328 bool HasConstantInitialization =
false;
3329 if (!usesThreadWrapperFunction(VD)) {
3330 HasConstantInitialization =
true;
3332 InitIsInitFunc =
true;
3333 llvm::Function *InitFuncToUse = InitFunc;
3337 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3344 Init = llvm::Function::Create(InitFnTy,
3345 llvm::GlobalVariable::ExternalWeakLinkage,
3353 Init->setVisibility(Var->getVisibility());
3355 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3356 Init->setDSOLocal(Var->isDSOLocal());
3359 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3367 isEmittedWithConstantInitializer(VD,
true) &&
3368 !mayNeedDestruction(VD)) {
3373 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3375 llvm::Function *
Func = llvm::Function::Create(
3376 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3382 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3383 CGBuilderTy Builder(CGM, Entry);
3384 Builder.CreateRetVoid();
3387 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3388 CGBuilderTy Builder(CGM, Entry);
3389 if (HasConstantInitialization) {
3391 }
else if (InitIsInitFunc) {
3393 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3395 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3396 llvm::Function *
Fn =
3398 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3409 Builder.CreateCall(InitFnTy,
Init);
3412 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3413 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3414 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3415 Builder.CreateCondBr(Have, InitBB, ExitBB);
3417 Builder.SetInsertPoint(InitBB);
3418 Builder.CreateCall(InitFnTy,
Init);
3419 Builder.CreateBr(ExitBB);
3421 Builder.SetInsertPoint(ExitBB);
3426 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3430 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3432 Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());
3434 Builder.CreateRet(Val);
3438LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
3440 QualType LValType) {
3442 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3444 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
3445 CallVal->setCallingConv(Wrapper->getCallingConv());
3459bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
3478ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3479 SmallString<256> MethodName;
3480 llvm::raw_svector_ostream
Out(MethodName);
3481 getMangleContext().mangleCXXName(MD, Out);
3482 MethodName +=
"_vfpthunk_";
3483 StringRef ThunkName = MethodName.str();
3484 llvm::Function *ThunkFn;
3485 if ((ThunkFn = cast_or_null<llvm::Function>(
3486 CGM.
getModule().getNamedValue(ThunkName))))
3491 llvm::GlobalValue::LinkageTypes
Linkage =
3493 : llvm::GlobalValue::InternalLinkage;
3496 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3497 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
3498 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3504 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3505 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3506 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3509 CodeGenFunction CGF(CGM);
3510 CGF.
CurGD = GlobalDecl(MD);
3514 FunctionArgList FunctionArgs;
3518 FunctionArgs, MD->
getLocation(), SourceLocation());
3523 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3524 setCXXABIThisValue(CGF, ThisVal);
3526 CallArgList CallArgs;
3527 for (
const VarDecl *VD : FunctionArgs)
3530 const FunctionProtoType *FPT = MD->
getType()->
getAs<FunctionProtoType>();
3532 const CGFunctionInfo &CallInfo =
3535 getThisAddress(CGF), ThunkTy);
3536 llvm::CallBase *CallOrInvoke;
3537 CGF.
EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke,
3538 true, SourceLocation(),
true);
3540 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3541 if (
Call->getType()->isVoidTy())
3554class ItaniumRTTIBuilder {
3556 llvm::LLVMContext &VMContext;
3557 const ItaniumCXXABI &
CXXABI;
3560 SmallVector<llvm::Constant *, 16> Fields;
3563 llvm::GlobalVariable *
3564 GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3568 llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
3571 void BuildVTablePointer(
const Type *Ty, llvm::Constant *StorageAddress);
3575 void BuildSIClassTypeInfo(
const CXXRecordDecl *RD);
3580 void BuildVMIClassTypeInfo(
const CXXRecordDecl *RD);
3584 void BuildPointerTypeInfo(QualType PointeeTy);
3588 void BuildObjCObjectTypeInfo(
const ObjCObjectType *Ty);
3592 void BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty);
3595 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3596 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3610 PTI_Incomplete = 0x8,
3614 PTI_ContainingClassIncomplete = 0x10,
3620 PTI_Noexcept = 0x40,
3626 VMI_NonDiamondRepeat = 0x1,
3629 VMI_DiamondShaped = 0x2
3643 llvm::Constant *BuildTypeInfo(QualType Ty);
3646 llvm::Constant *BuildTypeInfo(
3648 llvm::GlobalVariable::LinkageTypes
Linkage,
3649 llvm::GlobalValue::VisibilityTypes
Visibility,
3650 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3654llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3655 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage) {
3656 SmallString<256> Name;
3657 llvm::raw_svector_ostream
Out(Name);
3663 llvm::Constant *
Init;
3666 SmallString<256> DualEncodedName;
3667 llvm::ConverterEBCDIC::convertToEBCDIC(Name.substr(4), DualEncodedName);
3668 DualEncodedName +=
'\0';
3669 DualEncodedName += Name.substr(4);
3670 Init = llvm::ConstantDataArray::getString(VMContext, DualEncodedName);
3672 Init = llvm::ConstantDataArray::getString(VMContext, Name.substr(4));
3679 GV->setInitializer(
Init);
3685ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
3687 SmallString<256> Name;
3688 llvm::raw_svector_ostream
Out(Name);
3692 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3699 GV =
new llvm::GlobalVariable(
3701 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3708 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3735 case BuiltinType::Void:
3736 case BuiltinType::NullPtr:
3737 case BuiltinType::Bool:
3738 case BuiltinType::WChar_S:
3739 case BuiltinType::WChar_U:
3740 case BuiltinType::Char_U:
3741 case BuiltinType::Char_S:
3742 case BuiltinType::UChar:
3743 case BuiltinType::SChar:
3744 case BuiltinType::Short:
3745 case BuiltinType::UShort:
3746 case BuiltinType::Int:
3747 case BuiltinType::UInt:
3748 case BuiltinType::Long:
3749 case BuiltinType::ULong:
3750 case BuiltinType::LongLong:
3751 case BuiltinType::ULongLong:
3752 case BuiltinType::Half:
3753 case BuiltinType::Float:
3754 case BuiltinType::Double:
3755 case BuiltinType::LongDouble:
3756 case BuiltinType::Float16:
3757 case BuiltinType::Float128:
3758 case BuiltinType::Ibm128:
3759 case BuiltinType::Char8:
3760 case BuiltinType::Char16:
3761 case BuiltinType::Char32:
3762 case BuiltinType::Int128:
3763 case BuiltinType::UInt128:
3766#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3767 case BuiltinType::Id:
3768#include "clang/Basic/OpenCLImageTypes.def"
3769#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3770 case BuiltinType::Id:
3771#include "clang/Basic/OpenCLExtensionTypes.def"
3772 case BuiltinType::OCLSampler:
3773 case BuiltinType::OCLEvent:
3774 case BuiltinType::OCLClkEvent:
3775 case BuiltinType::OCLQueue:
3776 case BuiltinType::OCLReserveID:
3777#define SVE_TYPE(Name, Id, SingletonId) \
3778 case BuiltinType::Id:
3779#include "clang/Basic/AArch64ACLETypes.def"
3780#define PPC_VECTOR_TYPE(Name, Id, Size) \
3781 case BuiltinType::Id:
3782#include "clang/Basic/PPCTypes.def"
3783#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3784#include "clang/Basic/RISCVVTypes.def"
3785#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3786#include "clang/Basic/WebAssemblyReferenceTypes.def"
3787#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
3788#include "clang/Basic/AMDGPUTypes.def"
3789#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3790#include "clang/Basic/HLSLIntangibleTypes.def"
3791 case BuiltinType::ShortAccum:
3792 case BuiltinType::Accum:
3793 case BuiltinType::LongAccum:
3794 case BuiltinType::UShortAccum:
3795 case BuiltinType::UAccum:
3796 case BuiltinType::ULongAccum:
3797 case BuiltinType::ShortFract:
3798 case BuiltinType::Fract:
3799 case BuiltinType::LongFract:
3800 case BuiltinType::UShortFract:
3801 case BuiltinType::UFract:
3802 case BuiltinType::ULongFract:
3803 case BuiltinType::SatShortAccum:
3804 case BuiltinType::SatAccum:
3805 case BuiltinType::SatLongAccum:
3806 case BuiltinType::SatUShortAccum:
3807 case BuiltinType::SatUAccum:
3808 case BuiltinType::SatULongAccum:
3809 case BuiltinType::SatShortFract:
3810 case BuiltinType::SatFract:
3811 case BuiltinType::SatLongFract:
3812 case BuiltinType::SatUShortFract:
3813 case BuiltinType::SatUFract:
3814 case BuiltinType::SatULongFract:
3815 case BuiltinType::BFloat16:
3818 case BuiltinType::Dependent:
3819#define BUILTIN_TYPE(Id, SingletonId)
3820#define PLACEHOLDER_TYPE(Id, SingletonId) \
3821 case BuiltinType::Id:
3822#include "clang/AST/BuiltinTypes.def"
3823 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3825 case BuiltinType::ObjCId:
3826 case BuiltinType::ObjCClass:
3827 case BuiltinType::ObjCSel:
3828 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3831 llvm_unreachable(
"Invalid BuiltinType Kind!");
3836 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3854 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3859 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3875 if (!Context.getLangOpts().RTTI)
return false;
3877 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3890 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3900 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3913 return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
3928 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3933 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3937 dyn_cast<MemberPointerType>(Ty)) {
3939 if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
3960 if (
Base->isVirtual())
3968 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
3969 if (!BaseDecl->isEmpty() &&
3976void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty,
3977 llvm::Constant *StorageAddress) {
3979 static const char *
const ClassTypeInfo =
3980 "_ZTVN10__cxxabiv117__class_type_infoE";
3982 static const char *
const SIClassTypeInfo =
3983 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3985 static const char *
const VMIClassTypeInfo =
3986 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3988 const char *VTableName =
nullptr;
3991#define TYPE(Class, Base)
3992#define ABSTRACT_TYPE(Class, Base)
3993#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3994#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3995#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3996#include "clang/AST/TypeNodes.inc"
3997 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3999 case Type::LValueReference:
4000 case Type::RValueReference:
4001 llvm_unreachable(
"References shouldn't get here");
4004 case Type::DeducedTemplateSpecialization:
4005 llvm_unreachable(
"Undeduced type shouldn't get here");
4008 llvm_unreachable(
"Pipe types shouldn't get here");
4010 case Type::ArrayParameter:
4011 llvm_unreachable(
"Array Parameter types should not get here.");
4015 case Type::OverflowBehavior:
4018 case Type::ExtVector:
4019 case Type::ConstantMatrix:
4023 case Type::BlockPointer:
4025 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
4028 case Type::ConstantArray:
4029 case Type::IncompleteArray:
4030 case Type::VariableArray:
4032 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
4035 case Type::FunctionNoProto:
4036 case Type::FunctionProto:
4038 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
4043 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
4046 case Type::Record: {
4048 ->getDefinitionOrSelf();
4051 VTableName = ClassTypeInfo;
4053 VTableName = SIClassTypeInfo;
4055 VTableName = VMIClassTypeInfo;
4061 case Type::ObjCObject:
4067 VTableName = ClassTypeInfo;
4074 case Type::ObjCInterface:
4076 VTableName = SIClassTypeInfo;
4078 VTableName = ClassTypeInfo;
4082 case Type::ObjCObjectPointer:
4085 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
4088 case Type::MemberPointer:
4090 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
4093 case Type::HLSLAttributedResource:
4094 case Type::HLSLInlineSpirv:
4095 llvm_unreachable(
"HLSL doesn't support virtual functions");
4098 llvm::Constant *VTable =
nullptr;
4102 VTable = CGM.
getModule().getNamedAlias(VTableName);
4105 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
4110 llvm::Type *PtrDiffTy =
4117 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
4118 VTable = llvm::ConstantExpr::getInBoundsPtrAdd(VTable, Eight);
4120 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
4121 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
4125 if (
const auto &Schema =
4129 Schema.isAddressDiscriminated() ? StorageAddress :
nullptr,
4130 GlobalDecl(), QualType(Ty, 0));
4132 Fields.push_back(VTable);
4149 return llvm::GlobalValue::InternalLinkage;
4153 llvm_unreachable(
"Linkage hasn't been computed!");
4158 return llvm::GlobalValue::InternalLinkage;
4166 return llvm::GlobalValue::LinkOnceODRLinkage;
4168 if (
const RecordType *
Record = dyn_cast<RecordType>(Ty)) {
4172 return llvm::GlobalValue::WeakODRLinkage;
4173 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4174 if (RD->
hasAttr<DLLImportAttr>() &&
4176 return llvm::GlobalValue::ExternalLinkage;
4183 return llvm::GlobalValue::LinkOnceODRLinkage;
4186 llvm_unreachable(
"Invalid linkage!");
4189llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) {
4194 SmallString<256> Name;
4195 llvm::raw_svector_ostream
Out(Name);
4198 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4199 if (OldGV && !OldGV->isDeclaration()) {
4200 assert(!OldGV->hasAvailableExternallyLinkage() &&
4201 "available_externally typeinfos not yet implemented");
4209 return GetAddrOfExternalRTTIDescriptor(Ty);
4216 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4217 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4219 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
4221 ItaniumCXXABI::RUK_NonUniqueHidden)
4222 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
4226 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4227 llvm::GlobalValue::DefaultStorageClass;
4229 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4230 RD->
hasAttr<DLLExportAttr>()) ||
4232 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4233 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
4234 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4236 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass);
4239llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4241 llvm::GlobalVariable::LinkageTypes
Linkage,
4242 llvm::GlobalValue::VisibilityTypes
Visibility,
4243 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4244 SmallString<256> Name;
4245 llvm::raw_svector_ostream
Out(Name);
4248 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4250 llvm::GlobalVariable *GV =
4259 llvm::Constant *TypeNameField;
4263 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4265 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4268 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4269 llvm::Constant *flag =
4270 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
4271 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4277 Fields.push_back(TypeNameField);
4280#define TYPE(Class, Base)
4281#define ABSTRACT_TYPE(Class, Base)
4282#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4283#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4284#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4285#include "clang/AST/TypeNodes.inc"
4286 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4291 case Type::ExtVector:
4292 case Type::ConstantMatrix:
4294 case Type::BlockPointer:
4299 case Type::LValueReference:
4300 case Type::RValueReference:
4301 llvm_unreachable(
"References shouldn't get here");
4304 case Type::DeducedTemplateSpecialization:
4305 llvm_unreachable(
"Undeduced type shouldn't get here");
4313 case Type::ConstantArray:
4314 case Type::IncompleteArray:
4315 case Type::VariableArray:
4316 case Type::ArrayParameter:
4321 case Type::FunctionNoProto:
4322 case Type::FunctionProto:
4332 case Type::Record: {
4334 ->getDefinitionOrSelf();
4341 BuildSIClassTypeInfo(RD);
4343 BuildVMIClassTypeInfo(RD);
4348 case Type::ObjCObject:
4349 case Type::ObjCInterface:
4353 case Type::ObjCObjectPointer:
4361 case Type::MemberPointer:
4369 case Type::OverflowBehavior:
4372 case Type::HLSLAttributedResource:
4373 case Type::HLSLInlineSpirv:
4374 llvm_unreachable(
"HLSL doesn't support RTTI");
4377 GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));
4380 auto GVDLLStorageClass = DLLStorageClass;
4382 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
4383 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
4386 if (RD->
hasAttr<DLLExportAttr>() ||
4388 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
4394 GV->takeName(OldGV);
4395 OldGV->replaceAllUsesWith(GV);
4396 OldGV->eraseFromParent();
4400 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4427 TypeName->setDLLStorageClass(DLLStorageClass);
4428 GV->setDLLStorageClass(GVDLLStorageClass);
4438void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4440 const Type *
T = OT->getBaseType().getTypePtr();
4448 ObjCInterfaceDecl *Super =
Class->getSuperClass();
4456 llvm::Constant *BaseTypeInfo =
4457 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4458 Fields.push_back(BaseTypeInfo);
4463void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4467 llvm::Constant *BaseTypeInfo =
4469 Fields.push_back(BaseTypeInfo);
4476 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
4477 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
4489 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
4490 if (
Base->isVirtual()) {
4492 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4495 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4497 if (Bases.NonVirtualBases.count(BaseDecl))
4498 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4502 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4505 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4507 if (Bases.VirtualBases.count(BaseDecl))
4508 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4513 for (
const auto &I : BaseDecl->bases())
4524 for (
const auto &I : RD->
bases())
4533void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4534 llvm::Type *UnsignedIntLTy =
4542 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4547 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4580 llvm::Type *OffsetFlagsLTy =
4583 for (
const auto &Base : RD->
bases()) {
4585 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4587 auto *BaseDecl =
Base.getType()->castAsCXXRecordDecl();
4595 if (
Base.isVirtual())
4607 if (
Base.isVirtual())
4608 OffsetFlags |= BCTI_Virtual;
4610 OffsetFlags |= BCTI_Public;
4612 Fields.push_back(llvm::ConstantInt::getSigned(OffsetFlagsLTy, OffsetFlags));
4621 if (
Type.isConstQualified())
4622 Flags |= ItaniumRTTIBuilder::PTI_Const;
4623 if (
Type.isVolatileQualified())
4624 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4625 if (
Type.isRestrictQualified())
4626 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4633 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4636 if (Proto->isNothrow()) {
4637 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4647void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
4653 llvm::Type *UnsignedIntLTy =
4655 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4660 llvm::Constant *PointeeTypeInfo =
4661 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4662 Fields.push_back(PointeeTypeInfo);
4668ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty) {
4678 Flags |= PTI_ContainingClassIncomplete;
4680 llvm::Type *UnsignedIntLTy =
4682 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4687 llvm::Constant *PointeeTypeInfo =
4688 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4689 Fields.push_back(PointeeTypeInfo);
4696 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
T));
4699llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
4700 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4703void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4705 QualType FundamentalTypes[] = {
4706 getContext().VoidTy, getContext().NullPtrTy,
4707 getContext().BoolTy, getContext().WCharTy,
4708 getContext().CharTy, getContext().UnsignedCharTy,
4709 getContext().SignedCharTy, getContext().ShortTy,
4710 getContext().UnsignedShortTy, getContext().IntTy,
4711 getContext().UnsignedIntTy, getContext().LongTy,
4712 getContext().UnsignedLongTy, getContext().LongLongTy,
4713 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4714 getContext().UnsignedInt128Ty, getContext().HalfTy,
4715 getContext().FloatTy, getContext().DoubleTy,
4716 getContext().LongDoubleTy, getContext().Float128Ty,
4717 getContext().Char8Ty, getContext().Char16Ty,
4718 getContext().Char32Ty
4720 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4722 ? llvm::GlobalValue::DLLExportStorageClass
4723 : llvm::GlobalValue::DefaultStorageClass;
4724 llvm::GlobalValue::VisibilityTypes
Visibility =
4726 for (
const QualType &FundamentalType : FundamentalTypes) {
4727 QualType PointerType = getContext().getPointerType(FundamentalType);
4728 QualType PointerTypeConst = getContext().getPointerType(
4729 FundamentalType.withConst());
4730 for (QualType
Type : {FundamentalType, PointerType, PointerTypeConst})
4731 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4732 Type, llvm::GlobalValue::ExternalLinkage,
4739ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4740 QualType CanTy, llvm::GlobalValue::LinkageTypes
Linkage)
const {
4741 if (shouldRTTIBeUnique())
4745 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4746 Linkage != llvm::GlobalValue::WeakODRLinkage)
4754 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4755 return RUK_NonUniqueHidden;
4760 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4761 return RUK_NonUniqueVisible;
4766enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4771 return StructorCodegen::Emit;
4776 return StructorCodegen::Emit;
4779 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4787 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4788 return StructorCodegen::RAUW;
4791 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4792 return StructorCodegen::RAUW;
4794 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4798 return StructorCodegen::COMDAT;
4799 return StructorCodegen::Emit;
4802 return StructorCodegen::Alias;
4812 if (Entry && !Entry->isDeclaration())
4818 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4821 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4825 assert(Entry->getType() == Aliasee->getType() &&
4826 "declaration exists with different type");
4827 Alias->takeName(Entry);
4828 Entry->replaceAllUsesWith(Alias);
4829 Entry->eraseFromParent();
4831 Alias->setName(MangledName);
4838void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
4840 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4847 GlobalDecl BaseDecl;
4853 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4858 if (CGType == StructorCodegen::RAUW) {
4871 CGType != StructorCodegen::COMDAT &&
4889 if (CGType == StructorCodegen::COMDAT) {
4890 SmallString<256> Buffer;
4891 llvm::raw_svector_ostream
Out(Buffer);
4893 getMangleContext().mangleCXXDtorComdat(DD, Out);
4895 getMangleContext().mangleCXXCtorComdat(CD, Out);
4896 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(
Out.str());
4905 llvm::FunctionType *FTy = llvm::FunctionType::get(
4913 llvm::FunctionType *FTy =
4914 llvm::FunctionType::get(CGM.
VoidTy,
false);
4921 llvm::FunctionType *FTy = llvm::FunctionType::get(
4940 struct CallEndCatch final : EHScopeStack::Cleanup {
4941 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4944 void Emit(CodeGenFunction &CGF, Flags flags)
override {
4963 bool EndMightThrow) {
4964 llvm::CallInst *call =
4967 CGF.
EHStack.pushCleanup<CallEndCatch>(
4969 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4994 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4999 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
5008 unsigned HeaderSize =
5011 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
5034 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
5042 llvm::Value *ExnCast =
5043 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
5055 if (CatchType->hasPointerRepresentation()) {
5056 llvm::Value *CastExn =
5057 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
5074 llvm_unreachable(
"bad ownership qualifier!");
5092 llvm_unreachable(
"evaluation kind filtered out!");
5094 llvm_unreachable(
"bad evaluation kind");
5098 auto catchRD = CatchType->getAsCXXRecordDecl();
5108 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5109 LLVMCatchTy, caughtExnAlignment);
5118 llvm::CallInst *rawAdjustedExn =
5122 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5123 LLVMCatchTy, caughtExnAlignment);
5154void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5155 const CXXCatchStmt *S) {
5202 C.VoidTy, {C.getPointerType(C.CharTy)});
5205 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5206 llvm::Function *fn =
5211 fn->setDoesNotThrow();
5212 fn->setDoesNotReturn();
5217 fn->addFnAttr(llvm::Attribute::NoInline);
5221 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5222 fn->setVisibility(llvm::Function::HiddenVisibility);
5224 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5227 llvm::BasicBlock *entry =
5232 llvm::Value *exn = &*fn->arg_begin();
5235 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5236 catchCall->setDoesNotThrow();
5240 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5241 termCall->setDoesNotThrow();
5242 termCall->setDoesNotReturn();
5246 builder.CreateUnreachable();
5252ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5262std::pair<llvm::Value *, const CXXRecordDecl *>
5263ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
5264 const CXXRecordDecl *RD) {
5269ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5270 const CXXMethodDecl *origMD =
5274 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5280void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5281 const CXXCatchStmt *
C) {
5283 CGF.
EHStack.pushCleanup<CatchRetScope>(
5285 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5289WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5306void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
5307 llvm::FunctionCallee Dtor,
5308 llvm::Constant *
Addr) {
5313 llvm::FunctionType *AtExitTy =
5314 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5317 llvm::FunctionCallee
AtExit =
5325 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5333 llvm::Function *DtorStub =
5341 emitCXXStermFinalizer(D, DtorStub,
Addr);
5344void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
5345 llvm::Constant *addr) {
5346 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5347 SmallString<256> FnName;
5349 llvm::raw_svector_ostream
Out(FnName);
5350 getMangleContext().mangleDynamicStermFinalizer(&D, Out);
5358 CodeGenFunction CGF(CGM);
5372 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5377 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5382 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5385 CI->setCallingConv(dtorStub->getCallingConv());
5391 if (
auto *IPA = D.
getAttr<InitPriorityAttr>()) {
5393 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(cir::TLS_Model tls, 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.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void EmitAnyExprToExn(const Expr *E, Address Addr)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
const TargetInfo & getTarget() const
CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, const CXXRecordDecl *RD)
BuildVirtualCall - This routine makes indirect vtable call for call to virtual destructors.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, llvm::BasicBlock *InitBlock, llvm::BasicBlock *NoInitBlock, GuardKind Kind, const VarDecl *D)
Emit a branch to select whether or not to perform guarded initialization.
CGDebugInfo * getDebugInfo()
LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source=AlignmentSource::Type)
Same as MakeAddrLValue above except that the pointer is known to be unsigned.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Emit the concrete pointer authentication informaton for the given authentication schema.
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
llvm::Value * unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub)
Call unatexit() with function dtorStub.
llvm::Value * emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void registerGlobalDtorWithLLVM(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Registers the dtor using 'llvm.global_dtors' for platforms that do not support an 'atexit()' function...
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
llvm::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.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
@ Ctor_Comdat
The COMDAT used for ctors.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
@ Success
Annotation was successful.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ VisibleNone
No linkage according to the standard, but is visible from other translation units because of types de...
@ None
No linkage, which means that the entity is unique and can only be referred to from within its scope.
@ UniqueExternal
External linkage within a unique namespace.
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
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 * VoidPtrPtrTy
llvm::PointerType * GlobalsInt8PtrTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
CharUnits getSizeSize() const
CharUnits getSizeAlign() const
llvm::PointerType * Int8PtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
llvm::PointerType * DefaultPtrTy
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
Extra information about a function prototype.
PointerAuthSchema CXXVTTVTablePointers
The ABI for C++ virtual table pointers as installed in a VTT.
PointerAuthSchema CXXTypeInfoVTablePointer
TypeInfo has external ABI requirements and is emitted without actually having parsed the libcxx defin...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@103031170252120233124322035264172076254313213024 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@106065375072164260365214033034320247050276346205 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.