33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/GlobalValue.h"
35#include "llvm/IR/Instructions.h"
36#include "llvm/IR/Intrinsics.h"
37#include "llvm/IR/Value.h"
38#include "llvm/Support/ScopedPrinter.h"
43using namespace CodeGen;
48 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
55 bool UseARMMethodPtrABI;
56 bool UseARMGuardVarABI;
57 bool Use32BitVTableOffsetABI;
65 bool UseARMMethodPtrABI =
false,
66 bool UseARMGuardVarABI =
false) :
67 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
68 UseARMGuardVarABI(UseARMGuardVarABI),
69 Use32BitVTableOffsetABI(
false) { }
83 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
93 llvm_unreachable(
"emitting dtor comdat as function?");
95 llvm_unreachable(
"bad dtor kind");
97 if (isa<CXXConstructorDecl>(GD.
getDecl())) {
107 llvm_unreachable(
"closure ctors in Itanium ABI?");
110 llvm_unreachable(
"emitting ctor comdat as function?");
112 llvm_unreachable(
"bad dtor kind");
127 llvm::Value *&ThisPtrForCall,
128 llvm::Value *MemFnPtr,
134 bool IsInBounds)
override;
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);
229 std::optional<ExactDynamicCastInfo>
236 llvm::BasicBlock *CastEnd)
override;
241 const ExactDynamicCastInfo &CastInfo,
242 llvm::BasicBlock *CastSuccess,
243 llvm::BasicBlock *CastFail)
override;
257 AddedStructorArgCounts
311 llvm::Value *getVTableAddressPointInStructorWithVTT(
325 DeleteOrMemberCallExpr
E,
326 llvm::CallBase **CallOrInvoke)
override;
331 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
337 if (ForVTable && !Thunk->hasLocalLinkage())
338 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
339 CGM.setGVProperties(Thunk, GD);
354 assert(!Args.empty() &&
"expected the arglist to not be empty!");
355 return Args.size() - 1;
360 {
return "__cxa_deleted_virtual"; }
365 llvm::Value *NumElements,
373 llvm::GlobalVariable *DeclPtr,
374 bool PerformInit)
override;
376 llvm::FunctionCallee dtor,
377 llvm::Constant *addr)
override;
379 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
397 getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
404 virtual bool shouldRTTIBeUnique()
const {
return true; }
408 enum RTTIUniquenessKind {
426 classifyRTTIUniqueness(
QualType CanTy,
427 llvm::GlobalValue::LinkageTypes
Linkage)
const;
428 friend class ItaniumRTTIBuilder;
432 std::pair<llvm::Value *, const CXXRecordDecl *>
438 getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
440 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
441 const auto &VtableLayout =
442 CGM.getItaniumVTableContext().getVTableLayout(RD);
444 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
446 if (!VtableComponent.isUsedFunctionPointerKind())
451 const bool IsInlined =
456 StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
457 auto *Entry = CGM.GetGlobalValue(Name);
463 if (!Entry || Entry->isDeclaration())
470 const auto &VtableLayout =
471 CGM.getItaniumVTableContext().getVTableLayout(RD);
473 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
474 if (VtableComponent.isRTTIKind()) {
475 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
476 if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
478 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
480 if (
Method->getVisibility() == Visibility::HiddenVisibility &&
489class ARMCXXABI :
public ItaniumCXXABI {
492 ItaniumCXXABI(CGM,
true,
495 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
503 llvm::Value *NumElements,
510class AppleARM64CXXABI :
public ARMCXXABI {
513 Use32BitVTableOffsetABI =
true;
517 bool shouldRTTIBeUnique()
const override {
return false; }
520class FuchsiaCXXABI final :
public ItaniumCXXABI {
523 : ItaniumCXXABI(CGM) {}
526 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
529class WebAssemblyCXXABI final :
public ItaniumCXXABI {
532 : ItaniumCXXABI(CGM,
true,
537 llvm::Value *Exn)
override;
540 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
541 bool canCallMismatchedFunctionType()
const override {
return false; }
544class XLCXXABI final :
public ItaniumCXXABI {
547 : ItaniumCXXABI(CGM) {}
550 llvm::FunctionCallee dtor,
551 llvm::Constant *addr)
override;
553 bool useSinitAndSterm()
const override {
return true; }
556 void emitCXXStermFinalizer(
const VarDecl &
D, llvm::Function *dtorStub,
557 llvm::Constant *addr);
565 case TargetCXXABI::GenericARM:
566 case TargetCXXABI::iOS:
567 case TargetCXXABI::WatchOS:
568 return new ARMCXXABI(CGM);
570 case TargetCXXABI::AppleARM64:
571 return new AppleARM64CXXABI(CGM);
573 case TargetCXXABI::Fuchsia:
574 return new FuchsiaCXXABI(CGM);
579 case TargetCXXABI::GenericAArch64:
580 return new ItaniumCXXABI(CGM,
true,
583 case TargetCXXABI::GenericMIPS:
584 return new ItaniumCXXABI(CGM,
true);
586 case TargetCXXABI::WebAssembly:
587 return new WebAssemblyCXXABI(CGM);
589 case TargetCXXABI::XL:
590 return new XLCXXABI(CGM);
592 case TargetCXXABI::GenericItanium:
593 return new ItaniumCXXABI(CGM);
595 case TargetCXXABI::Microsoft:
596 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
598 llvm_unreachable(
"bad ABI kind");
604 return CGM.PtrDiffTy;
605 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
628CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
630 llvm::Value *&ThisPtrForCall,
638 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
645 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
648 llvm::Value *Adj = RawAdj;
649 if (UseARMMethodPtrABI)
650 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
655 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(),
This, Adj);
656 ThisPtrForCall =
This;
659 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
663 llvm::Value *IsVirtual;
664 if (UseARMMethodPtrABI)
665 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
667 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
668 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
669 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
687 llvm::Value *VTableOffset = FnAsInt;
688 if (!UseARMMethodPtrABI)
689 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
690 if (Use32BitVTableOffsetABI) {
691 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
692 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
697 llvm::Constant *CheckSourceLocation;
698 llvm::Constant *CheckTypeDesc;
699 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
700 CGM.HasHiddenLTOVisibility(RD);
702 if (ShouldEmitCFICheck) {
703 if (
const auto *BinOp = dyn_cast<BinaryOperator>(
E)) {
704 if (BinOp->isPtrMemOp() &&
707 ->hasPointeeToToCFIUncheckedCalleeFunctionType())
708 ShouldEmitCFICheck =
false;
712 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
713 CGM.HasHiddenLTOVisibility(RD);
714 bool ShouldEmitWPDInfo =
715 CGM.getCodeGenOpts().WholeProgramVTables &&
717 !CGM.AlwaysHasLTOVisibilityPublic(RD);
718 llvm::Value *VirtualFn =
nullptr;
721 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
722 auto CheckHandler = SanitizerHandler::CFICheckFail;
725 llvm::Value *TypeId =
nullptr;
726 llvm::Value *CheckResult =
nullptr;
728 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
732 CGM.CreateMetadataIdentifierForVirtualMemPtrType(
QualType(MPT, 0));
736 if (ShouldEmitVFEInfo) {
737 llvm::Value *VFPAddr =
738 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
745 llvm::Value *CheckedLoad = Builder.CreateCall(
746 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
747 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
748 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
749 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
753 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
754 llvm::Value *VFPAddr =
755 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
756 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
757 ? llvm::Intrinsic::type_test
758 : llvm::Intrinsic::public_type_test;
761 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
764 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
765 VirtualFn = CGF.
Builder.CreateCall(
766 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
767 {VTableOffset->getType()}),
768 {VTable, VTableOffset});
770 llvm::Value *VFPAddr =
777 assert(VirtualFn &&
"Virtual fuction pointer not created!");
778 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
780 "Check result required but not created!");
782 if (ShouldEmitCFICheck) {
786 llvm::Constant *StaticData[] = {
792 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
795 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
796 CGM.getLLVMContext(),
797 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
798 llvm::Value *ValidVtable = Builder.CreateCall(
799 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
800 CGF.
EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler,
801 StaticData, {VTable, ValidVtable});
804 FnVirtual = Builder.GetInsertBlock();
813 llvm::Value *NonVirtualFn =
814 Builder.CreateIntToPtr(FnAsInt, CGF.
UnqualPtrTy,
"memptr.nonvirtualfn");
817 if (ShouldEmitCFICheck) {
820 auto CheckOrdinal = SanitizerKind::SO_CFIMFCall;
821 auto CheckHandler = SanitizerHandler::CFICheckFail;
824 llvm::Constant *StaticData[] = {
830 llvm::Value *Bit = Builder.getFalse();
832 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
835 Base->getCanonicalDecl()));
836 llvm::Value *TypeId =
839 llvm::Value *TypeTest =
840 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
841 {NonVirtualFn, TypeId});
842 Bit = Builder.CreateOr(Bit, TypeTest);
845 CGF.
EmitCheck(std::make_pair(Bit, CheckOrdinal), CheckHandler, StaticData,
846 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
848 FnNonVirtual = Builder.GetInsertBlock();
854 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
UnqualPtrTy, 2);
855 CalleePtr->addIncoming(VirtualFn, FnVirtual);
856 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
860 if (
const auto &Schema =
861 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
862 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
863 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
865 const auto &AuthInfo =
866 CGM.getMemberFunctionPointerAuthInfo(
QualType(MPT, 0));
867 assert(Schema.getKey() == AuthInfo.getKey() &&
868 "Keys for virtual and non-virtual member functions must match");
869 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
870 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
872 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
873 Schema.authenticatesNullValues(), DiscriminatorPHI);
882llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
885 assert(MemPtr->getType() == CGM.PtrDiffTy);
890 llvm::Value *BaseAddr =
Base.emitRawPointer(CGF);
891 return Builder.CreateGEP(CGF.
Int8Ty, BaseAddr, MemPtr,
"memptr.offset",
892 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
893 : llvm::GEPNoWrapFlags::none());
900 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
905 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
906 CPA->getAddrDiscriminator()->isZeroValue() &&
908 "unexpected key or discriminators");
911 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
943 if (isa<llvm::Constant>(src))
944 return EmitMemberPointerConversion(
E, cast<llvm::Constant>(src));
946 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
947 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
948 E->getCastKind() == CK_ReinterpretMemberPointer);
954 if (
const auto &NewAuthInfo =
955 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
958 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
959 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
960 llvm::Type *OrigTy = MemFnPtr->getType();
962 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
967 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
968 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
969 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
970 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
971 llvm::Value *IsVirtualOffset =
972 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
973 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
976 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
977 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
980 isa<llvm::Constant>(src));
981 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
982 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
983 ResignBB = Builder.GetInsertBlock();
986 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
987 NewSrc->addIncoming(src, StartBB);
988 NewSrc->addIncoming(ResignedVal, ResignBB);
994 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
996 llvm::Constant *adj = getMemberPointerAdjustment(
E);
997 if (!adj)
return src;
999 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
1008 if (isDerivedToBase)
1009 dst = Builder.CreateNSWSub(src, adj,
"adj");
1011 dst = Builder.CreateNSWAdd(src, adj,
"adj");
1014 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
1015 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
1016 return Builder.CreateSelect(isNull, src, dst);
1020 if (UseARMMethodPtrABI) {
1021 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1023 adj = llvm::ConstantInt::get(adj->getType(), offset);
1026 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1027 llvm::Value *dstAdj;
1028 if (isDerivedToBase)
1029 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1031 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1033 return Builder.CreateInsertValue(src, dstAdj, 1);
1036static llvm::Constant *
1041 "member function pointers expected");
1042 if (DestType == SrcType)
1048 if (!NewAuthInfo && !CurAuthInfo)
1051 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1052 if (MemFnPtr->getNumOperands() == 0) {
1054 assert(isa<llvm::ConstantInt>(MemFnPtr) &&
"constant int expected");
1059 cast<llvm::User>(MemFnPtr)->getOperand(0), CurAuthInfo, NewAuthInfo, CGM);
1060 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1061 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1065ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *
E,
1066 llvm::Constant *src) {
1067 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
1068 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
1069 E->getCastKind() == CK_ReinterpretMemberPointer);
1075 src, DstType,
E->getSubExpr()->
getType(), CGM);
1078 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
1081 llvm::Constant *adj = getMemberPointerAdjustment(
E);
1082 if (!adj)
return src;
1084 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
1093 if (src->isAllOnesValue())
return src;
1095 if (isDerivedToBase)
1096 return llvm::ConstantExpr::getNSWSub(src, adj);
1098 return llvm::ConstantExpr::getNSWAdd(src, adj);
1102 if (UseARMMethodPtrABI) {
1103 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1105 adj = llvm::ConstantInt::get(adj->getType(), offset);
1108 llvm::Constant *srcAdj = src->getAggregateElement(1);
1109 llvm::Constant *dstAdj;
1110 if (isDerivedToBase)
1111 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1113 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1115 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1116 assert(res !=
nullptr &&
"Folding must succeed");
1125 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1127 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1128 llvm::Constant *Values[2] = {
Zero,
Zero };
1129 return llvm::ConstantStruct::getAnon(Values);
1138 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1142ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1146llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1148 assert(MD->
isInstance() &&
"Member function must not be static!");
1153 llvm::Constant *MemPtr[2];
1155 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1157 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1159 VTableOffset = Index * 4;
1164 VTableOffset = Index * PointerWidth.
getQuantity();
1167 if (UseARMMethodPtrABI) {
1189 const auto &Schema =
1190 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1192 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1193 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1195 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1198 MemPtr[1] = llvm::ConstantInt::get(
1205 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1206 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1213 if (Types.isFuncTypeConvertible(FPT)) {
1215 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
1221 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1223 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1224 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1225 (UseARMMethodPtrABI ? 2 : 1) *
1229 return llvm::ConstantStruct::getAnon(MemPtr);
1232llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1237 return EmitNullMemberPointer(MPT);
1241 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1243 QualType SrcType = getContext().getMemberPointerType(
1249 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1265 llvm::ICmpInst::Predicate
Eq;
1266 llvm::Instruction::BinaryOps
And,
Or;
1268 Eq = llvm::ICmpInst::ICMP_NE;
1269 And = llvm::Instruction::Or;
1270 Or = llvm::Instruction::And;
1272 Eq = llvm::ICmpInst::ICMP_EQ;
1273 And = llvm::Instruction::And;
1274 Or = llvm::Instruction::Or;
1280 return Builder.CreateICmp(
Eq, L, R);
1292 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1293 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1297 llvm::Value *PtrEq = Builder.CreateICmp(
Eq, LPtr, RPtr,
"cmp.ptr");
1302 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1303 llvm::Value *EqZero = Builder.CreateICmp(
Eq, LPtr,
Zero,
"cmp.ptr.null");
1307 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1308 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1309 llvm::Value *AdjEq = Builder.CreateICmp(
Eq, LAdj, RAdj,
"cmp.adj");
1313 if (UseARMMethodPtrABI) {
1314 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1317 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1318 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1319 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(
Eq, OrAdjAnd1,
Zero,
1321 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1325 llvm::Value *Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1326 Result = Builder.CreateBinOp(
And, PtrEq, Result,
1327 Inequality ?
"memptr.ne" :
"memptr.eq");
1333 llvm::Value *MemPtr,
1339 assert(MemPtr->getType() == CGM.PtrDiffTy);
1340 llvm::Value *NegativeOne =
1341 llvm::Constant::getAllOnesValue(MemPtr->getType());
1342 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1346 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1348 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1349 llvm::Value *Result = Builder.CreateICmpNE(Ptr,
Zero,
"memptr.tobool");
1353 if (UseARMMethodPtrABI) {
1354 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1355 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1356 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1357 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit,
Zero,
1358 "memptr.isvirtual");
1359 Result = Builder.CreateOr(Result, IsVirtual);
1365bool ItaniumCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1372 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1374 Align, CGM.getDataLayout().getAllocaAddrSpace(),
1395 if (UseGlobalDelete) {
1404 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1405 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1423 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
1426 if (UseGlobalDelete)
1430void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1433 llvm::FunctionType *FTy =
1434 llvm::FunctionType::get(CGM.VoidTy,
false);
1436 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1447 llvm::FunctionType *FTy =
1458 llvm::FunctionType *FTy =
1459 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1467 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1468 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1472 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1476 E->getSubExpr(),
Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));
1479 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1484 llvm::Constant *Dtor =
nullptr;
1496 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1498 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1500 llvm::Value *args[] = { ExceptionPtr,
TypeInfo, Dtor };
1512 llvm::Type *PtrDiffTy =
1515 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1517 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1521 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1522 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1523 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1524 llvm::AttributeList Attrs = llvm::AttributeList::get(
1525 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1532 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1549 unsigned NumPublicPaths = 0;
1562 if (PathElement.Base->isVirtual())
1565 if (NumPublicPaths > 1)
1571 PathElement.Base->getType()->getAsCXXRecordDecl());
1576 if (NumPublicPaths == 0)
1580 if (NumPublicPaths > 1)
1590 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1595bool ItaniumCXXABI::shouldTypeidBeNullChecked(
QualType SrcRecordTy) {
1602 Call->setDoesNotReturn();
1603 CGF.
Builder.CreateUnreachable();
1609 llvm::Type *StdTypeInfoPtrTy) {
1614 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1617 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1618 {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});
1622 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1628bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1633llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1636 llvm::Type *PtrDiffLTy =
1639 llvm::Value *SrcRTTI =
1641 llvm::Value *DestRTTI =
1647 llvm::Value *OffsetHint = llvm::ConstantInt::get(
1653 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1659 llvm::Value *Vtable =
1661 CodeGenFunction::VTableAuthMode::MustTrap);
1666 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1672 llvm::BasicBlock *BadCastBlock =
1679 EmitBadCastCall(CGF);
1685std::optional<CGCXXABI::ExactDynamicCastInfo>
1686ItaniumCXXABI::getExactDynamicCastInfo(
QualType SrcRecordTy,
QualType DestTy,
1688 assert(shouldEmitExactDynamicCast(DestRecordTy));
1701 std::optional<CharUnits> Offset;
1711 PathElement.Base->getType()->getAsCXXRecordDecl();
1712 if (PathElement.Base->isVirtual()) {
1725 Offset = PathOffset;
1726 else if (Offset != PathOffset) {
1728 return ExactDynamicCastInfo{
true,
1733 return std::nullopt;
1734 return ExactDynamicCastInfo{
false, *Offset};
1737llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1740 const ExactDynamicCastInfo &ExactCastInfo, llvm::BasicBlock *CastSuccess,
1741 llvm::BasicBlock *CastFail) {
1745 llvm::Value *VTable =
nullptr;
1746 if (ExactCastInfo.RequiresCastToPrimaryBase) {
1751 llvm::Value *PrimaryBase =
1752 emitDynamicCastToVoid(CGF, ThisAddr, SrcRecordTy);
1762 llvm::Constant *ExpectedVTable = getVTableAddressPoint(
1764 llvm::Value *
Success = CGF.
Builder.CreateICmpEQ(VTable, ExpectedVTable);
1767 if (!ExactCastInfo.Offset.isZero()) {
1769 llvm::Constant *OffsetConstant =
1770 llvm::ConstantInt::get(CGF.
PtrDiffTy, -Offset);
1776 return AdjustedThisPtr;
1779llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(
CodeGenFunction &CGF,
1783 llvm::Value *OffsetToTop;
1784 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1786 llvm::Value *VTable =
1791 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1795 llvm::Type *PtrDiffLTy =
1799 llvm::Value *VTable =
1804 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1816 Call->setDoesNotReturn();
1817 CGF.
Builder.CreateUnreachable();
1828 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1830 llvm::Value *VBaseOffsetPtr =
1831 CGF.
Builder.CreateConstGEP1_64(
1833 "vbase.offset.ptr");
1835 llvm::Value *VBaseOffset;
1836 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1842 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1849 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1857 if (!
D->getParent()->isAbstract()) {
1864ItaniumCXXABI::buildStructorSignature(
GlobalDecl GD,
1874 cast<CXXMethodDecl>(GD.
getDecl())->getParent()->getNumVBases() != 0) {
1875 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1877 ArgTys.insert(ArgTys.begin() + 1,
1879 return AddedStructorArgCounts::prefix(1);
1881 return AddedStructorArgCounts{};
1904 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1907 if (NeedsVTTParameter(CGF.
CurGD)) {
1911 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1916 T, ImplicitParamKind::CXXVTT);
1917 Params.insert(Params.begin() + 1, VTTDecl);
1918 getStructorImplicitParamDecl(CGF) = VTTDecl;
1929 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1932 if (getStructorImplicitParamDecl(CGF)) {
1945 if (HasThisReturn(CGF.
CurGD))
1953 return AddedStructorArgs{};
1960 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1961 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
1962 QualType VTTTy = getContext().getPointerType(Q);
1963 return AddedStructorArgs::prefix({{VTT, VTTTy}});
1966llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
1981 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1984 if (getContext().getLangOpts().AppleKext &&
1991 ThisTy, VTT, VTTTy,
nullptr);
1995template <
typename T>
1998 if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
2011 llvm::GlobalVariable *VTable,
2013 if (VTable->getDLLStorageClass() !=
2014 llvm::GlobalVariable::DefaultStorageClass ||
2019 if (CXXRecordNonInlineHasAttr<DLLImportAttr>(RD))
2020 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2021 }
else if (CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
2022 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2027 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
2028 if (VTable->hasInitializer())
2033 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2034 llvm::Constant *RTTI =
2035 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getCanonicalTagType(RD));
2039 auto components = builder.beginStruct();
2041 llvm::GlobalValue::isLocalLinkage(
Linkage));
2042 components.finishAndSetAsInitializer(VTable);
2047 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2048 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2050 if (CGM.getTarget().hasPS4DLLImportExport())
2054 CGM.setGVProperties(VTable, RD);
2062 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
2063 cast<NamespaceDecl>(DC)->getIdentifier()->isStr(
"__cxxabiv1") &&
2065 EmitFundamentalRTTIDescriptors(RD);
2072 if (!VTable->isDeclarationForLinker() ||
2073 CGM.getCodeGenOpts().WholeProgramVTables) {
2074 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2078 if (VTable->isDeclarationForLinker()) {
2079 assert(CGM.getCodeGenOpts().WholeProgramVTables);
2080 CGM.addCompilerUsedGlobal(VTable);
2086 if (!VTable->isDSOLocal())
2092 DI->emitVTableSymbol(VTable, RD);
2095bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2099 return NeedsVTTParameter(CGF.
CurGD);
2102llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2106 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2107 NeedsVTTParameter(CGF.
CurGD)) {
2108 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass,
Base,
2111 return getVTableAddressPoint(
Base, VTableClass);
2117 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
2122 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2125 llvm::Value *Indices[] = {
2126 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2127 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2133 unsigned ComponentSize =
2134 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2135 unsigned VTableSize =
2138 llvm::ConstantRange InRange(
2139 llvm::APInt(32, (
int)-Offset,
true),
2140 llvm::APInt(32, (
int)(VTableSize - Offset),
true));
2141 return llvm::ConstantExpr::getGetElementPtr(
2142 VTable->getValueType(), VTable, Indices,
true, InRange);
2145llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2148 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2149 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2153 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass,
Base);
2157 if (VirtualPointerIndex)
2159 VirtualPointerIndex);
2176llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2178 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2180 llvm::GlobalVariable *&VTable = VTables[RD];
2185 CGM.addDeferredVTable(RD);
2188 llvm::raw_svector_ostream Out(Name);
2189 getMangleContext().mangleCXXVTable(RD, Out);
2192 CGM.getItaniumVTableContext().getVTableLayout(RD);
2193 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2198 unsigned PAlign = CGM.getVtableGlobalVarAlignment();
2200 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2201 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2202 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2203 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2205 if (CGM.getTarget().hasPS4DLLImportExport())
2208 CGM.setGVProperties(VTable, RD);
2217 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2218 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
2219 llvm::Value *VTable = CGF.
GetVTablePtr(
This, PtrTy, MethodDecl->getParent());
2221 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2222 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2223 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2225 llvm::Type *ComponentTy = CGM.getVTables().getVTableComponentType();
2227 VTableIndex * CGM.getDataLayout().getTypeSizeInBits(ComponentTy) / 8;
2235 llvm::Value *VFuncLoad;
2236 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
2237 VFuncLoad = CGF.
Builder.CreateCall(
2238 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2239 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, ByteOffset)});
2241 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2242 PtrTy, VTable, VTableIndex,
"vfn");
2253 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2254 CGM.getCodeGenOpts().StrictVTablePointers) {
2255 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2256 VFuncLoadInstr->setMetadata(
2257 llvm::LLVMContext::MD_invariant_load,
2258 llvm::MDNode::get(CGM.getLLVMContext(),
2267 assert(VTableSlotPtr &&
"virtual function pointer not set");
2268 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2275llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2277 Address This, DeleteOrMemberCallExpr
E, llvm::CallBase **CallOrInvoke) {
2278 auto *CE = dyn_cast<const CXXMemberCallExpr *>(
E);
2279 auto *
D = dyn_cast<const CXXDeleteExpr *>(
E);
2280 assert((CE !=
nullptr) ^ (
D !=
nullptr));
2281 assert(CE ==
nullptr || CE->arguments().empty());
2286 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2292 ThisTy = CE->getObjectType();
2294 ThisTy =
D->getDestroyedType();
2298 nullptr,
QualType(),
nullptr, CallOrInvoke);
2302void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2308bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2312 if (CGM.getLangOpts().AppleKext)
2317 if (isVTableHidden(RD))
2320 if (CGM.getCodeGenOpts().ForceEmitVTables)
2337 if (hasAnyUnusedVirtualInlineFunction(RD))
2345 for (
const auto &B : RD->
bases()) {
2346 auto *BRD = B.getType()->getAsCXXRecordDecl();
2347 assert(BRD &&
"no class for base specifier");
2348 if (B.isVirtual() || !BRD->isDynamicClass())
2350 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2358bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2359 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2367 for (
const auto &B : RD->
vbases()) {
2368 auto *BRD = B.getType()->getAsCXXRecordDecl();
2369 assert(BRD &&
"no class for base specifier");
2370 if (!BRD->isDynamicClass())
2372 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2381 int64_t NonVirtualAdjustment,
2382 int64_t VirtualAdjustment,
2383 bool IsReturnAdjustment) {
2384 if (!NonVirtualAdjustment && !VirtualAdjustment)
2390 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2396 llvm::Value *ResultPtr;
2397 if (VirtualAdjustment) {
2398 llvm::Value *VTablePtr =
2401 llvm::Value *Offset;
2402 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2403 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2410 llvm::Type *PtrDiffTy =
2419 V.emitRawPointer(CGF), Offset);
2421 ResultPtr =
V.emitRawPointer(CGF);
2426 if (NonVirtualAdjustment && IsReturnAdjustment) {
2427 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2428 NonVirtualAdjustment);
2455 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2460 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2469 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2474 llvm::Value *NumElements,
2477 assert(requiresArrayCookie(
expr));
2487 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2491 CharUnits CookieOffset = CookieSize - SizeSize;
2492 if (!CookieOffset.
isZero())
2500 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2501 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2502 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2504 SI->setNoSanitizeMetadata();
2505 llvm::FunctionType *FTy =
2506 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2507 llvm::FunctionCallee F =
2508 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2521 Address numElementsPtr = allocPtr;
2523 if (!numElementsOffset.
isZero())
2529 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2536 llvm::FunctionType *FTy =
2538 llvm::FunctionCallee F =
2539 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2553 CGM.getContext().getTypeAlignInChars(elementType));
2558 llvm::Value *numElements,
2561 assert(requiresArrayCookie(
expr));
2568 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2569 getContext().getTypeSizeInChars(elementType).getQuantity());
2578 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2597 llvm::PointerType *GuardPtrTy) {
2599 llvm::FunctionType *FTy =
2603 FTy,
"__cxa_guard_acquire",
2605 llvm::AttributeList::FunctionIndex,
2606 llvm::Attribute::NoUnwind));
2610 llvm::PointerType *GuardPtrTy) {
2612 llvm::FunctionType *FTy =
2613 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2615 FTy,
"__cxa_guard_release",
2617 llvm::AttributeList::FunctionIndex,
2618 llvm::Attribute::NoUnwind));
2622 llvm::PointerType *GuardPtrTy) {
2624 llvm::FunctionType *FTy =
2625 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2627 FTy,
"__cxa_guard_abort",
2629 llvm::AttributeList::FunctionIndex,
2630 llvm::Attribute::NoUnwind));
2635 llvm::GlobalVariable *Guard;
2636 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2649 llvm::GlobalVariable *var,
2650 bool shouldPerformInit) {
2655 bool NonTemplateInline =
2662 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2663 (
D.isLocalVarDecl() || NonTemplateInline) &&
2668 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2670 llvm::IntegerType *guardTy;
2672 if (useInt8GuardVariable) {
2678 if (UseARMGuardVarABI) {
2687 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2693 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&
D);
2698 llvm::raw_svector_ostream
out(guardName);
2699 getMangleContext().mangleStaticGuardVariable(&
D,
out);
2705 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2706 false,
var->getLinkage(),
2707 llvm::ConstantInt::get(guardTy, 0),
2709 guard->setDSOLocal(
var->isDSOLocal());
2710 guard->setVisibility(
var->getVisibility());
2711 guard->setDLLStorageClass(
var->getDLLStorageClass());
2713 guard->setThreadLocalMode(
var->getThreadLocalMode());
2714 guard->setAlignment(guardAlignment.
getAsAlign());
2719 llvm::Comdat *
C =
var->getComdat();
2720 if (!
D.isLocalVarDecl() &&
C &&
2721 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2722 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2723 guard->setComdat(
C);
2724 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2725 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2728 CGM.setStaticLocalDeclGuardAddress(&
D, guard);
2731 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2756 if (!threadsafe || MaxInlineWidthInBits) {
2758 llvm::LoadInst *LI =
2768 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2791 (UseARMGuardVarABI && !useInt8GuardVariable)
2792 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2794 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2800 CodeGenFunction::GuardKind::VariableGuard, &
D);
2828 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2829 InitBlock, EndBlock);
2835 }
else if (!
D.isLocalVarDecl()) {
2839 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2853 }
else if (
D.isLocalVarDecl()) {
2857 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2866 llvm::FunctionCallee dtor,
2867 llvm::Constant *addr,
bool TLS) {
2869 "unexpected call to emitGlobalDtorWithCXAAtExit");
2871 "__cxa_atexit is disabled");
2872 const char *Name =
"__cxa_atexit";
2875 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2883 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2884 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2888 llvm::Constant *handle =
2890 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2891 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2894 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2895 llvm::FunctionType *atexitTy =
2896 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2900 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2901 fn->setDoesNotThrow();
2908 llvm::Constant *dtorCallee = cast<llvm::Constant>(dtor.getCallee());
2916 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2918 llvm::Value *args[] = {dtorCallee, addr, handle};
2926 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2930 return GlobalInitOrCleanupFn;
2933void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
2934 for (
const auto &I : DtorsUsingAtExit) {
2936 std::string GlobalCleanupFnName =
2937 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
2939 llvm::Function *GlobalCleanupFn =
2949 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
2953 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2954 auto itv = Dtors.rbegin();
2955 while (itv != Dtors.rend()) {
2956 llvm::Function *Dtor = *itv;
2961 llvm::Value *NeedsDestruct =
2964 llvm::BasicBlock *DestructCallBlock =
2967 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
2970 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
2975 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
2977 CI->setCallingConv(Dtor->getCallingConv());
2989void CodeGenModule::registerGlobalDtorsWithAtExit() {
2990 for (
const auto &I : DtorsUsingAtExit) {
2992 std::string GlobalInitFnName =
2993 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
2994 llvm::Function *GlobalInitFn =
3008 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
3009 for (
auto *Dtor : Dtors) {
3026 unregisterGlobalDtorsWithUnAtExit();
3031 llvm::FunctionCallee dtor,
3032 llvm::Constant *addr) {
3033 if (
D.isNoDestroy(CGM.getContext()))
3037 if (CGM.getLangOpts().HLSL)
3038 return CGM.AddCXXDtorEntry(dtor, addr);
3045 if (!CGM.getLangOpts().hasAtExit() && !
D.isStaticLocal())
3052 if (CGM.getCodeGenOpts().CXAAtExit ||
D.getTLSKind())
3057 if (CGM.getLangOpts().AppleKext) {
3059 return CGM.AddCXXDtorEntry(dtor, addr);
3067 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3077static llvm::GlobalValue::LinkageTypes
3079 llvm::GlobalValue::LinkageTypes VarLinkage =
3083 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3088 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3089 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3091 return llvm::GlobalValue::WeakODRLinkage;
3095ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3100 llvm::raw_svector_ostream Out(WrapperName);
3101 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3106 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3107 return cast<llvm::Function>(
V);
3113 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3116 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3117 llvm::Function *Wrapper =
3119 WrapperName.str(), &CGM.getModule());
3121 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3122 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3124 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, Wrapper,
false);
3127 if (!Wrapper->hasLocalLinkage())
3129 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3130 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3132 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
3135 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3136 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3139 ThreadWrappers.push_back({VD, Wrapper});
3143void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3147 llvm::Function *InitFunc =
nullptr;
3152 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3153 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3156 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3157 CXXThreadLocalInits[I];
3159 OrderedInits.push_back(CXXThreadLocalInits[I]);
3162 if (!OrderedInits.empty()) {
3164 llvm::FunctionType *FTy =
3165 llvm::FunctionType::get(CGM.
VoidTy,
false);
3170 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3172 llvm::GlobalVariable::InternalLinkage,
3173 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3174 Guard->setThreadLocal(
true);
3178 Guard->setAlignment(GuardAlign.
getAsAlign());
3184 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3185 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3191 for (
const VarDecl *VD : CXXThreadLocals) {
3195 getOrCreateThreadLocalWrapper(VD, GV);
3200 for (
auto VDAndWrapper : ThreadWrappers) {
3201 const VarDecl *VD = VDAndWrapper.first;
3202 llvm::GlobalVariable *Var =
3204 llvm::Function *Wrapper = VDAndWrapper.second;
3211 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3217 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3218 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3226 llvm::raw_svector_ostream Out(InitFnName);
3227 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3230 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3235 llvm::GlobalValue *
Init =
nullptr;
3236 bool InitIsInitFunc =
false;
3237 bool HasConstantInitialization =
false;
3238 if (!usesThreadWrapperFunction(VD)) {
3239 HasConstantInitialization =
true;
3241 InitIsInitFunc =
true;
3242 llvm::Function *InitFuncToUse = InitFunc;
3246 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3253 Init = llvm::Function::Create(InitFnTy,
3254 llvm::GlobalVariable::ExternalWeakLinkage,
3262 Init->setVisibility(Var->getVisibility());
3264 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3265 Init->setDSOLocal(Var->isDSOLocal());
3268 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3276 isEmittedWithConstantInitializer(VD,
true) &&
3277 !mayNeedDestruction(VD)) {
3282 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3284 llvm::Function *
Func = llvm::Function::Create(
3285 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3288 cast<llvm::Function>(
Func),
3291 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3293 Builder.CreateRetVoid();
3296 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3298 if (HasConstantInitialization) {
3300 }
else if (InitIsInitFunc) {
3302 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3304 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3305 llvm::Function *
Fn =
3306 cast<llvm::Function>(cast<llvm::GlobalAlias>(
Init)->getAliasee());
3307 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3318 Builder.CreateCall(InitFnTy,
Init);
3321 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3322 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3323 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3324 Builder.CreateCondBr(Have, InitBB, ExitBB);
3326 Builder.SetInsertPoint(InitBB);
3327 Builder.CreateCall(InitFnTy,
Init);
3328 Builder.CreateBr(ExitBB);
3330 Builder.SetInsertPoint(ExitBB);
3335 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3339 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3341 Val = Builder.CreateAddrSpaceCast(Val, Wrapper->getReturnType());
3343 Builder.CreateRet(Val);
3351 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3353 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
3354 CallVal->setCallingConv(Wrapper->getCallingConv());
3368bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
3387ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3389 llvm::raw_svector_ostream Out(MethodName);
3390 getMangleContext().mangleCXXName(MD, Out);
3391 MethodName +=
"_vfpthunk_";
3392 StringRef ThunkName = MethodName.str();
3393 llvm::Function *ThunkFn;
3394 if ((ThunkFn = cast_or_null<llvm::Function>(
3395 CGM.
getModule().getNamedValue(ThunkName))))
3400 llvm::GlobalValue::LinkageTypes
Linkage =
3402 : llvm::GlobalValue::InternalLinkage;
3405 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3406 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
3407 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3413 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3414 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3415 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3428 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3429 setCXXABIThisValue(CGF, ThisVal);
3432 for (
const VarDecl *VD : FunctionArgs)
3440 getThisAddress(CGF), ThunkTy);
3441 llvm::CallBase *CallOrInvoke;
3444 auto *
Call = cast<llvm::CallInst>(CallOrInvoke);
3445 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3446 if (
Call->getType()->isVoidTy())
3459class ItaniumRTTIBuilder {
3461 llvm::LLVMContext &VMContext;
3462 const ItaniumCXXABI &
CXXABI;
3468 llvm::GlobalVariable *
3469 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3473 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
3476 void BuildVTablePointer(
const Type *Ty, llvm::Constant *StorageAddress);
3489 void BuildPointerTypeInfo(
QualType PointeeTy);
3500 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3501 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3515 PTI_Incomplete = 0x8,
3519 PTI_ContainingClassIncomplete = 0x10,
3525 PTI_Noexcept = 0x40,
3531 VMI_NonDiamondRepeat = 0x1,
3534 VMI_DiamondShaped = 0x2
3548 llvm::Constant *BuildTypeInfo(
QualType Ty);
3551 llvm::Constant *BuildTypeInfo(
3553 llvm::GlobalVariable::LinkageTypes
Linkage,
3554 llvm::GlobalValue::VisibilityTypes
Visibility,
3555 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3559llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3562 llvm::raw_svector_ostream Out(Name);
3568 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
3575 GV->setInitializer(
Init);
3581ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
3584 llvm::raw_svector_ostream Out(Name);
3588 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3595 GV =
new llvm::GlobalVariable(
3597 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3603 if (RD && CXXRecordNonInlineHasAttr<DLLImportAttr>(RD)) {
3604 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3631 case BuiltinType::Void:
3632 case BuiltinType::NullPtr:
3633 case BuiltinType::Bool:
3634 case BuiltinType::WChar_S:
3635 case BuiltinType::WChar_U:
3636 case BuiltinType::Char_U:
3637 case BuiltinType::Char_S:
3638 case BuiltinType::UChar:
3639 case BuiltinType::SChar:
3640 case BuiltinType::Short:
3641 case BuiltinType::UShort:
3642 case BuiltinType::Int:
3643 case BuiltinType::UInt:
3644 case BuiltinType::Long:
3645 case BuiltinType::ULong:
3646 case BuiltinType::LongLong:
3647 case BuiltinType::ULongLong:
3648 case BuiltinType::Half:
3649 case BuiltinType::Float:
3650 case BuiltinType::Double:
3651 case BuiltinType::LongDouble:
3652 case BuiltinType::Float16:
3653 case BuiltinType::Float128:
3654 case BuiltinType::Ibm128:
3655 case BuiltinType::Char8:
3656 case BuiltinType::Char16:
3657 case BuiltinType::Char32:
3658 case BuiltinType::Int128:
3659 case BuiltinType::UInt128:
3662#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3663 case BuiltinType::Id:
3664#include "clang/Basic/OpenCLImageTypes.def"
3665#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3666 case BuiltinType::Id:
3667#include "clang/Basic/OpenCLExtensionTypes.def"
3668 case BuiltinType::OCLSampler:
3669 case BuiltinType::OCLEvent:
3670 case BuiltinType::OCLClkEvent:
3671 case BuiltinType::OCLQueue:
3672 case BuiltinType::OCLReserveID:
3673#define SVE_TYPE(Name, Id, SingletonId) \
3674 case BuiltinType::Id:
3675#include "clang/Basic/AArch64ACLETypes.def"
3676#define PPC_VECTOR_TYPE(Name, Id, Size) \
3677 case BuiltinType::Id:
3678#include "clang/Basic/PPCTypes.def"
3679#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3680#include "clang/Basic/RISCVVTypes.def"
3681#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3682#include "clang/Basic/WebAssemblyReferenceTypes.def"
3683#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
3684#include "clang/Basic/AMDGPUTypes.def"
3685#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3686#include "clang/Basic/HLSLIntangibleTypes.def"
3687 case BuiltinType::ShortAccum:
3688 case BuiltinType::Accum:
3689 case BuiltinType::LongAccum:
3690 case BuiltinType::UShortAccum:
3691 case BuiltinType::UAccum:
3692 case BuiltinType::ULongAccum:
3693 case BuiltinType::ShortFract:
3694 case BuiltinType::Fract:
3695 case BuiltinType::LongFract:
3696 case BuiltinType::UShortFract:
3697 case BuiltinType::UFract:
3698 case BuiltinType::ULongFract:
3699 case BuiltinType::SatShortAccum:
3700 case BuiltinType::SatAccum:
3701 case BuiltinType::SatLongAccum:
3702 case BuiltinType::SatUShortAccum:
3703 case BuiltinType::SatUAccum:
3704 case BuiltinType::SatULongAccum:
3705 case BuiltinType::SatShortFract:
3706 case BuiltinType::SatFract:
3707 case BuiltinType::SatLongFract:
3708 case BuiltinType::SatUShortFract:
3709 case BuiltinType::SatUFract:
3710 case BuiltinType::SatULongFract:
3711 case BuiltinType::BFloat16:
3714 case BuiltinType::Dependent:
3715#define BUILTIN_TYPE(Id, SingletonId)
3716#define PLACEHOLDER_TYPE(Id, SingletonId) \
3717 case BuiltinType::Id:
3718#include "clang/AST/BuiltinTypes.def"
3719 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3721 case BuiltinType::ObjCId:
3722 case BuiltinType::ObjCClass:
3723 case BuiltinType::ObjCSel:
3724 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3727 llvm_unreachable(
"Invalid BuiltinType Kind!");
3732 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3750 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3755 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3773 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3786 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3796 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3826 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3831 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3835 dyn_cast<MemberPointerType>(Ty)) {
3837 if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
3858 if (
Base->isVirtual())
3866 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
3867 if (!BaseDecl->isEmpty() &&
3874void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty,
3875 llvm::Constant *StorageAddress) {
3877 static const char *
const ClassTypeInfo =
3878 "_ZTVN10__cxxabiv117__class_type_infoE";
3880 static const char *
const SIClassTypeInfo =
3881 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3883 static const char *
const VMIClassTypeInfo =
3884 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3886 const char *VTableName =
nullptr;
3889#define TYPE(Class, Base)
3890#define ABSTRACT_TYPE(Class, Base)
3891#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3892#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3893#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3894#include "clang/AST/TypeNodes.inc"
3895 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3897 case Type::LValueReference:
3898 case Type::RValueReference:
3899 llvm_unreachable(
"References shouldn't get here");
3902 case Type::DeducedTemplateSpecialization:
3903 llvm_unreachable(
"Undeduced type shouldn't get here");
3906 llvm_unreachable(
"Pipe types shouldn't get here");
3908 case Type::ArrayParameter:
3909 llvm_unreachable(
"Array Parameter types should not get here.");
3915 case Type::ExtVector:
3916 case Type::ConstantMatrix:
3920 case Type::BlockPointer:
3922 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3925 case Type::ConstantArray:
3926 case Type::IncompleteArray:
3927 case Type::VariableArray:
3929 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3932 case Type::FunctionNoProto:
3933 case Type::FunctionProto:
3935 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3940 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3943 case Type::Record: {
3945 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getOriginalDecl())
3949 VTableName = ClassTypeInfo;
3951 VTableName = SIClassTypeInfo;
3953 VTableName = VMIClassTypeInfo;
3959 case Type::ObjCObject:
3961 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3964 if (isa<BuiltinType>(Ty)) {
3965 VTableName = ClassTypeInfo;
3969 assert(isa<ObjCInterfaceType>(Ty));
3972 case Type::ObjCInterface:
3973 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3974 VTableName = SIClassTypeInfo;
3976 VTableName = ClassTypeInfo;
3980 case Type::ObjCObjectPointer:
3983 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3986 case Type::MemberPointer:
3988 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3991 case Type::HLSLAttributedResource:
3992 case Type::HLSLInlineSpirv:
3993 llvm_unreachable(
"HLSL doesn't support virtual functions");
3996 llvm::Constant *VTable =
nullptr;
4000 VTable = CGM.
getModule().getNamedAlias(VTableName);
4003 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
4006 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
4008 llvm::Type *PtrDiffTy =
4015 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
4017 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8Ty, VTable, Eight);
4019 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
4020 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
4024 if (
const auto &Schema =
4028 Schema.isAddressDiscriminated() ? StorageAddress :
nullptr,
4031 Fields.push_back(VTable);
4048 return llvm::GlobalValue::InternalLinkage;
4052 llvm_unreachable(
"Linkage hasn't been computed!");
4057 return llvm::GlobalValue::InternalLinkage;
4065 return llvm::GlobalValue::LinkOnceODRLinkage;
4071 return llvm::GlobalValue::WeakODRLinkage;
4072 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4073 if (RD->
hasAttr<DLLImportAttr>() &&
4075 return llvm::GlobalValue::ExternalLinkage;
4082 return llvm::GlobalValue::LinkOnceODRLinkage;
4085 llvm_unreachable(
"Invalid linkage!");
4088llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
4094 llvm::raw_svector_ostream Out(Name);
4097 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4098 if (OldGV && !OldGV->isDeclaration()) {
4099 assert(!OldGV->hasAvailableExternallyLinkage() &&
4100 "available_externally typeinfos not yet implemented");
4108 return GetAddrOfExternalRTTIDescriptor(Ty);
4115 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4116 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4118 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
4120 ItaniumCXXABI::RUK_NonUniqueHidden)
4121 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
4125 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4126 llvm::GlobalValue::DefaultStorageClass;
4128 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4129 RD->
hasAttr<DLLExportAttr>()) ||
4131 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4132 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
4133 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4135 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass);
4138llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4140 llvm::GlobalVariable::LinkageTypes
Linkage,
4141 llvm::GlobalValue::VisibilityTypes
Visibility,
4142 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4144 llvm::raw_svector_ostream Out(Name);
4147 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4149 llvm::GlobalVariable *GV =
4154 BuildVTablePointer(cast<Type>(Ty), GV);
4158 llvm::Constant *TypeNameField;
4162 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4164 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4167 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4168 llvm::Constant *flag =
4169 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
4170 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4176 Fields.push_back(TypeNameField);
4179#define TYPE(Class, Base)
4180#define ABSTRACT_TYPE(Class, Base)
4181#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4182#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4183#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4184#include "clang/AST/TypeNodes.inc"
4185 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4190 case Type::ExtVector:
4191 case Type::ConstantMatrix:
4193 case Type::BlockPointer:
4198 case Type::LValueReference:
4199 case Type::RValueReference:
4200 llvm_unreachable(
"References shouldn't get here");
4203 case Type::DeducedTemplateSpecialization:
4204 llvm_unreachable(
"Undeduced type shouldn't get here");
4212 case Type::ConstantArray:
4213 case Type::IncompleteArray:
4214 case Type::VariableArray:
4215 case Type::ArrayParameter:
4220 case Type::FunctionNoProto:
4221 case Type::FunctionProto:
4231 case Type::Record: {
4233 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getOriginalDecl())
4241 BuildSIClassTypeInfo(RD);
4243 BuildVMIClassTypeInfo(RD);
4248 case Type::ObjCObject:
4249 case Type::ObjCInterface:
4250 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
4253 case Type::ObjCObjectPointer:
4254 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->
getPointeeType());
4261 case Type::MemberPointer:
4262 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
4269 case Type::HLSLAttributedResource:
4270 case Type::HLSLInlineSpirv:
4271 llvm_unreachable(
"HLSL doesn't support RTTI");
4274 GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));
4277 auto GVDLLStorageClass = DLLStorageClass;
4279 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
4280 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
4281 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
4283 if (RD->
hasAttr<DLLExportAttr>() ||
4284 CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
4285 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
4291 GV->takeName(OldGV);
4292 OldGV->replaceAllUsesWith(GV);
4293 OldGV->eraseFromParent();
4297 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4324 TypeName->setDLLStorageClass(DLLStorageClass);
4325 GV->setDLLStorageClass(GVDLLStorageClass);
4335void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4338 assert(isa<BuiltinType>(
T) || isa<ObjCInterfaceType>(
T));
4342 if (isa<BuiltinType>(
T))
return;
4353 llvm::Constant *BaseTypeInfo =
4354 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4355 Fields.push_back(BaseTypeInfo);
4360void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4364 llvm::Constant *BaseTypeInfo =
4366 Fields.push_back(BaseTypeInfo);
4386 auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
4387 if (
Base->isVirtual()) {
4389 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4392 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4394 if (Bases.NonVirtualBases.count(BaseDecl))
4395 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4399 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4402 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4404 if (Bases.VirtualBases.count(BaseDecl))
4405 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4410 for (
const auto &I : BaseDecl->bases())
4421 for (
const auto &I : RD->
bases())
4430void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4431 llvm::Type *UnsignedIntLTy =
4439 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4444 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4477 llvm::Type *OffsetFlagsLTy =
4482 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4484 auto *BaseDecl =
Base.getType()->castAsCXXRecordDecl();
4492 if (
Base.isVirtual())
4500 OffsetFlags =
uint64_t(Offset.getQuantity()) << 8;
4504 if (
Base.isVirtual())
4505 OffsetFlags |= BCTI_Virtual;
4507 OffsetFlags |= BCTI_Public;
4509 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
4518 if (
Type.isConstQualified())
4519 Flags |= ItaniumRTTIBuilder::PTI_Const;
4520 if (
Type.isVolatileQualified())
4521 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4522 if (
Type.isRestrictQualified())
4523 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4530 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4533 if (Proto->isNothrow()) {
4534 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4544void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
4550 llvm::Type *UnsignedIntLTy =
4552 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4557 llvm::Constant *PointeeTypeInfo =
4558 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4559 Fields.push_back(PointeeTypeInfo);
4575 Flags |= PTI_ContainingClassIncomplete;
4577 llvm::Type *UnsignedIntLTy =
4579 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4584 llvm::Constant *PointeeTypeInfo =
4585 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4586 Fields.push_back(PointeeTypeInfo);
4593 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
T));
4596llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
4597 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4600void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4603 getContext().VoidTy, getContext().NullPtrTy,
4604 getContext().BoolTy, getContext().WCharTy,
4605 getContext().CharTy, getContext().UnsignedCharTy,
4606 getContext().SignedCharTy, getContext().ShortTy,
4607 getContext().UnsignedShortTy, getContext().IntTy,
4608 getContext().UnsignedIntTy, getContext().LongTy,
4609 getContext().UnsignedLongTy, getContext().LongLongTy,
4610 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4611 getContext().UnsignedInt128Ty, getContext().HalfTy,
4612 getContext().FloatTy, getContext().DoubleTy,
4613 getContext().LongDoubleTy, getContext().Float128Ty,
4614 getContext().Char8Ty, getContext().Char16Ty,
4615 getContext().Char32Ty
4617 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4619 ? llvm::GlobalValue::DLLExportStorageClass
4620 : llvm::GlobalValue::DefaultStorageClass;
4621 llvm::GlobalValue::VisibilityTypes
Visibility =
4623 for (
const QualType &FundamentalType : FundamentalTypes) {
4625 QualType PointerTypeConst = getContext().getPointerType(
4626 FundamentalType.withConst());
4628 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4629 Type, llvm::GlobalValue::ExternalLinkage,
4636ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4638 if (shouldRTTIBeUnique())
4642 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4643 Linkage != llvm::GlobalValue::WeakODRLinkage)
4651 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4652 return RUK_NonUniqueHidden;
4657 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4658 return RUK_NonUniqueVisible;
4663enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4668 return StructorCodegen::Emit;
4673 return StructorCodegen::Emit;
4676 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4679 const auto *CD = cast<CXXConstructorDecl>(MD);
4684 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4685 return StructorCodegen::RAUW;
4688 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4689 return StructorCodegen::RAUW;
4691 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4695 return StructorCodegen::COMDAT;
4696 return StructorCodegen::Emit;
4699 return StructorCodegen::Alias;
4709 if (Entry && !Entry->isDeclaration())
4712 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
4715 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4718 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4722 assert(Entry->getType() == Aliasee->getType() &&
4723 "declaration exists with different type");
4724 Alias->takeName(Entry);
4725 Entry->replaceAllUsesWith(Alias);
4726 Entry->eraseFromParent();
4728 Alias->setName(MangledName);
4735void ItaniumCXXABI::emitCXXStructor(
GlobalDecl GD) {
4736 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
4737 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4750 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4755 if (CGType == StructorCodegen::RAUW) {
4768 CGType != StructorCodegen::COMDAT &&
4786 if (CGType == StructorCodegen::COMDAT) {
4788 llvm::raw_svector_ostream Out(Buffer);
4790 getMangleContext().mangleCXXDtorComdat(DD, Out);
4792 getMangleContext().mangleCXXCtorComdat(CD, Out);
4793 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(Out.str());
4802 llvm::FunctionType *FTy = llvm::FunctionType::get(
4810 llvm::FunctionType *FTy =
4811 llvm::FunctionType::get(CGM.
VoidTy,
false);
4818 llvm::FunctionType *FTy = llvm::FunctionType::get(
4838 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4860 bool EndMightThrow) {
4861 llvm::CallInst *call =
4864 CGF.
EHStack.pushCleanup<CallEndCatch>(
4866 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4886 if (isa<ReferenceType>(CatchType)) {
4891 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4896 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4905 unsigned HeaderSize =
4908 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
4931 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
4939 llvm::Value *ExnCast =
4940 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
4952 if (CatchType->hasPointerRepresentation()) {
4953 llvm::Value *CastExn =
4954 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
4971 llvm_unreachable(
"bad ownership qualifier!");
4989 llvm_unreachable(
"evaluation kind filtered out!");
4991 llvm_unreachable(
"bad evaluation kind");
4994 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
4995 auto catchRD = CatchType->getAsCXXRecordDecl();
5005 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5006 LLVMCatchTy, caughtExnAlignment);
5015 llvm::CallInst *rawAdjustedExn =
5019 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
5020 LLVMCatchTy, caughtExnAlignment);
5076 VarDecl *CatchParam = S->getExceptionDecl();
5099 C.VoidTy, {C.getPointerType(C.CharTy)});
5102 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5103 llvm::Function *fn =
5104 cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
5108 fn->setDoesNotThrow();
5109 fn->setDoesNotReturn();
5114 fn->addFnAttr(llvm::Attribute::NoInline);
5118 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5119 fn->setVisibility(llvm::Function::HiddenVisibility);
5121 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5124 llvm::BasicBlock *entry =
5129 llvm::Value *exn = &*fn->arg_begin();
5132 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5133 catchCall->setDoesNotThrow();
5137 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5138 termCall->setDoesNotThrow();
5139 termCall->setDoesNotReturn();
5143 builder.CreateUnreachable();
5149ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5159std::pair<llvm::Value *, const CXXRecordDecl *>
5166ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5171 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5182 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5186WebAssemblyCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5204 llvm::FunctionCallee Dtor,
5205 llvm::Constant *
Addr) {
5210 llvm::FunctionType *AtExitTy =
5211 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5214 llvm::FunctionCallee
AtExit =
5222 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5230 llvm::Function *DtorStub =
5238 emitCXXStermFinalizer(
D, DtorStub,
Addr);
5241void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &
D, llvm::Function *dtorStub,
5242 llvm::Constant *addr) {
5243 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5246 llvm::raw_svector_ostream Out(FnName);
5247 getMangleContext().mangleDynamicStermFinalizer(&
D, Out);
5259 D.getInit()->getExprLoc());
5269 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5274 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5279 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5282 CI->setCallingConv(dtorStub->getCallingConv());
5288 if (
auto *IPA =
D.
getAttr<InitPriorityAttr>()) {
5290 IPA->getPriority());
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF)
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void @__clang_call_terminate(i8* exn) nounwind noreturn This co...
static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD)
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF)
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::FunctionCallee dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
static llvm::FunctionCallee getBadCastFn(CodeGenFunction &CGF)
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM)
static llvm::Constant * pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType, QualType SrcType, CodeGenModule &CGM)
static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty)
Return the linkage that the type info and type info name constants should have for the given type.
static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static llvm::Value * performTypeAdjustment(CodeGenFunction &CGF, Address InitialPtr, const CXXRecordDecl *UnadjustedClass, int64_t NonVirtualAdjustment, int64_t VirtualAdjustment, bool IsReturnAdjustment)
static llvm::Function * createGlobalInitOrCleanupFn(CodeGen::CodeGenModule &CGM, StringRef FnName)
static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM)
static bool IsStandardLibraryRTTIDescriptor(QualType Ty)
IsStandardLibraryRTTIDescriptor - Returns whether the type information for the given type exists in t...
static llvm::Value * CallBeginCatch(CodeGenFunction &CGF, llvm::Value *Exn, bool EndMightThrow)
Emits a call to __cxa_begin_catch and enters a cleanup to call __cxa_end_catch.
static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static CharUnits computeOffsetHint(ASTContext &Context, const CXXRecordDecl *Src, const CXXRecordDecl *Dst)
Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7].
static bool isThreadWrapperReplaceable(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
static void InitCatchParam(CodeGenFunction &CGF, const VarDecl &CatchParam, Address ParamAddr, SourceLocation Loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty)
TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type info for that type is de...
static bool CanUseSingleInheritance(const CXXRecordDecl *RD)
static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM)
static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
Get the appropriate linkage for the wrapper function.
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void setVTableSelectiveDLLImportExport(CodeGenModule &CGM, llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static bool ContainsIncompleteClassType(QualType Ty)
ContainsIncompleteClassType - Returns whether the given type contains an incomplete class type.
static llvm::Constant * pointerAuthResignConstant(llvm::Value *Ptr, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, CodeGenModule &CGM)
static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM)
static void dtorTy(Block *, std::byte *Ptr, const Descriptor *)
llvm::MachO::Record Record
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D)
Determine what kind of template specialization the given declaration is.
static QualType getPointeeType(const MemRegion *R)
#define CXXABI(Name, Str)
C Language Family Type Representation.
a trap message and trap category.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const ValueDecl * getMemberPointerDecl() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod) const
Retrieves the default calling convention for the current context.
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'.
Implements C++ ABI-specific semantic analysis functions.
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.
CXXCatchStmt - This represents a C++ catch block.
Represents a C++ constructor within a class.
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
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 new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
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()
base_class_range vbases()
bool isDynamicClass() const
bool hasDefinition() const
CXXRecordDecl * getDefinitionOrSelf() 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.
A C++ throw-expression (C++ [except.throw]).
static CanQual< Type > CreateUnsafe(QualType Other)
Builds a canonical type from a QualType.
Qualifiers getQualifiers() const
Retrieve all qualifiers.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
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.
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ... produce name = getelementptr inbounds addr, i64 index where i64 is actually the t...
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual bool shouldEmitExactDynamicCast(QualType DestRecordTy)=0
virtual void EmitCXXConstructors(const CXXConstructorDecl *D)=0
Emit constructor variants required by this ABI.
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual llvm::Value * getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, const CXXRecordDecl *NearestVBase)=0
Get the address point of the vtable for the given base subobject while building a constructor or a de...
virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0
virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn)=0
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
virtual bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr)=0
Checks if ABI requires extra virtual offset for vtable field.
virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)=0
Emits the guarded initializer and destructor setup for the given variable, given that it couldn't be ...
virtual void EmitCXXDestructors(const CXXDestructorDecl *D)=0
Emit destructor variants required by this ABI.
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, CXXDtorType DT) const =0
Returns true if the given destructor type should be emitted as a linkonce delegating thunk,...
virtual bool NeedsVTTParameter(GlobalDecl GD)
Return whether the given global decl needs a VTT parameter.
virtual llvm::CallInst * emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn)
@ RAA_Default
Pass it using the normal C aggregate rules for the ABI, potentially introducing extra copies and pass...
@ RAA_Indirect
Pass it as a pointer to temporary memory.
virtual bool shouldTypeidBeNullChecked(QualType SrcRecordTy)=0
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const CXXRecordDecl *UnadjustedClass, const ThunkInfo &TI)=0
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual StringRef GetPureVirtualCallName()=0
Gets the pure virtual member call function.
virtual CharUnits getArrayCookieSizeImpl(QualType elementType)
Returns the extra size required in order to store the array cookie for the given type.
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
virtual std::optional< ExactDynamicCastInfo > getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy)=0
virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const =0
Determine whether it's possible to emit a vtable for RD, even though we do not know that the vtable h...
virtual StringRef GetDeletedVirtualCallName()=0
Gets the deleted virtual member call name.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const CXXRecordDecl *UnadjustedClass, const ReturnAdjustment &RA)=0
virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType)=0
Emit a reference to a non-local thread_local variable (including triggering the initialization of all...
bool isEmittedWithConstantInitializer(const VarDecl *VD, bool InspectInitForWeakDef=false) const
Determine whether we will definitely emit this variable with a constant initializer,...
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Constant * EmitMemberPointer(const APValue &MP, QualType MPT)
Create a member pointer for the given member pointer constant.
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
virtual llvm::Value * readArrayCookieImpl(CodeGenFunction &IGF, Address ptr, CharUnits cookieSize)
Reads the array cookie for an allocation which is known to have one.
virtual llvm::Value * getCXXDestructorImplicitParam(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating)=0
Get the implicit (second) parameter that comes after the "this" pointer, or nullptr if there is isn't...
virtual std::pair< llvm::Value *, const CXXRecordDecl * > LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD)=0
Load a vtable from This, an object of polymorphic type RD, or from one of its virtual bases if it doe...
virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment)=0
bool mayNeedDestruction(const VarDecl *VD) const
virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)=0
Checks if ABI requires to initialize vptrs for given dynamic class.
virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0
virtual llvm::Value * GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl)=0
virtual bool isThisCompleteObject(GlobalDecl GD) const =0
Determine whether there's something special about the rules of the ABI tell us that 'this' is a compl...
virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, Address This, llvm::Type *Ty, SourceLocation Loc)=0
Build a virtual function pointer in the ABI-specific way.
virtual bool classifyReturnType(CGFunctionInfo &FI) const =0
If the C++ ABI requires the given type be returned in a particular way, this method sets RetAI and re...
virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0
virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0
virtual void EmitThreadLocalInitFuncs(CodeGenModule &CGM, ArrayRef< const VarDecl * > CXXThreadLocals, ArrayRef< llvm::Function * > CXXThreadLocalInits, ArrayRef< const VarDecl * > CXXThreadLocalInitVars)=0
Emits ABI-required functions necessary to initialize thread_local variables in this translation unit.
virtual bool usesThreadWrapperFunction(const VarDecl *VD) const =0
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
virtual llvm::Value * EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, const MemberPointerType *MPT, bool IsInBounds)
Calculate an l-value from an object and a data member pointer.
virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)=0
Emit the destructor call.
virtual llvm::GlobalVariable * getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset)=0
Get the address of the vtable for the given record decl which should be used for the vptr at the give...
virtual bool EmitBadCastCall(CodeGenFunction &CGF)=0
virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)
Create a member pointer for the given field.
virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD)=0
Emit any tables needed to implement virtual inheritance.
virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD)=0
Emits the VTable definitions required for the given record type.
virtual CGCallee EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, Address This, llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr, const MemberPointerType *MPT)
Load a member function from an object and a member function pointer.
virtual void emitCXXStructor(GlobalDecl GD)=0
Emit a single constructor/destructor with the given type from a C++ constructor Decl.
virtual llvm::Value * EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke)=0
Emit the ABI-specific virtual destructor call.
virtual bool exportThunk()=0
virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0
virtual llvm::Value * emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy)=0
virtual bool isZeroInitializable(const MemberPointerType *MPT)
Return true if the given member pointer can be zero-initialized (in the C++ sense) with an LLVM zeroi...
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)
Create a member pointer for the given method.
virtual llvm::Value * emitDynamicCastCall(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd)=0
virtual Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType)
Initialize the array cookie for the given allocation.
virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, QualType SrcRecordTy)=0
virtual AddedStructorArgCounts buildStructorSignature(GlobalDecl GD, SmallVectorImpl< CanQualType > &ArgTys)=0
Build the signature of the given constructor or destructor variant by adding any required parameters.
virtual llvm::Value * emitExactDynamicCast(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, const ExactDynamicCastInfo &CastInfo, llvm::BasicBlock *CastSuccess, llvm::BasicBlock *CastFail)=0
Emit a dynamic_cast from SrcRecordTy to DestRecordTy.
MangleContext & getMangleContext()
Gets the mangle context.
virtual AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating)=0
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())
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
llvm::Value * getDiscriminator() const
CallArgList - Type for representing both the value and type of arguments in a call.
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass, VTableAuthMode AuthMode=VTableAuthMode::Authenticate)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
llvm::Function * createTLSAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr, llvm::FunctionCallee &AtExit)
Create a stub function, suitable for being passed to __pt_atexit_np, which passes the given address t...
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitARCInitWeak(Address addr, llvm::Value *value)
i8* @objc_initWeak(i8** addr, i8* value) Returns value.
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
llvm::Type * ConvertType(QualType T)
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
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 GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, llvm::BasicBlock *InitBlock, llvm::BasicBlock *NoInitBlock, GuardKind Kind, const VarDecl *D)
Emit a branch to select whether or not to perform guarded initialization.
CGDebugInfo * getDebugInfo()
LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source=AlignmentSource::Type)
Same as MakeAddrLValue above except that the pointer is known to be unsigned.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Emit the concrete pointer authentication informaton for the given authentication schema.
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
llvm::Value * unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub)
Call unatexit() with function dtorStub.
llvm::Value * emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void registerGlobalDtorWithLLVM(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Registers the dtor using 'llvm.global_dtors' for platforms that do not support an 'atexit()' function...
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
llvm::Type * ConvertTypeForMem(QualType T)
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Instruction * CurrentFuncletPad
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::LLVMContext & getLLVMContext()
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
This class organizes the cross-function state that is used while generating LLVM code.
void AddCXXPrioritizedStermFinalizerEntry(llvm::Function *StermFinalizer, int Priority)
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
void AddCXXStermFinalizerToGlobalDtor(llvm::Function *StermFinalizer, int Priority)
Add an sterm finalizer to its own llvm.global_dtors entry.
llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const
Get LLVM TLS mode from CodeGenOptions.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenVTables & getVTables()
void AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn)
Add an sterm finalizer to the C++ global cleanup function.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
llvm::Constant * getFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return the ABI-correct function pointer value for a reference to the given function.
CGPointerAuthInfo getMemberFunctionPointerAuthInfo(QualType FT)
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const
const TargetInfo & getTarget() const
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD)
Returns LLVM linkage for a declarator.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V)
llvm::Constant * getMemberFunctionPointer(const FunctionDecl *FD, llvm::Type *Ty=nullptr)
llvm::Function * codegenCXXStructor(GlobalDecl GD)
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const llvm::Triple & getTriple() const
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD)
void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535, bool IsDtorAttrFunc=false)
AddGlobalDtor - Add a function to the list that will be called when the module is unloaded.
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 AddGlobalCtor(llvm::Function *Ctor, int Priority=65535, unsigned LexOrder=~0U, llvm::Constant *AssociatedData=nullptr)
AddGlobalCtor - Add a function to the list that will be called before main() runs.
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)
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
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.
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.
A specialization of Address that requires the address to be an LLVM Constant.
The standard implementation of ConstantInitBuilder used in Clang.
Information for lazily generating a cleanup.
void popTerminate()
Pops a terminate handler off the stack.
void pushTerminate()
Push a terminate handler on the stack.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
A class for recording the number of arguments that a function signature requires.
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
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.
Represents a function declaration or definition.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
Represents a prototype with parameter type info, e.g.
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
CXXCtorType getCtorType() const
GlobalDecl getCanonicalDecl() const
GlobalDecl getWithDtorType(CXXDtorType Type)
CXXDtorType getDtorType() const
const Decl * getDecl() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
bool isRelativeLayout() const
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
GlobalDecl findOriginalMethod(GlobalDecl GD)
Return the method that added the v-table slot that will be used to call the given method.
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
bool isExternallyVisible() const
Represents an ObjC class declaration.
Represents a class type in Objective C.
QualType getBaseType() const
Gets the base type of this object type.
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.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) 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.
RecordDecl * getDefinitionOrSelf() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
Encodes a location in the source.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
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
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
TLSKind getTLSKind() const
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
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.
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)
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.
The JSON file list parser is used to communicate input to InstallAPI.
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.
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
@ Success
Annotation was successful.
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_Comdat
The COMDAT used for dtors.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
bool isDiscardableGVALinkage(GVALinkage L)
LangAS
Defines the address space values used by the address space qualifier of QualType.
const FunctionProtoType * T
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ EST_None
no exception specification
Visibility
Describes the different kinds of visibility that a declaration may have.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
const half4 dst(half4 Src0, half4 Src1)
Represents an element in a path from a derived class to a base class.
Similar to AddedStructorArgs, but only notes the number of additional arguments.
Additional implicit arguments to add to the beginning (Prefix) and end (Suffix) of a constructor / de...
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
Struct with all information about dynamic [sub]class needed to set vptr.
const CXXRecordDecl * NearestVBase
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
llvm::PointerType * GlobalsVoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * CharTy
char
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * SizeTy
llvm::PointerType * VoidPtrPtrTy
llvm::PointerType * GlobalsInt8PtrTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
CharUnits getSizeSize() const
CharUnits getSizeAlign() const
llvm::PointerType * Int8PtrTy
llvm::PointerType * UnqualPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
static const EHPersonality & get(CodeGenModule &CGM, const FunctionDecl *FD)
Extra information about a function prototype.
PointerAuthSchema CXXVTTVTablePointers
The ABI for C++ virtual table pointers as installed in a VTT.
PointerAuthSchema CXXTypeInfoVTablePointer
TypeInfo has external ABI requirements and is emitted without actually having parsed the libcxx defin...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
A this pointer adjustment.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
The this pointer adjustment as well as an optional return adjustment for a thunk.
ThisAdjustment This
The this pointer adjustment.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@179 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.
struct clang::ThisAdjustment::VirtualAdjustment::@181 Itanium