33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/GlobalValue.h"
35#include "llvm/IR/Instructions.h"
36#include "llvm/IR/Intrinsics.h"
37#include "llvm/IR/Value.h"
38#include "llvm/Support/ConvertEBCDIC.h"
39#include "llvm/Support/ScopedPrinter.h"
49 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
52 llvm::SmallVector<std::pair<const VarDecl *, llvm::Function *>, 8>
56 bool UseARMMethodPtrABI;
57 bool UseARMGuardVarABI;
58 bool Use32BitVTableOffsetABI;
60 ItaniumMangleContext &getMangleContext() {
65 ItaniumCXXABI(CodeGen::CodeGenModule &CGM,
66 bool UseARMMethodPtrABI =
false,
67 bool UseARMGuardVarABI =
false) :
68 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
69 UseARMGuardVarABI(UseARMGuardVarABI),
70 Use32BitVTableOffsetABI(
false) { }
81 bool isThisCompleteObject(GlobalDecl GD)
const override {
94 llvm_unreachable(
"emitting dtor comdat as function?");
96 llvm_unreachable(
"emitting unified dtor as function?");
98 llvm_unreachable(
"unexpected dtor kind for this ABI");
100 llvm_unreachable(
"bad dtor kind");
112 llvm_unreachable(
"closure ctors in Itanium ABI?");
115 llvm_unreachable(
"emitting ctor comdat as function?");
118 llvm_unreachable(
"emitting unified ctor as function?");
120 llvm_unreachable(
"bad dtor kind");
127 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
129 llvm::Type *ConvertMemberPointerType(
const MemberPointerType *MPT)
override;
132 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
135 llvm::Value *&ThisPtrForCall,
136 llvm::Value *MemFnPtr,
137 const MemberPointerType *MPT)
override;
139 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
const Expr *E,
140 Address Base, llvm::Value *MemPtr,
141 const MemberPointerType *MPT,
142 bool IsInBounds)
override;
144 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
146 llvm::Value *Src)
override;
147 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
148 llvm::Constant *Src)
override;
150 llvm::Constant *EmitNullMemberPointer(
const MemberPointerType *MPT)
override;
152 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
153 llvm::Constant *EmitMemberDataPointer(
const MemberPointerType *MPT,
154 CharUnits offset)
override;
155 llvm::Constant *EmitMemberPointer(
const APValue &MP, QualType MPT)
override;
156 llvm::Constant *BuildMemberPointer(
const CXXMethodDecl *MD,
157 CharUnits ThisAdjustment);
159 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
160 llvm::Value *L, llvm::Value *R,
161 const MemberPointerType *MPT,
162 bool Inequality)
override;
164 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
166 const MemberPointerType *MPT)
override;
168 void emitVirtualObjectDelete(CodeGenFunction &CGF,
const CXXDeleteExpr *DE,
169 Address Ptr, QualType ElementType,
170 const CXXDestructorDecl *Dtor)
override;
172 void emitRethrow(CodeGenFunction &CGF,
bool isNoReturn)
override;
173 void emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E)
override;
175 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
178 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
179 llvm::Value *Exn)
override;
181 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
182 llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty)
override;
184 getAddrOfCXXCatchHandlerType(QualType Ty,
185 QualType CatchHandlerType)
override {
186 return CatchTypeInfo{getAddrOfRTTIDescriptor(Ty), 0};
189 bool shouldTypeidBeNullChecked(QualType SrcRecordTy)
override;
190 void EmitBadTypeidCall(CodeGenFunction &CGF)
override;
191 llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
193 llvm::Type *StdTypeInfoPtrTy)
override;
195 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
196 QualType SrcRecordTy)
override;
202 bool hasUniqueVTablePointer(QualType RecordTy) {
207 if (!CGM.getCodeGenOpts().AssumeUniqueVTables ||
208 getContext().getLangOpts().AppleKext)
213 if (!CGM.shouldEmitRTTI())
218 if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))
227 llvm::GlobalValue::DefaultVisibility)
233 bool shouldEmitExactDynamicCast(QualType DestRecordTy)
override {
234 return hasUniqueVTablePointer(DestRecordTy);
237 std::optional<ExactDynamicCastInfo>
238 getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
239 QualType DestRecordTy)
override;
241 llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address
Value,
242 QualType SrcRecordTy, QualType DestTy,
243 QualType DestRecordTy,
244 llvm::BasicBlock *CastEnd)
override;
247 QualType SrcRecordTy, QualType DestTy,
248 QualType DestRecordTy,
249 const ExactDynamicCastInfo &CastInfo,
250 llvm::BasicBlock *CastSuccess,
251 llvm::BasicBlock *CastFail)
override;
254 QualType SrcRecordTy)
override;
256 bool EmitBadCastCall(CodeGenFunction &CGF)
override;
259 GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
260 const CXXRecordDecl *ClassDecl,
261 const CXXRecordDecl *BaseClassDecl)
override;
263 void EmitCXXConstructors(
const CXXConstructorDecl *D)
override;
265 AddedStructorArgCounts
266 buildStructorSignature(GlobalDecl GD,
267 SmallVectorImpl<CanQualType> &ArgTys)
override;
269 bool useThunkForDtorVariant(
const CXXDestructorDecl *Dtor,
277 void EmitCXXDestructors(
const CXXDestructorDecl *D)
override;
279 void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
280 FunctionArgList &Params)
override;
282 void EmitInstanceFunctionProlog(CodeGenFunction &CGF)
override;
284 AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
285 const CXXConstructorDecl *D,
291 const CXXDestructorDecl *DD,
296 void EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
299 QualType ThisTy)
override;
301 void emitVTableDefinitions(CodeGenVTables &CGVT,
302 const CXXRecordDecl *RD)
override;
304 bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
305 CodeGenFunction::VPtr Vptr)
override;
307 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
312 getVTableAddressPoint(BaseSubobject Base,
313 const CXXRecordDecl *VTableClass)
override;
315 llvm::Value *getVTableAddressPointInStructor(
316 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
317 BaseSubobject Base,
const CXXRecordDecl *NearestVBase)
override;
319 llvm::Value *getVTableAddressPointInStructorWithVTT(
320 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
321 BaseSubobject Base,
const CXXRecordDecl *NearestVBase);
323 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
324 CharUnits VPtrOffset)
override;
326 CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
327 Address This, llvm::Type *Ty,
328 SourceLocation Loc)
override;
331 EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
333 DeleteOrMemberCallExpr E,
334 llvm::CallBase **CallOrInvoke)
override;
336 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
338 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
339 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
341 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable, GlobalDecl GD,
342 bool ReturnAdjustment)
override {
345 if (ForVTable && !Thunk->hasLocalLinkage())
346 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
347 CGM.setGVProperties(Thunk, GD);
350 bool exportThunk()
override {
return true; }
352 llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
353 const CXXRecordDecl *UnadjustedThisClass,
354 const ThunkInfo &TI)
override;
357 const CXXRecordDecl *UnadjustedRetClass,
358 const ReturnAdjustment &RA)
override;
360 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
361 FunctionArgList &Args)
const override {
362 assert(!Args.empty() &&
"expected the arglist to not be empty!");
363 return Args.size() - 1;
366 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
367 StringRef GetDeletedVirtualCallName()
override
368 {
return "__cxa_deleted_virtual"; }
370 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
371 Address InitializeArrayCookie(CodeGenFunction &CGF,
373 llvm::Value *NumElements,
374 const CXXNewExpr *
expr,
375 QualType ElementType)
override;
376 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
378 CharUnits cookieSize)
override;
380 void EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
381 llvm::GlobalVariable *DeclPtr,
382 bool PerformInit)
override;
383 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
384 llvm::FunctionCallee dtor,
385 llvm::Constant *addr)
override;
387 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
389 void EmitThreadLocalInitFuncs(
391 ArrayRef<const VarDecl *> CXXThreadLocals,
392 ArrayRef<llvm::Function *> CXXThreadLocalInits,
393 ArrayRef<const VarDecl *> CXXThreadLocalInitVars)
override;
395 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
396 return !isEmittedWithConstantInitializer(VD) ||
397 mayNeedDestruction(VD);
399 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
const VarDecl *VD,
400 QualType LValType)
override;
402 bool NeedsVTTParameter(GlobalDecl GD)
override;
405 getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
412 virtual bool shouldRTTIBeUnique()
const {
return true; }
416 enum RTTIUniquenessKind {
434 classifyRTTIUniqueness(QualType CanTy,
435 llvm::GlobalValue::LinkageTypes
Linkage)
const;
436 friend class ItaniumRTTIBuilder;
438 void emitCXXStructor(GlobalDecl GD)
override;
440 std::pair<llvm::Value *, const CXXRecordDecl *>
441 LoadVTablePtr(CodeGenFunction &CGF, Address This,
442 const CXXRecordDecl *RD)
override;
446 getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
448 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
449 const auto &VtableLayout =
450 CGM.getItaniumVTableContext().getVTableLayout(RD);
452 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
454 if (!VtableComponent.isUsedFunctionPointerKind())
457 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
458 const FunctionDecl *FD =
Method->getDefinition();
459 const bool IsInlined =
464 StringRef Name = CGM.getMangledName(
465 VtableComponent.getGlobalDecl(
false));
466 auto *Entry = CGM.GetGlobalValue(Name);
472 if (!Entry || Entry->isDeclaration())
478 bool isVTableHidden(
const CXXRecordDecl *RD)
const {
479 const auto &VtableLayout =
480 CGM.getItaniumVTableContext().getVTableLayout(RD);
482 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
483 if (VtableComponent.isRTTIKind()) {
484 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
485 if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
487 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
488 const CXXMethodDecl *
Method = VtableComponent.getFunctionDecl();
489 if (
Method->getVisibility() == Visibility::HiddenVisibility &&
498class ARMCXXABI :
public ItaniumCXXABI {
500 ARMCXXABI(CodeGen::CodeGenModule &CGM) :
501 ItaniumCXXABI(CGM,
true,
504 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
506 void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,
507 QualType ResTy)
override;
509 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
510 Address InitializeArrayCookie(CodeGenFunction &CGF,
512 llvm::Value *NumElements,
513 const CXXNewExpr *
expr,
514 QualType ElementType)
override;
515 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, Address allocPtr,
516 CharUnits cookieSize)
override;
519class AppleARM64CXXABI :
public ARMCXXABI {
521 AppleARM64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {
522 Use32BitVTableOffsetABI =
true;
526 bool shouldRTTIBeUnique()
const override {
return false; }
529class FuchsiaCXXABI final :
public ItaniumCXXABI {
531 explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM)
532 : ItaniumCXXABI(CGM) {}
535 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
538class WebAssemblyCXXABI final :
public ItaniumCXXABI {
540 explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM)
541 : ItaniumCXXABI(CGM,
true,
543 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
545 emitTerminateForUnexpectedException(CodeGenFunction &CGF,
546 llvm::Value *Exn)
override;
549 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
550 bool canCallMismatchedFunctionType()
const override {
return false; }
553class XLCXXABI final :
public ItaniumCXXABI {
555 explicit XLCXXABI(CodeGen::CodeGenModule &CGM)
556 : ItaniumCXXABI(CGM) {}
558 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
559 llvm::FunctionCallee dtor,
560 llvm::Constant *addr)
override;
562 bool useSinitAndSterm()
const override {
return true; }
565 void emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
566 llvm::Constant *addr);
574 case TargetCXXABI::GenericARM:
575 case TargetCXXABI::iOS:
576 case TargetCXXABI::WatchOS:
577 return new ARMCXXABI(CGM);
579 case TargetCXXABI::AppleARM64:
580 return new AppleARM64CXXABI(CGM);
582 case TargetCXXABI::Fuchsia:
583 return new FuchsiaCXXABI(CGM);
588 case TargetCXXABI::GenericAArch64:
589 return new ItaniumCXXABI(CGM,
true,
592 case TargetCXXABI::GenericMIPS:
593 return new ItaniumCXXABI(CGM,
true);
595 case TargetCXXABI::WebAssembly:
596 return new WebAssemblyCXXABI(CGM);
598 case TargetCXXABI::XL:
599 return new XLCXXABI(CGM);
601 case TargetCXXABI::GenericItanium:
602 return new ItaniumCXXABI(CGM);
604 case TargetCXXABI::Microsoft:
605 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
607 llvm_unreachable(
"bad ABI kind");
613 return CGM.PtrDiffTy;
614 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
637CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
639 llvm::Value *&ThisPtrForCall,
647 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
654 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
657 llvm::Value *Adj = RawAdj;
658 if (UseARMMethodPtrABI)
659 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
664 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(),
This, Adj);
665 ThisPtrForCall =
This;
668 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
672 llvm::Value *IsVirtual;
673 if (UseARMMethodPtrABI)
674 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
676 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
677 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
678 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
696 llvm::Value *VTableOffset = FnAsInt;
697 if (!UseARMMethodPtrABI)
698 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
699 if (Use32BitVTableOffsetABI) {
700 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
701 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
706 llvm::Constant *CheckSourceLocation;
707 llvm::Constant *CheckTypeDesc;
708 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
709 CGM.HasHiddenLTOVisibility(RD);
711 if (ShouldEmitCFICheck) {
712 if (
const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
713 if (BinOp->isPtrMemOp() &&
716 ->hasPointeeToCFIUncheckedCalleeFunctionType())
717 ShouldEmitCFICheck =
false;
721 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
722 CGM.HasHiddenLTOVisibility(RD);
726 bool ShouldEmitWPDInfo =
727 (CGM.getCodeGenOpts().WholeProgramVTables &&
729 !CGM.AlwaysHasLTOVisibilityPublic(RD)) ||
730 CGM.getCodeGenOpts().DevirtualizeSpeculatively;
731 llvm::Value *VirtualFn =
nullptr;
734 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
735 auto CheckHandler = SanitizerHandler::CFICheckFail;
736 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
738 llvm::Value *TypeId =
nullptr;
739 llvm::Value *CheckResult =
nullptr;
741 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
745 CGM.CreateMetadataIdentifierForVirtualMemPtrType(QualType(MPT, 0));
749 if (ShouldEmitVFEInfo) {
750 llvm::Value *VFPAddr =
751 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
758 llvm::Value *CheckedLoad = Builder.CreateCall(
759 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
760 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
761 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
762 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
766 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
767 llvm::Value *VFPAddr =
768 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
769 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
770 ? llvm::Intrinsic::type_test
771 : llvm::Intrinsic::public_type_test;
774 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
777 if (CGM.getLangOpts().RelativeCXXABIVTables) {
778 VirtualFn = CGF.
Builder.CreateCall(
779 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
780 {VTableOffset->getType()}),
781 {VTable, VTableOffset});
783 llvm::Value *VFPAddr =
790 assert(VirtualFn &&
"Virtual fuction pointer not created!");
791 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
793 "Check result required but not created!");
795 if (ShouldEmitCFICheck) {
799 llvm::Constant *StaticData[] = {
805 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
808 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
809 CGM.getLLVMContext(),
810 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
811 llvm::Value *ValidVtable = Builder.CreateCall(
812 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
813 CGF.
EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,
814 StaticData, {VTable, ValidVtable});
817 FnVirtual = Builder.GetInsertBlock();
826 llvm::Value *NonVirtualFn =
827 Builder.CreateIntToPtr(FnAsInt, CGF.
DefaultPtrTy,
"memptr.nonvirtualfn");
830 if (ShouldEmitCFICheck) {
833 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
834 auto CheckHandler = SanitizerHandler::CFICheckFail;
835 SanitizerDebugLocation SanScope(&CGF, {CheckOrdinal}, CheckHandler);
837 llvm::Constant *StaticData[] = {
843 llvm::Value *Bit = Builder.getFalse();
844 for (
const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {
845 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
848 Base->getCanonicalDecl()));
849 llvm::Value *TypeId =
852 llvm::Value *TypeTest =
853 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
854 {NonVirtualFn, TypeId});
855 Bit = Builder.CreateOr(Bit, TypeTest);
858 CGF.
EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,
859 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
861 FnNonVirtual = Builder.GetInsertBlock();
867 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
DefaultPtrTy, 2);
868 CalleePtr->addIncoming(VirtualFn, FnVirtual);
869 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
871 CGPointerAuthInfo PointerAuth;
873 if (
const auto &Schema =
874 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
875 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
876 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
878 const auto &AuthInfo =
879 CGM.getMemberFunctionPointerAuthInfo(QualType(MPT, 0));
880 assert(Schema.getKey() == AuthInfo.getKey() &&
881 "Keys for virtual and non-virtual member functions must match");
882 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
883 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
884 PointerAuth = CGPointerAuthInfo(
885 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
886 Schema.authenticatesNullValues(), DiscriminatorPHI);
889 CGCallee
Callee(FPT, CalleePtr, PointerAuth);
895llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
896 CodeGenFunction &CGF,
const Expr *E, Address Base, llvm::Value *MemPtr,
897 const MemberPointerType *MPT,
bool IsInBounds) {
898 assert(MemPtr->getType() == CGM.PtrDiffTy);
900 CGBuilderTy &Builder = CGF.
Builder;
903 llvm::Value *BaseAddr =
Base.emitRawPointer(CGF);
904 return Builder.CreateGEP(CGF.
Int8Ty, BaseAddr, MemPtr,
"memptr.offset",
905 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
906 : llvm::GEPNoWrapFlags::none());
913 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
918 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
919 CPA->getAddrDiscriminator()->isNullValue() &&
921 "unexpected key or discriminators");
924 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
952ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
959 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
960 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
963 CGBuilderTy &Builder = CGF.
Builder;
964 QualType DstType = E->
getType();
967 if (
const auto &NewAuthInfo =
968 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
971 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
972 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
973 llvm::Type *OrigTy = MemFnPtr->getType();
975 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
980 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
981 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
982 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
983 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
984 llvm::Value *IsVirtualOffset =
985 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
986 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
989 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
990 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
994 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
995 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
996 ResignBB = Builder.GetInsertBlock();
999 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
1000 NewSrc->addIncoming(src, StartBB);
1001 NewSrc->addIncoming(ResignedVal, ResignBB);
1007 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1009 llvm::Constant *adj = getMemberPointerAdjustment(E);
1010 if (!adj)
return src;
1012 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1014 const MemberPointerType *destTy =
1021 if (isDerivedToBase)
1022 dst = Builder.CreateNSWSub(src, adj,
"adj");
1024 dst = Builder.CreateNSWAdd(src, adj,
"adj");
1027 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
1028 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
1029 return Builder.CreateSelect(isNull, src, dst);
1033 if (UseARMMethodPtrABI) {
1036 adj = llvm::ConstantInt::get(adj->getType(), offset);
1039 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1040 llvm::Value *dstAdj;
1041 if (isDerivedToBase)
1042 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1044 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1046 return Builder.CreateInsertValue(src, dstAdj, 1);
1049static llvm::Constant *
1054 "member function pointers expected");
1055 if (DestType == SrcType)
1061 if (!NewAuthInfo && !CurAuthInfo)
1064 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1065 if (MemFnPtr->getNumOperands() == 0) {
1073 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1074 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1078ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
1079 llvm::Constant *src) {
1080 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
1081 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
1084 QualType DstType = E->
getType();
1091 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
1094 llvm::Constant *adj = getMemberPointerAdjustment(E);
1095 if (!adj)
return src;
1097 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
1099 const MemberPointerType *destTy =
1106 if (src->isAllOnesValue())
return src;
1108 if (isDerivedToBase)
1109 return llvm::ConstantExpr::getNSWSub(src, adj);
1111 return llvm::ConstantExpr::getNSWAdd(src, adj);
1115 if (UseARMMethodPtrABI) {
1118 adj = llvm::ConstantInt::get(adj->getType(), offset);
1121 llvm::Constant *srcAdj = src->getAggregateElement(1);
1122 llvm::Constant *dstAdj;
1123 if (isDerivedToBase)
1124 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1126 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1128 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1129 assert(res !=
nullptr &&
"Folding must succeed");
1134ItaniumCXXABI::EmitNullMemberPointer(
const MemberPointerType *MPT) {
1138 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1140 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1141 llvm::Constant *Values[2] = {
Zero,
Zero };
1142 return llvm::ConstantStruct::getAnon(Values);
1146ItaniumCXXABI::EmitMemberDataPointer(
const MemberPointerType *MPT,
1151 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1155ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1159llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1160 CharUnits ThisAdjustment) {
1161 assert(MD->
isInstance() &&
"Member function must not be static!");
1163 CodeGenTypes &Types = CGM.getTypes();
1166 llvm::Constant *MemPtr[2];
1168 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1170 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1172 VTableOffset = Index * 4;
1174 const ASTContext &Context = getContext();
1177 VTableOffset = Index * PointerWidth.
getQuantity();
1180 if (UseARMMethodPtrABI) {
1202 const auto &Schema =
1203 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1205 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1206 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1208 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1211 MemPtr[1] = llvm::ConstantInt::get(
1212 CGM.PtrDiffTy, 2 * ThisAdjustment.
getQuantity() + !Schema);
1218 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1219 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1223 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
1234 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1236 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1237 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1238 (UseARMMethodPtrABI ? 2 : 1) *
1242 return llvm::ConstantStruct::getAnon(MemPtr);
1245llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1247 const MemberPointerType *MPT = MPType->
castAs<MemberPointerType>();
1250 return EmitNullMemberPointer(MPT);
1252 CharUnits ThisAdjustment = getContext().getMemberPointerPathAdjustment(MP);
1254 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1255 llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment);
1256 QualType SrcType = getContext().getMemberPointerType(
1261 getContext().recordMemberDataPointerEvaluation(MPD);
1262 CharUnits FieldOffset =
1263 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1264 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
1272ItaniumCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
1275 const MemberPointerType *MPT,
1277 CGBuilderTy &Builder = CGF.
Builder;
1279 llvm::ICmpInst::Predicate Eq;
1280 llvm::Instruction::BinaryOps
And,
Or;
1282 Eq = llvm::ICmpInst::ICMP_NE;
1283 And = llvm::Instruction::Or;
1284 Or = llvm::Instruction::And;
1286 Eq = llvm::ICmpInst::ICMP_EQ;
1287 And = llvm::Instruction::And;
1288 Or = llvm::Instruction::Or;
1294 return Builder.CreateICmp(Eq, L, R);
1306 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1307 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1311 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1316 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1317 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr,
Zero,
"cmp.ptr.null");
1321 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1322 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1323 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1327 if (UseARMMethodPtrABI) {
1328 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1331 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1332 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1333 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1,
Zero,
1335 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1339 llvm::Value *
Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1341 Inequality ?
"memptr.ne" :
"memptr.eq");
1346ItaniumCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
1347 llvm::Value *MemPtr,
1348 const MemberPointerType *MPT) {
1349 CGBuilderTy &Builder = CGF.
Builder;
1353 assert(MemPtr->getType() == CGM.PtrDiffTy);
1354 llvm::Value *NegativeOne =
1355 llvm::Constant::getAllOnesValue(MemPtr->getType());
1356 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1360 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1362 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1363 llvm::Value *
Result = Builder.CreateICmpNE(Ptr,
Zero,
"memptr.tobool");
1367 if (UseARMMethodPtrABI) {
1368 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1369 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1370 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1371 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit,
Zero,
1372 "memptr.isvirtual");
1379bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI)
const {
1380 const CXXRecordDecl *RD = FI.
getReturnType()->getAsCXXRecordDecl();
1387 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1388 LangAS SRetAS = CGM.getTargetCodeGenInfo().getSRetAddrSpace(RD);
1389 unsigned AS = CGM.getContext().getTargetAddressSpace(SRetAS);
1399bool ItaniumCXXABI::isZeroInitializable(
const MemberPointerType *MPT) {
1405void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
1406 const CXXDeleteExpr *DE,
1408 QualType ElementType,
1409 const CXXDestructorDecl *Dtor) {
1411 if (UseGlobalDelete) {
1420 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1421 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1439 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
1442 if (UseGlobalDelete)
1446void ItaniumCXXABI::emitRethrow(CodeGenFunction &CGF,
bool isNoReturn) {
1449 llvm::FunctionType *FTy =
1450 llvm::FunctionType::get(CGM.VoidTy,
false);
1452 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1463 llvm::FunctionType *FTy =
1474 llvm::FunctionType *FTy =
1475 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1480void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E) {
1483 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1484 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1488 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1495 llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1500 llvm::Constant *Dtor =
nullptr;
1506 const ASTContext &Ctx = getContext();
1508 FunctionProtoType::ExtProtoInfo());
1510 CXXDestructorDecl *DtorD =
Record->getDestructor();
1511 Dtor = CGM.getAddrOfCXXStructor(GlobalDecl(DtorD,
Dtor_Complete));
1512 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1514 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1516 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
1528 llvm::Type *PtrDiffTy =
1531 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1533 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1537 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1538 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1539 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1540 llvm::AttributeList Attrs = llvm::AttributeList::get(
1541 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1548 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1565 unsigned NumPublicPaths = 0;
1578 if (PathElement.Base->isVirtual())
1581 if (NumPublicPaths > 1)
1585 const ASTRecordLayout &L = Context.getASTRecordLayout(PathElement.Class);
1587 PathElement.Base->getType()->getAsCXXRecordDecl());
1592 if (NumPublicPaths == 0)
1596 if (NumPublicPaths > 1)
1606 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1611bool ItaniumCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
1615void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1618 Call->setDoesNotReturn();
1619 CGF.
Builder.CreateUnreachable();
1622llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
1623 QualType SrcRecordTy,
1625 llvm::Type *StdTypeInfoPtrTy) {
1630 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1633 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1634 {Value, llvm::ConstantInt::getSigned(CGM.Int32Ty, -4)});
1638 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1644bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1645 QualType SrcRecordTy) {
1649llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1650 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1651 QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1652 llvm::Type *PtrDiffLTy =
1655 llvm::Value *SrcRTTI =
1657 llvm::Value *DestRTTI =
1663 llvm::Value *OffsetHint = llvm::ConstantInt::getSigned(
1669 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1675 llvm::Value *Vtable =
1677 CodeGenFunction::VTableAuthMode::MustTrap);
1682 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1688 llvm::BasicBlock *BadCastBlock =
1695 EmitBadCastCall(CGF);
1701std::optional<CGCXXABI::ExactDynamicCastInfo>
1702ItaniumCXXABI::getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
1703 QualType DestRecordTy) {
1704 assert(shouldEmitExactDynamicCast(DestRecordTy));
1706 ASTContext &Context = getContext();
1711 CXXBasePaths Paths(
true,
true,
1717 std::optional<CharUnits> Offset;
1718 for (
const CXXBasePath &Path : Paths) {
1723 CharUnits PathOffset;
1724 for (
const CXXBasePathElement &PathElement : Path) {
1726 const CXXRecordDecl *
Base =
1727 PathElement.Base->getType()->getAsCXXRecordDecl();
1728 if (PathElement.Base->isVirtual()) {
1734 const ASTRecordLayout &L =
1741 Offset = PathOffset;
1742 else if (Offset != PathOffset) {
1744 return ExactDynamicCastInfo{
true,
1749 return std::nullopt;
1750 return ExactDynamicCastInfo{
false, *Offset};
1753llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1754 CodeGenFunction &CGF, Address ThisAddr, QualType SrcRecordTy,
1755 QualType DestTy, QualType DestRecordTy,
1756 const ExactDynamicCastInfo &ExactCastInfo, llvm::BasicBlock *CastSuccess,
1757 llvm::BasicBlock *CastFail) {
1760 auto AuthenticateVTable = [&](
Address ThisAddr,
const CXXRecordDecl *
Decl) {
1764 CodeGenFunction::VTableAuthMode::MustTrap);
1767 bool PerformPostCastAuthentication =
false;
1768 llvm::Value *VTable =
nullptr;
1769 if (ExactCastInfo.RequiresCastToPrimaryBase) {
1774 llvm::Value *PrimaryBase =
1781 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1782 CGPointerAuthInfo StrippingAuthInfo(0, PointerAuthenticationMode::Strip,
1783 false,
false,
nullptr);
1786 if (PerformPostCastAuthentication)
1793 llvm::Constant *ExpectedVTable = getVTableAddressPoint(
1794 BaseSubobject(SrcDecl, ExactCastInfo.Offset), DestDecl);
1795 llvm::Value *
Success = CGF.
Builder.CreateICmpEQ(VTable, ExpectedVTable);
1798 if (!ExactCastInfo.Offset.isZero()) {
1800 llvm::Constant *OffsetConstant =
1801 llvm::ConstantInt::get(CGF.
PtrDiffTy, -Offset);
1804 PerformPostCastAuthentication = CGF.
getLangOpts().PointerAuthCalls;
1807 if (PerformPostCastAuthentication) {
1810 llvm::BasicBlock *NonNullBlock = CGF.
Builder.GetInsertBlock();
1811 llvm::BasicBlock *PostCastAuthSuccess =
1813 llvm::BasicBlock *PostCastAuthComplete =
1816 PostCastAuthComplete);
1820 AuthenticateVTable(AdjustedThisAddr, DestDecl);
1823 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(AdjustedThisPtr->getType(), 2);
1824 PHI->addIncoming(AdjustedThisPtr, PostCastAuthSuccess);
1825 llvm::Value *NullValue =
1826 llvm::Constant::getNullValue(AdjustedThisPtr->getType());
1827 PHI->addIncoming(NullValue, NonNullBlock);
1828 AdjustedThisPtr = PHI;
1831 return AdjustedThisPtr;
1834llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
1836 QualType SrcRecordTy) {
1838 llvm::Value *OffsetToTop;
1839 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1841 llvm::Value *VTable =
1846 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1850 llvm::Type *PtrDiffLTy =
1854 llvm::Value *VTable =
1859 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1868bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1871 Call->setDoesNotReturn();
1872 CGF.
Builder.CreateUnreachable();
1877ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
1879 const CXXRecordDecl *ClassDecl,
1880 const CXXRecordDecl *BaseClassDecl) {
1881 llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1882 CharUnits VBaseOffsetOffset =
1883 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1885 llvm::Value *VBaseOffsetPtr =
1886 CGF.
Builder.CreateConstGEP1_64(
1888 "vbase.offset.ptr");
1890 llvm::Value *VBaseOffset;
1891 if (CGM.getLangOpts().RelativeCXXABIVTables) {
1897 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1902void ItaniumCXXABI::EmitCXXConstructors(
const CXXConstructorDecl *D) {
1904 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1908 CGM.EmitGlobal(GlobalDecl(D,
Ctor_Base));
1918CGCXXABI::AddedStructorArgCounts
1919ItaniumCXXABI::buildStructorSignature(GlobalDecl GD,
1920 SmallVectorImpl<CanQualType> &ArgTys) {
1921 ASTContext &Context = getContext();
1930 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1932 ArgTys.insert(ArgTys.begin() + 1,
1934 return AddedStructorArgCounts::prefix(1);
1936 return AddedStructorArgCounts{};
1939void ItaniumCXXABI::EmitCXXDestructors(
const CXXDestructorDecl *D) {
1942 CGM.EmitGlobal(GlobalDecl(D,
Dtor_Base));
1955void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1957 FunctionArgList &Params) {
1962 if (NeedsVTTParameter(CGF.
CurGD)) {
1963 ASTContext &Context = getContext();
1966 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1971 T, ImplicitParamKind::CXXVTT);
1972 Params.insert(Params.begin() + 1, VTTDecl);
1973 getStructorImplicitParamDecl(CGF) = VTTDecl;
1977void ItaniumCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1984 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1987 if (getStructorImplicitParamDecl(CGF)) {
2000 if (HasThisReturn(CGF.
CurGD))
2004CGCXXABI::AddedStructorArgs ItaniumCXXABI::getImplicitConstructorArgs(
2007 if (!NeedsVTTParameter(GlobalDecl(D,
Type)))
2008 return AddedStructorArgs{};
2015 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
2016 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
2017 QualType VTTTy = getContext().getPointerType(Q);
2018 return AddedStructorArgs::prefix({{VTT, VTTTy}});
2021llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
2024 GlobalDecl GD(DD,
Type);
2028void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
2029 const CXXDestructorDecl *DD,
2033 GlobalDecl GD(DD,
Type);
2036 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
2039 if (getContext().getLangOpts().AppleKext &&
2046 ThisTy, VTT, VTTTy,
nullptr);
2050template <
typename T>
2053 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
2066 llvm::GlobalVariable *VTable,
2068 if (VTable->getDLLStorageClass() !=
2069 llvm::GlobalVariable::DefaultStorageClass ||
2075 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2077 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2080void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
2081 const CXXRecordDecl *RD) {
2082 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, CharUnits());
2083 if (VTable->hasInitializer())
2086 ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
2088 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2089 llvm::Constant *RTTI =
2090 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getCanonicalTagType(RD));
2093 ConstantInitBuilder builder(CGM);
2094 auto components = builder.beginStruct();
2096 llvm::GlobalValue::isLocalLinkage(
Linkage));
2097 components.finishAndSetAsInitializer(VTable);
2102 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2103 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2105 if (CGM.getTarget().hasPS4DLLImportExport())
2109 CGM.setGVProperties(VTable, RD);
2120 EmitFundamentalRTTIDescriptors(RD);
2128 if (!VTable->isDeclarationForLinker() ||
2129 CGM.getCodeGenOpts().WholeProgramVTables ||
2130 CGM.getCodeGenOpts().DevirtualizeSpeculatively) {
2131 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2135 if (VTable->isDeclarationForLinker()) {
2136 assert(CGM.getCodeGenOpts().WholeProgramVTables ||
2137 CGM.getCodeGenOpts().DevirtualizeSpeculatively);
2138 CGM.addCompilerUsedGlobal(VTable);
2142 if (CGM.getLangOpts().RelativeCXXABIVTables) {
2144 if (!VTable->isDSOLocal())
2149 if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
2150 DI->emitVTableSymbol(VTable, RD);
2153bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2154 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
2157 return NeedsVTTParameter(CGF.
CurGD);
2160llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2161 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2162 const CXXRecordDecl *NearestVBase) {
2164 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2165 NeedsVTTParameter(CGF.
CurGD)) {
2166 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
2169 return getVTableAddressPoint(Base, VTableClass);
2173ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
2174 const CXXRecordDecl *VTableClass) {
2175 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass, CharUnits());
2179 const VTableLayout &Layout =
2180 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2181 VTableLayout::AddressPointLocation AddressPoint =
2183 llvm::Value *Indices[] = {
2184 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2185 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2191 unsigned ComponentSize =
2192 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2193 unsigned VTableSize =
2196 llvm::ConstantRange InRange(
2197 llvm::APInt(32, (
int)-Offset,
true),
2198 llvm::APInt(32, (
int)(VTableSize - Offset),
true));
2199 return llvm::ConstantExpr::getGetElementPtr(
2200 VTable->getValueType(), VTable, Indices,
true, InRange);
2203llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2204 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
2205 const CXXRecordDecl *NearestVBase) {
2206 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2207 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2211 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
2215 if (VirtualPointerIndex)
2217 VirtualPointerIndex);
2234llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2235 CharUnits VPtrOffset) {
2236 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2238 llvm::GlobalVariable *&VTable = VTables[RD];
2243 CGM.addDeferredVTable(RD);
2245 SmallString<256> Name;
2246 llvm::raw_svector_ostream
Out(Name);
2247 getMangleContext().mangleCXXVTable(RD, Out);
2249 const VTableLayout &VTLayout =
2250 CGM.getItaniumVTableContext().getVTableLayout(RD);
2251 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2256 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2258 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2259 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2260 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2261 if (!CGM.shouldEmitRTTI())
2262 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2264 if (CGM.getTarget().hasPS4DLLImportExport())
2267 CGM.setGVProperties(VTable, RD);
2271CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
2275 SourceLocation Loc) {
2276 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2278 llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
2284 if (CGM.getLangOpts().OpenMPIsTargetDevice) {
2285 auto *NewPtrTy = CGM.VoidPtrTy;
2286 llvm::Type *RtlFnArgs[] = {NewPtrTy};
2287 llvm::FunctionCallee DeviceRtlFn = CGM.CreateRuntimeFunction(
2288 llvm::FunctionType::get(NewPtrTy, RtlFnArgs,
false),
2289 "__llvm_omp_indirect_call_lookup");
2290 auto *BackupTy = VTable->getType();
2298 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2299 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2300 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2302 llvm::Type *ComponentTy = CGM.getVTables().getVTableComponentType();
2304 VTableIndex * CGM.getDataLayout().getTypeSizeInBits(ComponentTy) / 8;
2312 llvm::Value *VFuncLoad;
2313 if (CGM.getLangOpts().RelativeCXXABIVTables) {
2314 VFuncLoad = CGF.
Builder.CreateCall(
2315 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2316 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, ByteOffset)});
2318 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2319 PtrTy, VTable, VTableIndex,
"vfn");
2330 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2331 CGM.getCodeGenOpts().StrictVTablePointers) {
2332 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2333 VFuncLoadInstr->setMetadata(
2334 llvm::LLVMContext::MD_invariant_load,
2335 llvm::MDNode::get(CGM.getLLVMContext(),
2336 llvm::ArrayRef<llvm::Metadata *>()));
2342 CGPointerAuthInfo PointerAuth;
2344 assert(VTableSlotPtr &&
"virtual function pointer not set");
2345 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2348 CGCallee
Callee(GD, VFunc, PointerAuth);
2352llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2353 CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
CXXDtorType DtorType,
2354 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
2355 auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
2356 auto *D = dyn_cast<const CXXDeleteExpr *>(E);
2357 assert((CE !=
nullptr) ^ (D !=
nullptr));
2358 assert(CE ==
nullptr || CE->arguments().empty());
2361 GlobalDecl GD(Dtor, DtorType);
2362 const CGFunctionInfo *FInfo =
2363 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2369 ThisTy = CE->getObjectType();
2371 ThisTy = D->getDestroyedType();
2375 nullptr, QualType(),
nullptr, CallOrInvoke);
2379void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2380 CodeGenVTables &VTables = CGM.getVTables();
2385bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2386 const CXXRecordDecl *RD)
const {
2389 if (CGM.getLangOpts().AppleKext)
2394 if (isVTableHidden(RD))
2397 if (CGM.getCodeGenOpts().ForceEmitVTables)
2414 if (hasAnyUnusedVirtualInlineFunction(RD))
2422 for (
const auto &B : RD->
bases()) {
2423 auto *BRD = B.getType()->getAsCXXRecordDecl();
2424 assert(BRD &&
"no class for base specifier");
2425 if (B.isVirtual() || !BRD->isDynamicClass())
2427 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2435bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2436 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2444 for (
const auto &B : RD->
vbases()) {
2445 auto *BRD = B.getType()->getAsCXXRecordDecl();
2446 assert(BRD &&
"no class for base specifier");
2447 if (!BRD->isDynamicClass())
2449 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2458 int64_t NonVirtualAdjustment,
2459 int64_t VirtualAdjustment,
2460 bool IsReturnAdjustment) {
2461 if (!NonVirtualAdjustment && !VirtualAdjustment)
2467 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2473 llvm::Value *ResultPtr;
2474 if (VirtualAdjustment) {
2475 llvm::Value *VTablePtr =
2478 llvm::Value *Offset;
2479 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2480 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2487 llvm::Type *PtrDiffTy =
2496 V.emitRawPointer(CGF), Offset);
2498 ResultPtr =
V.emitRawPointer(CGF);
2503 if (NonVirtualAdjustment && IsReturnAdjustment) {
2504 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2505 NonVirtualAdjustment);
2512ItaniumCXXABI::performThisAdjustment(CodeGenFunction &CGF, Address This,
2513 const CXXRecordDecl *UnadjustedClass,
2514 const ThunkInfo &TI) {
2521ItaniumCXXABI::performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
2522 const CXXRecordDecl *UnadjustedClass,
2523 const ReturnAdjustment &RA) {
2529void ARMCXXABI::EmitReturnFromThunk(CodeGenFunction &CGF,
2530 RValue RV, QualType ResultType) {
2532 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2536 RValue Undef =
RValue::get(llvm::UndefValue::get(T));
2537 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2542CharUnits ItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2546 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2549Address ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2551 llvm::Value *NumElements,
2552 const CXXNewExpr *
expr,
2553 QualType ElementType) {
2554 assert(requiresArrayCookie(
expr));
2558 ASTContext &Ctx = getContext();
2562 CharUnits CookieSize =
2564 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2568 CharUnits CookieOffset = CookieSize - SizeSize;
2569 if (!CookieOffset.
isZero())
2577 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2578 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2579 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2581 SI->setNoSanitizeMetadata();
2582 llvm::FunctionType *FTy =
2583 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2584 llvm::FunctionCallee F =
2585 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2594llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2596 CharUnits cookieSize) {
2598 Address numElementsPtr = allocPtr;
2599 CharUnits numElementsOffset = cookieSize - CGF.
getSizeSize();
2600 if (!numElementsOffset.
isZero())
2606 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2613 llvm::FunctionType *FTy =
2615 llvm::FunctionCallee F =
2616 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2620CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2630 CGM.getContext().getTypeAlignInChars(elementType));
2633Address ARMCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2635 llvm::Value *numElements,
2636 const CXXNewExpr *
expr,
2637 QualType elementType) {
2638 assert(requiresArrayCookie(
expr));
2645 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2646 getContext().getTypeSizeInChars(elementType).getQuantity());
2655 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2659llvm::Value *ARMCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2661 CharUnits cookieSize) {
2674 llvm::PointerType *GuardPtrTy) {
2676 llvm::FunctionType *FTy =
2680 FTy,
"__cxa_guard_acquire",
2682 llvm::AttributeList::FunctionIndex,
2683 llvm::Attribute::NoUnwind));
2687 llvm::PointerType *GuardPtrTy) {
2689 llvm::FunctionType *FTy =
2690 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2692 FTy,
"__cxa_guard_release",
2694 llvm::AttributeList::FunctionIndex,
2695 llvm::Attribute::NoUnwind));
2699 llvm::PointerType *GuardPtrTy) {
2701 llvm::FunctionType *FTy =
2702 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2704 FTy,
"__cxa_guard_abort",
2706 llvm::AttributeList::FunctionIndex,
2707 llvm::Attribute::NoUnwind));
2711 struct CallGuardAbort final : EHScopeStack::Cleanup {
2712 llvm::GlobalVariable *Guard;
2713 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2715 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2724void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
2726 llvm::GlobalVariable *var,
2727 bool shouldPerformInit) {
2728 CGBuilderTy &Builder = CGF.
Builder;
2732 bool NonTemplateInline =
2739 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2745 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2747 llvm::IntegerType *guardTy;
2748 CharUnits guardAlignment;
2749 if (useInt8GuardVariable) {
2755 if (UseARMGuardVarABI) {
2764 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2770 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2773 SmallString<256> guardName;
2775 llvm::raw_svector_ostream
out(guardName);
2776 getMangleContext().mangleStaticGuardVariable(&D,
out);
2782 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2783 false,
var->getLinkage(),
2784 llvm::ConstantInt::get(guardTy, 0),
2786 guard->setDSOLocal(
var->isDSOLocal());
2787 guard->setVisibility(
var->getVisibility());
2788 guard->setDLLStorageClass(
var->getDLLStorageClass());
2790 guard->setThreadLocalMode(
var->getThreadLocalMode());
2791 guard->setAlignment(guardAlignment.
getAsAlign());
2796 llvm::Comdat *
C =
var->getComdat();
2798 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2799 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2800 guard->setComdat(
C);
2801 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2802 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2805 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2808 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2833 if (!threadsafe || MaxInlineWidthInBits) {
2835 llvm::LoadInst *LI =
2845 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2868 (UseARMGuardVarABI && !useInt8GuardVariable)
2869 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2871 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2877 CodeGenFunction::GuardKind::VariableGuard, &D);
2905 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2906 InitBlock, EndBlock);
2916 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2934 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2943 llvm::FunctionCallee dtor,
2944 llvm::Constant *addr,
bool TLS) {
2946 "unexpected call to emitGlobalDtorWithCXAAtExit");
2948 "__cxa_atexit is disabled");
2949 const char *Name =
"__cxa_atexit";
2952 Name = T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2960 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2961 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2965 llvm::Constant *handle =
2968 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2971 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2972 llvm::FunctionType *atexitTy =
2973 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2977 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2978 fn->setDoesNotThrow();
2984 Context.getFunctionType(Context.VoidTy, {Context.VoidPtrTy}, EPI);
2985 llvm::Value *dtorCallee = dtor.getCallee();
2989 if (dtorCallee->getType()->getPointerAddressSpace() != AddrAS)
2997 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2999 llvm::Value *args[] = {dtorCallee, addr, handle};
3007 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3011 return GlobalInitOrCleanupFn;
3014void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
3015 for (
const auto &I : DtorsUsingAtExit) {
3016 int Priority = I.first;
3017 std::string GlobalCleanupFnName =
3018 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
3020 llvm::Function *GlobalCleanupFn =
3023 CodeGenFunction CGF(*
this);
3024 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalCleanupFn,
3025 getTypes().arrangeNullaryFunction(), FunctionArgList(),
3026 SourceLocation(), SourceLocation());
3030 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
3034 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3035 auto itv = Dtors.rbegin();
3036 while (itv != Dtors.rend()) {
3037 llvm::Function *Dtor = *itv;
3042 llvm::Value *NeedsDestruct =
3045 llvm::BasicBlock *DestructCallBlock =
3048 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
3051 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
3056 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
3058 CI->setCallingConv(Dtor->getCallingConv());
3066 AddGlobalDtor(GlobalCleanupFn, Priority);
3070void CodeGenModule::registerGlobalDtorsWithAtExit() {
3071 for (
const auto &I : DtorsUsingAtExit) {
3072 int Priority = I.first;
3073 std::string GlobalInitFnName =
3074 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
3075 llvm::Function *GlobalInitFn =
3078 CodeGenFunction CGF(*
this);
3079 CGF.
StartFunction(GlobalDecl(), getContext().VoidTy, GlobalInitFn,
3080 getTypes().arrangeNullaryFunction(), FunctionArgList(),
3081 SourceLocation(), SourceLocation());
3089 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3090 for (
auto *Dtor : Dtors) {
3093 if (getCodeGenOpts().CXAAtExit) {
3103 AddGlobalCtor(GlobalInitFn, Priority);
3106 if (getCXXABI().useSinitAndSterm())
3107 unregisterGlobalDtorsWithUnAtExit();
3111void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
3112 llvm::FunctionCallee dtor,
3113 llvm::Constant *addr) {
3118 if (CGM.getLangOpts().HLSL)
3119 return CGM.AddCXXDtorEntry(dtor, addr);
3133 if (CGM.getCodeGenOpts().CXAAtExit || D.
getTLSKind())
3138 if (CGM.getLangOpts().AppleKext) {
3140 return CGM.AddCXXDtorEntry(dtor, addr);
3148 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3158static llvm::GlobalValue::LinkageTypes
3160 llvm::GlobalValue::LinkageTypes VarLinkage =
3164 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3169 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3170 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3172 return llvm::GlobalValue::WeakODRLinkage;
3176ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3179 SmallString<256> WrapperName;
3181 llvm::raw_svector_ostream
Out(WrapperName);
3182 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3187 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3190 QualType RetQT = VD->
getType();
3194 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3195 getContext().getPointerType(RetQT), FunctionArgList());
3197 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3198 llvm::Function *Wrapper =
3200 WrapperName.str(), &CGM.getModule());
3202 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3203 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3205 CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, Wrapper,
false);
3208 if (!Wrapper->hasLocalLinkage())
3210 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3211 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3213 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
3216 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3217 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3220 ThreadWrappers.push_back({VD, Wrapper});
3224void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3225 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
3226 ArrayRef<llvm::Function *> CXXThreadLocalInits,
3227 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
3228 llvm::Function *InitFunc =
nullptr;
3232 llvm::SmallVector<llvm::Function *, 8> OrderedInits;
3233 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3234 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3237 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3238 CXXThreadLocalInits[I];
3240 OrderedInits.push_back(CXXThreadLocalInits[I]);
3243 if (!OrderedInits.empty()) {
3245 llvm::FunctionType *FTy =
3246 llvm::FunctionType::get(CGM.
VoidTy,
false);
3251 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3253 llvm::GlobalVariable::InternalLinkage,
3254 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3255 Guard->setThreadLocal(
true);
3259 Guard->setAlignment(GuardAlign.
getAsAlign());
3261 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(
3262 InitFunc, OrderedInits, ConstantAddress(Guard, CGM.
Int8Ty, GuardAlign));
3265 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3266 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3272 for (
const VarDecl *VD : CXXThreadLocals) {
3276 getOrCreateThreadLocalWrapper(VD, GV);
3281 for (
auto VDAndWrapper : ThreadWrappers) {
3282 const VarDecl *VD = VDAndWrapper.first;
3283 llvm::GlobalVariable *Var =
3285 llvm::Function *Wrapper = VDAndWrapper.second;
3292 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3298 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3299 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3305 SmallString<256> InitFnName;
3307 llvm::raw_svector_ostream
Out(InitFnName);
3308 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3311 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3316 llvm::GlobalValue *
Init =
nullptr;
3317 bool InitIsInitFunc =
false;
3318 bool HasConstantInitialization =
false;
3319 if (!usesThreadWrapperFunction(VD)) {
3320 HasConstantInitialization =
true;
3322 InitIsInitFunc =
true;
3323 llvm::Function *InitFuncToUse = InitFunc;
3327 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3334 Init = llvm::Function::Create(InitFnTy,
3335 llvm::GlobalVariable::ExternalWeakLinkage,
3343 Init->setVisibility(Var->getVisibility());
3345 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3346 Init->setDSOLocal(Var->isDSOLocal());
3349 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3357 isEmittedWithConstantInitializer(VD,
true) &&
3358 !mayNeedDestruction(VD)) {
3363 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3365 llvm::Function *
Func = llvm::Function::Create(
3366 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3372 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3373 CGBuilderTy Builder(CGM, Entry);
3374 Builder.CreateRetVoid();
3377 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3378 CGBuilderTy Builder(CGM, Entry);
3379 if (HasConstantInitialization) {
3381 }
else if (InitIsInitFunc) {
3383 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3385 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3386 llvm::Function *
Fn =
3388 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3399 Builder.CreateCall(InitFnTy,
Init);
3402 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3403 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3404 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3405 Builder.CreateCondBr(Have, InitBB, ExitBB);
3407 Builder.SetInsertPoint(InitBB);
3408 Builder.CreateCall(InitFnTy,
Init);
3409 Builder.CreateBr(ExitBB);
3411 Builder.SetInsertPoint(ExitBB);
3416 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3420 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3422 Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());
3424 Builder.CreateRet(Val);
3428LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
3430 QualType LValType) {
3432 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3434 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
3435 CallVal->setCallingConv(Wrapper->getCallingConv());
3449bool ItaniumCXXABI::NeedsVTTParameter(GlobalDecl GD) {
3468ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3469 SmallString<256> MethodName;
3470 llvm::raw_svector_ostream
Out(MethodName);
3471 getMangleContext().mangleCXXName(MD, Out);
3472 MethodName +=
"_vfpthunk_";
3473 StringRef ThunkName = MethodName.str();
3474 llvm::Function *ThunkFn;
3475 if ((ThunkFn = cast_or_null<llvm::Function>(
3476 CGM.
getModule().getNamedValue(ThunkName))))
3481 llvm::GlobalValue::LinkageTypes
Linkage =
3483 : llvm::GlobalValue::InternalLinkage;
3486 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3487 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
3488 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3494 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3495 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3496 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3499 CodeGenFunction CGF(CGM);
3500 CGF.
CurGD = GlobalDecl(MD);
3504 FunctionArgList FunctionArgs;
3508 FunctionArgs, MD->
getLocation(), SourceLocation());
3513 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3514 setCXXABIThisValue(CGF, ThisVal);
3516 CallArgList CallArgs;
3517 for (
const VarDecl *VD : FunctionArgs)
3520 const FunctionProtoType *FPT = MD->
getType()->
getAs<FunctionProtoType>();
3522 const CGFunctionInfo &CallInfo =
3525 getThisAddress(CGF), ThunkTy);
3526 llvm::CallBase *CallOrInvoke;
3527 CGF.
EmitCall(CallInfo, Callee, ReturnValueSlot(), CallArgs, &CallOrInvoke,
3528 true, SourceLocation(),
true);
3530 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3531 if (
Call->getType()->isVoidTy())
3544class ItaniumRTTIBuilder {
3546 llvm::LLVMContext &VMContext;
3547 const ItaniumCXXABI &
CXXABI;
3550 SmallVector<llvm::Constant *, 16> Fields;
3553 llvm::GlobalVariable *
3554 GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3558 llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
3561 void BuildVTablePointer(
const Type *Ty, llvm::Constant *StorageAddress);
3565 void BuildSIClassTypeInfo(
const CXXRecordDecl *RD);
3570 void BuildVMIClassTypeInfo(
const CXXRecordDecl *RD);
3574 void BuildPointerTypeInfo(QualType PointeeTy);
3578 void BuildObjCObjectTypeInfo(
const ObjCObjectType *Ty);
3582 void BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty);
3585 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3586 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3600 PTI_Incomplete = 0x8,
3604 PTI_ContainingClassIncomplete = 0x10,
3610 PTI_Noexcept = 0x40,
3616 VMI_NonDiamondRepeat = 0x1,
3619 VMI_DiamondShaped = 0x2
3633 llvm::Constant *BuildTypeInfo(QualType Ty);
3636 llvm::Constant *BuildTypeInfo(
3638 llvm::GlobalVariable::LinkageTypes
Linkage,
3639 llvm::GlobalValue::VisibilityTypes
Visibility,
3640 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3644llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3645 QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage) {
3646 SmallString<256> Name;
3647 llvm::raw_svector_ostream
Out(Name);
3653 llvm::Constant *
Init;
3656 SmallString<256> DualEncodedName;
3657 llvm::ConverterEBCDIC::convertToEBCDIC(Name.substr(4), DualEncodedName);
3658 DualEncodedName +=
'\0';
3659 DualEncodedName += Name.substr(4);
3660 Init = llvm::ConstantDataArray::getString(VMContext, DualEncodedName);
3662 Init = llvm::ConstantDataArray::getString(VMContext, Name.substr(4));
3669 GV->setInitializer(
Init);
3675ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
3677 SmallString<256> Name;
3678 llvm::raw_svector_ostream
Out(Name);
3682 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3689 GV =
new llvm::GlobalVariable(
3691 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3698 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3725 case BuiltinType::Void:
3726 case BuiltinType::NullPtr:
3727 case BuiltinType::Bool:
3728 case BuiltinType::WChar_S:
3729 case BuiltinType::WChar_U:
3730 case BuiltinType::Char_U:
3731 case BuiltinType::Char_S:
3732 case BuiltinType::UChar:
3733 case BuiltinType::SChar:
3734 case BuiltinType::Short:
3735 case BuiltinType::UShort:
3736 case BuiltinType::Int:
3737 case BuiltinType::UInt:
3738 case BuiltinType::Long:
3739 case BuiltinType::ULong:
3740 case BuiltinType::LongLong:
3741 case BuiltinType::ULongLong:
3742 case BuiltinType::Half:
3743 case BuiltinType::Float:
3744 case BuiltinType::Double:
3745 case BuiltinType::LongDouble:
3746 case BuiltinType::Float16:
3747 case BuiltinType::Float128:
3748 case BuiltinType::Ibm128:
3749 case BuiltinType::Char8:
3750 case BuiltinType::Char16:
3751 case BuiltinType::Char32:
3752 case BuiltinType::Int128:
3753 case BuiltinType::UInt128:
3756#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3757 case BuiltinType::Id:
3758#include "clang/Basic/OpenCLImageTypes.def"
3759#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3760 case BuiltinType::Id:
3761#include "clang/Basic/OpenCLExtensionTypes.def"
3762 case BuiltinType::OCLSampler:
3763 case BuiltinType::OCLEvent:
3764 case BuiltinType::OCLClkEvent:
3765 case BuiltinType::OCLQueue:
3766 case BuiltinType::OCLReserveID:
3767#define SVE_TYPE(Name, Id, SingletonId) \
3768 case BuiltinType::Id:
3769#include "clang/Basic/AArch64ACLETypes.def"
3770#define PPC_VECTOR_TYPE(Name, Id, Size) \
3771 case BuiltinType::Id:
3772#include "clang/Basic/PPCTypes.def"
3773#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3774#include "clang/Basic/RISCVVTypes.def"
3775#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3776#include "clang/Basic/WebAssemblyReferenceTypes.def"
3777#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
3778#include "clang/Basic/AMDGPUTypes.def"
3779#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3780#include "clang/Basic/HLSLIntangibleTypes.def"
3781 case BuiltinType::ShortAccum:
3782 case BuiltinType::Accum:
3783 case BuiltinType::LongAccum:
3784 case BuiltinType::UShortAccum:
3785 case BuiltinType::UAccum:
3786 case BuiltinType::ULongAccum:
3787 case BuiltinType::ShortFract:
3788 case BuiltinType::Fract:
3789 case BuiltinType::LongFract:
3790 case BuiltinType::UShortFract:
3791 case BuiltinType::UFract:
3792 case BuiltinType::ULongFract:
3793 case BuiltinType::SatShortAccum:
3794 case BuiltinType::SatAccum:
3795 case BuiltinType::SatLongAccum:
3796 case BuiltinType::SatUShortAccum:
3797 case BuiltinType::SatUAccum:
3798 case BuiltinType::SatULongAccum:
3799 case BuiltinType::SatShortFract:
3800 case BuiltinType::SatFract:
3801 case BuiltinType::SatLongFract:
3802 case BuiltinType::SatUShortFract:
3803 case BuiltinType::SatUFract:
3804 case BuiltinType::SatULongFract:
3805 case BuiltinType::BFloat16:
3808 case BuiltinType::Dependent:
3809#define BUILTIN_TYPE(Id, SingletonId)
3810#define PLACEHOLDER_TYPE(Id, SingletonId) \
3811 case BuiltinType::Id:
3812#include "clang/AST/BuiltinTypes.def"
3813 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3815 case BuiltinType::ObjCId:
3816 case BuiltinType::ObjCClass:
3817 case BuiltinType::ObjCSel:
3818 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3821 llvm_unreachable(
"Invalid BuiltinType Kind!");
3826 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3844 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3849 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3865 if (!Context.getLangOpts().RTTI)
return false;
3867 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3880 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3890 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3903 return !RecordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
3918 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3923 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3927 dyn_cast<MemberPointerType>(Ty)) {
3929 if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
3950 if (
Base->isVirtual())
3958 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
3959 if (!BaseDecl->isEmpty() &&
3966void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty,
3967 llvm::Constant *StorageAddress) {
3969 static const char *
const ClassTypeInfo =
3970 "_ZTVN10__cxxabiv117__class_type_infoE";
3972 static const char *
const SIClassTypeInfo =
3973 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3975 static const char *
const VMIClassTypeInfo =
3976 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3978 const char *VTableName =
nullptr;
3981#define TYPE(Class, Base)
3982#define ABSTRACT_TYPE(Class, Base)
3983#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3984#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3985#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3986#include "clang/AST/TypeNodes.inc"
3987 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3989 case Type::LValueReference:
3990 case Type::RValueReference:
3991 llvm_unreachable(
"References shouldn't get here");
3994 case Type::DeducedTemplateSpecialization:
3995 llvm_unreachable(
"Undeduced type shouldn't get here");
3998 llvm_unreachable(
"Pipe types shouldn't get here");
4000 case Type::ArrayParameter:
4001 llvm_unreachable(
"Array Parameter types should not get here.");
4005 case Type::OverflowBehavior:
4008 case Type::ExtVector:
4009 case Type::ConstantMatrix:
4013 case Type::BlockPointer:
4015 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
4018 case Type::ConstantArray:
4019 case Type::IncompleteArray:
4020 case Type::VariableArray:
4022 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
4025 case Type::FunctionNoProto:
4026 case Type::FunctionProto:
4028 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
4033 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
4036 case Type::Record: {
4038 ->getDefinitionOrSelf();
4041 VTableName = ClassTypeInfo;
4043 VTableName = SIClassTypeInfo;
4045 VTableName = VMIClassTypeInfo;
4051 case Type::ObjCObject:
4057 VTableName = ClassTypeInfo;
4064 case Type::ObjCInterface:
4066 VTableName = SIClassTypeInfo;
4068 VTableName = ClassTypeInfo;
4072 case Type::ObjCObjectPointer:
4075 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
4078 case Type::MemberPointer:
4080 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
4083 case Type::HLSLAttributedResource:
4084 case Type::HLSLInlineSpirv:
4085 llvm_unreachable(
"HLSL doesn't support virtual functions");
4088 llvm::Constant *VTable =
nullptr;
4092 VTable = CGM.
getModule().getNamedAlias(VTableName);
4095 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
4100 llvm::Type *PtrDiffTy =
4107 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
4108 VTable = llvm::ConstantExpr::getInBoundsPtrAdd(VTable, Eight);
4110 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
4111 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
4115 if (
const auto &Schema =
4119 Schema.isAddressDiscriminated() ? StorageAddress :
nullptr,
4120 GlobalDecl(), QualType(Ty, 0));
4122 Fields.push_back(VTable);
4139 return llvm::GlobalValue::InternalLinkage;
4143 llvm_unreachable(
"Linkage hasn't been computed!");
4148 return llvm::GlobalValue::InternalLinkage;
4156 return llvm::GlobalValue::LinkOnceODRLinkage;
4158 if (
const RecordType *
Record = dyn_cast<RecordType>(Ty)) {
4162 return llvm::GlobalValue::WeakODRLinkage;
4163 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4164 if (RD->
hasAttr<DLLImportAttr>() &&
4166 return llvm::GlobalValue::ExternalLinkage;
4173 return llvm::GlobalValue::LinkOnceODRLinkage;
4176 llvm_unreachable(
"Invalid linkage!");
4179llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty) {
4184 SmallString<256> Name;
4185 llvm::raw_svector_ostream
Out(Name);
4188 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4189 if (OldGV && !OldGV->isDeclaration()) {
4190 assert(!OldGV->hasAvailableExternallyLinkage() &&
4191 "available_externally typeinfos not yet implemented");
4199 return GetAddrOfExternalRTTIDescriptor(Ty);
4206 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4207 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4209 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
4211 ItaniumCXXABI::RUK_NonUniqueHidden)
4212 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
4216 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4217 llvm::GlobalValue::DefaultStorageClass;
4219 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4220 RD->
hasAttr<DLLExportAttr>()) ||
4222 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4223 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
4224 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4226 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass);
4229llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4231 llvm::GlobalVariable::LinkageTypes
Linkage,
4232 llvm::GlobalValue::VisibilityTypes
Visibility,
4233 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4234 SmallString<256> Name;
4235 llvm::raw_svector_ostream
Out(Name);
4238 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4240 llvm::GlobalVariable *GV =
4249 llvm::Constant *TypeNameField;
4253 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4255 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4258 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4259 llvm::Constant *flag =
4260 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
4261 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4267 Fields.push_back(TypeNameField);
4270#define TYPE(Class, Base)
4271#define ABSTRACT_TYPE(Class, Base)
4272#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4273#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4274#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4275#include "clang/AST/TypeNodes.inc"
4276 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4281 case Type::ExtVector:
4282 case Type::ConstantMatrix:
4284 case Type::BlockPointer:
4289 case Type::LValueReference:
4290 case Type::RValueReference:
4291 llvm_unreachable(
"References shouldn't get here");
4294 case Type::DeducedTemplateSpecialization:
4295 llvm_unreachable(
"Undeduced type shouldn't get here");
4303 case Type::ConstantArray:
4304 case Type::IncompleteArray:
4305 case Type::VariableArray:
4306 case Type::ArrayParameter:
4311 case Type::FunctionNoProto:
4312 case Type::FunctionProto:
4322 case Type::Record: {
4324 ->getDefinitionOrSelf();
4331 BuildSIClassTypeInfo(RD);
4333 BuildVMIClassTypeInfo(RD);
4338 case Type::ObjCObject:
4339 case Type::ObjCInterface:
4343 case Type::ObjCObjectPointer:
4351 case Type::MemberPointer:
4359 case Type::OverflowBehavior:
4362 case Type::HLSLAttributedResource:
4363 case Type::HLSLInlineSpirv:
4364 llvm_unreachable(
"HLSL doesn't support RTTI");
4367 GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));
4370 auto GVDLLStorageClass = DLLStorageClass;
4372 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
4373 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
4376 if (RD->
hasAttr<DLLExportAttr>() ||
4378 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
4384 GV->takeName(OldGV);
4385 OldGV->replaceAllUsesWith(GV);
4386 OldGV->eraseFromParent();
4390 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4417 TypeName->setDLLStorageClass(DLLStorageClass);
4418 GV->setDLLStorageClass(GVDLLStorageClass);
4428void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4430 const Type *T = OT->getBaseType().getTypePtr();
4438 ObjCInterfaceDecl *Super =
Class->getSuperClass();
4446 llvm::Constant *BaseTypeInfo =
4447 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4448 Fields.push_back(BaseTypeInfo);
4453void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4457 llvm::Constant *BaseTypeInfo =
4459 Fields.push_back(BaseTypeInfo);
4466 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
4467 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
4479 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
4480 if (
Base->isVirtual()) {
4482 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4485 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4487 if (Bases.NonVirtualBases.count(BaseDecl))
4488 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4492 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4495 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4497 if (Bases.VirtualBases.count(BaseDecl))
4498 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4503 for (
const auto &I : BaseDecl->bases())
4514 for (
const auto &I : RD->
bases())
4523void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4524 llvm::Type *UnsignedIntLTy =
4532 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4537 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4570 llvm::Type *OffsetFlagsLTy =
4573 for (
const auto &Base : RD->
bases()) {
4575 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4577 auto *BaseDecl =
Base.getType()->castAsCXXRecordDecl();
4585 if (
Base.isVirtual())
4597 if (
Base.isVirtual())
4598 OffsetFlags |= BCTI_Virtual;
4600 OffsetFlags |= BCTI_Public;
4602 Fields.push_back(llvm::ConstantInt::getSigned(OffsetFlagsLTy, OffsetFlags));
4611 if (
Type.isConstQualified())
4612 Flags |= ItaniumRTTIBuilder::PTI_Const;
4613 if (
Type.isVolatileQualified())
4614 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4615 if (
Type.isRestrictQualified())
4616 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4623 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4626 if (Proto->isNothrow()) {
4627 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4637void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
4643 llvm::Type *UnsignedIntLTy =
4645 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4650 llvm::Constant *PointeeTypeInfo =
4651 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4652 Fields.push_back(PointeeTypeInfo);
4658ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(
const MemberPointerType *Ty) {
4668 Flags |= PTI_ContainingClassIncomplete;
4670 llvm::Type *UnsignedIntLTy =
4672 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4677 llvm::Constant *PointeeTypeInfo =
4678 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4679 Fields.push_back(PointeeTypeInfo);
4686 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(T));
4689llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
4690 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4693void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4695 QualType FundamentalTypes[] = {
4696 getContext().VoidTy, getContext().NullPtrTy,
4697 getContext().BoolTy, getContext().WCharTy,
4698 getContext().CharTy, getContext().UnsignedCharTy,
4699 getContext().SignedCharTy, getContext().ShortTy,
4700 getContext().UnsignedShortTy, getContext().IntTy,
4701 getContext().UnsignedIntTy, getContext().LongTy,
4702 getContext().UnsignedLongTy, getContext().LongLongTy,
4703 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4704 getContext().UnsignedInt128Ty, getContext().HalfTy,
4705 getContext().FloatTy, getContext().DoubleTy,
4706 getContext().LongDoubleTy, getContext().Float128Ty,
4707 getContext().Char8Ty, getContext().Char16Ty,
4708 getContext().Char32Ty
4710 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4712 ? llvm::GlobalValue::DLLExportStorageClass
4713 : llvm::GlobalValue::DefaultStorageClass;
4714 llvm::GlobalValue::VisibilityTypes
Visibility =
4716 for (
const QualType &FundamentalType : FundamentalTypes) {
4717 QualType PointerType = getContext().getPointerType(FundamentalType);
4718 QualType PointerTypeConst = getContext().getPointerType(
4719 FundamentalType.withConst());
4720 for (QualType
Type : {FundamentalType, PointerType, PointerTypeConst})
4721 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4722 Type, llvm::GlobalValue::ExternalLinkage,
4729ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4730 QualType CanTy, llvm::GlobalValue::LinkageTypes
Linkage)
const {
4731 if (shouldRTTIBeUnique())
4735 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4736 Linkage != llvm::GlobalValue::WeakODRLinkage)
4744 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4745 return RUK_NonUniqueHidden;
4750 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4751 return RUK_NonUniqueVisible;
4756enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4761 return StructorCodegen::Emit;
4766 return StructorCodegen::Emit;
4769 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4777 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4778 return StructorCodegen::RAUW;
4781 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4782 return StructorCodegen::RAUW;
4784 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4788 return StructorCodegen::COMDAT;
4789 return StructorCodegen::Emit;
4792 return StructorCodegen::Alias;
4802 if (Entry && !Entry->isDeclaration())
4808 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4811 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4815 assert(Entry->getType() == Aliasee->getType() &&
4816 "declaration exists with different type");
4817 Alias->takeName(Entry);
4818 Entry->replaceAllUsesWith(Alias);
4819 Entry->eraseFromParent();
4821 Alias->setName(MangledName);
4828void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
4830 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4837 GlobalDecl BaseDecl;
4843 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4848 if (CGType == StructorCodegen::RAUW) {
4861 CGType != StructorCodegen::COMDAT &&
4879 if (CGType == StructorCodegen::COMDAT) {
4880 SmallString<256> Buffer;
4881 llvm::raw_svector_ostream
Out(Buffer);
4883 getMangleContext().mangleCXXDtorComdat(DD, Out);
4885 getMangleContext().mangleCXXCtorComdat(CD, Out);
4886 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(
Out.str());
4895 llvm::FunctionType *FTy = llvm::FunctionType::get(
4903 llvm::FunctionType *FTy =
4904 llvm::FunctionType::get(CGM.
VoidTy,
false);
4911 llvm::FunctionType *FTy = llvm::FunctionType::get(
4930 struct CallEndCatch final : EHScopeStack::Cleanup {
4931 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4934 void Emit(CodeGenFunction &CGF, Flags flags)
override {
4953 bool EndMightThrow) {
4954 llvm::CallInst *call =
4957 CGF.
EHStack.pushCleanup<CallEndCatch>(
4959 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4984 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4989 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4998 unsigned HeaderSize =
5001 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
5024 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
5032 llvm::Value *ExnCast =
5033 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
5045 if (CatchType->hasPointerRepresentation()) {
5046 llvm::Value *CastExn =
5047 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
5064 llvm_unreachable(
"bad ownership qualifier!");
5082 llvm_unreachable(
"evaluation kind filtered out!");
5084 llvm_unreachable(
"bad evaluation kind");
5088 auto catchRD = CatchType->getAsCXXRecordDecl();
5098 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5099 LLVMCatchTy, caughtExnAlignment);
5108 llvm::CallInst *rawAdjustedExn =
5112 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5113 LLVMCatchTy, caughtExnAlignment);
5144void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5145 const CXXCatchStmt *S) {
5192 C.VoidTy, {C.getPointerType(C.CharTy)});
5195 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5196 llvm::Function *fn =
5201 fn->setDoesNotThrow();
5202 fn->setDoesNotReturn();
5207 fn->addFnAttr(llvm::Attribute::NoInline);
5211 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5212 fn->setVisibility(llvm::Function::HiddenVisibility);
5214 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5217 llvm::BasicBlock *entry =
5222 llvm::Value *exn = &*fn->arg_begin();
5225 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5226 catchCall->setDoesNotThrow();
5230 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5231 termCall->setDoesNotThrow();
5232 termCall->setDoesNotReturn();
5236 builder.CreateUnreachable();
5242ItaniumCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5252std::pair<llvm::Value *, const CXXRecordDecl *>
5253ItaniumCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
5254 const CXXRecordDecl *RD) {
5259ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5260 const CXXMethodDecl *origMD =
5264 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5270void WebAssemblyCXXABI::emitBeginCatch(CodeGenFunction &CGF,
5271 const CXXCatchStmt *
C) {
5273 CGF.
EHStack.pushCleanup<CatchRetScope>(
5275 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5279WebAssemblyCXXABI::emitTerminateForUnexpectedException(CodeGenFunction &CGF,
5296void XLCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
5297 llvm::FunctionCallee Dtor,
5298 llvm::Constant *
Addr) {
5303 llvm::FunctionType *AtExitTy =
5304 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5307 llvm::FunctionCallee
AtExit =
5315 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5323 llvm::Function *DtorStub =
5331 emitCXXStermFinalizer(D, DtorStub,
Addr);
5334void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
5335 llvm::Constant *addr) {
5336 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5337 SmallString<256> FnName;
5339 llvm::raw_svector_ostream
Out(FnName);
5340 getMangleContext().mangleDynamicStermFinalizer(&D, Out);
5348 CodeGenFunction CGF(CGM);
5362 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5367 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5372 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5375 CI->setCallingConv(dtorStub->getCallingConv());
5381 if (
auto *IPA = D.
getAttr<InitPriorityAttr>()) {
5383 IPA->getPriority());
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static CharUnits computeOffsetHint(ASTContext &astContext, const CXXRecordDecl *src, const CXXRecordDecl *dst)
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, QualType ty)
Return the linkage that the type info and type info name constants should have for the given type.
static mlir::Value performTypeAdjustment(CIRGenFunction &cgf, Address initialPtr, const CXXRecordDecl *unadjustedClass, int64_t nonVirtualAdjustment, int64_t virtualAdjustment, bool isReturnAdjustment)
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
static RValue performReturnAdjustment(CIRGenFunction &cgf, QualType resultType, RValue rv, const ThunkInfo &thunk)
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void @__clang_call_terminate(i8* exn) nounwind noreturn This co...
static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD)
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF)
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::FunctionCallee dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM)
static llvm::Constant * pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType, QualType SrcType, CodeGenModule &CGM)
static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static llvm::Function * createGlobalInitOrCleanupFn(CodeGen::CodeGenModule &CGM, StringRef FnName)
static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM)
static bool IsStandardLibraryRTTIDescriptor(QualType Ty)
IsStandardLibraryRTTIDescriptor - Returns whether the type information for the given type exists in t...
static llvm::Value * CallBeginCatch(CodeGenFunction &CGF, llvm::Value *Exn, bool EndMightThrow)
Emits a call to __cxa_begin_catch and enters a cleanup to call __cxa_end_catch.
static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static void InitCatchParam(CodeGenFunction &CGF, const VarDecl &CatchParam, Address ParamAddr, SourceLocation Loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty)
TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type info for that type is de...
static bool CanUseSingleInheritance(const CXXRecordDecl *RD)
static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM)
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void setVTableSelectiveDLLImportExport(CodeGenModule &CGM, llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static bool ContainsIncompleteClassType(QualType Ty)
ContainsIncompleteClassType - Returns whether the given type contains an incomplete class type.
static llvm::Constant * pointerAuthResignConstant(llvm::Value *Ptr, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, CodeGenModule &CGM)
static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM)
static void dtorTy(Block *, std::byte *Ptr, const Descriptor *)
Result
Implement __builtin_bit_cast and related operations.
static cir::GlobalLinkageKind getThreadLocalWrapperLinkage(GlobalOp op, clang::ASTContext &astCtx)
static bool isThreadWrapperReplaceable(cir::TLS_Model tls, clang::ASTContext &astCtx)
llvm::MachO::Record Record
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D)
Determine what kind of template specialization the given declaration is.
static QualType getPointeeType(const MemRegion *R)
#define CXXABI(Name, Str)
C Language Family Type Representation.
a trap message and trap category.
const ValueDecl * getMemberPointerDecl() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
This class is used for builtin types like 'int'.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Represents a C++ struct/union/class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
const Expr * getSubExpr() const
static CanQual< Type > CreateUnsafe(QualType Other)
Qualifiers getQualifiers() const
Retrieve all qualifiers.
CastKind getCastKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
std::string SymbolPartition
The name of the partition that symbols are assigned to, specified with -fsymbol-partition (see https:...
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
unsigned getAddressSpace() const
Return the address space that this address resides in.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ... produce name = getelementptr inbounds addr, i64 index where i64 is actually the t...
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual llvm::CallInst * emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn)
MangleContext & getMangleContext()
Gets the mangle context.
All available information about a concrete callee.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
llvm::Value * getDiscriminator() const
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass, VTableAuthMode AuthMode=VTableAuthMode::Authenticate)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
llvm::Function * createTLSAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr, llvm::FunctionCallee &AtExit)
Create a stub function, suitable for being passed to __pt_atexit_np, which passes the given address t...
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitARCInitWeak(Address addr, llvm::Value *value)
i8* @objc_initWeak(i8** addr, i8* value) Returns value.
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
llvm::Type * ConvertType(QualType T)
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void EmitAnyExprToExn(const Expr *E, Address Addr)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
const TargetInfo & getTarget() const
CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, const CXXRecordDecl *RD)
BuildVirtualCall - This routine makes indirect vtable call for call to virtual destructors.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, llvm::BasicBlock *InitBlock, llvm::BasicBlock *NoInitBlock, GuardKind Kind, const VarDecl *D)
Emit a branch to select whether or not to perform guarded initialization.
CGDebugInfo * getDebugInfo()
LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source=AlignmentSource::Type)
Same as MakeAddrLValue above except that the pointer is known to be unsigned.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Emit the concrete pointer authentication informaton for the given authentication schema.
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
llvm::Value * unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub)
Call unatexit() with function dtorStub.
llvm::Value * emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void registerGlobalDtorWithLLVM(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Registers the dtor using 'llvm.global_dtors' for platforms that do not support an 'atexit()' function...
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
llvm::Type * ConvertTypeForMem(QualType T)
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Instruction * CurrentFuncletPad
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::LLVMContext & getLLVMContext()
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
This class organizes the cross-function state that is used while generating LLVM code.
void AddCXXPrioritizedStermFinalizerEntry(llvm::Function *StermFinalizer, int Priority)
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
void AddCXXStermFinalizerToGlobalDtor(llvm::Function *StermFinalizer, int Priority)
Add an sterm finalizer to its own llvm.global_dtors entry.
llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const
Get LLVM TLS mode from CodeGenOptions.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenVTables & getVTables()
void AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn)
Add an sterm finalizer to the C++ global cleanup function.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
llvm::Constant * getFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return the ABI-correct function pointer value for a reference to the given function.
CGPointerAuthInfo getMemberFunctionPointerAuthInfo(QualType FT)
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const
const TargetInfo & getTarget() const
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD)
Returns LLVM linkage for a declarator.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V)
llvm::Constant * getMemberFunctionPointer(const FunctionDecl *FD, llvm::Type *Ty=nullptr)
llvm::Function * codegenCXXStructor(GlobalDecl GD)
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const llvm::Triple & getTriple() const
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD)
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, const CXXRecordDecl *Class, CharUnits ExpectedTargetAlign)
Given a class pointer with an actual known alignment, and the expected alignment of an object at a dy...
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
ItaniumVTableContext & getItaniumVTableContext()
ASTContext & getContext() const
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
bool supportsCOMDAT() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, llvm::Align Alignment)
Will return a global variable of the given type.
llvm::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
llvm::LLVMContext & getLLVMContext()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void addReplacement(StringRef Name, llvm::Constant *C)
llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Sign a constant pointer using the given scheme, producing a constant with the same IR type.
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Function * CreateGlobalInitOrCleanUpFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false, llvm::GlobalVariable::LinkageTypes Linkage=llvm::GlobalVariable::InternalLinkage)
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CGFunctionInfo & 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, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
GlobalDecl findOriginalMethod(GlobalDecl GD)
Return the method that added the v-table slot that will be used to call the given method.
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
bool isExternallyVisible() const
static const OpaqueValueExpr * findInCopyConstruct(const Expr *expr)
Given an expression which invokes a copy constructor — i.e.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
Encodes a location in the source.
SourceLocation getBeginLoc() const LLVM_READONLY
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getMaxAtomicInlineWidth() const
Return the maximum width lock-free atomic operation which can be inlined given the supported features...
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool hasPS4DLLImportExport() const
uint64_t getPointerAlign(LangAS AddrSpace) const
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Visibility getVisibility() const
Determine the visibility of this type.
bool isMemberFunctionPointerType() const
Linkage getLinkage() const
Determine the linkage of this type.
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
AddressPointLocation getAddressPoint(BaseSubobject Base) const
size_t getVTableSize(size_t i) const
Represents a variable declaration or definition.
TLSKind getTLSKind() const
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isInline() const
Whether this variable is (C++1z) inline.
const Expr * getInit() const
@ TLS_Dynamic
TLS with a dynamic initializer.
@ TLS_None
Not a TLS variable.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
CGCXXABI * CreateItaniumCXXABI(CodeGenModule &CGM)
Creates an Itanium-family ABI.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
constexpr Variable var(Literal L)
Returns the variable of L.
bool This(InterpState &S, CodePtr OpPC)
@ Address
A pointer to a ValueDecl.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
@ Ctor_Comdat
The COMDAT used for ctors.
@ Ctor_Unified
GCC-style unified dtor.
bool isa(CodeGen::Address addr)
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
@ Success
Annotation was successful.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ VisibleNone
No linkage according to the standard, but is visible from other translation units because of types de...
@ None
No linkage, which means that the entity is unique and can only be referred to from within its scope.
@ UniqueExternal
External linkage within a unique namespace.
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
CXXDtorType
C++ destructor types.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
bool isDiscardableGVALinkage(GVALinkage L)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ EST_None
no exception specification
Visibility
Describes the different kinds of visibility that a declaration may have.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
Represents an element in a path from a derived class to a base class.
const CXXRecordDecl * NearestVBase
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
llvm::PointerType * GlobalsVoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * CharTy
char
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * SizeTy
llvm::PointerType * VoidPtrPtrTy
llvm::PointerType * GlobalsInt8PtrTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
CharUnits getSizeSize() const
CharUnits getSizeAlign() const
llvm::PointerType * Int8PtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
llvm::PointerType * DefaultPtrTy
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
Extra information about a function prototype.
PointerAuthSchema CXXVTTVTablePointers
The ABI for C++ virtual table pointers as installed in a VTT.
PointerAuthSchema CXXTypeInfoVTablePointer
TypeInfo has external ABI requirements and is emitted without actually having parsed the libcxx defin...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@103031170252120233124322035264172076254313213024 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@106065375072164260365214033034320247050276346205 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.