32#include "llvm/IR/DataLayout.h"
33#include "llvm/IR/GlobalValue.h"
34#include "llvm/IR/Instructions.h"
35#include "llvm/IR/Intrinsics.h"
36#include "llvm/IR/Value.h"
37#include "llvm/Support/ScopedPrinter.h"
42using namespace CodeGen;
47 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
54 bool UseARMMethodPtrABI;
55 bool UseARMGuardVarABI;
56 bool Use32BitVTableOffsetABI;
64 bool UseARMMethodPtrABI =
false,
65 bool UseARMGuardVarABI =
false) :
66 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
67 UseARMGuardVarABI(UseARMGuardVarABI),
68 Use32BitVTableOffsetABI(
false) { }
82 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
92 llvm_unreachable(
"emitting dtor comdat as function?");
94 llvm_unreachable(
"bad dtor kind");
96 if (isa<CXXConstructorDecl>(GD.
getDecl())) {
106 llvm_unreachable(
"closure ctors in Itanium ABI?");
109 llvm_unreachable(
"emitting ctor comdat as function?");
111 llvm_unreachable(
"bad dtor kind");
126 llvm::Value *&ThisPtrForCall,
127 llvm::Value *MemFnPtr,
138 llvm::Value *Src)
override;
140 llvm::Constant *Src)
override;
152 llvm::Value *L, llvm::Value *R,
154 bool Inequality)
override;
171 llvm::Value *Exn)
override;
173 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
177 QualType CatchHandlerType)
override {
185 llvm::Type *StdTypeInfoPtrTy)
override;
194 bool hasUniqueVTablePointer(
QualType RecordTy) {
199 if (!CGM.getCodeGenOpts().AssumeUniqueVTables ||
200 getContext().getLangOpts().AppleKext)
205 if (!CGM.shouldEmitRTTI())
210 if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))
219 llvm::GlobalValue::DefaultVisibility)
226 return hasUniqueVTablePointer(DestRecordTy);
232 llvm::BasicBlock *CastEnd)
override;
237 llvm::BasicBlock *CastSuccess,
238 llvm::BasicBlock *CastFail)
override;
252 AddedStructorArgCounts
292 CodeGenFunction::VPtr Vptr)
override;
306 llvm::Value *getVTableAddressPointInStructorWithVTT(
320 DeleteOrMemberCallExpr
E,
321 llvm::CallBase **CallOrInvoke)
override;
326 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
332 if (ForVTable && !Thunk->hasLocalLinkage())
333 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
334 CGM.setGVProperties(Thunk, GD);
349 assert(!Args.empty() &&
"expected the arglist to not be empty!");
350 return Args.size() - 1;
355 {
return "__cxa_deleted_virtual"; }
360 llvm::Value *NumElements,
368 llvm::GlobalVariable *DeclPtr,
369 bool PerformInit)
override;
371 llvm::FunctionCallee dtor,
372 llvm::Constant *addr)
override;
374 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
392 getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
399 virtual bool shouldRTTIBeUnique()
const {
return true; }
403 enum RTTIUniquenessKind {
421 classifyRTTIUniqueness(
QualType CanTy,
422 llvm::GlobalValue::LinkageTypes
Linkage)
const;
423 friend class ItaniumRTTIBuilder;
427 std::pair<llvm::Value *, const CXXRecordDecl *>
433 getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
435 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
436 const auto &VtableLayout =
437 CGM.getItaniumVTableContext().getVTableLayout(RD);
439 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
441 if (!VtableComponent.isUsedFunctionPointerKind())
444 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
446 const bool IsInlined =
451 StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
452 auto *Entry = CGM.GetGlobalValue(Name);
458 if (!Entry || Entry->isDeclaration())
465 const auto &VtableLayout =
466 CGM.getItaniumVTableContext().getVTableLayout(RD);
468 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
469 if (VtableComponent.isRTTIKind()) {
470 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
471 if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
473 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
474 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
475 if (Method->
getVisibility() == Visibility::HiddenVisibility &&
484class ARMCXXABI :
public ItaniumCXXABI {
487 ItaniumCXXABI(CGM,
true,
490 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
498 llvm::Value *NumElements,
505class AppleARM64CXXABI :
public ARMCXXABI {
508 Use32BitVTableOffsetABI =
true;
512 bool shouldRTTIBeUnique()
const override {
return false; }
515class FuchsiaCXXABI final :
public ItaniumCXXABI {
518 : ItaniumCXXABI(CGM) {}
521 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
524class WebAssemblyCXXABI final :
public ItaniumCXXABI {
527 : ItaniumCXXABI(CGM,
true,
532 llvm::Value *Exn)
override;
535 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
536 bool canCallMismatchedFunctionType()
const override {
return false; }
539class XLCXXABI final :
public ItaniumCXXABI {
542 : ItaniumCXXABI(CGM) {}
545 llvm::FunctionCallee dtor,
546 llvm::Constant *addr)
override;
548 bool useSinitAndSterm()
const override {
return true; }
551 void emitCXXStermFinalizer(
const VarDecl &
D, llvm::Function *dtorStub,
552 llvm::Constant *addr);
560 case TargetCXXABI::GenericARM:
561 case TargetCXXABI::iOS:
562 case TargetCXXABI::WatchOS:
563 return new ARMCXXABI(CGM);
565 case TargetCXXABI::AppleARM64:
566 return new AppleARM64CXXABI(CGM);
568 case TargetCXXABI::Fuchsia:
569 return new FuchsiaCXXABI(CGM);
574 case TargetCXXABI::GenericAArch64:
575 return new ItaniumCXXABI(CGM,
true,
578 case TargetCXXABI::GenericMIPS:
579 return new ItaniumCXXABI(CGM,
true);
581 case TargetCXXABI::WebAssembly:
582 return new WebAssemblyCXXABI(CGM);
584 case TargetCXXABI::XL:
585 return new XLCXXABI(CGM);
587 case TargetCXXABI::GenericItanium:
588 return new ItaniumCXXABI(CGM);
590 case TargetCXXABI::Microsoft:
591 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
593 llvm_unreachable(
"bad ABI kind");
599 return CGM.PtrDiffTy;
600 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
623CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
625 llvm::Value *&ThisPtrForCall,
634 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
641 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
644 llvm::Value *Adj = RawAdj;
645 if (UseARMMethodPtrABI)
646 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
651 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(), This, Adj);
652 ThisPtrForCall = This;
655 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
659 llvm::Value *IsVirtual;
660 if (UseARMMethodPtrABI)
661 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
663 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
664 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
665 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
683 llvm::Value *VTableOffset = FnAsInt;
684 if (!UseARMMethodPtrABI)
685 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
686 if (Use32BitVTableOffsetABI) {
687 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
688 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
693 llvm::Constant *CheckSourceLocation;
694 llvm::Constant *CheckTypeDesc;
695 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
696 CGM.HasHiddenLTOVisibility(RD);
697 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
698 CGM.HasHiddenLTOVisibility(RD);
699 bool ShouldEmitWPDInfo =
700 CGM.getCodeGenOpts().WholeProgramVTables &&
702 !CGM.AlwaysHasLTOVisibilityPublic(RD);
703 llvm::Value *VirtualFn =
nullptr;
706 CodeGenFunction::SanitizerScope SanScope(&CGF);
707 llvm::Value *TypeId =
nullptr;
708 llvm::Value *CheckResult =
nullptr;
710 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
714 CGM.CreateMetadataIdentifierForVirtualMemPtrType(
QualType(MPT, 0));
718 if (ShouldEmitVFEInfo) {
719 llvm::Value *VFPAddr =
720 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
727 llvm::Value *CheckedLoad = Builder.CreateCall(
728 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
729 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
730 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
731 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
735 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
736 llvm::Value *VFPAddr =
737 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
738 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
739 ? llvm::Intrinsic::type_test
740 : llvm::Intrinsic::public_type_test;
743 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
746 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
747 VirtualFn = CGF.
Builder.CreateCall(
748 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
749 {VTableOffset->getType()}),
750 {VTable, VTableOffset});
752 llvm::Value *VFPAddr =
759 assert(VirtualFn &&
"Virtual fuction pointer not created!");
760 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
762 "Check result required but not created!");
764 if (ShouldEmitCFICheck) {
768 llvm::Constant *StaticData[] = {
769 llvm::ConstantInt::get(CGF.
Int8Ty, CodeGenFunction::CFITCK_VMFCall),
774 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
775 CGF.
EmitTrapCheck(CheckResult, SanitizerHandler::CFICheckFail);
777 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
778 CGM.getLLVMContext(),
779 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
780 llvm::Value *ValidVtable = Builder.CreateCall(
781 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
782 CGF.
EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIMFCall),
783 SanitizerHandler::CFICheckFail, StaticData,
784 {VTable, ValidVtable});
787 FnVirtual = Builder.GetInsertBlock();
796 llvm::Value *NonVirtualFn =
797 Builder.CreateIntToPtr(FnAsInt, CGF.
UnqualPtrTy,
"memptr.nonvirtualfn");
800 if (ShouldEmitCFICheck) {
803 CodeGenFunction::SanitizerScope SanScope(&CGF);
805 llvm::Constant *StaticData[] = {
806 llvm::ConstantInt::get(CGF.
Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
811 llvm::Value *Bit = Builder.getFalse();
813 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
814 getContext().getMemberPointerType(
817 llvm::Value *TypeId =
820 llvm::Value *TypeTest =
821 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
822 {NonVirtualFn, TypeId});
823 Bit = Builder.CreateOr(Bit, TypeTest);
826 CGF.
EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
827 SanitizerHandler::CFICheckFail, StaticData,
828 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
830 FnNonVirtual = Builder.GetInsertBlock();
836 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
UnqualPtrTy, 2);
837 CalleePtr->addIncoming(VirtualFn, FnVirtual);
838 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
842 if (
const auto &Schema =
843 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
844 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
845 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
847 const auto &AuthInfo =
848 CGM.getMemberFunctionPointerAuthInfo(
QualType(MPT, 0));
849 assert(Schema.getKey() == AuthInfo.getKey() &&
850 "Keys for virtual and non-virtual member functions must match");
851 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
852 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
854 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
855 Schema.authenticatesNullValues(), DiscriminatorPHI);
864llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
867 assert(MemPtr->getType() == CGM.PtrDiffTy);
872 return Builder.CreateInBoundsGEP(CGF.
Int8Ty,
Base.emitRawPointer(CGF), MemPtr,
880 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
885 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
886 CPA->getAddrDiscriminator()->isZeroValue() &&
888 "unexpected key or discriminators");
891 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
923 if (isa<llvm::Constant>(src))
924 return EmitMemberPointerConversion(
E, cast<llvm::Constant>(src));
926 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
927 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
928 E->getCastKind() == CK_ReinterpretMemberPointer);
934 if (
const auto &NewAuthInfo =
935 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
938 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
939 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
940 llvm::Type *OrigTy = MemFnPtr->getType();
942 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
947 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
948 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
949 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
950 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
951 llvm::Value *IsVirtualOffset =
952 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
953 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
956 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.Int8Ty);
957 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
960 isa<llvm::Constant>(src));
961 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
962 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
963 ResignBB = Builder.GetInsertBlock();
966 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
967 NewSrc->addIncoming(src, StartBB);
968 NewSrc->addIncoming(ResignedVal, ResignBB);
974 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
976 llvm::Constant *adj = getMemberPointerAdjustment(
E);
977 if (!adj)
return src;
979 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
989 dst = Builder.CreateNSWSub(src, adj,
"adj");
991 dst = Builder.CreateNSWAdd(src, adj,
"adj");
994 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
995 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
996 return Builder.CreateSelect(isNull, src, dst);
1000 if (UseARMMethodPtrABI) {
1001 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1003 adj = llvm::ConstantInt::get(adj->getType(), offset);
1006 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1007 llvm::Value *dstAdj;
1008 if (isDerivedToBase)
1009 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1011 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1013 return Builder.CreateInsertValue(src, dstAdj, 1);
1016static llvm::Constant *
1021 "member function pointers expected");
1022 if (DestType == SrcType)
1028 if (!NewAuthInfo && !CurAuthInfo)
1031 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1032 if (MemFnPtr->getNumOperands() == 0) {
1034 assert(isa<llvm::ConstantInt>(MemFnPtr) &&
"constant int expected");
1039 cast<llvm::User>(MemFnPtr)->getOperand(0), CurAuthInfo, NewAuthInfo, CGM);
1040 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1041 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1045ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *
E,
1046 llvm::Constant *src) {
1047 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
1048 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
1049 E->getCastKind() == CK_ReinterpretMemberPointer);
1055 src, DstType,
E->getSubExpr()->
getType(), CGM);
1058 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
1061 llvm::Constant *adj = getMemberPointerAdjustment(
E);
1062 if (!adj)
return src;
1064 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
1073 if (src->isAllOnesValue())
return src;
1075 if (isDerivedToBase)
1076 return llvm::ConstantExpr::getNSWSub(src, adj);
1078 return llvm::ConstantExpr::getNSWAdd(src, adj);
1082 if (UseARMMethodPtrABI) {
1083 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1085 adj = llvm::ConstantInt::get(adj->getType(), offset);
1088 llvm::Constant *srcAdj = src->getAggregateElement(1);
1089 llvm::Constant *dstAdj;
1090 if (isDerivedToBase)
1091 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1093 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1095 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1096 assert(res !=
nullptr &&
"Folding must succeed");
1105 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1107 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1108 llvm::Constant *Values[2] = {
Zero,
Zero };
1109 return llvm::ConstantStruct::getAnon(Values);
1118 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1122ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1126llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1128 assert(MD->
isInstance() &&
"Member function must not be static!");
1133 llvm::Constant *MemPtr[2];
1135 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1137 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1139 VTableOffset = Index * 4;
1144 VTableOffset = Index * PointerWidth.
getQuantity();
1147 if (UseARMMethodPtrABI) {
1169 const auto &Schema =
1170 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1172 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1173 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1175 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1178 MemPtr[1] = llvm::ConstantInt::get(
1185 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1186 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1193 if (Types.isFuncTypeConvertible(FPT)) {
1195 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
1201 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1203 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1204 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1205 (UseARMMethodPtrABI ? 2 : 1) *
1209 return llvm::ConstantStruct::getAnon(MemPtr);
1212llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1217 return EmitNullMemberPointer(MPT);
1221 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1223 QualType SrcType = getContext().getMemberPointerType(
1229 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1245 llvm::ICmpInst::Predicate
Eq;
1246 llvm::Instruction::BinaryOps
And,
Or;
1248 Eq = llvm::ICmpInst::ICMP_NE;
1249 And = llvm::Instruction::Or;
1250 Or = llvm::Instruction::And;
1252 Eq = llvm::ICmpInst::ICMP_EQ;
1253 And = llvm::Instruction::And;
1254 Or = llvm::Instruction::Or;
1260 return Builder.CreateICmp(
Eq, L, R);
1272 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1273 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1277 llvm::Value *PtrEq = Builder.CreateICmp(
Eq, LPtr, RPtr,
"cmp.ptr");
1282 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1283 llvm::Value *EqZero = Builder.CreateICmp(
Eq, LPtr, Zero,
"cmp.ptr.null");
1287 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1288 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1289 llvm::Value *AdjEq = Builder.CreateICmp(
Eq, LAdj, RAdj,
"cmp.adj");
1293 if (UseARMMethodPtrABI) {
1294 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1297 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1298 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1299 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(
Eq, OrAdjAnd1, Zero,
1301 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1305 llvm::Value *Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1306 Result = Builder.CreateBinOp(
And, PtrEq, Result,
1307 Inequality ?
"memptr.ne" :
"memptr.eq");
1313 llvm::Value *MemPtr,
1319 assert(MemPtr->getType() == CGM.PtrDiffTy);
1320 llvm::Value *NegativeOne =
1321 llvm::Constant::getAllOnesValue(MemPtr->getType());
1322 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1326 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1328 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1329 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
1333 if (UseARMMethodPtrABI) {
1334 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1335 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1336 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1337 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1338 "memptr.isvirtual");
1339 Result = Builder.CreateOr(Result, IsVirtual);
1345bool ItaniumCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1352 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1373 if (UseGlobalDelete) {
1383 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1384 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1402 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
1405 if (UseGlobalDelete)
1409void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1412 llvm::FunctionType *FTy =
1413 llvm::FunctionType::get(CGM.VoidTy,
false);
1415 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1426 llvm::FunctionType *FTy =
1437 llvm::FunctionType *FTy =
1438 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1446 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1447 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1451 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1455 E->getSubExpr(),
Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));
1458 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1463 llvm::Constant *Dtor =
nullptr;
1466 if (!
Record->hasTrivialDestructor()) {
1476 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1479 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1481 llvm::Value *args[] = { ExceptionPtr,
TypeInfo, Dtor };
1493 llvm::Type *PtrDiffTy =
1496 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1498 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1502 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1503 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1504 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1505 llvm::AttributeList Attrs = llvm::AttributeList::get(
1506 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1513 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1530 unsigned NumPublicPaths = 0;
1543 if (PathElement.Base->isVirtual())
1546 if (NumPublicPaths > 1)
1552 PathElement.Base->getType()->getAsCXXRecordDecl());
1557 if (NumPublicPaths == 0)
1561 if (NumPublicPaths > 1)
1571 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1576bool ItaniumCXXABI::shouldTypeidBeNullChecked(
QualType SrcRecordTy) {
1583 Call->setDoesNotReturn();
1584 CGF.
Builder.CreateUnreachable();
1590 llvm::Type *StdTypeInfoPtrTy) {
1596 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1599 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1600 {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});
1604 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1610bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1615llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1618 llvm::Type *PtrDiffLTy =
1621 llvm::Value *SrcRTTI =
1623 llvm::Value *DestRTTI =
1629 llvm::Value *OffsetHint = llvm::ConstantInt::get(
1635 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1641 llvm::Value *Vtable =
1643 CodeGenFunction::VTableAuthMode::MustTrap);
1648 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1654 llvm::BasicBlock *BadCastBlock =
1661 EmitBadCastCall(CGF);
1667llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1670 llvm::BasicBlock *CastFail) {
1682 std::optional<CharUnits> Offset;
1692 PathElement.Base->getType()->getAsCXXRecordDecl();
1693 if (PathElement.Base->isVirtual()) {
1706 Offset = PathOffset;
1707 else if (Offset != PathOffset) {
1712 ThisAddr =
Address(emitDynamicCastToVoid(CGF, ThisAddr, SrcRecordTy),
1723 return llvm::PoisonValue::get(CGF.
VoidPtrTy);
1732 CGM.DecorateInstructionWithTBAA(
1733 VPtr, CGM.getTBAAVTablePtrAccessInfo(CGF.
VoidPtrPtrTy));
1735 VPtr, getVTableAddressPoint(
BaseSubobject(SrcDecl, *Offset), DestDecl));
1737 if (!Offset->isZero())
1740 {llvm::ConstantInt::get(CGF.PtrDiffTy, -Offset->getQuantity())});
1745llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(
CodeGenFunction &CGF,
1750 llvm::Value *OffsetToTop;
1751 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1753 llvm::Value *VTable =
1758 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1762 llvm::Type *PtrDiffLTy =
1766 llvm::Value *VTable =
1771 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1783 Call->setDoesNotReturn();
1784 CGF.
Builder.CreateUnreachable();
1793 llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1795 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1797 llvm::Value *VBaseOffsetPtr =
1798 CGF.
Builder.CreateConstGEP1_64(
1800 "vbase.offset.ptr");
1802 llvm::Value *VBaseOffset;
1803 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1809 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1816 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1824 if (!
D->getParent()->isAbstract()) {
1831ItaniumCXXABI::buildStructorSignature(
GlobalDecl GD,
1841 cast<CXXMethodDecl>(GD.
getDecl())->getParent()->getNumVBases() != 0) {
1842 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1844 ArgTys.insert(ArgTys.begin() + 1,
1846 return AddedStructorArgCounts::prefix(1);
1848 return AddedStructorArgCounts{};
1871 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1874 if (NeedsVTTParameter(CGF.
CurGD)) {
1878 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1883 T, ImplicitParamKind::CXXVTT);
1884 Params.insert(Params.begin() + 1, VTTDecl);
1885 getStructorImplicitParamDecl(CGF) = VTTDecl;
1896 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1899 if (getStructorImplicitParamDecl(CGF)) {
1912 if (HasThisReturn(CGF.
CurGD))
1920 return AddedStructorArgs{};
1927 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1928 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
1929 QualType VTTTy = getContext().getPointerType(Q);
1930 return AddedStructorArgs::prefix({{VTT, VTTTy}});
1933llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
1948 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1951 if (getContext().getLangOpts().AppleKext &&
1958 ThisTy, VTT, VTTTy,
nullptr);
1962template <
typename T>
1965 if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
1978 llvm::GlobalVariable *VTable,
1980 if (VTable->getDLLStorageClass() !=
1981 llvm::GlobalVariable::DefaultStorageClass ||
1986 if (CXXRecordNonInlineHasAttr<DLLImportAttr>(RD))
1987 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1988 }
else if (CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
1989 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1994 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1995 if (VTable->hasInitializer())
2000 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2001 llvm::Constant *RTTI =
2002 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
2006 auto components = builder.beginStruct();
2008 llvm::GlobalValue::isLocalLinkage(
Linkage));
2009 components.finishAndSetAsInitializer(VTable);
2014 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2015 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2017 if (CGM.getTarget().hasPS4DLLImportExport())
2021 CGM.setGVProperties(VTable, RD);
2029 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
2030 cast<NamespaceDecl>(DC)->getIdentifier()->isStr(
"__cxxabiv1") &&
2032 EmitFundamentalRTTIDescriptors(RD);
2039 if (!VTable->isDeclarationForLinker() ||
2040 CGM.getCodeGenOpts().WholeProgramVTables) {
2041 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2045 if (VTable->isDeclarationForLinker()) {
2046 assert(CGM.getCodeGenOpts().WholeProgramVTables);
2047 CGM.addCompilerUsedGlobal(VTable);
2053 if (!VTable->isDSOLocal())
2058bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2060 if (Vptr.NearestVBase ==
nullptr)
2062 return NeedsVTTParameter(CGF.
CurGD);
2065llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2069 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2070 NeedsVTTParameter(CGF.
CurGD)) {
2071 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass,
Base,
2074 return getVTableAddressPoint(
Base, VTableClass);
2080 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
2085 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2088 llvm::Value *Indices[] = {
2089 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2090 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2096 unsigned ComponentSize =
2097 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2098 unsigned VTableSize =
2102 llvm::APInt(32, (
int)-Offset,
true),
2103 llvm::APInt(32, (
int)(VTableSize - Offset),
true));
2104 return llvm::ConstantExpr::getGetElementPtr(
2105 VTable->getValueType(), VTable, Indices,
true, InRange);
2108llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2111 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2112 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2116 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass,
Base);
2120 if (VirtualPointerIndex)
2122 VirtualPointerIndex);
2139llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2141 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2143 llvm::GlobalVariable *&VTable = VTables[RD];
2148 CGM.addDeferredVTable(RD);
2151 llvm::raw_svector_ostream Out(Name);
2152 getMangleContext().mangleCXXVTable(RD, Out);
2155 CGM.getItaniumVTableContext().getVTableLayout(RD);
2156 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2161 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
2162 unsigned PAlign = CGM.getItaniumVTableContext().isRelativeLayout()
2164 : CGM.getTarget().getPointerAlign(AS);
2166 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2167 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2168 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2169 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2171 if (CGM.getTarget().hasPS4DLLImportExport())
2174 CGM.setGVProperties(VTable, RD);
2183 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2184 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
2185 llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
2187 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2188 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2189 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2192 MethodDecl->getParent(), VTable, PtrTy,
2194 CGM.getContext().getTargetInfo().getPointerWidth(LangAS::Default) /
2199 llvm::Value *VFuncLoad;
2200 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
2201 VFuncLoad = CGF.
Builder.CreateCall(
2202 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2203 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, 4 * VTableIndex)});
2205 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2206 PtrTy, VTable, VTableIndex,
"vfn");
2217 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2218 CGM.getCodeGenOpts().StrictVTablePointers) {
2219 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2220 VFuncLoadInstr->setMetadata(
2221 llvm::LLVMContext::MD_invariant_load,
2222 llvm::MDNode::get(CGM.getLLVMContext(),
2231 assert(VTableSlotPtr &&
"virtual function pointer not set");
2232 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2239llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2241 Address This, DeleteOrMemberCallExpr
E, llvm::CallBase **CallOrInvoke) {
2244 assert((CE !=
nullptr) ^ (
D !=
nullptr));
2245 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
2250 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2256 ThisTy = CE->getObjectType();
2258 ThisTy =
D->getDestroyedType();
2262 nullptr,
QualType(),
nullptr, CallOrInvoke);
2266void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2272bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2276 if (CGM.getLangOpts().AppleKext)
2281 if (isVTableHidden(RD))
2284 if (CGM.getCodeGenOpts().ForceEmitVTables)
2301 if (hasAnyUnusedVirtualInlineFunction(RD))
2309 for (
const auto &B : RD->
bases()) {
2310 auto *BRD = B.getType()->getAsCXXRecordDecl();
2311 assert(BRD &&
"no class for base specifier");
2312 if (B.isVirtual() || !BRD->isDynamicClass())
2314 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2322bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2323 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2331 for (
const auto &B : RD->
vbases()) {
2332 auto *BRD = B.getType()->getAsCXXRecordDecl();
2333 assert(BRD &&
"no class for base specifier");
2334 if (!BRD->isDynamicClass())
2336 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2345 int64_t NonVirtualAdjustment,
2346 int64_t VirtualAdjustment,
2347 bool IsReturnAdjustment) {
2348 if (!NonVirtualAdjustment && !VirtualAdjustment)
2354 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2360 llvm::Value *ResultPtr;
2361 if (VirtualAdjustment) {
2362 llvm::Value *VTablePtr =
2365 llvm::Value *Offset;
2366 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2367 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2374 llvm::Type *PtrDiffTy =
2383 V.emitRawPointer(CGF), Offset);
2385 ResultPtr =
V.emitRawPointer(CGF);
2390 if (NonVirtualAdjustment && IsReturnAdjustment) {
2391 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2392 NonVirtualAdjustment);
2419 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2424 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2433 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2438 llvm::Value *NumElements,
2441 assert(requiresArrayCookie(
expr));
2451 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2455 CharUnits CookieOffset = CookieSize - SizeSize;
2456 if (!CookieOffset.
isZero())
2464 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2465 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2466 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2468 SI->setNoSanitizeMetadata();
2469 llvm::FunctionType *FTy =
2470 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2471 llvm::FunctionCallee F =
2472 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2485 Address numElementsPtr = allocPtr;
2487 if (!numElementsOffset.
isZero())
2493 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2500 llvm::FunctionType *FTy =
2502 llvm::FunctionCallee F =
2503 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2517 CGM.getContext().getTypeAlignInChars(elementType));
2522 llvm::Value *numElements,
2525 assert(requiresArrayCookie(
expr));
2532 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2533 getContext().getTypeSizeInChars(elementType).getQuantity());
2542 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2561 llvm::PointerType *GuardPtrTy) {
2563 llvm::FunctionType *FTy =
2567 FTy,
"__cxa_guard_acquire",
2569 llvm::AttributeList::FunctionIndex,
2570 llvm::Attribute::NoUnwind));
2574 llvm::PointerType *GuardPtrTy) {
2576 llvm::FunctionType *FTy =
2577 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2579 FTy,
"__cxa_guard_release",
2581 llvm::AttributeList::FunctionIndex,
2582 llvm::Attribute::NoUnwind));
2586 llvm::PointerType *GuardPtrTy) {
2588 llvm::FunctionType *FTy =
2589 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2591 FTy,
"__cxa_guard_abort",
2593 llvm::AttributeList::FunctionIndex,
2594 llvm::Attribute::NoUnwind));
2599 llvm::GlobalVariable *Guard;
2600 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2613 llvm::GlobalVariable *var,
2614 bool shouldPerformInit) {
2619 bool NonTemplateInline =
2626 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2627 (
D.isLocalVarDecl() || NonTemplateInline) &&
2632 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2634 llvm::IntegerType *guardTy;
2636 if (useInt8GuardVariable) {
2642 if (UseARMGuardVarABI) {
2651 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2657 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&
D);
2662 llvm::raw_svector_ostream out(guardName);
2663 getMangleContext().mangleStaticGuardVariable(&
D, out);
2669 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2670 false,
var->getLinkage(),
2671 llvm::ConstantInt::get(guardTy, 0),
2673 guard->setDSOLocal(
var->isDSOLocal());
2674 guard->setVisibility(
var->getVisibility());
2675 guard->setDLLStorageClass(
var->getDLLStorageClass());
2677 guard->setThreadLocalMode(
var->getThreadLocalMode());
2678 guard->setAlignment(guardAlignment.
getAsAlign());
2683 llvm::Comdat *
C =
var->getComdat();
2684 if (!
D.isLocalVarDecl() &&
C &&
2685 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2686 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2687 guard->setComdat(
C);
2688 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2689 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2692 CGM.setStaticLocalDeclGuardAddress(&
D, guard);
2695 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2720 if (!threadsafe || MaxInlineWidthInBits) {
2722 llvm::LoadInst *LI =
2732 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2755 (UseARMGuardVarABI && !useInt8GuardVariable)
2756 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2758 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2764 CodeGenFunction::GuardKind::VariableGuard, &
D);
2792 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2793 InitBlock, EndBlock);
2799 }
else if (!
D.isLocalVarDecl()) {
2803 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2817 }
else if (
D.isLocalVarDecl()) {
2821 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2830 llvm::FunctionCallee dtor,
2831 llvm::Constant *addr,
bool TLS) {
2833 "unexpected call to emitGlobalDtorWithCXAAtExit");
2835 "__cxa_atexit is disabled");
2836 const char *Name =
"__cxa_atexit";
2839 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2847 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2848 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2852 llvm::Constant *handle =
2854 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2855 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2858 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2859 llvm::FunctionType *atexitTy =
2860 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2864 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2865 fn->setDoesNotThrow();
2872 llvm::Constant *dtorCallee = cast<llvm::Constant>(dtor.getCallee());
2880 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2882 llvm::Value *args[] = {dtorCallee, addr, handle};
2890 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2894 return GlobalInitOrCleanupFn;
2897void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
2898 for (
const auto &I : DtorsUsingAtExit) {
2900 std::string GlobalCleanupFnName =
2901 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
2903 llvm::Function *GlobalCleanupFn =
2913 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
2917 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2918 auto itv = Dtors.rbegin();
2919 while (itv != Dtors.rend()) {
2920 llvm::Function *Dtor = *itv;
2925 llvm::Value *NeedsDestruct =
2928 llvm::BasicBlock *DestructCallBlock =
2931 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
2934 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
2939 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
2941 CI->setCallingConv(Dtor->getCallingConv());
2953void CodeGenModule::registerGlobalDtorsWithAtExit() {
2954 for (
const auto &I : DtorsUsingAtExit) {
2956 std::string GlobalInitFnName =
2957 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
2958 llvm::Function *GlobalInitFn =
2972 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2973 for (
auto *Dtor : Dtors) {
2990 unregisterGlobalDtorsWithUnAtExit();
2995 llvm::FunctionCallee dtor,
2996 llvm::Constant *addr) {
2997 if (
D.isNoDestroy(CGM.getContext()))
3001 if (CGM.getLangOpts().HLSL)
3002 return CGM.AddCXXDtorEntry(dtor, addr);
3009 if (!CGM.getLangOpts().hasAtExit() && !
D.isStaticLocal())
3016 if (CGM.getCodeGenOpts().CXAAtExit ||
D.getTLSKind())
3021 if (CGM.getLangOpts().AppleKext) {
3023 return CGM.AddCXXDtorEntry(dtor, addr);
3031 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3041static llvm::GlobalValue::LinkageTypes
3043 llvm::GlobalValue::LinkageTypes VarLinkage =
3047 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3052 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3053 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3055 return llvm::GlobalValue::WeakODRLinkage;
3059ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3064 llvm::raw_svector_ostream Out(WrapperName);
3065 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3070 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3071 return cast<llvm::Function>(
V);
3077 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3080 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3081 llvm::Function *Wrapper =
3083 WrapperName.str(), &CGM.getModule());
3085 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3086 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3088 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, Wrapper,
false);
3091 if (!Wrapper->hasLocalLinkage())
3093 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3094 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3096 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
3099 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3100 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3103 ThreadWrappers.push_back({VD, Wrapper});
3107void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3111 llvm::Function *InitFunc =
nullptr;
3116 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3117 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3120 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3121 CXXThreadLocalInits[I];
3123 OrderedInits.push_back(CXXThreadLocalInits[I]);
3126 if (!OrderedInits.empty()) {
3128 llvm::FunctionType *FTy =
3129 llvm::FunctionType::get(CGM.
VoidTy,
false);
3134 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3136 llvm::GlobalVariable::InternalLinkage,
3137 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3138 Guard->setThreadLocal(
true);
3142 Guard->setAlignment(GuardAlign.
getAsAlign());
3148 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3149 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3155 for (
const VarDecl *VD : CXXThreadLocals) {
3159 getOrCreateThreadLocalWrapper(VD, GV);
3164 for (
auto VDAndWrapper : ThreadWrappers) {
3165 const VarDecl *VD = VDAndWrapper.first;
3166 llvm::GlobalVariable *Var =
3168 llvm::Function *Wrapper = VDAndWrapper.second;
3175 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3181 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3182 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3190 llvm::raw_svector_ostream Out(InitFnName);
3191 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3194 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3199 llvm::GlobalValue *
Init =
nullptr;
3200 bool InitIsInitFunc =
false;
3201 bool HasConstantInitialization =
false;
3202 if (!usesThreadWrapperFunction(VD)) {
3203 HasConstantInitialization =
true;
3205 InitIsInitFunc =
true;
3206 llvm::Function *InitFuncToUse = InitFunc;
3210 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3217 Init = llvm::Function::Create(InitFnTy,
3218 llvm::GlobalVariable::ExternalWeakLinkage,
3226 Init->setVisibility(Var->getVisibility());
3228 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3229 Init->setDSOLocal(Var->isDSOLocal());
3232 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3240 isEmittedWithConstantInitializer(VD,
true) &&
3241 !mayNeedDestruction(VD)) {
3246 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3248 llvm::Function *
Func = llvm::Function::Create(
3249 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3252 cast<llvm::Function>(
Func),
3255 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3257 Builder.CreateRetVoid();
3260 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3262 if (HasConstantInitialization) {
3264 }
else if (InitIsInitFunc) {
3266 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3268 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3269 llvm::Function *
Fn =
3270 cast<llvm::Function>(cast<llvm::GlobalAlias>(
Init)->getAliasee());
3271 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3282 Builder.CreateCall(InitFnTy,
Init);
3285 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3286 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3287 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3288 Builder.CreateCondBr(Have, InitBB, ExitBB);
3290 Builder.SetInsertPoint(InitBB);
3291 Builder.CreateCall(InitFnTy,
Init);
3292 Builder.CreateBr(ExitBB);
3294 Builder.SetInsertPoint(ExitBB);
3299 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3303 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3305 Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());
3307 Builder.CreateRet(Val);
3315 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3317 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
3318 CallVal->setCallingConv(Wrapper->getCallingConv());
3332bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
3351ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3353 llvm::raw_svector_ostream Out(MethodName);
3354 getMangleContext().mangleCXXName(MD, Out);
3355 MethodName +=
"_vfpthunk_";
3356 StringRef ThunkName = MethodName.str();
3357 llvm::Function *ThunkFn;
3358 if ((ThunkFn = cast_or_null<llvm::Function>(
3359 CGM.
getModule().getNamedValue(ThunkName))))
3364 llvm::GlobalValue::LinkageTypes
Linkage =
3366 : llvm::GlobalValue::InternalLinkage;
3369 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3370 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
3371 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3377 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3378 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3379 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3392 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3393 setCXXABIThisValue(CGF, ThisVal);
3396 for (
const VarDecl *VD : FunctionArgs)
3404 getThisAddress(CGF), ThunkTy);
3405 llvm::CallBase *CallOrInvoke;
3408 auto *
Call = cast<llvm::CallInst>(CallOrInvoke);
3409 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3410 if (
Call->getType()->isVoidTy())
3423class ItaniumRTTIBuilder {
3425 llvm::LLVMContext &VMContext;
3426 const ItaniumCXXABI &
CXXABI;
3432 llvm::GlobalVariable *
3433 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3437 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
3440 void BuildVTablePointer(
const Type *Ty, llvm::Constant *StorageAddress);
3453 void BuildPointerTypeInfo(
QualType PointeeTy);
3464 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3465 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3479 PTI_Incomplete = 0x8,
3483 PTI_ContainingClassIncomplete = 0x10,
3489 PTI_Noexcept = 0x40,
3495 VMI_NonDiamondRepeat = 0x1,
3498 VMI_DiamondShaped = 0x2
3512 llvm::Constant *BuildTypeInfo(
QualType Ty);
3515 llvm::Constant *BuildTypeInfo(
3517 llvm::GlobalVariable::LinkageTypes
Linkage,
3518 llvm::GlobalValue::VisibilityTypes
Visibility,
3519 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3523llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3526 llvm::raw_svector_ostream Out(Name);
3532 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
3539 GV->setInitializer(
Init);
3545ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
3548 llvm::raw_svector_ostream Out(Name);
3552 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3559 GV =
new llvm::GlobalVariable(
3561 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3567 if (RD && CXXRecordNonInlineHasAttr<DLLImportAttr>(RD)) {
3568 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3595 case BuiltinType::Void:
3596 case BuiltinType::NullPtr:
3597 case BuiltinType::Bool:
3598 case BuiltinType::WChar_S:
3599 case BuiltinType::WChar_U:
3600 case BuiltinType::Char_U:
3601 case BuiltinType::Char_S:
3602 case BuiltinType::UChar:
3603 case BuiltinType::SChar:
3604 case BuiltinType::Short:
3605 case BuiltinType::UShort:
3606 case BuiltinType::Int:
3607 case BuiltinType::UInt:
3608 case BuiltinType::Long:
3609 case BuiltinType::ULong:
3610 case BuiltinType::LongLong:
3611 case BuiltinType::ULongLong:
3612 case BuiltinType::Half:
3613 case BuiltinType::Float:
3614 case BuiltinType::Double:
3615 case BuiltinType::LongDouble:
3616 case BuiltinType::Float16:
3617 case BuiltinType::Float128:
3618 case BuiltinType::Ibm128:
3619 case BuiltinType::Char8:
3620 case BuiltinType::Char16:
3621 case BuiltinType::Char32:
3622 case BuiltinType::Int128:
3623 case BuiltinType::UInt128:
3626#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3627 case BuiltinType::Id:
3628#include "clang/Basic/OpenCLImageTypes.def"
3629#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3630 case BuiltinType::Id:
3631#include "clang/Basic/OpenCLExtensionTypes.def"
3632 case BuiltinType::OCLSampler:
3633 case BuiltinType::OCLEvent:
3634 case BuiltinType::OCLClkEvent:
3635 case BuiltinType::OCLQueue:
3636 case BuiltinType::OCLReserveID:
3637#define SVE_TYPE(Name, Id, SingletonId) \
3638 case BuiltinType::Id:
3639#include "clang/Basic/AArch64SVEACLETypes.def"
3640#define PPC_VECTOR_TYPE(Name, Id, Size) \
3641 case BuiltinType::Id:
3642#include "clang/Basic/PPCTypes.def"
3643#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3644#include "clang/Basic/RISCVVTypes.def"
3645#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3646#include "clang/Basic/WebAssemblyReferenceTypes.def"
3647#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
3648#include "clang/Basic/AMDGPUTypes.def"
3649#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3650#include "clang/Basic/HLSLIntangibleTypes.def"
3651 case BuiltinType::ShortAccum:
3652 case BuiltinType::Accum:
3653 case BuiltinType::LongAccum:
3654 case BuiltinType::UShortAccum:
3655 case BuiltinType::UAccum:
3656 case BuiltinType::ULongAccum:
3657 case BuiltinType::ShortFract:
3658 case BuiltinType::Fract:
3659 case BuiltinType::LongFract:
3660 case BuiltinType::UShortFract:
3661 case BuiltinType::UFract:
3662 case BuiltinType::ULongFract:
3663 case BuiltinType::SatShortAccum:
3664 case BuiltinType::SatAccum:
3665 case BuiltinType::SatLongAccum:
3666 case BuiltinType::SatUShortAccum:
3667 case BuiltinType::SatUAccum:
3668 case BuiltinType::SatULongAccum:
3669 case BuiltinType::SatShortFract:
3670 case BuiltinType::SatFract:
3671 case BuiltinType::SatLongFract:
3672 case BuiltinType::SatUShortFract:
3673 case BuiltinType::SatUFract:
3674 case BuiltinType::SatULongFract:
3675 case BuiltinType::BFloat16:
3678 case BuiltinType::Dependent:
3679#define BUILTIN_TYPE(Id, SingletonId)
3680#define PLACEHOLDER_TYPE(Id, SingletonId) \
3681 case BuiltinType::Id:
3682#include "clang/AST/BuiltinTypes.def"
3683 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3685 case BuiltinType::ObjCId:
3686 case BuiltinType::ObjCClass:
3687 case BuiltinType::ObjCSel:
3688 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3691 llvm_unreachable(
"Invalid BuiltinType Kind!");
3696 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3714 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3719 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3737 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3738 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
3749 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3752 if (CGM.
getTriple().isWindowsGNUEnvironment())
3759 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3787 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3792 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3796 dyn_cast<MemberPointerType>(Ty)) {
3798 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
3820 if (
Base->isVirtual())
3830 if (!BaseDecl->isEmpty() &&
3837void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty,
3838 llvm::Constant *StorageAddress) {
3840 static const char *
const ClassTypeInfo =
3841 "_ZTVN10__cxxabiv117__class_type_infoE";
3843 static const char *
const SIClassTypeInfo =
3844 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3846 static const char *
const VMIClassTypeInfo =
3847 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3849 const char *VTableName =
nullptr;
3852#define TYPE(Class, Base)
3853#define ABSTRACT_TYPE(Class, Base)
3854#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3855#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3856#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3857#include "clang/AST/TypeNodes.inc"
3858 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3860 case Type::LValueReference:
3861 case Type::RValueReference:
3862 llvm_unreachable(
"References shouldn't get here");
3865 case Type::DeducedTemplateSpecialization:
3866 llvm_unreachable(
"Undeduced type shouldn't get here");
3869 llvm_unreachable(
"Pipe types shouldn't get here");
3871 case Type::ArrayParameter:
3872 llvm_unreachable(
"Array Parameter types should not get here.");
3878 case Type::ExtVector:
3879 case Type::ConstantMatrix:
3883 case Type::BlockPointer:
3885 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3888 case Type::ConstantArray:
3889 case Type::IncompleteArray:
3890 case Type::VariableArray:
3892 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3895 case Type::FunctionNoProto:
3896 case Type::FunctionProto:
3898 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3903 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3906 case Type::Record: {
3908 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3911 VTableName = ClassTypeInfo;
3913 VTableName = SIClassTypeInfo;
3915 VTableName = VMIClassTypeInfo;
3921 case Type::ObjCObject:
3923 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3926 if (isa<BuiltinType>(Ty)) {
3927 VTableName = ClassTypeInfo;
3931 assert(isa<ObjCInterfaceType>(Ty));
3934 case Type::ObjCInterface:
3935 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3936 VTableName = SIClassTypeInfo;
3938 VTableName = ClassTypeInfo;
3942 case Type::ObjCObjectPointer:
3945 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3948 case Type::MemberPointer:
3950 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3953 case Type::HLSLAttributedResource:
3954 llvm_unreachable(
"HLSL doesn't support virtual functions");
3957 llvm::Constant *VTable =
nullptr;
3961 VTable = CGM.
getModule().getNamedAlias(VTableName);
3964 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
3967 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3969 llvm::Type *PtrDiffTy =
3976 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
3978 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8Ty, VTable, Eight);
3980 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3981 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
3985 if (
const auto &Schema =
3989 Schema.isAddressDiscriminated() ? StorageAddress :
nullptr,
3992 Fields.push_back(VTable);
4009 return llvm::GlobalValue::InternalLinkage;
4013 llvm_unreachable(
"Linkage hasn't been computed!");
4018 return llvm::GlobalValue::InternalLinkage;
4026 return llvm::GlobalValue::LinkOnceODRLinkage;
4031 return llvm::GlobalValue::WeakODRLinkage;
4032 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4033 if (RD->
hasAttr<DLLImportAttr>() &&
4035 return llvm::GlobalValue::ExternalLinkage;
4041 .isWindowsGNUEnvironment())
4045 return llvm::GlobalValue::LinkOnceODRLinkage;
4048 llvm_unreachable(
"Invalid linkage!");
4051llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
4057 llvm::raw_svector_ostream Out(Name);
4060 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4061 if (OldGV && !OldGV->isDeclaration()) {
4062 assert(!OldGV->hasAvailableExternallyLinkage() &&
4063 "available_externally typeinfos not yet implemented");
4071 return GetAddrOfExternalRTTIDescriptor(Ty);
4078 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4079 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4081 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
4083 ItaniumCXXABI::RUK_NonUniqueHidden)
4084 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
4088 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4089 llvm::GlobalValue::DefaultStorageClass;
4091 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4092 RD->
hasAttr<DLLExportAttr>()) ||
4094 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4095 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
4096 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4098 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass);
4101llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4103 llvm::GlobalVariable::LinkageTypes
Linkage,
4104 llvm::GlobalValue::VisibilityTypes
Visibility,
4105 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4107 llvm::raw_svector_ostream Out(Name);
4110 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4112 llvm::GlobalVariable *GV =
4117 BuildVTablePointer(cast<Type>(Ty), GV);
4121 llvm::Constant *TypeNameField;
4125 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4127 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4130 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4131 llvm::Constant *flag =
4132 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
4133 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4139 Fields.push_back(TypeNameField);
4142#define TYPE(Class, Base)
4143#define ABSTRACT_TYPE(Class, Base)
4144#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4145#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4146#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4147#include "clang/AST/TypeNodes.inc"
4148 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4153 case Type::ExtVector:
4154 case Type::ConstantMatrix:
4156 case Type::BlockPointer:
4161 case Type::LValueReference:
4162 case Type::RValueReference:
4163 llvm_unreachable(
"References shouldn't get here");
4166 case Type::DeducedTemplateSpecialization:
4167 llvm_unreachable(
"Undeduced type shouldn't get here");
4175 case Type::ConstantArray:
4176 case Type::IncompleteArray:
4177 case Type::VariableArray:
4178 case Type::ArrayParameter:
4183 case Type::FunctionNoProto:
4184 case Type::FunctionProto:
4194 case Type::Record: {
4196 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
4203 BuildSIClassTypeInfo(RD);
4205 BuildVMIClassTypeInfo(RD);
4210 case Type::ObjCObject:
4211 case Type::ObjCInterface:
4212 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
4215 case Type::ObjCObjectPointer:
4216 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->
getPointeeType());
4223 case Type::MemberPointer:
4224 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
4231 case Type::HLSLAttributedResource:
4232 llvm_unreachable(
"HLSL doesn't support RTTI");
4235 GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));
4238 auto GVDLLStorageClass = DLLStorageClass;
4240 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
4241 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
4242 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
4243 if (RD->
hasAttr<DLLExportAttr>() ||
4244 CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
4245 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
4251 GV->takeName(OldGV);
4252 OldGV->replaceAllUsesWith(GV);
4253 OldGV->eraseFromParent();
4257 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4284 TypeName->setDLLStorageClass(DLLStorageClass);
4285 GV->setDLLStorageClass(GVDLLStorageClass);
4295void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4298 assert(isa<BuiltinType>(
T) || isa<ObjCInterfaceType>(
T));
4302 if (isa<BuiltinType>(
T))
return;
4313 llvm::Constant *BaseTypeInfo =
4314 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4315 Fields.push_back(BaseTypeInfo);
4320void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4324 llvm::Constant *BaseTypeInfo =
4326 Fields.push_back(BaseTypeInfo);
4349 if (
Base->isVirtual()) {
4351 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4354 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4356 if (Bases.NonVirtualBases.count(BaseDecl))
4357 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4361 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4364 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4366 if (Bases.VirtualBases.count(BaseDecl))
4367 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4372 for (
const auto &I : BaseDecl->bases())
4383 for (
const auto &I : RD->
bases())
4392void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4393 llvm::Type *UnsignedIntLTy =
4401 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4406 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4439 llvm::Type *OffsetFlagsLTy =
4444 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4456 if (
Base.isVirtual())
4464 OffsetFlags =
uint64_t(Offset.getQuantity()) << 8;
4468 if (
Base.isVirtual())
4469 OffsetFlags |= BCTI_Virtual;
4471 OffsetFlags |= BCTI_Public;
4473 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
4482 if (
Type.isConstQualified())
4483 Flags |= ItaniumRTTIBuilder::PTI_Const;
4484 if (
Type.isVolatileQualified())
4485 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4486 if (
Type.isRestrictQualified())
4487 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4494 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4497 if (Proto->isNothrow()) {
4498 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4508void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
4514 llvm::Type *UnsignedIntLTy =
4516 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4521 llvm::Constant *PointeeTypeInfo =
4522 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4523 Fields.push_back(PointeeTypeInfo);
4539 Flags |= PTI_ContainingClassIncomplete;
4541 llvm::Type *UnsignedIntLTy =
4543 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4548 llvm::Constant *PointeeTypeInfo =
4549 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4550 Fields.push_back(PointeeTypeInfo);
4557 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
4560llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
4561 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4564void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4567 getContext().VoidTy, getContext().NullPtrTy,
4568 getContext().BoolTy, getContext().WCharTy,
4569 getContext().CharTy, getContext().UnsignedCharTy,
4570 getContext().SignedCharTy, getContext().ShortTy,
4571 getContext().UnsignedShortTy, getContext().IntTy,
4572 getContext().UnsignedIntTy, getContext().LongTy,
4573 getContext().UnsignedLongTy, getContext().LongLongTy,
4574 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4575 getContext().UnsignedInt128Ty, getContext().HalfTy,
4576 getContext().FloatTy, getContext().DoubleTy,
4577 getContext().LongDoubleTy, getContext().Float128Ty,
4578 getContext().Char8Ty, getContext().Char16Ty,
4579 getContext().Char32Ty
4581 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4583 ? llvm::GlobalValue::DLLExportStorageClass
4584 : llvm::GlobalValue::DefaultStorageClass;
4585 llvm::GlobalValue::VisibilityTypes
Visibility =
4587 for (
const QualType &FundamentalType : FundamentalTypes) {
4589 QualType PointerTypeConst = getContext().getPointerType(
4590 FundamentalType.withConst());
4592 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4593 Type, llvm::GlobalValue::ExternalLinkage,
4600ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4602 if (shouldRTTIBeUnique())
4606 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4607 Linkage != llvm::GlobalValue::WeakODRLinkage)
4615 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4616 return RUK_NonUniqueHidden;
4621 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4622 return RUK_NonUniqueVisible;
4627enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4632 return StructorCodegen::Emit;
4637 return StructorCodegen::Emit;
4640 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4643 const auto *CD = cast<CXXConstructorDecl>(MD);
4648 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4649 return StructorCodegen::RAUW;
4652 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4653 return StructorCodegen::RAUW;
4655 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4659 return StructorCodegen::COMDAT;
4660 return StructorCodegen::Emit;
4663 return StructorCodegen::Alias;
4673 if (Entry && !Entry->isDeclaration())
4676 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
4679 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4682 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4686 assert(Entry->getType() == Aliasee->getType() &&
4687 "declaration exists with different type");
4688 Alias->takeName(Entry);
4689 Entry->replaceAllUsesWith(Alias);
4690 Entry->eraseFromParent();
4692 Alias->setName(MangledName);
4699void ItaniumCXXABI::emitCXXStructor(
GlobalDecl GD) {
4700 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
4701 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4714 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4719 if (CGType == StructorCodegen::RAUW) {
4732 CGType != StructorCodegen::COMDAT &&
4750 if (CGType == StructorCodegen::COMDAT) {
4752 llvm::raw_svector_ostream Out(Buffer);
4754 getMangleContext().mangleCXXDtorComdat(DD, Out);
4756 getMangleContext().mangleCXXCtorComdat(CD, Out);
4757 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(Out.str());
4766 llvm::FunctionType *FTy = llvm::FunctionType::get(
4774 llvm::FunctionType *FTy =
4775 llvm::FunctionType::get(CGM.
VoidTy,
false);
4782 llvm::FunctionType *FTy = llvm::FunctionType::get(
4802 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4824 bool EndMightThrow) {
4825 llvm::CallInst *call =
4828 CGF.
EHStack.pushCleanup<CallEndCatch>(
4830 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4850 if (isa<ReferenceType>(CatchType)) {
4855 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4860 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4869 unsigned HeaderSize =
4872 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
4895 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
4903 llvm::Value *ExnCast =
4904 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
4916 if (CatchType->hasPointerRepresentation()) {
4917 llvm::Value *CastExn =
4918 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
4935 llvm_unreachable(
"bad ownership qualifier!");
4953 llvm_unreachable(
"evaluation kind filtered out!");
4955 llvm_unreachable(
"bad evaluation kind");
4958 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
4959 auto catchRD = CatchType->getAsCXXRecordDecl();
4969 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4970 LLVMCatchTy, caughtExnAlignment);
4979 llvm::CallInst *rawAdjustedExn =
4983 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4984 LLVMCatchTy, caughtExnAlignment);
4988 CodeGenFunction::OpaqueValueMapping
5040 VarDecl *CatchParam = S->getExceptionDecl();
5059 C.VoidTy, {C.getPointerType(C.CharTy)});
5062 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5063 llvm::Function *fn =
5064 cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
5068 fn->setDoesNotThrow();
5069 fn->setDoesNotReturn();
5074 fn->addFnAttr(llvm::Attribute::NoInline);
5078 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5079 fn->setVisibility(llvm::Function::HiddenVisibility);
5081 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5084 llvm::BasicBlock *entry =
5089 llvm::Value *exn = &*fn->arg_begin();
5092 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5093 catchCall->setDoesNotThrow();
5097 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5098 termCall->setDoesNotThrow();
5099 termCall->setDoesNotReturn();
5103 builder.CreateUnreachable();
5109ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5119std::pair<llvm::Value *, const CXXRecordDecl *>
5126ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5131 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5142 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5146WebAssemblyCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5159 llvm::FunctionCallee Dtor,
5160 llvm::Constant *Addr) {
5165 llvm::FunctionType *AtExitTy =
5166 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5169 llvm::FunctionCallee
AtExit =
5177 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5185 llvm::Function *DtorStub =
5193 emitCXXStermFinalizer(
D, DtorStub, Addr);
5196void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &
D, llvm::Function *dtorStub,
5197 llvm::Constant *addr) {
5198 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5201 llvm::raw_svector_ostream Out(FnName);
5202 getMangleContext().mangleDynamicStermFinalizer(&
D, Out);
5214 D.getInit()->getExprLoc());
5224 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5229 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5234 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5237 CI->setCallingConv(dtorStub->getCallingConv());
5243 if (
auto *IPA =
D.
getAttr<InitPriorityAttr>()) {
5245 IPA->getPriority());
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF)
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void @__clang_call_terminate(i8* exn) nounwind noreturn This co...
static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD)
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF)
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::FunctionCallee dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
static llvm::FunctionCallee getBadCastFn(CodeGenFunction &CGF)
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM)
static llvm::Constant * pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType, QualType SrcType, CodeGenModule &CGM)
static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty)
Return the linkage that the type info and type info name constants should have for the given type.
static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static llvm::Value * performTypeAdjustment(CodeGenFunction &CGF, Address InitialPtr, const CXXRecordDecl *UnadjustedClass, int64_t NonVirtualAdjustment, int64_t VirtualAdjustment, bool IsReturnAdjustment)
static llvm::Function * createGlobalInitOrCleanupFn(CodeGen::CodeGenModule &CGM, StringRef FnName)
static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM)
static bool IsStandardLibraryRTTIDescriptor(QualType Ty)
IsStandardLibraryRTTIDescriptor - Returns whether the type information for the given type exists in t...
static llvm::Value * CallBeginCatch(CodeGenFunction &CGF, llvm::Value *Exn, bool EndMightThrow)
Emits a call to __cxa_begin_catch and enters a cleanup to call __cxa_end_catch.
static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static CharUnits computeOffsetHint(ASTContext &Context, const CXXRecordDecl *Src, const CXXRecordDecl *Dst)
Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7].
static bool isThreadWrapperReplaceable(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
static void InitCatchParam(CodeGenFunction &CGF, const VarDecl &CatchParam, Address ParamAddr, SourceLocation Loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty)
TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type info for that type is de...
static bool CanUseSingleInheritance(const CXXRecordDecl *RD)
static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM)
static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
Get the appropriate linkage for the wrapper function.
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void setVTableSelectiveDLLImportExport(CodeGenModule &CGM, llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)