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