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(
"unexpected dtor kind for this ABI");
99 llvm_unreachable(
"bad dtor kind");
111 llvm_unreachable(
"closure ctors in Itanium ABI?");
114 llvm_unreachable(
"emitting ctor comdat as function?");
117 llvm_unreachable(
"emitting unified ctor as function?");
119 llvm_unreachable(
"bad dtor kind");
126 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
128 llvm::Type *ConvertMemberPointerType(
const MemberPointerType *MPT)
override;
131 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
134 llvm::Value *&ThisPtrForCall,
135 llvm::Value *MemFnPtr,
136 const MemberPointerType *MPT)
override;
138 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
const Expr *E,
139 Address Base, llvm::Value *MemPtr,
140 const MemberPointerType *MPT,
141 bool IsInBounds)
override;
143 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
145 llvm::Value *Src)
override;
146 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
147 llvm::Constant *Src)
override;
149 llvm::Constant *EmitNullMemberPointer(
const MemberPointerType *MPT)
override;
151 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
152 llvm::Constant *EmitMemberDataPointer(
const MemberPointerType *MPT,
153 CharUnits offset)
override;
154 llvm::Constant *EmitMemberPointer(
const APValue &MP, QualType MPT)
override;
155 llvm::Constant *BuildMemberPointer(
const CXXMethodDecl *MD,
156 CharUnits ThisAdjustment);
158 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
159 llvm::Value *L, llvm::Value *R,
160 const MemberPointerType *MPT,
161 bool Inequality)
override;
163 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
165 const MemberPointerType *MPT)
override;
167 void emitVirtualObjectDelete(CodeGenFunction &CGF,
const CXXDeleteExpr *DE,
168 Address Ptr, QualType ElementType,
169 const CXXDestructorDecl *Dtor)
override;
171 void emitRethrow(CodeGenFunction &CGF,
bool isNoReturn)
override;
172 void emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E)
override;
174 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
177 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
178 llvm::Value *Exn)
override;
180 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
181 llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty)
override;
183 getAddrOfCXXCatchHandlerType(QualType Ty,
184 QualType CatchHandlerType)
override {
185 return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0};
188 bool shouldTypeidBeNullChecked(QualType SrcRecordTy)
override;
189 void EmitBadTypeidCall(CodeGenFunction &CGF)
override;
190 llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
192 llvm::Type *StdTypeInfoPtrTy)
override;
194 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
195 QualType SrcRecordTy)
override;
201 bool hasUniqueVTablePointer(QualType RecordTy) {
206 if (!CGM.getCodeGenOpts().AssumeUniqueVTables ||
207 getContext().getLangOpts().AppleKext)
212 if (!CGM.shouldEmitRTTI())
217 if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))
226 llvm::GlobalValue::DefaultVisibility)
232 bool shouldEmitExactDynamicCast(QualType DestRecordTy)
override {
233 return hasUniqueVTablePointer(DestRecordTy);
236 std::optional<ExactDynamicCastInfo>
237 getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
238 QualType DestRecordTy)
override;
240 llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address
Value,
241 QualType SrcRecordTy, QualType DestTy,
242 QualType DestRecordTy,
243 llvm::BasicBlock *CastEnd)
override;
246 QualType SrcRecordTy, QualType DestTy,
247 QualType DestRecordTy,
248 const ExactDynamicCastInfo &CastInfo,
249 llvm::BasicBlock *CastSuccess,
250 llvm::BasicBlock *CastFail)
override;
253 QualType SrcRecordTy)
override;
255 bool EmitBadCastCall(CodeGenFunction &CGF)
override;
258 GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
259 const CXXRecordDecl *ClassDecl,
260 const CXXRecordDecl *BaseClassDecl)
override;
262 void EmitCXXConstructors(
const CXXConstructorDecl *D)
override;
264 AddedStructorArgCounts
265 buildStructorSignature(GlobalDecl GD,
266 SmallVectorImpl<CanQualType> &ArgTys)
override;
268 bool useThunkForDtorVariant(
const CXXDestructorDecl *Dtor,
276 void EmitCXXDestructors(
const CXXDestructorDecl *D)
override;
278 void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
279 FunctionArgList &Params)
override;
281 void EmitInstanceFunctionProlog(CodeGenFunction &CGF)
override;
283 AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
284 const CXXConstructorDecl *D,
290 const CXXDestructorDecl *DD,
295 void EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
298 QualType ThisTy)
override;
300 void emitVTableDefinitions(CodeGenVTables &CGVT,
301 const CXXRecordDecl *RD)
override;
303 bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
304 CodeGenFunction::VPtr Vptr)
override;
306 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
311 getVTableAddressPoint(BaseSubobject Base,
312 const CXXRecordDecl *VTableClass)
override;
314 llvm::Value *getVTableAddressPointInStructor(
315 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
316 BaseSubobject Base,
const CXXRecordDecl *NearestVBase)
override;
318 llvm::Value *getVTableAddressPointInStructorWithVTT(
319 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
320 BaseSubobject Base,
const CXXRecordDecl *NearestVBase);
322 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
323 CharUnits VPtrOffset)
override;
325 CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
326 Address This, llvm::Type *Ty,
327 SourceLocation Loc)
override;
330 EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
332 DeleteOrMemberCallExpr E,
333 llvm::CallBase **CallOrInvoke)
override;
335 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
337 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
338 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
340 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable, GlobalDecl GD,
341 bool ReturnAdjustment)
override {
344 if (ForVTable && !Thunk->hasLocalLinkage())
345 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
346 CGM.setGVProperties(Thunk, GD);
349 bool exportThunk()
override {
return true; }
351 llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
352 const CXXRecordDecl *UnadjustedThisClass,
353 const ThunkInfo &TI)
override;
355 llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
356 const CXXRecordDecl *UnadjustedRetClass,
357 const ReturnAdjustment &RA)
override;
359 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
360 FunctionArgList &Args)
const override {
361 assert(!Args.empty() &&
"expected the arglist to not be empty!");
362 return Args.size() - 1;
365 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
366 StringRef GetDeletedVirtualCallName()
override
367 {
return "__cxa_deleted_virtual"; }
369 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
370 Address InitializeArrayCookie(CodeGenFunction &CGF,
372 llvm::Value *NumElements,
373 const CXXNewExpr *
expr,
374 QualType ElementType)
override;
375 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
377 CharUnits cookieSize)
override;
379 void EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
380 llvm::GlobalVariable *DeclPtr,
381 bool PerformInit)
override;
382 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
383 llvm::FunctionCallee dtor,
384 llvm::Constant *addr)
override;
386 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
388 void EmitThreadLocalInitFuncs(
390 ArrayRef<const VarDecl *> CXXThreadLocals,
391 ArrayRef<llvm::Function *> CXXThreadLocalInits,
392 ArrayRef<const VarDecl *> CXXThreadLocalInitVars)
override;
394 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
395 return !isEmittedWithConstantInitializer(VD) ||
396 mayNeedDestruction(VD);
398 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
const VarDecl *VD,
399 QualType LValType)
override;
401 bool NeedsVTTParameter(GlobalDecl GD)
override;
404 getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
411 virtual bool shouldRTTIBeUnique()
const {
return true; }
415 enum RTTIUniquenessKind {
433 classifyRTTIUniqueness(QualType CanTy,
434 llvm::GlobalValue::LinkageTypes
Linkage)
const;
435 friend class ItaniumRTTIBuilder;
437 void emitCXXStructor(GlobalDecl GD)
override;
439 std::pair<llvm::Value *, const CXXRecordDecl *>
440 LoadVTablePtr(CodeGenFunction &CGF, Address This,
441 const CXXRecordDecl *RD)
override;
445 getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
447 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
448 const auto &VtableLayout =
449 CGM.getItaniumVTableContext().getVTableLayout(RD);
451 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
453 if (!VtableComponent.isUsedFunctionPointerKind())
456 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
457 const FunctionDecl *FD =
Method->getDefinition();
458 const bool IsInlined =
463 StringRef Name = CGM.getMangledName(
464 VtableComponent.getGlobalDecl(
false));
465 auto *Entry = CGM.GetGlobalValue(Name);
471 if (!Entry || Entry->isDeclaration())
477 bool isVTableHidden(
const CXXRecordDecl *RD)
const {
478 const auto &VtableLayout =
479 CGM.getItaniumVTableContext().getVTableLayout(RD);
481 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
482 if (VtableComponent.isRTTIKind()) {
483 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
484 if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
486 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
487 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
488 if (
Method->getVisibility() == Visibility::HiddenVisibility &&
497class ARMCXXABI :
public ItaniumCXXABI {
499 ARMCXXABI(CodeGen::CodeGenModule &CGM) :
500 ItaniumCXXABI(CGM,
true,
503 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
505 void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,
506 QualType ResTy)
override;
508 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
509 Address InitializeArrayCookie(CodeGenFunction &CGF,
511 llvm::Value *NumElements,
512 const CXXNewExpr *
expr,
513 QualType ElementType)
override;
514 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr,
515 CharUnits cookieSize)
override;
518class AppleARM64CXXABI :
public ARMCXXABI {
520 AppleARM64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {
521 Use32BitVTableOffsetABI =
true;
525 bool shouldRTTIBeUnique()
const override {
return false; }
528class FuchsiaCXXABI final :
public ItaniumCXXABI {
530 explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM)
531 : ItaniumCXXABI(CGM) {}
534 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
537class WebAssemblyCXXABI final :
public ItaniumCXXABI {
539 explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM)
540 : ItaniumCXXABI(CGM,
true,
542 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
544 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
545 llvm::Value *Exn)
override;
548 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
549 bool canCallMismatchedFunctionType()
const override {
return false; }
552class XLCXXABI final :
public ItaniumCXXABI {
554 explicit XLCXXABI(CodeGen::CodeGenModule &CGM)
555 : ItaniumCXXABI(CGM) {}
557 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
558 llvm::FunctionCallee dtor,
559 llvm::Constant *addr)
override;
561 bool useSinitAndSterm()
const override {
return true; }
564 void emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
565 llvm::Constant *addr);
573 case TargetCXXABI::GenericARM:
574 case TargetCXXABI::iOS:
575 case TargetCXXABI::WatchOS:
576 return new ARMCXXABI(CGM);
578 case TargetCXXABI::AppleARM64:
579 return new AppleARM64CXXABI(CGM);
581 case TargetCXXABI::Fuchsia:
582 return new FuchsiaCXXABI(CGM);
587 case TargetCXXABI::GenericAArch64:
588 return new ItaniumCXXABI(CGM,
true,
591 case TargetCXXABI::GenericMIPS:
592 return new ItaniumCXXABI(CGM,
true);
594 case TargetCXXABI::WebAssembly:
595 return new WebAssemblyCXXABI(CGM);
597 case TargetCXXABI::XL:
598 return new XLCXXABI(CGM);
600 case TargetCXXABI::GenericItanium:
601 return new ItaniumCXXABI(CGM);
603 case TargetCXXABI::Microsoft:
604 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
606 llvm_unreachable(
"bad ABI kind");
612 return CGM.PtrDiffTy;
613 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
636CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
638 llvm::Value *&ThisPtrForCall,
646 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
653 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
656 llvm::Value *Adj = RawAdj;
657 if (UseARMMethodPtrABI)
658 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
663 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(),
This, Adj);
664 ThisPtrForCall =
This;
667 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
671 llvm::Value *IsVirtual;
672 if (UseARMMethodPtrABI)
673 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
675 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
676 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
677 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
695 llvm::Value *VTableOffset = FnAsInt;
696 if (!UseARMMethodPtrABI)
697 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
698 if (Use32BitVTableOffsetABI) {
699 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
700 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
705 llvm::Constant *CheckSourceLocation;
706 llvm::Constant *CheckTypeDesc;
707 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
708 CGM.HasHiddenLTOVisibility(RD);
710 if (ShouldEmitCFICheck) {
711 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
712 if (BinOp->isPtrMemOp() &&
715 ->hasPointeeToToCFIUncheckedCalleeFunctionType())
716 ShouldEmitCFICheck =
false;
720 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
721 CGM.HasHiddenLTOVisibility(RD);
722 bool ShouldEmitWPDInfo =
723 CGM.getCodeGenOpts().WholeProgramVTables &&
725 !CGM.AlwaysHasLTOVisibilityPublic(RD);
726 llvm::Value *VirtualFn =
nullptr;
729 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
730 auto CheckHandler = SanitizerHandler::CFICheckFail;
731 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
733 llvm::Value *TypeId =
nullptr;
734 llvm::Value *CheckResult =
nullptr;
736 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
740 CGM.CreateMetadataIdentifierForVirtualMemPtrType(QualType(MPT, 0));
744 if (ShouldEmitVFEInfo) {
745 llvm::Value *VFPAddr =
746 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
753 llvm::Value *CheckedLoad = Builder.CreateCall(
754 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
755 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
756 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
757 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
761 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
762 llvm::Value *VFPAddr =
763 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
764 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
765 ? llvm::Intrinsic::type_test
766 : llvm::Intrinsic::public_type_test;
769 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
772 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
773 VirtualFn = CGF.
Builder.CreateCall(
774 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
775 {VTableOffset->getType()}),
776 {VTable, VTableOffset});
778 llvm::Value *VFPAddr =
785 assert(VirtualFn &&
"Virtual fuction pointer not created!");
786 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
788 "Check result required but not created!");
790 if (ShouldEmitCFICheck) {
794 llvm::Constant *StaticData[] = {
800 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
803 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
804 CGM.getLLVMContext(),
805 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
806 llvm::Value *ValidVtable = Builder.CreateCall(
807 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
808 CGF.
EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,
809 StaticData, {VTable, ValidVtable});
812 FnVirtual = Builder.GetInsertBlock();
821 llvm::Value *NonVirtualFn =
822 Builder.CreateIntToPtr(FnAsInt, CGF.
DefaultPtrTy,
"memptr.nonvirtualfn");
825 if (ShouldEmitCFICheck) {
828 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
829 auto CheckHandler = SanitizerHandler::CFICheckFail;
830 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
832 llvm::Constant *StaticData[] = {
838 llvm::Value *Bit = Builder.getFalse();
839 for (
const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {
840 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
843 Base->getCanonicalDecl()));
844 llvm::Value *TypeId =
847 llvm::Value *TypeTest =
848 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
849 {NonVirtualFn, TypeId});
850 Bit = Builder.CreateOr(Bit, TypeTest);
853 CGF.
EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,
854 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
856 FnNonVirtual = Builder.GetInsertBlock();
862 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
DefaultPtrTy, 2);
863 CalleePtr->addIncoming(VirtualFn, FnVirtual);
864 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
866 CGPointerAuthInfo PointerAuth;
868 if (
const auto &Schema =
869 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
870 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
871 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
873 const auto &AuthInfo =
874 CGM.getMemberFunctionPointerAuthInfo(QualType(MPT, 0));
875 assert(Schema.getKey() == AuthInfo.getKey() &&
876 "Keys for virtual and non-virtual member functions must match");
877 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
878 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
879 PointerAuth = CGPointerAuthInfo(
880 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
881 Schema.authenticatesNullValues(), DiscriminatorPHI);
884 CGCallee
Callee(FPT, CalleePtr, PointerAuth);
890llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
891 CodeGenFunction &CGF,
const Expr *E, Address Base, llvm::Value *MemPtr,
892 const MemberPointerType *MPT,
bool IsInBounds) {
893 assert(MemPtr->getType() == CGM.PtrDiffTy);
895 CGBuilderTy &Builder = CGF.
Builder;
898 llvm::Value *BaseAddr =
Base.emitRawPointer(CGF);
899 return Builder.CreateGEP(CGF.
Int8Ty, BaseAddr, MemPtr,
"memptr.offset",
900 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
901 : llvm::GEPNoWrapFlags::none());
908 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
913 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
914 CPA->getAddrDiscriminator()->isZeroValue() &&
916 "unexpected key or discriminators");
919 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
947ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
954 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
955 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
958 CGBuilderTy &Builder = CGF.
Builder;
959 QualType DstType = E->
getType();
962 if (
const auto &NewAuthInfo =
963 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
966 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
967 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
968 llvm::Type *OrigTy = MemFnPtr->getType();
970 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
975 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
976 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
977 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
978 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
979 llvm::Value *IsVirtualOffset =
980 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
981 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
984 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
985 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
989 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
990 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
991 ResignBB = Builder.GetInsertBlock();
994 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
995 NewSrc->addIncoming(src, StartBB);
996 NewSrc->addIncoming(ResignedVal, ResignBB);
1002 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1004 llvm::Constant *adj = getMemberPointerAdjustment(E);
1005 if (!adj)
return src;
1007 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1009 const MemberPointerType *destTy =
1016 if (isDerivedToBase)
1017 dst = Builder.CreateNSWSub(src, adj,
"adj");
1019 dst = Builder.CreateNSWAdd(src, adj,
"adj");
1022 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
1023 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
1024 return Builder.CreateSelect(isNull, src, dst);
1028 if (UseARMMethodPtrABI) {
1031 adj = llvm::ConstantInt::get(adj->getType(), offset);
1034 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1035 llvm::Value *dstAdj;
1036 if (isDerivedToBase)
1037 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1039 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1041 return Builder.CreateInsertValue(src, dstAdj, 1);
1044static llvm::Constant *
1049 "member function pointers expected");
1050 if (DestType == SrcType)
1056 if (!NewAuthInfo && !CurAuthInfo)
1059 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1060 if (MemFnPtr->getNumOperands() == 0) {
1068 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1069 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1073ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
1074 llvm::Constant *src) {
1075 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
1076 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
1079 QualType DstType = E->
getType();
1086 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1089 llvm::Constant *adj = getMemberPointerAdjustment(E);
1090 if (!adj)
return src;
1092 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1094 const MemberPointerType *destTy =
1101 if (src->isAllOnesValue())
return src;
1103 if (isDerivedToBase)
1104 return llvm::ConstantExpr::getNSWSub(src, adj);
1106 return llvm::ConstantExpr::getNSWAdd(src, adj);
1110 if (UseARMMethodPtrABI) {
1113 adj = llvm::ConstantInt::get(adj->getType(), offset);
1116 llvm::Constant *srcAdj = src->getAggregateElement(1);
1117 llvm::Constant *dstAdj;
1118 if (isDerivedToBase)
1119 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1121 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1123 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1124 assert(res !=
nullptr &&
"Folding must succeed");
1129ItaniumCXXABI::EmitNullMemberPointer(
const MemberPointerType *MPT) {
1133 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1135 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1136 llvm::Constant *Values[2] = {
Zero,
Zero };
1137 return llvm::ConstantStruct::getAnon(Values);
1141ItaniumCXXABI::EmitMemberDataPointer(
const MemberPointerType *MPT,
1146 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1150ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1154llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1155 CharUnits ThisAdjustment) {
1156 assert(MD->
isInstance() &&
"Member function must not be static!");
1158 CodeGenTypes &Types = CGM.getTypes();
1161 llvm::Constant *MemPtr[2];
1163 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1165 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1167 VTableOffset = Index * 4;
1169 const ASTContext &Context = getContext();
1172 VTableOffset = Index * PointerWidth.
getQuantity();
1175 if (UseARMMethodPtrABI) {
1197 const auto &Schema =
1198 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1200 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1201 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1203 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1206 MemPtr[1] = llvm::ConstantInt::get(
1207 CGM.PtrDiffTy, 2 * ThisAdjustment.
getQuantity() + !Schema);
1213 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1214 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1218 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
1229 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1231 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1232 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1233 (UseARMMethodPtrABI ? 2 : 1) *
1237 return llvm::ConstantStruct::getAnon(MemPtr);
1240llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1242 const MemberPointerType *MPT = MPType->
castAs<MemberPointerType>();
1245 return EmitNullMemberPointer(MPT);
1247 CharUnits ThisAdjustment = getContext().getMemberPointerPathAdjustment(MP);
1249 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1250 llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment);
1251 QualType SrcType = getContext().getMemberPointerType(
1256 CharUnits FieldOffset =
1257 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1258 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
1266ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
1269 const MemberPointerType *MPT,
1271 CGBuilderTy &Builder = CGF.
Builder;
1273 llvm::ICmpInst::Predicate Eq;
1274 llvm::Instruction::BinaryOps
And,
Or;
1276 Eq = llvm::ICmpInst::ICMP_NE;
1277 And = llvm::Instruction::Or;
1278 Or = llvm::Instruction::And;
1280 Eq = llvm::ICmpInst::ICMP_EQ;
1281 And = llvm::Instruction::And;
1282 Or = llvm::Instruction::Or;
1288 return Builder.CreateICmp(Eq, L, R);
1300 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1301 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1305 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1310 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1311 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr,
Zero,
"cmp.ptr.null");
1315 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1316 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1317 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1321 if (UseARMMethodPtrABI) {
1322 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1325 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1326 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1327 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1,
Zero,
1329 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1333 llvm::Value *
Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1335 Inequality ?
"memptr.ne" :
"memptr.eq");
1340ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
1341 llvm::Value *MemPtr,
1342 const MemberPointerType *MPT) {
1343 CGBuilderTy &Builder = CGF.
Builder;
1347 assert(MemPtr->getType() == CGM.PtrDiffTy);
1348 llvm::Value *NegativeOne =
1349 llvm::Constant::getAllOnesValue(MemPtr->getType());
1350 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1354 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1356 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1357 llvm::Value *
Result = Builder.CreateICmpNE(Ptr,
Zero,
"memptr.tobool");
1361 if (UseARMMethodPtrABI) {
1362 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1363 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1364 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1365 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit,
Zero,
1366 "memptr.isvirtual");
1373bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI)
const {
1374 const CXXRecordDecl *RD = FI.
getReturnType()->getAsCXXRecordDecl();
1380 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1382 Align, CGM.getDataLayout().getAllocaAddrSpace(),
1391bool ItaniumCXXABI::isZeroInitializable(
const MemberPointerType *MPT) {
1397void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
1398 const CXXDeleteExpr *DE,
1400 QualType ElementType,
1401 const CXXDestructorDecl *Dtor) {
1403 if (UseGlobalDelete) {
1412 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1413 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1431 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
1434 if (UseGlobalDelete)
1438void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF,
bool isNoReturn) {
1441 llvm::FunctionType *FTy =
1442 llvm::FunctionType::get(CGM.VoidTy,
false);
1444 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1455 llvm::FunctionType *FTy =
1466 llvm::FunctionType *FTy =
1467 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1472void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E) {
1475 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1476 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1480 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1484 E->
getSubExpr(), Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));
1487 llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1492 llvm::Constant *Dtor =
nullptr;
1498 const ASTContext &Ctx = getContext();
1500 FunctionProtoType::ExtProtoInfo());
1502 CXXDestructorDecl *DtorD =
Record->getDestructor();
1503 Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD,
Dtor_Complete));
1504 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1506 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1508 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
1520 llvm::Type *PtrDiffTy =
1523 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1525 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1529 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1530 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1531 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1532 llvm::AttributeList Attrs = llvm::AttributeList::get(
1533 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1540 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1557 unsigned NumPublicPaths = 0;
1570 if (PathElement.Base->isVirtual())
1573 if (NumPublicPaths > 1)
1577 const ASTRecordLayout &L = Context.getASTRecordLayout(PathElement.Class);
1579 PathElement.Base->getType()->getAsCXXRecordDecl());
1584 if (NumPublicPaths == 0)
1588 if (NumPublicPaths > 1)
1598 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1603bool ItaniumCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
1607void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1610 Call->setDoesNotReturn();
1611 CGF.
Builder.CreateUnreachable();
1614llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
1615 QualType SrcRecordTy,
1617 llvm::Type *StdTypeInfoPtrTy) {
1622 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1625 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1626 {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});
1630 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1636bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1637 QualType SrcRecordTy) {
1641llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1642 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1643 QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1644 llvm::Type *PtrDiffLTy =
1647 llvm::Value *SrcRTTI =
1649 llvm::Value *DestRTTI =
1655 llvm::Value *OffsetHint = llvm::ConstantInt::get(
1661 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1667 llvm::Value *Vtable =
1669 CodeGenFunction::VTableAuthMode::MustTrap);
1674 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1680 llvm::BasicBlock *BadCastBlock =
1687 EmitBadCastCall(CGF);
1693std::optional<CGCXXABI::ExactDynamicCastInfo>
1694ItaniumCXXABI::getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
1695 QualType DestRecordTy) {
1696 assert(shouldEmitExactDynamicCast(DestRecordTy));
1698 ASTContext &Context = getContext();
1703 CXXBasePaths Paths(
true,
true,
1709 std::optional<CharUnits> Offset;
1710 for (
const CXXBasePath &Path : Paths) {
1715 CharUnits PathOffset;
1716 for (
const CXXBasePathElement &PathElement : Path) {
1718 const CXXRecordDecl *
Base =
1719 PathElement.Base->getType()->getAsCXXRecordDecl();
1720 if (PathElement.Base->isVirtual()) {
1726 const ASTRecordLayout &L =
1733 Offset = PathOffset;
1734 else if (Offset != PathOffset) {
1736 return ExactDynamicCastInfo{
true,
1741 return std::nullopt;
1742 return ExactDynamicCastInfo{
false, *Offset};
1745llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1746 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1747 QualType DestTy, QualType DestRecordTy,
1748 const ExactDynamicCastInfo &ExactCastInfo, llvm::BasicBlock *CastSuccess,
1749 llvm::BasicBlock *CastFail) {
1752 auto AuthenticateVTable = [&](Address ThisAddr,
const CXXRecordDecl *
Decl) {
1756 CodeGenFunction::VTableAuthMode::MustTrap);
1759 bool PerformPostCastAuthentication =
false;
1760 llvm::Value *VTable =
nullptr;
1761 if (ExactCastInfo.RequiresCastToPrimaryBase) {
1766 llvm::Value *PrimaryBase =
1773 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1774 CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip,
1775 false,
false,
nullptr);
1778 if (PerformPostCastAuthentication)
1785 llvm::Constant *ExpectedVTable = getVTableAddressPoint(
1786 BaseSubobject(SrcDecl, ExactCastInfo.Offset), DestDecl);
1787 llvm::Value *
Success = CGF.
Builder.CreateICmpEQ(VTable, ExpectedVTable);
1790 if (!ExactCastInfo.Offset.isZero()) {
1792 llvm::Constant *OffsetConstant =
1793 llvm::ConstantInt::get(CGF.
PtrDiffTy, -Offset);
1796 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1799 if (PerformPostCastAuthentication) {
1802 llvm::BasicBlock *NonNullBlock = CGF.
Builder.GetInsertBlock();
1803 llvm::BasicBlock *PostCastAuthSuccess =
1805 llvm::BasicBlock *PostCastAuthComplete =
1808 PostCastAuthComplete);
1810 Address AdjustedThisAddr =
1812 AuthenticateVTable(AdjustedThisAddr, DestDecl);
1815 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(AdjustedThisPtr->getType(), 2);
1816 PHI->addIncoming(AdjustedThisPtr, PostCastAuthSuccess);
1817 llvm::Value *NullValue =
1818 llvm::Constant::getNullValue(AdjustedThisPtr->getType());
1819 PHI->addIncoming(NullValue, NonNullBlock);
1820 AdjustedThisPtr = PHI;
1823 return AdjustedThisPtr;
1826llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
1828 QualType SrcRecordTy) {
1830 llvm::Value *OffsetToTop;
1831 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1833 llvm::Value *VTable =
1838 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1842 llvm::Type *PtrDiffLTy =
1846 llvm::Value *VTable =
1851 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1860bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1863 Call->setDoesNotReturn();
1864 CGF.
Builder.CreateUnreachable();
1869ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
1871 const CXXRecordDecl *ClassDecl,
1872 const CXXRecordDecl *BaseClassDecl) {
1873 llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1874 CharUnits VBaseOffsetOffset =
1875 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1877 llvm::Value *VBaseOffsetPtr =
1878 CGF.
Builder.CreateConstGEP1_64(
1880 "vbase.offset.ptr");
1882 llvm::Value *VBaseOffset;
1883 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1889 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1894void ItaniumCXXABI::EmitCXXConstructors(
const CXXConstructorDecl *D) {
1896 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1900 CGM.EmitGlobal(GlobalDecl(D,
Ctor_Base));
1910CGCXXABI::AddedStructorArgCounts
1911ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
1912 SmallVectorImpl<CanQualType> &ArgTys) {
1913 ASTContext &Context = getContext();
1922 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1924 ArgTys.insert(ArgTys.begin() + 1,
1926 return AddedStructorArgCounts::prefix(1);
1928 return AddedStructorArgCounts{};
1931void ItaniumCXXABI::EmitCXXDestructors(
const CXXDestructorDecl *D) {
1934 CGM.EmitGlobal(GlobalDecl(D,
Dtor_Base));
1947void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1949 FunctionArgList &Params) {
1954 if (NeedsVTTParameter(CGF.
CurGD)) {
1955 ASTContext &Context = getContext();
1958 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1963 T, ImplicitParamKind::CXXVTT);
1964 Params.insert(Params.begin() + 1, VTTDecl);
1965 getStructorImplicitParamDecl(CGF) = VTTDecl;
1969void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1976 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1979 if (getStructorImplicitParamDecl(CGF)) {
1992 if (HasThisReturn(CGF.
CurGD))
1996CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
1999 if (!NeedsVTTParameter(GlobalDecl(D,
Type)))
2000 return AddedStructorArgs{};
2007 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
2008 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
2009 QualType VTTTy = getContext().getPointerType(Q);
2010 return AddedStructorArgs::prefix({{VTT, VTTTy}});
2013llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
2016 GlobalDecl GD(DD,
Type);
2020void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
2021 const CXXDestructorDecl *DD,
2025 GlobalDecl GD(DD,
Type);
2028 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
2031 if (getContext().getLangOpts().AppleKext &&
2038 ThisTy, VTT, VTTTy,
nullptr);
2042template <
typename T>
2045 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2058 llvm::GlobalVariable *VTable,
2060 if (VTable->getDLLStorageClass() !=
2061 llvm::GlobalVariable::DefaultStorageClass ||
2067 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2069 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2072void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
2073 const CXXRecordDecl *RD) {
2074 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());
2075 if (VTable->hasInitializer())
2078 ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
2080 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2081 llvm::Constant *RTTI =
2082 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getCanonicalTagType(RD));
2085 ConstantInitBuilder builder(CGM);
2086 auto components = builder.beginStruct();
2088 llvm::GlobalValue::isLocalLinkage(
Linkage));
2089 components.finishAndSetAsInitializer(VTable);
2094 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2095 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2097 if (CGM.getTarget().hasPS4DLLImportExport())
2101 CGM.setGVProperties(VTable, RD);
2112 EmitFundamentalRTTIDescriptors(RD);
2119 if (!VTable->isDeclarationForLinker() ||
2120 CGM.getCodeGenOpts().WholeProgramVTables) {
2121 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2125 if (VTable->isDeclarationForLinker()) {
2126 assert(CGM.getCodeGenOpts().WholeProgramVTables);
2127 CGM.addCompilerUsedGlobal(VTable);
2133 if (!VTable->isDSOLocal())
2138 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
2139 DI->emitVTableSymbol(VTable, RD);
2142bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2143 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
2146 return NeedsVTTParameter(CGF.
CurGD);
2149llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2150 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2151 const CXXRecordDecl *NearestVBase) {
2153 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2154 NeedsVTTParameter(CGF.
CurGD)) {
2155 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
2158 return getVTableAddressPoint(Base, VTableClass);
2162ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
2163 const CXXRecordDecl *VTableClass) {
2164 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());
2168 const VTableLayout &Layout =
2169 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2170 VTableLayout::AddressPointLocation AddressPoint =
2172 llvm::Value *Indices[] = {
2173 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2174 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2180 unsigned ComponentSize =
2181 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2182 unsigned VTableSize =
2185 llvm::ConstantRange InRange(
2186 llvm::APInt(32, (
int)-Offset,
true),
2187 llvm::APInt(32, (
int)(VTableSize - Offset),
true));
2188 return llvm::ConstantExpr::getGetElementPtr(
2189 VTable->getValueType(), VTable, Indices,
true, InRange);
2192llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2193 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2194 const CXXRecordDecl *NearestVBase) {
2195 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2196 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2200 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
2204 if (VirtualPointerIndex)
2206 VirtualPointerIndex);
2223llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2224 CharUnits VPtrOffset) {
2225 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2227 llvm::GlobalVariable *&VTable = VTables[RD];
2232 CGM.addDeferredVTable(RD);
2234 SmallString<256> Name;
2235 llvm::raw_svector_ostream
Out(Name);
2236 getMangleContext().mangleCXXVTable(RD, Out);
2238 const VTableLayout &VTLayout =
2239 CGM.getItaniumVTableContext().getVTableLayout(RD);
2240 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2245 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2247 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2248 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2249 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2250 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2252 if (CGM.getTarget().hasPS4DLLImportExport())
2255 CGM.setGVProperties(VTable, RD);
2259CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
2263 SourceLocation Loc) {
2264 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2266 llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
2268 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2269 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2270 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2272 llvm::Type *ComponentTy = CGM.getVTables().getVTableComponentType();
2274 VTableIndex * CGM.getDataLayout().getTypeSizeInBits(ComponentTy) / 8;
2282 llvm::Value *VFuncLoad;
2283 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
2284 VFuncLoad = CGF.
Builder.CreateCall(
2285 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2286 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, ByteOffset)});
2288 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2289 PtrTy, VTable, VTableIndex,
"vfn");
2300 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2301 CGM.getCodeGenOpts().StrictVTablePointers) {
2302 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2303 VFuncLoadInstr->setMetadata(
2304 llvm::LLVMContext::MD_invariant_load,
2305 llvm::MDNode::get(CGM.getLLVMContext(),
2306 llvm::ArrayRef<llvm::Metadata *>()));
2312 CGPointerAuthInfo PointerAuth;
2314 assert(VTableSlotPtr &&
"virtual function pointer not set");
2315 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2318 CGCallee
Callee(GD, VFunc, PointerAuth);
2322llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2323 CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
CXXDtorType DtorType,
2324 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
2325 auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
2326 auto *D = dyn_cast<const CXXDeleteExpr *>(E);
2327 assert((CE !=
nullptr) ^ (D !=
nullptr));
2328 assert(CE ==
nullptr || CE->arguments().empty());
2331 GlobalDecl GD(Dtor, DtorType);
2332 const CGFunctionInfo *FInfo =
2333 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2339 ThisTy = CE->getObjectType();
2341 ThisTy = D->getDestroyedType();
2345 nullptr, QualType(),
nullptr, CallOrInvoke);
2349void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2350 CodeGenVTables &VTables = CGM.getVTables();
2355bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2356 const CXXRecordDecl *RD)
const {
2359 if (CGM.getLangOpts().AppleKext)
2364 if (isVTableHidden(RD))
2367 if (CGM.getCodeGenOpts().ForceEmitVTables)
2384 if (hasAnyUnusedVirtualInlineFunction(RD))
2392 for (
const auto &B : RD->
bases()) {
2393 auto *BRD = B.getType()->getAsCXXRecordDecl();
2394 assert(BRD &&
"no class for base specifier");
2395 if (B.isVirtual() || !BRD->isDynamicClass())
2397 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2405bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2406 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2414 for (
const auto &B : RD->
vbases()) {
2415 auto *BRD = B.getType()->getAsCXXRecordDecl();
2416 assert(BRD &&
"no class for base specifier");
2417 if (!BRD->isDynamicClass())
2419 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2428 int64_t NonVirtualAdjustment,
2429 int64_t VirtualAdjustment,
2430 bool IsReturnAdjustment) {
2431 if (!NonVirtualAdjustment && !VirtualAdjustment)
2437 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2443 llvm::Value *ResultPtr;
2444 if (VirtualAdjustment) {
2445 llvm::Value *VTablePtr =
2448 llvm::Value *Offset;
2449 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2450 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2457 llvm::Type *PtrDiffTy =
2466 V.emitRawPointer(CGF), Offset);
2468 ResultPtr =
V.emitRawPointer(CGF);
2473 if (NonVirtualAdjustment && IsReturnAdjustment) {
2474 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2475 NonVirtualAdjustment);
2482ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This,
2483 const CXXRecordDecl *UnadjustedClass,
2484 const ThunkInfo &TI) {
2491ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
2492 const CXXRecordDecl *UnadjustedClass,
2493 const ReturnAdjustment &RA) {
2499void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
2500 RValue RV, QualType ResultType) {
2502 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2507 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2512CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2516 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2519Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2521 llvm::Value *NumElements,
2522 const CXXNewExpr *
expr,
2523 QualType ElementType) {
2524 assert(requiresArrayCookie(
expr));
2528 ASTContext &Ctx = getContext();
2532 CharUnits CookieSize =
2534 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2537 Address CookiePtr = NewPtr;
2538 CharUnits CookieOffset = CookieSize - SizeSize;
2539 if (!CookieOffset.
isZero())
2547 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2548 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2549 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2551 SI->setNoSanitizeMetadata();
2552 llvm::FunctionType *FTy =
2553 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2554 llvm::FunctionCallee F =
2555 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2564llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2566 CharUnits cookieSize) {
2568 Address numElementsPtr = allocPtr;
2569 CharUnits numElementsOffset = cookieSize - CGF.
getSizeSize();
2570 if (!numElementsOffset.
isZero())
2576 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2583 llvm::FunctionType *FTy =
2585 llvm::FunctionCallee F =
2586 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2590CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2600 CGM.getContext().getTypeAlignInChars(elementType));
2603Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2605 llvm::Value *numElements,
2606 const CXXNewExpr *
expr,
2607 QualType elementType) {
2608 assert(requiresArrayCookie(
expr));
2611 Address cookie = newPtr;
2615 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2616 getContext().getTypeSizeInChars(elementType).getQuantity());
2625 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2629llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2631 CharUnits cookieSize) {
2634 Address numElementsPtr
2644 llvm::PointerType *GuardPtrTy) {
2646 llvm::FunctionType *FTy =
2650 FTy,
"__cxa_guard_acquire",
2652 llvm::AttributeList::FunctionIndex,
2653 llvm::Attribute::NoUnwind));
2657 llvm::PointerType *GuardPtrTy) {
2659 llvm::FunctionType *FTy =
2660 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2662 FTy,
"__cxa_guard_release",
2664 llvm::AttributeList::FunctionIndex,
2665 llvm::Attribute::NoUnwind));
2669 llvm::PointerType *GuardPtrTy) {
2671 llvm::FunctionType *FTy =
2672 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2674 FTy,
"__cxa_guard_abort",
2676 llvm::AttributeList::FunctionIndex,
2677 llvm::Attribute::NoUnwind));
2681 struct CallGuardAbort final : EHScopeStack::Cleanup {
2682 llvm::GlobalVariable *Guard;
2683 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2685 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2694void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
2696 llvm::GlobalVariable *var,
2697 bool shouldPerformInit) {
2698 CGBuilderTy &Builder = CGF.
Builder;
2702 bool NonTemplateInline =
2709 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2715 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2717 llvm::IntegerType *guardTy;
2718 CharUnits guardAlignment;
2719 if (useInt8GuardVariable) {
2725 if (UseARMGuardVarABI) {
2734 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2740 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2743 SmallString<256> guardName;
2745 llvm::raw_svector_ostream
out(guardName);
2746 getMangleContext().mangleStaticGuardVariable(&D,
out);
2752 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2753 false,
var->getLinkage(),
2754 llvm::ConstantInt::get(guardTy, 0),
2756 guard->setDSOLocal(
var->isDSOLocal());
2757 guard->setVisibility(
var->getVisibility());
2758 guard->setDLLStorageClass(
var->getDLLStorageClass());
2760 guard->setThreadLocalMode(
var->getThreadLocalMode());
2761 guard->setAlignment(guardAlignment.
getAsAlign());
2766 llvm::Comdat *
C =
var->getComdat();
2768 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2769 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2770 guard->setComdat(
C);
2771 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2772 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2775 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2778 Address guardAddr = Address(guard, guard->getValueType(), guardAlignment);
2803 if (!threadsafe || MaxInlineWidthInBits) {
2805 llvm::LoadInst *LI =
2815 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2838 (UseARMGuardVarABI && !useInt8GuardVariable)
2839 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2841 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2847 CodeGenFunction::GuardKind::VariableGuard, &D);
2875 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2876 InitBlock, EndBlock);
2886 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2904 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2913 llvm::FunctionCallee dtor,
2914 llvm::Constant *addr,
bool TLS) {
2916 "unexpected call to emitGlobalDtorWithCXAAtExit");
2918 "__cxa_atexit is disabled");
2919 const char *Name =
"__cxa_atexit";
2922 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2930 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2931 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2935 llvm::Constant *handle =
2938 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2941 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2942 llvm::FunctionType *atexitTy =
2943 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2947 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2948 fn->setDoesNotThrow();
2954 Context.getFunctionType(Context.VoidTy, {Context.VoidPtrTy}, EPI);
2963 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2965 llvm::Value *args[] = {dtorCallee, addr, handle};
2973 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2977 return GlobalInitOrCleanupFn;
2980void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
2981 for (
const auto &I : DtorsUsingAtExit) {
2982 int Priority = I.first;
2983 std::string GlobalCleanupFnName =
2984 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
2986 llvm::Function *GlobalCleanupFn =
2989 CodeGenFunction CGF(*
this);
2990 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalCleanupFn,
2991 getTypes().arrangeNullaryFunction(), FunctionArgList(),
2992 SourceLocation(), SourceLocation());
2996 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
3000 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3001 auto itv = Dtors.rbegin();
3002 while (itv != Dtors.rend()) {
3003 llvm::Function *Dtor = *itv;
3008 llvm::Value *NeedsDestruct =
3011 llvm::BasicBlock *DestructCallBlock =
3014 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
3017 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
3022 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
3024 CI->setCallingConv(Dtor->getCallingConv());
3032 AddGlobalDtor(GlobalCleanupFn, Priority);
3036void CodeGenModule::registerGlobalDtorsWithAtExit() {
3037 for (
const auto &I : DtorsUsingAtExit) {
3038 int Priority = I.first;
3039 std::string GlobalInitFnName =
3040 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
3041 llvm::Function *GlobalInitFn =
3044 CodeGenFunction CGF(*
this);
3045 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalInitFn,
3046 getTypes().arrangeNullaryFunction(), FunctionArgList(),
3047 SourceLocation(), SourceLocation());
3055 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3056 for (
auto *Dtor : Dtors) {
3059 if (getCodeGenOpts().CXAAtExit) {
3069 AddGlobalCtor(GlobalInitFn, Priority);
3072 if (getCXXABI().useSinitAndSterm())
3073 unregisterGlobalDtorsWithUnAtExit();
3077void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
3078 llvm::FunctionCallee dtor,
3079 llvm::Constant *addr) {
3084 if (CGM.getLangOpts().HLSL)
3085 return CGM.AddCXXDtorEntry(dtor, addr);
3099 if (CGM.getCodeGenOpts().CXAAtExit || D.
getTLSKind())
3104 if (CGM.getLangOpts().AppleKext) {
3106 return CGM.AddCXXDtorEntry(dtor, addr);
3114 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3124static llvm::GlobalValue::LinkageTypes
3126 llvm::GlobalValue::LinkageTypes VarLinkage =
3130 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3135 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3136 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3138 return llvm::GlobalValue::WeakODRLinkage;
3142ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3145 SmallString<256> WrapperName;
3147 llvm::raw_svector_ostream
Out(WrapperName);
3148 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3153 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3156 QualType RetQT = VD->
getType();
3160 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3161 getContext().getPointerType(RetQT), FunctionArgList());
3163 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3164 llvm::Function *Wrapper =
3166 WrapperName.str(), &CGM.getModule());
3168 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3169 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3171 CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper,
false);
3174 if (!Wrapper->hasLocalLinkage())
3176 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3177 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3179 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
3182 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3183 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3186 ThreadWrappers.push_back({VD, Wrapper});
3190void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3191 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
3192 ArrayRef<llvm::Function *> CXXThreadLocalInits,
3193 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
3194 llvm::Function *InitFunc =
nullptr;
3198 llvm::SmallVector<llvm::Function *, 8> OrderedInits;
3199 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3200 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3203 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3204 CXXThreadLocalInits[I];
3206 OrderedInits.push_back(CXXThreadLocalInits[I]);
3209 if (!OrderedInits.empty()) {
3211 llvm::FunctionType *FTy =
3212 llvm::FunctionType::get(CGM.
VoidTy,
false);
3217 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3219 llvm::GlobalVariable::InternalLinkage,
3220 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3221 Guard->setThreadLocal(
true);
3225 Guard->setAlignment(GuardAlign.
getAsAlign());
3227 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(
3228 InitFunc, OrderedInits, ConstantAddress(Guard, CGM.
Int8Ty, GuardAlign));
3231 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3232 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3238 for (
const VarDecl *VD : CXXThreadLocals) {
3242 getOrCreateThreadLocalWrapper(VD, GV);
3247 for (
auto VDAndWrapper : ThreadWrappers) {
3248 const VarDecl *VD = VDAndWrapper.first;
3249 llvm::GlobalVariable *Var =
3251 llvm::Function *Wrapper = VDAndWrapper.second;
3258 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3264 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3265 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3271 SmallString<256> InitFnName;
3273 llvm::raw_svector_ostream
Out(InitFnName);
3274 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3277 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3282 llvm::GlobalValue *
Init =
nullptr;
3283 bool InitIsInitFunc =
false;
3284 bool HasConstantInitialization =
false;
3285 if (!usesThreadWrapperFunction(VD)) {
3286 HasConstantInitialization =
true;
3288 InitIsInitFunc =
true;
3289 llvm::Function *InitFuncToUse = InitFunc;
3293 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3300 Init = llvm::Function::Create(InitFnTy,
3301 llvm::GlobalVariable::ExternalWeakLinkage,
3309 Init->setVisibility(Var->getVisibility());
3311 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3312 Init->setDSOLocal(Var->isDSOLocal());
3315 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3323 isEmittedWithConstantInitializer(VD,
true) &&
3324 !mayNeedDestruction(VD)) {
3329 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3331 llvm::Function *
Func = llvm::Function::Create(
3332 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3338 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3339 CGBuilderTy Builder(CGM, Entry);
3340 Builder.CreateRetVoid();
3343 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3344 CGBuilderTy Builder(CGM, Entry);
3345 if (HasConstantInitialization) {
3347 }
else if (InitIsInitFunc) {
3349 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3351 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3352 llvm::Function *
Fn =
3354 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3365 Builder.CreateCall(InitFnTy,
Init);
3368 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3369 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3370 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3371 Builder.CreateCondBr(Have, InitBB, ExitBB);
3373 Builder.SetInsertPoint(InitBB);
3374 Builder.CreateCall(InitFnTy,
Init);
3375 Builder.CreateBr(ExitBB);
3377 Builder.SetInsertPoint(ExitBB);
3382 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3386 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3388 Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());
3390 Builder.CreateRet(Val);
3394LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
3396 QualType LValType) {
3398 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3400 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
3401 CallVal->setCallingConv(Wrapper->getCallingConv());
3415bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
3434ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3435 SmallString<256> MethodName;
3436 llvm::raw_svector_ostream
Out(MethodName);
3437 getMangleContext().mangleCXXName(MD, Out);
3438 MethodName +=
"_vfpthunk_";
3439 StringRef ThunkName = MethodName.str();
3440 llvm::Function *ThunkFn;
3441 if ((ThunkFn = cast_or_null<llvm::Function>(
3442 CGM.
getModule().getNamedValue(ThunkName))))
3447 llvm::GlobalValue::LinkageTypes
Linkage =
3449 : llvm::GlobalValue::InternalLinkage;
3452 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3453 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
3454 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3460 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3461 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3462 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3465 CodeGenFunction CGF(CGM);
3466 CGF.
CurGD = GlobalDecl(MD);
3470 FunctionArgList FunctionArgs;
3474 FunctionArgs, MD->
getLocation(), SourceLocation());
3475 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3476 setCXXABIThisValue(CGF, ThisVal);
3478 CallArgList CallArgs;
3479 for (
const VarDecl *VD : FunctionArgs)
3482 const FunctionProtoType *FPT = MD->
getType()->
getAs<FunctionProtoType>();
3484 const CGFunctionInfo &CallInfo =
3487 getThisAddress(CGF), ThunkTy);
3488 llvm::CallBase *CallOrInvoke;
3489 CGF.
EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke,
3490 true, SourceLocation(),
true);
3492 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3493 if (
Call->getType()->isVoidTy())
3506class ItaniumRTTIBuilder {
3508 llvm::LLVMContext &VMContext;
3509 const ItaniumCXXABI &
CXXABI;
3512 SmallVector<llvm::Constant *, 16> Fields;
3515 llvm::GlobalVariable *
3516 GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3520 llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
3523 void BuildVTablePointer(
const Type *Ty, llvm::Constant *StorageAddress);
3527 void BuildSIClassTypeInfo(
const CXXRecordDecl *RD);
3532 void BuildVMIClassTypeInfo(
const CXXRecordDecl *RD);
3536 void BuildPointerTypeInfo(QualType PointeeTy);
3540 void BuildObjCObjectTypeInfo(
const ObjCObjectType *Ty);
3544 void BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty);
3547 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3548 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3562 PTI_Incomplete = 0x8,
3566 PTI_ContainingClassIncomplete = 0x10,
3572 PTI_Noexcept = 0x40,
3578 VMI_NonDiamondRepeat = 0x1,
3581 VMI_DiamondShaped = 0x2
3595 llvm::Constant *BuildTypeInfo(QualType Ty);
3598 llvm::Constant *BuildTypeInfo(
3600 llvm::GlobalVariable::LinkageTypes
Linkage,
3601 llvm::GlobalValue::VisibilityTypes
Visibility,
3602 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3606llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3607 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage) {
3608 SmallString<256> Name;
3609 llvm::raw_svector_ostream
Out(Name);
3615 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
3622 GV->setInitializer(
Init);
3628ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
3630 SmallString<256> Name;
3631 llvm::raw_svector_ostream
Out(Name);
3635 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3642 GV =
new llvm::GlobalVariable(
3644 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3651 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3678 case BuiltinType::Void:
3679 case BuiltinType::NullPtr:
3680 case BuiltinType::Bool:
3681 case BuiltinType::WChar_S:
3682 case BuiltinType::WChar_U:
3683 case BuiltinType::Char_U:
3684 case BuiltinType::Char_S:
3685 case BuiltinType::UChar:
3686 case BuiltinType::SChar:
3687 case BuiltinType::Short:
3688 case BuiltinType::UShort:
3689 case BuiltinType::Int:
3690 case BuiltinType::UInt:
3691 case BuiltinType::Long:
3692 case BuiltinType::ULong:
3693 case BuiltinType::LongLong:
3694 case BuiltinType::ULongLong:
3695 case BuiltinType::Half:
3696 case BuiltinType::Float:
3697 case BuiltinType::Double:
3698 case BuiltinType::LongDouble:
3699 case BuiltinType::Float16:
3700 case BuiltinType::Float128:
3701 case BuiltinType::Ibm128:
3702 case BuiltinType::Char8:
3703 case BuiltinType::Char16:
3704 case BuiltinType::Char32:
3705 case BuiltinType::Int128:
3706 case BuiltinType::UInt128:
3709#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3710 case BuiltinType::Id:
3711#include "clang/Basic/OpenCLImageTypes.def"
3712#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3713 case BuiltinType::Id:
3714#include "clang/Basic/OpenCLExtensionTypes.def"
3715 case BuiltinType::OCLSampler:
3716 case BuiltinType::OCLEvent:
3717 case BuiltinType::OCLClkEvent:
3718 case BuiltinType::OCLQueue:
3719 case BuiltinType::OCLReserveID:
3720#define SVE_TYPE(Name, Id, SingletonId) \
3721 case BuiltinType::Id:
3722#include "clang/Basic/AArch64ACLETypes.def"
3723#define PPC_VECTOR_TYPE(Name, Id, Size) \
3724 case BuiltinType::Id:
3725#include "clang/Basic/PPCTypes.def"
3726#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3727#include "clang/Basic/RISCVVTypes.def"
3728#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3729#include "clang/Basic/WebAssemblyReferenceTypes.def"
3730#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
3731#include "clang/Basic/AMDGPUTypes.def"
3732#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3733#include "clang/Basic/HLSLIntangibleTypes.def"
3734 case BuiltinType::ShortAccum:
3735 case BuiltinType::Accum:
3736 case BuiltinType::LongAccum:
3737 case BuiltinType::UShortAccum:
3738 case BuiltinType::UAccum:
3739 case BuiltinType::ULongAccum:
3740 case BuiltinType::ShortFract:
3741 case BuiltinType::Fract:
3742 case BuiltinType::LongFract:
3743 case BuiltinType::UShortFract:
3744 case BuiltinType::UFract:
3745 case BuiltinType::ULongFract:
3746 case BuiltinType::SatShortAccum:
3747 case BuiltinType::SatAccum:
3748 case BuiltinType::SatLongAccum:
3749 case BuiltinType::SatUShortAccum:
3750 case BuiltinType::SatUAccum:
3751 case BuiltinType::SatULongAccum:
3752 case BuiltinType::SatShortFract:
3753 case BuiltinType::SatFract:
3754 case BuiltinType::SatLongFract:
3755 case BuiltinType::SatUShortFract:
3756 case BuiltinType::SatUFract:
3757 case BuiltinType::SatULongFract:
3758 case BuiltinType::BFloat16:
3761 case BuiltinType::Dependent:
3762#define BUILTIN_TYPE(Id, SingletonId)
3763#define PLACEHOLDER_TYPE(Id, SingletonId) \
3764 case BuiltinType::Id:
3765#include "clang/AST/BuiltinTypes.def"
3766 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3768 case BuiltinType::ObjCId:
3769 case BuiltinType::ObjCClass:
3770 case BuiltinType::ObjCSel:
3771 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3774 llvm_unreachable(
"Invalid BuiltinType Kind!");
3779 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3797 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3802 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3818 if (!Context.getLangOpts().RTTI)
return false;
3820 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3833 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3843 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3856 return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
3871 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3876 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3880 dyn_cast<MemberPointerType>(Ty)) {
3882 if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
3903 if (
Base->isVirtual())
3911 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
3912 if (!BaseDecl->isEmpty() &&
3919void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty,
3920 llvm::Constant *StorageAddress) {
3922 static const char *
const ClassTypeInfo =
3923 "_ZTVN10__cxxabiv117__class_type_infoE";
3925 static const char *
const SIClassTypeInfo =
3926 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3928 static const char *
const VMIClassTypeInfo =
3929 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3931 const char *VTableName =
nullptr;
3934#define TYPE(Class, Base)
3935#define ABSTRACT_TYPE(Class, Base)
3936#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3937#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3938#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3939#include "clang/AST/TypeNodes.inc"
3940 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3942 case Type::LValueReference:
3943 case Type::RValueReference:
3944 llvm_unreachable(
"References shouldn't get here");
3947 case Type::DeducedTemplateSpecialization:
3948 llvm_unreachable(
"Undeduced type shouldn't get here");
3951 llvm_unreachable(
"Pipe types shouldn't get here");
3953 case Type::ArrayParameter:
3954 llvm_unreachable(
"Array Parameter types should not get here.");
3960 case Type::ExtVector:
3961 case Type::ConstantMatrix:
3965 case Type::BlockPointer:
3967 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3970 case Type::ConstantArray:
3971 case Type::IncompleteArray:
3972 case Type::VariableArray:
3974 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3977 case Type::FunctionNoProto:
3978 case Type::FunctionProto:
3980 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3985 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3988 case Type::Record: {
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: {
4277 ->getDefinitionOrSelf();
4284 BuildSIClassTypeInfo(RD);
4286 BuildVMIClassTypeInfo(RD);
4291 case Type::ObjCObject:
4292 case Type::ObjCInterface:
4296 case Type::ObjCObjectPointer:
4304 case Type::MemberPointer:
4312 case Type::HLSLAttributedResource:
4313 case Type::HLSLInlineSpirv:
4314 llvm_unreachable(
"HLSL doesn't support RTTI");
4317 GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));
4320 auto GVDLLStorageClass = DLLStorageClass;
4322 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
4323 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
4326 if (RD->
hasAttr<DLLExportAttr>() ||
4328 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
4334 GV->takeName(OldGV);
4335 OldGV->replaceAllUsesWith(GV);
4336 OldGV->eraseFromParent();
4340 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4367 TypeName->setDLLStorageClass(DLLStorageClass);
4368 GV->setDLLStorageClass(GVDLLStorageClass);
4378void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4380 const Type *
T = OT->getBaseType().getTypePtr();
4388 ObjCInterfaceDecl *Super =
Class->getSuperClass();
4396 llvm::Constant *BaseTypeInfo =
4397 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4398 Fields.push_back(BaseTypeInfo);
4403void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4407 llvm::Constant *BaseTypeInfo =
4409 Fields.push_back(BaseTypeInfo);
4416 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
4417 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
4429 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
4430 if (
Base->isVirtual()) {
4432 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4435 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4437 if (Bases.NonVirtualBases.count(BaseDecl))
4438 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4442 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4445 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4447 if (Bases.VirtualBases.count(BaseDecl))
4448 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4453 for (
const auto &I : BaseDecl->bases())
4464 for (
const auto &I : RD->
bases())
4473void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4474 llvm::Type *UnsignedIntLTy =
4482 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4487 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4520 llvm::Type *OffsetFlagsLTy =
4523 for (
const auto &Base : RD->
bases()) {
4525 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4527 auto *BaseDecl =
Base.getType()->castAsCXXRecordDecl();
4535 if (
Base.isVirtual())
4547 if (
Base.isVirtual())
4548 OffsetFlags |= BCTI_Virtual;
4550 OffsetFlags |= BCTI_Public;
4552 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
4561 if (
Type.isConstQualified())
4562 Flags |= ItaniumRTTIBuilder::PTI_Const;
4563 if (
Type.isVolatileQualified())
4564 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4565 if (
Type.isRestrictQualified())
4566 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4573 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4576 if (Proto->isNothrow()) {
4577 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4587void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
4593 llvm::Type *UnsignedIntLTy =
4595 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4600 llvm::Constant *PointeeTypeInfo =
4601 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4602 Fields.push_back(PointeeTypeInfo);
4608ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty) {
4618 Flags |= PTI_ContainingClassIncomplete;
4620 llvm::Type *UnsignedIntLTy =
4622 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4627 llvm::Constant *PointeeTypeInfo =
4628 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4629 Fields.push_back(PointeeTypeInfo);
4636 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
T));
4639llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
4640 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4643void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4645 QualType FundamentalTypes[] = {
4646 getContext().VoidTy, getContext().NullPtrTy,
4647 getContext().BoolTy, getContext().WCharTy,
4648 getContext().CharTy, getContext().UnsignedCharTy,
4649 getContext().SignedCharTy, getContext().ShortTy,
4650 getContext().UnsignedShortTy, getContext().IntTy,
4651 getContext().UnsignedIntTy, getContext().LongTy,
4652 getContext().UnsignedLongTy, getContext().LongLongTy,
4653 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4654 getContext().UnsignedInt128Ty, getContext().HalfTy,
4655 getContext().FloatTy, getContext().DoubleTy,
4656 getContext().LongDoubleTy, getContext().Float128Ty,
4657 getContext().Char8Ty, getContext().Char16Ty,
4658 getContext().Char32Ty
4660 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4662 ? llvm::GlobalValue::DLLExportStorageClass
4663 : llvm::GlobalValue::DefaultStorageClass;
4664 llvm::GlobalValue::VisibilityTypes
Visibility =
4666 for (
const QualType &FundamentalType : FundamentalTypes) {
4667 QualType PointerType = getContext().getPointerType(FundamentalType);
4668 QualType PointerTypeConst = getContext().getPointerType(
4669 FundamentalType.withConst());
4670 for (QualType
Type : {FundamentalType, PointerType, PointerTypeConst})
4671 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4672 Type, llvm::GlobalValue::ExternalLinkage,
4679ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4680 QualType CanTy, llvm::GlobalValue::LinkageTypes
Linkage)
const {
4681 if (shouldRTTIBeUnique())
4685 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4686 Linkage != llvm::GlobalValue::WeakODRLinkage)
4694 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4695 return RUK_NonUniqueHidden;
4700 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4701 return RUK_NonUniqueVisible;
4706enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4711 return StructorCodegen::Emit;
4716 return StructorCodegen::Emit;
4719 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4727 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4728 return StructorCodegen::RAUW;
4731 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4732 return StructorCodegen::RAUW;
4734 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4738 return StructorCodegen::COMDAT;
4739 return StructorCodegen::Emit;
4742 return StructorCodegen::Alias;
4752 if (Entry && !Entry->isDeclaration())
4758 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4761 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4765 assert(Entry->getType() == Aliasee->getType() &&
4766 "declaration exists with different type");
4767 Alias->takeName(Entry);
4768 Entry->replaceAllUsesWith(Alias);
4769 Entry->eraseFromParent();
4771 Alias->setName(MangledName);
4778void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
4780 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4787 GlobalDecl BaseDecl;
4793 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4798 if (CGType == StructorCodegen::RAUW) {
4811 CGType != StructorCodegen::COMDAT &&
4829 if (CGType == StructorCodegen::COMDAT) {
4830 SmallString<256> Buffer;
4831 llvm::raw_svector_ostream
Out(Buffer);
4833 getMangleContext().mangleCXXDtorComdat(DD, Out);
4835 getMangleContext().mangleCXXCtorComdat(CD, Out);
4836 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(
Out.str());
4845 llvm::FunctionType *FTy = llvm::FunctionType::get(
4853 llvm::FunctionType *FTy =
4854 llvm::FunctionType::get(CGM.
VoidTy,
false);
4861 llvm::FunctionType *FTy = llvm::FunctionType::get(
4880 struct CallEndCatch final : EHScopeStack::Cleanup {
4881 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4884 void Emit(CodeGenFunction &CGF, Flags flags)
override {
4903 bool EndMightThrow) {
4904 llvm::CallInst *call =
4907 CGF.
EHStack.pushCleanup<CallEndCatch>(
4909 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4934 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4939 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4948 unsigned HeaderSize =
4951 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
4974 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
4982 llvm::Value *ExnCast =
4983 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
4995 if (CatchType->hasPointerRepresentation()) {
4996 llvm::Value *CastExn =
4997 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
5014 llvm_unreachable(
"bad ownership qualifier!");
5032 llvm_unreachable(
"evaluation kind filtered out!");
5034 llvm_unreachable(
"bad evaluation kind");
5038 auto catchRD = CatchType->getAsCXXRecordDecl();
5048 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5049 LLVMCatchTy, caughtExnAlignment);
5058 llvm::CallInst *rawAdjustedExn =
5062 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5063 LLVMCatchTy, caughtExnAlignment);
5094void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5095 const CXXCatchStmt *S) {
5142 C.VoidTy, {C.getPointerType(C.CharTy)});
5145 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5146 llvm::Function *fn =
5151 fn->setDoesNotThrow();
5152 fn->setDoesNotReturn();
5157 fn->addFnAttr(llvm::Attribute::NoInline);
5161 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5162 fn->setVisibility(llvm::Function::HiddenVisibility);
5164 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5167 llvm::BasicBlock *entry =
5172 llvm::Value *exn = &*fn->arg_begin();
5175 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5176 catchCall->setDoesNotThrow();
5180 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5181 termCall->setDoesNotThrow();
5182 termCall->setDoesNotReturn();
5186 builder.CreateUnreachable();
5192ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5202std::pair<llvm::Value *, const CXXRecordDecl *>
5203ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
5204 const CXXRecordDecl *RD) {
5209ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5210 const CXXMethodDecl *origMD =
5214 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5220void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5221 const CXXCatchStmt *
C) {
5223 CGF.
EHStack.pushCleanup<CatchRetScope>(
5225 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5229WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5246void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
5247 llvm::FunctionCallee Dtor,
5248 llvm::Constant *
Addr) {
5253 llvm::FunctionType *AtExitTy =
5254 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5257 llvm::FunctionCallee
AtExit =
5265 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5273 llvm::Function *DtorStub =
5281 emitCXXStermFinalizer(D, DtorStub,
Addr);
5284void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
5285 llvm::Constant *addr) {
5286 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5287 SmallString<256> FnName;
5289 llvm::raw_svector_ostream
Out(FnName);
5290 getMangleContext().mangleDynamicStermFinalizer(&D, Out);
5298 CodeGenFunction CGF(CGM);
5312 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5317 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5322 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5325 CI->setCallingConv(dtorStub->getCallingConv());
5331 if (
auto *IPA = D.
getAttr<InitPriorityAttr>()) {
5333 IPA->getPriority());
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static CharUnits computeOffsetHint(ASTContext &astContext, const CXXRecordDecl *src, const CXXRecordDecl *dst)
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, QualType ty)
Return the linkage that the type info and type info name constants should have for the given type.
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void @__clang_call_terminate(i8* exn) nounwind noreturn This co...
static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD)
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF)
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::FunctionCallee dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM)
static llvm::Constant * pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType, QualType SrcType, CodeGenModule &CGM)
static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static llvm::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 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.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
This class is used for builtin types like 'int'.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a C++ struct/union/class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
const Expr * getSubExpr() const
static CanQual< Type > CreateUnsafe(QualType Other)
Qualifiers getQualifiers() const
Retrieve all qualifiers.
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
std::string SymbolPartition
The name of the partition that symbols are assigned to, specified with -fsymbol-partition (see https:...
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
unsigned getAddressSpace() const
Return the address space that this address resides in.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
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_VectorDeleting
Vector deleting dtor.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
bool isDiscardableGVALinkage(GVALinkage L)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ EST_None
no exception specification
Visibility
Describes the different kinds of visibility that a declaration may have.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
const 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::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
llvm::PointerType * DefaultPtrTy
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
Extra information about a function prototype.
PointerAuthSchema CXXVTTVTablePointers
The ABI for C++ virtual table pointers as installed in a VTT.
PointerAuthSchema CXXTypeInfoVTablePointer
TypeInfo has external ABI requirements and is emitted without actually having parsed the libcxx defin...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@103031170252120233124322035264172076254313213024 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@106065375072164260365214033034320247050276346205 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.