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"
42 using namespace clang;
43 using 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) { }
80 bool isThisCompleteObject(
GlobalDecl GD)
const override {
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,
139 llvm::Value *Src)
override;
140 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *
E,
141 llvm::Constant *Src)
override;
145 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
148 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
153 llvm::Value *L, llvm::Value *R,
155 bool Inequality)
override;
172 llvm::Value *Exn)
override;
174 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
175 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
177 getAddrOfCXXCatchHandlerType(
QualType Ty,
178 QualType CatchHandlerType)
override {
182 bool shouldTypeidBeNullChecked(
QualType SrcRecordTy)
override;
186 llvm::Type *StdTypeInfoPtrTy)
override;
188 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
195 bool hasUniqueVTablePointer(
QualType RecordTy) {
200 if (!CGM.getCodeGenOpts().AssumeUniqueVTables ||
201 getContext().getLangOpts().AppleKext)
206 if (!CGM.shouldEmitRTTI())
211 if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))
226 bool shouldEmitExactDynamicCast(
QualType DestRecordTy)
override {
227 return hasUniqueVTablePointer(DestRecordTy);
233 llvm::BasicBlock *CastEnd)
override;
238 llvm::BasicBlock *CastSuccess,
239 llvm::BasicBlock *CastFail)
override;
253 AddedStructorArgCounts
276 bool Delegating)
override;
282 bool Delegating)
override;
295 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
303 llvm::Value *getVTableAddressPointInStructor(
307 llvm::Value *getVTableAddressPointInStructorWithVTT(
311 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
321 DeleteOrMemberCallExpr
E)
override;
323 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
325 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
326 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
328 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
GlobalDecl GD,
332 if (ForVTable && !Thunk->hasLocalLinkage())
333 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
334 CGM.setGVProperties(Thunk, GD);
337 bool exportThunk()
override {
return true; }
349 assert(!Args.empty() &&
"expected the arglist to not be empty!");
350 return Args.size() - 1;
353 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
354 StringRef GetDeletedVirtualCallName()
override
355 {
return "__cxa_deleted_virtual"; }
360 llvm::Value *NumElements,
368 llvm::GlobalVariable *DeclPtr,
369 bool PerformInit)
override;
371 llvm::FunctionCallee dtor,
372 llvm::Constant *addr)
override;
374 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
376 void EmitThreadLocalInitFuncs(
382 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
383 return !isEmittedWithConstantInitializer(VD) ||
384 mayNeedDestruction(VD);
389 bool NeedsVTTParameter(
GlobalDecl GD)
override;
392 getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
399 virtual bool shouldRTTIBeUnique()
const {
return true; }
403 enum RTTIUniquenessKind {
421 classifyRTTIUniqueness(
QualType CanTy,
422 llvm::GlobalValue::LinkageTypes
Linkage)
const;
423 friend class ItaniumRTTIBuilder;
427 std::pair<llvm::Value *, const CXXRecordDecl *>
433 getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
435 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
436 const auto &VtableLayout =
437 CGM.getItaniumVTableContext().getVTableLayout(RD);
439 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
441 if (!VtableComponent.isUsedFunctionPointerKind())
444 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
448 StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
449 auto *Entry = CGM.GetGlobalValue(Name);
455 if (!Entry || Entry->isDeclaration())
462 const auto &VtableLayout =
463 CGM.getItaniumVTableContext().getVTableLayout(RD);
465 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
466 if (VtableComponent.isRTTIKind()) {
467 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
470 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
471 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
481 class ARMCXXABI :
public ItaniumCXXABI {
484 ItaniumCXXABI(CGM,
true,
487 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
495 llvm::Value *NumElements,
502 class AppleARM64CXXABI :
public ARMCXXABI {
505 Use32BitVTableOffsetABI =
true;
509 bool shouldRTTIBeUnique()
const override {
return false; }
512 class FuchsiaCXXABI final :
public ItaniumCXXABI {
515 : ItaniumCXXABI(CGM) {}
518 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
521 class WebAssemblyCXXABI final :
public ItaniumCXXABI {
524 : ItaniumCXXABI(CGM,
true,
529 llvm::Value *Exn)
override;
532 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
533 bool canCallMismatchedFunctionType()
const override {
return false; }
536 class XLCXXABI final :
public ItaniumCXXABI {
539 : ItaniumCXXABI(CGM) {}
542 llvm::FunctionCallee dtor,
543 llvm::Constant *addr)
override;
545 bool useSinitAndSterm()
const override {
return true; }
548 void emitCXXStermFinalizer(
const VarDecl &
D, llvm::Function *dtorStub,
549 llvm::Constant *addr);
557 case TargetCXXABI::GenericARM:
558 case TargetCXXABI::iOS:
559 case TargetCXXABI::WatchOS:
560 return new ARMCXXABI(CGM);
562 case TargetCXXABI::AppleARM64:
563 return new AppleARM64CXXABI(CGM);
565 case TargetCXXABI::Fuchsia:
566 return new FuchsiaCXXABI(CGM);
571 case TargetCXXABI::GenericAArch64:
572 return new ItaniumCXXABI(CGM,
true,
575 case TargetCXXABI::GenericMIPS:
576 return new ItaniumCXXABI(CGM,
true);
578 case TargetCXXABI::WebAssembly:
579 return new WebAssemblyCXXABI(CGM);
581 case TargetCXXABI::XL:
582 return new XLCXXABI(CGM);
584 case TargetCXXABI::GenericItanium:
585 return new ItaniumCXXABI(CGM);
587 case TargetCXXABI::Microsoft:
588 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
590 llvm_unreachable(
"bad ABI kind");
596 return CGM.PtrDiffTy;
597 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
620 CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
622 llvm::Value *&ThisPtrForCall,
631 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
638 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
641 llvm::Value *Adj = RawAdj;
642 if (UseARMMethodPtrABI)
643 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
648 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(),
This, Adj);
649 ThisPtrForCall =
This;
652 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
656 llvm::Value *IsVirtual;
657 if (UseARMMethodPtrABI)
658 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
660 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
661 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
662 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
680 llvm::Value *VTableOffset = FnAsInt;
681 if (!UseARMMethodPtrABI)
682 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
683 if (Use32BitVTableOffsetABI) {
684 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
685 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
690 llvm::Constant *CheckSourceLocation;
691 llvm::Constant *CheckTypeDesc;
692 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
693 CGM.HasHiddenLTOVisibility(RD);
694 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
695 CGM.HasHiddenLTOVisibility(RD);
696 bool ShouldEmitWPDInfo =
697 CGM.getCodeGenOpts().WholeProgramVTables &&
699 !CGM.AlwaysHasLTOVisibilityPublic(RD);
700 llvm::Value *VirtualFn =
nullptr;
704 llvm::Value *TypeId =
nullptr;
705 llvm::Value *CheckResult =
nullptr;
707 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
711 CGM.CreateMetadataIdentifierForVirtualMemPtrType(
QualType(MPT, 0));
715 if (ShouldEmitVFEInfo) {
716 llvm::Value *VFPAddr =
717 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
724 llvm::Value *CheckedLoad = Builder.CreateCall(
725 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
726 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
727 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
728 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
732 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
733 llvm::Value *VFPAddr =
734 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
736 ? llvm::Intrinsic::type_test
737 : llvm::Intrinsic::public_type_test;
740 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
743 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
744 VirtualFn = CGF.
Builder.CreateCall(
745 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
746 {VTableOffset->getType()}),
747 {VTable, VTableOffset});
749 llvm::Value *VFPAddr =
756 assert(VirtualFn &&
"Virtual fuction pointer not created!");
757 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
759 "Check result required but not created!");
761 if (ShouldEmitCFICheck) {
765 llvm::Constant *StaticData[] = {
771 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
772 CGF.
EmitTrapCheck(CheckResult, SanitizerHandler::CFICheckFail);
774 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
775 CGM.getLLVMContext(),
776 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
777 llvm::Value *ValidVtable = Builder.CreateCall(
778 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
779 CGF.
EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIMFCall),
780 SanitizerHandler::CFICheckFail, StaticData,
781 {VTable, ValidVtable});
784 FnVirtual = Builder.GetInsertBlock();
793 llvm::Value *NonVirtualFn = Builder.CreateIntToPtr(
795 "memptr.nonvirtualfn");
798 if (ShouldEmitCFICheck) {
803 llvm::Constant *StaticData[] = {
809 llvm::Value *Bit = Builder.getFalse();
811 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
812 getContext().getMemberPointerType(
815 llvm::Value *TypeId =
818 llvm::Value *TypeTest =
819 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
820 {NonVirtualFn, TypeId});
821 Bit = Builder.CreateOr(Bit, TypeTest);
824 CGF.
EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
825 SanitizerHandler::CFICheckFail, StaticData,
826 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
828 FnNonVirtual = Builder.GetInsertBlock();
834 llvm::PHINode *CalleePtr =
835 Builder.CreatePHI(llvm::PointerType::getUnqual(CGF.
getLLVMContext()), 2);
836 CalleePtr->addIncoming(VirtualFn, FnVirtual);
837 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
841 if (
const auto &Schema =
842 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
843 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
844 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
846 const auto &AuthInfo =
847 CGM.getMemberFunctionPointerAuthInfo(
QualType(MPT, 0));
848 assert(Schema.getKey() == AuthInfo.getKey() &&
849 "Keys for virtual and non-virtual member functions must match");
850 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
851 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
853 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
854 Schema.authenticatesNullValues(), DiscriminatorPHI);
863 llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
866 assert(MemPtr->getType() == CGM.PtrDiffTy);
871 return Builder.CreateInBoundsGEP(CGF.
Int8Ty,
Base.emitRawPointer(CGF), MemPtr,
879 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
884 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
885 CPA->getAddrDiscriminator()->isZeroValue() &&
887 "unexpected key or discriminators");
890 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
922 if (isa<llvm::Constant>(src))
923 return EmitMemberPointerConversion(
E, cast<llvm::Constant>(src));
925 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
926 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
927 E->getCastKind() == CK_ReinterpretMemberPointer);
933 if (
const auto &NewAuthInfo =
934 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
937 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
938 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
939 llvm::Type *OrigTy = MemFnPtr->getType();
941 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
946 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
947 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
948 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
949 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
950 llvm::Value *IsVirtualOffset =
951 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
952 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
955 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.Int8Ty);
956 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
959 isa<llvm::Constant>(src));
960 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
961 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
962 ResignBB = Builder.GetInsertBlock();
965 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
966 NewSrc->addIncoming(src, StartBB);
967 NewSrc->addIncoming(ResignedVal, ResignBB);
973 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
975 llvm::Constant *adj = getMemberPointerAdjustment(
E);
976 if (!adj)
return src;
978 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
988 dst = Builder.CreateNSWSub(src, adj,
"adj");
990 dst = Builder.CreateNSWAdd(src, adj,
"adj");
993 llvm::Value *
null = llvm::Constant::getAllOnesValue(src->getType());
994 llvm::Value *isNull = Builder.CreateICmpEQ(src,
null,
"memptr.isnull");
995 return Builder.CreateSelect(isNull, src, dst);
999 if (UseARMMethodPtrABI) {
1000 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1002 adj = llvm::ConstantInt::get(adj->getType(), offset);
1005 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1006 llvm::Value *dstAdj;
1007 if (isDerivedToBase)
1008 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1010 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1012 return Builder.CreateInsertValue(src, dstAdj, 1);
1015 static llvm::Constant *
1020 "member function pointers expected");
1021 if (DestType == SrcType)
1027 if (!NewAuthInfo && !CurAuthInfo)
1030 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1031 if (MemFnPtr->getNumOperands() == 0) {
1033 assert(isa<llvm::ConstantInt>(MemFnPtr) &&
"constant int expected");
1038 cast<llvm::User>(MemFnPtr)->getOperand(0), CurAuthInfo, NewAuthInfo, CGM);
1039 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1040 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1044 ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *
E,
1045 llvm::Constant *src) {
1046 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
1047 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
1048 E->getCastKind() == CK_ReinterpretMemberPointer);
1054 src, DstType,
E->getSubExpr()->
getType(), CGM);
1057 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
1060 llvm::Constant *adj = getMemberPointerAdjustment(
E);
1061 if (!adj)
return src;
1063 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
1072 if (src->isAllOnesValue())
return src;
1074 if (isDerivedToBase)
1075 return llvm::ConstantExpr::getNSWSub(src, adj);
1077 return llvm::ConstantExpr::getNSWAdd(src, adj);
1081 if (UseARMMethodPtrABI) {
1082 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1084 adj = llvm::ConstantInt::get(adj->getType(), offset);
1087 llvm::Constant *srcAdj = src->getAggregateElement(1);
1088 llvm::Constant *dstAdj;
1089 if (isDerivedToBase)
1090 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1092 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1094 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1095 assert(res !=
nullptr &&
"Folding must succeed");
1104 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1106 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1107 llvm::Constant *Values[2] = {
Zero,
Zero };
1108 return llvm::ConstantStruct::getAnon(Values);
1117 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1121 ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1125 llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1127 assert(MD->
isInstance() &&
"Member function must not be static!");
1132 llvm::Constant *MemPtr[2];
1134 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1136 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1138 VTableOffset = Index * 4;
1143 VTableOffset = Index * PointerWidth.
getQuantity();
1146 if (UseARMMethodPtrABI) {
1168 const auto &Schema =
1169 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1171 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1172 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1174 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1177 MemPtr[1] = llvm::ConstantInt::get(
1184 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1185 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1192 if (Types.isFuncTypeConvertible(FPT)) {
1194 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
1200 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1202 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1203 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1204 (UseARMMethodPtrABI ? 2 : 1) *
1208 return llvm::ConstantStruct::getAnon(MemPtr);
1211 llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1216 return EmitNullMemberPointer(MPT);
1220 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1222 QualType SrcType = getContext().getMemberPointerType(
1228 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1244 llvm::ICmpInst::Predicate
Eq;
1245 llvm::Instruction::BinaryOps
And,
Or;
1247 Eq = llvm::ICmpInst::ICMP_NE;
1248 And = llvm::Instruction::Or;
1251 Eq = llvm::ICmpInst::ICMP_EQ;
1253 Or = llvm::Instruction::Or;
1259 return Builder.CreateICmp(Eq, L, R);
1271 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1272 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1276 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1281 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1282 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero,
"cmp.ptr.null");
1286 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1287 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1288 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1292 if (UseARMMethodPtrABI) {
1293 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1296 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1297 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1298 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
1300 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
1304 llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
1305 Result = Builder.CreateBinOp(And, PtrEq, Result,
1306 Inequality ?
"memptr.ne" :
"memptr.eq");
1312 llvm::Value *MemPtr,
1318 assert(MemPtr->getType() == CGM.PtrDiffTy);
1319 llvm::Value *NegativeOne =
1320 llvm::Constant::getAllOnesValue(MemPtr->getType());
1321 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1325 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1327 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1328 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
1332 if (UseARMMethodPtrABI) {
1333 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1334 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1335 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1336 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1337 "memptr.isvirtual");
1338 Result = Builder.CreateOr(Result, IsVirtual);
1351 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1372 if (UseGlobalDelete) {
1380 Ptr, llvm::PointerType::getUnqual(CGF.
getLLVMContext()), ClassDecl);
1383 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1384 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1402 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
1404 if (UseGlobalDelete)
1408 void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1411 llvm::FunctionType *FTy =
1412 llvm::FunctionType::get(CGM.VoidTy,
false);
1414 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1425 llvm::FunctionType *FTy =
1436 llvm::FunctionType *FTy =
1437 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1445 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1446 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1450 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1454 E->getSubExpr(),
Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));
1457 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1462 llvm::Constant *Dtor =
nullptr;
1465 if (!
Record->hasTrivialDestructor()) {
1475 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1478 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1480 llvm::Value *args[] = { ExceptionPtr,
TypeInfo, Dtor };
1492 llvm::Type *PtrDiffTy =
1495 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1497 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1501 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1502 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1503 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1504 llvm::AttributeList Attrs = llvm::AttributeList::get(
1505 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1512 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1529 unsigned NumPublicPaths = 0;
1542 if (PathElement.Base->isVirtual())
1545 if (NumPublicPaths > 1)
1551 PathElement.Base->getType()->getAsCXXRecordDecl());
1556 if (NumPublicPaths == 0)
1560 if (NumPublicPaths > 1)
1570 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1575 bool ItaniumCXXABI::shouldTypeidBeNullChecked(
QualType SrcRecordTy) {
1582 Call->setDoesNotReturn();
1583 CGF.
Builder.CreateUnreachable();
1589 llvm::Type *StdTypeInfoPtrTy) {
1595 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1598 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1599 {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});
1603 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1609 bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1614 llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1617 llvm::Type *PtrDiffLTy =
1620 llvm::Value *SrcRTTI =
1622 llvm::Value *DestRTTI =
1628 llvm::Value *OffsetHint = llvm::ConstantInt::get(
1634 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1640 llvm::Value *Vtable =
1647 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1653 llvm::BasicBlock *BadCastBlock =
1657 CGF.
Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1660 EmitBadCastCall(CGF);
1666 llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1669 llvm::BasicBlock *CastFail) {
1681 std::optional<CharUnits>
Offset;
1691 PathElement.Base->getType()->getAsCXXRecordDecl();
1692 if (PathElement.Base->isVirtual()) {
1706 else if (
Offset != PathOffset) {
1711 ThisAddr =
Address(emitDynamicCastToVoid(CGF, ThisAddr, SrcRecordTy),
1722 return llvm::PoisonValue::get(CGF.
VoidPtrTy);
1731 CGM.DecorateInstructionWithTBAA(
1732 VPtr, CGM.getTBAAVTablePtrAccessInfo(CGF.
VoidPtrPtrTy));
1739 {llvm::ConstantInt::get(CGF.PtrDiffTy, -Offset->getQuantity())});
1740 CGF.
Builder.CreateCondBr(Success, CastSuccess, CastFail);
1744 llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(
CodeGenFunction &CGF,
1749 llvm::Value *OffsetToTop;
1750 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1758 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1762 llvm::Type *PtrDiffLTy =
1772 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1784 Call->setDoesNotReturn();
1785 CGF.
Builder.CreateUnreachable();
1796 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1798 llvm::Value *VBaseOffsetPtr =
1799 CGF.
Builder.CreateConstGEP1_64(
1801 "vbase.offset.ptr");
1803 llvm::Value *VBaseOffset;
1804 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1810 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1817 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1825 if (!
D->getParent()->isAbstract()) {
1832 ItaniumCXXABI::buildStructorSignature(
GlobalDecl GD,
1842 cast<CXXMethodDecl>(GD.
getDecl())->getParent()->getNumVBases() != 0) {
1843 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1845 ArgTys.insert(ArgTys.begin() + 1,
1847 return AddedStructorArgCounts::prefix(1);
1849 return AddedStructorArgCounts{};
1872 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1875 if (NeedsVTTParameter(CGF.
CurGD)) {
1879 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1885 Params.insert(Params.begin() + 1, VTTDecl);
1886 getStructorImplicitParamDecl(CGF) = VTTDecl;
1890 void ItaniumCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1897 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1900 if (getStructorImplicitParamDecl(CGF)) {
1913 if (HasThisReturn(CGF.
CurGD))
1919 bool ForVirtualBase,
bool Delegating) {
1921 return AddedStructorArgs{};
1928 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1929 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
1930 QualType VTTTy = getContext().getPointerType(Q);
1931 return AddedStructorArgs::prefix({{VTT, VTTTy}});
1936 bool ForVirtualBase,
bool Delegating) {
1949 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1952 if (getContext().getLangOpts().AppleKext &&
1959 ThisTy, VTT, VTTTy,
nullptr);
1963 template <
typename T>
1966 if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
1967 if (FD->isInlined() || FD->doesThisDeclarationHaveABody() ||
1968 FD->isPureVirtual())
1979 llvm::GlobalVariable *VTable,
1981 if (VTable->getDLLStorageClass() !=
1982 llvm::GlobalVariable::DefaultStorageClass ||
1987 if (CXXRecordNonInlineHasAttr<DLLImportAttr>(RD))
1988 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1989 }
else if (CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
1990 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1995 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1996 if (VTable->hasInitializer())
2001 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2002 llvm::Constant *RTTI =
2003 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
2007 auto components = builder.beginStruct();
2009 llvm::GlobalValue::isLocalLinkage(
Linkage));
2010 components.finishAndSetAsInitializer(VTable);
2015 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2016 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2018 if (CGM.getTarget().hasPS4DLLImportExport())
2022 CGM.setGVProperties(VTable, RD);
2030 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
2031 cast<NamespaceDecl>(DC)->getIdentifier()->isStr(
"__cxxabiv1") &&
2033 EmitFundamentalRTTIDescriptors(RD);
2040 if (!VTable->isDeclarationForLinker() ||
2041 CGM.getCodeGenOpts().WholeProgramVTables) {
2042 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2046 if (VTable->isDeclarationForLinker()) {
2047 assert(CGM.getCodeGenOpts().WholeProgramVTables);
2048 CGM.addCompilerUsedGlobal(VTable);
2054 if (!VTable->isDSOLocal())
2059 bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2063 return NeedsVTTParameter(CGF.
CurGD);
2066 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2070 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2071 NeedsVTTParameter(CGF.
CurGD)) {
2072 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass,
Base,
2075 return getVTableAddressPoint(
Base, VTableClass);
2081 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
2086 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2089 llvm::Value *Indices[] = {
2090 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2091 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2097 unsigned ComponentSize =
2098 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2099 unsigned VTableSize =
2104 return llvm::ConstantExpr::getGetElementPtr(
2105 VTable->getValueType(), VTable, Indices,
true,
InRange);
2108 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2111 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2112 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2116 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass,
Base);
2120 if (VirtualPointerIndex)
2122 VirtualPointerIndex);
2139 llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2141 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2143 llvm::GlobalVariable *&VTable = VTables[RD];
2148 CGM.addDeferredVTable(RD);
2151 llvm::raw_svector_ostream Out(Name);
2152 getMangleContext().mangleCXXVTable(RD, Out);
2155 CGM.getItaniumVTableContext().getVTableLayout(RD);
2156 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2161 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
2162 unsigned PAlign = CGM.getItaniumVTableContext().isRelativeLayout()
2164 : CGM.getTarget().getPointerAlign(AS);
2166 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2167 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2168 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2169 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2171 if (CGM.getTarget().hasPS4DLLImportExport())
2174 CGM.setGVProperties(VTable, RD);
2182 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2183 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
2184 llvm::Value *VTable = CGF.
GetVTablePtr(
This, PtrTy, MethodDecl->getParent());
2186 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2187 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2188 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2191 MethodDecl->getParent(), VTable, PtrTy,
2198 llvm::Value *VFuncLoad;
2199 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
2200 VFuncLoad = CGF.
Builder.CreateCall(
2201 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2202 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, 4 * VTableIndex)});
2204 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2205 PtrTy, VTable, VTableIndex,
"vfn");
2216 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2217 CGM.getCodeGenOpts().StrictVTablePointers) {
2218 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2219 VFuncLoadInstr->setMetadata(
2220 llvm::LLVMContext::MD_invariant_load,
2221 llvm::MDNode::get(CGM.getLLVMContext(),
2230 assert(VTableSlotPtr &&
"virtual function pointer not set");
2231 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2238 llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2243 assert((CE !=
nullptr) ^ (
D !=
nullptr));
2244 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
2249 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2255 ThisTy = CE->getObjectType();
2257 ThisTy =
D->getDestroyedType();
2265 void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2271 bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2275 if (CGM.getLangOpts().AppleKext)
2280 if (isVTableHidden(RD))
2283 if (CGM.getCodeGenOpts().ForceEmitVTables)
2290 if (hasAnyUnusedVirtualInlineFunction(RD))
2298 for (
const auto &B : RD->
bases()) {
2299 auto *BRD = B.getType()->getAsCXXRecordDecl();
2300 assert(BRD &&
"no class for base specifier");
2301 if (B.isVirtual() || !BRD->isDynamicClass())
2303 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2311 bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2312 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2320 for (
const auto &B : RD->
vbases()) {
2321 auto *BRD = B.getType()->getAsCXXRecordDecl();
2322 assert(BRD &&
"no class for base specifier");
2323 if (!BRD->isDynamicClass())
2325 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2336 bool IsReturnAdjustment) {
2337 if (!NonVirtualAdjustment && !VirtualAdjustment)
2343 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2349 llvm::Value *ResultPtr;
2350 if (VirtualAdjustment) {
2351 llvm::Value *VTablePtr =
2355 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2356 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2363 llvm::Type *PtrDiffTy =
2372 V.emitRawPointer(CGF),
Offset);
2374 ResultPtr =
V.emitRawPointer(CGF);
2379 if (NonVirtualAdjustment && IsReturnAdjustment) {
2380 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2381 NonVirtualAdjustment);
2408 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2413 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2422 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2427 llvm::Value *NumElements,
2430 assert(requiresArrayCookie(
expr));
2440 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2444 CharUnits CookieOffset = CookieSize - SizeSize;
2445 if (!CookieOffset.
isZero())
2453 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2454 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2455 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2457 SI->setNoSanitizeMetadata();
2458 llvm::FunctionType *FTy =
2459 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2460 llvm::FunctionCallee F =
2461 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2474 Address numElementsPtr = allocPtr;
2476 if (!numElementsOffset.
isZero())
2482 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2489 llvm::FunctionType *FTy = llvm::FunctionType::get(
2491 llvm::FunctionCallee F =
2492 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2506 CGM.getContext().getTypeAlignInChars(elementType));
2511 llvm::Value *numElements,
2514 assert(requiresArrayCookie(
expr));
2521 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2522 getContext().getTypeSizeInChars(elementType).getQuantity());
2531 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2550 llvm::PointerType *GuardPtrTy) {
2552 llvm::FunctionType *FTy =
2556 FTy,
"__cxa_guard_acquire",
2558 llvm::AttributeList::FunctionIndex,
2559 llvm::Attribute::NoUnwind));
2563 llvm::PointerType *GuardPtrTy) {
2565 llvm::FunctionType *FTy =
2566 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2568 FTy,
"__cxa_guard_release",
2570 llvm::AttributeList::FunctionIndex,
2571 llvm::Attribute::NoUnwind));
2575 llvm::PointerType *GuardPtrTy) {
2577 llvm::FunctionType *FTy =
2578 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2580 FTy,
"__cxa_guard_abort",
2582 llvm::AttributeList::FunctionIndex,
2583 llvm::Attribute::NoUnwind));
2588 llvm::GlobalVariable *Guard;
2589 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2602 llvm::GlobalVariable *
var,
2603 bool shouldPerformInit) {
2608 bool NonTemplateInline =
2615 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2616 (
D.isLocalVarDecl() || NonTemplateInline) &&
2621 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2623 llvm::IntegerType *guardTy;
2625 if (useInt8GuardVariable) {
2631 if (UseARMGuardVarABI) {
2640 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2646 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&
D);
2651 llvm::raw_svector_ostream out(guardName);
2652 getMangleContext().mangleStaticGuardVariable(&
D, out);
2658 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2659 false,
var->getLinkage(),
2660 llvm::ConstantInt::get(guardTy, 0),
2662 guard->setDSOLocal(
var->isDSOLocal());
2663 guard->setVisibility(
var->getVisibility());
2664 guard->setDLLStorageClass(
var->getDLLStorageClass());
2666 guard->setThreadLocalMode(
var->getThreadLocalMode());
2667 guard->setAlignment(guardAlignment.
getAsAlign());
2672 llvm::Comdat *
C =
var->getComdat();
2673 if (!
D.isLocalVarDecl() && C &&
2674 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2675 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2676 guard->setComdat(C);
2677 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2678 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2681 CGM.setStaticLocalDeclGuardAddress(&
D, guard);
2684 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2709 if (!threadsafe || MaxInlineWidthInBits) {
2711 llvm::LoadInst *LI =
2721 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2744 (UseARMGuardVarABI && !useInt8GuardVariable)
2745 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2747 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2781 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2782 InitBlock, EndBlock);
2788 }
else if (!
D.isLocalVarDecl()) {
2792 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2806 }
else if (
D.isLocalVarDecl()) {
2810 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2819 llvm::FunctionCallee dtor,
2820 llvm::Constant *addr,
bool TLS) {
2822 "unexpected call to emitGlobalDtorWithCXAAtExit");
2824 "__cxa_atexit is disabled");
2825 const char *Name =
"__cxa_atexit";
2828 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2836 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2837 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2841 llvm::Constant *handle =
2843 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2847 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2848 llvm::FunctionType *atexitTy =
2849 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2853 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2854 fn->setDoesNotThrow();
2861 llvm::Constant *dtorCallee = cast<llvm::Constant>(dtor.getCallee());
2869 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2871 llvm::Value *args[] = {dtorCallee, addr, handle};
2879 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2883 return GlobalInitOrCleanupFn;
2886 void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
2887 for (
const auto &I : DtorsUsingAtExit) {
2889 std::string GlobalCleanupFnName =
2890 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(
Priority);
2892 llvm::Function *GlobalCleanupFn =
2902 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
2906 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2907 auto itv = Dtors.rbegin();
2908 while (itv != Dtors.rend()) {
2909 llvm::Function *Dtor = *itv;
2914 llvm::Value *NeedsDestruct =
2917 llvm::BasicBlock *DestructCallBlock =
2920 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
2923 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
2928 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
2930 CI->setCallingConv(Dtor->getCallingConv());
2942 void CodeGenModule::registerGlobalDtorsWithAtExit() {
2943 for (
const auto &I : DtorsUsingAtExit) {
2945 std::string GlobalInitFnName =
2946 std::string(
"__GLOBAL_init_") + llvm::to_string(
Priority);
2947 llvm::Function *GlobalInitFn =
2961 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2962 for (
auto *Dtor : Dtors) {
2979 unregisterGlobalDtorsWithUnAtExit();
2984 llvm::FunctionCallee dtor,
2985 llvm::Constant *addr) {
2986 if (
D.isNoDestroy(CGM.getContext()))
2994 if (!CGM.getLangOpts().hasAtExit() && !
D.isStaticLocal())
3001 if (CGM.getCodeGenOpts().CXAAtExit ||
D.getTLSKind())
3006 if (CGM.getLangOpts().AppleKext) {
3008 return CGM.AddCXXDtorEntry(dtor, addr);
3016 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3026 static llvm::GlobalValue::LinkageTypes
3028 llvm::GlobalValue::LinkageTypes VarLinkage =
3032 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3037 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3038 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3040 return llvm::GlobalValue::WeakODRLinkage;
3044 ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3049 llvm::raw_svector_ostream Out(WrapperName);
3050 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3055 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3056 return cast<llvm::Function>(
V);
3062 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3065 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3066 llvm::Function *Wrapper =
3068 WrapperName.str(), &CGM.getModule());
3070 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3071 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3073 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, Wrapper,
false);
3076 if (!Wrapper->hasLocalLinkage())
3078 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3079 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3084 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3085 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3088 ThreadWrappers.push_back({VD, Wrapper});
3092 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3096 llvm::Function *InitFunc =
nullptr;
3101 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3102 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3105 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3106 CXXThreadLocalInits[I];
3108 OrderedInits.push_back(CXXThreadLocalInits[I]);
3111 if (!OrderedInits.empty()) {
3113 llvm::FunctionType *FTy =
3114 llvm::FunctionType::get(CGM.
VoidTy,
false);
3119 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3121 llvm::GlobalVariable::InternalLinkage,
3122 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3123 Guard->setThreadLocal(
true);
3127 Guard->setAlignment(GuardAlign.
getAsAlign());
3133 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3134 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3140 for (
const VarDecl *VD : CXXThreadLocals) {
3144 getOrCreateThreadLocalWrapper(VD, GV);
3149 for (
auto VDAndWrapper : ThreadWrappers) {
3150 const VarDecl *VD = VDAndWrapper.first;
3151 llvm::GlobalVariable *Var =
3153 llvm::Function *Wrapper = VDAndWrapper.second;
3160 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3166 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3167 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3175 llvm::raw_svector_ostream Out(InitFnName);
3176 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3179 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3184 llvm::GlobalValue *
Init =
nullptr;
3185 bool InitIsInitFunc =
false;
3186 bool HasConstantInitialization =
false;
3187 if (!usesThreadWrapperFunction(VD)) {
3188 HasConstantInitialization =
true;
3190 InitIsInitFunc =
true;
3191 llvm::Function *InitFuncToUse = InitFunc;
3202 Init = llvm::Function::Create(InitFnTy,
3203 llvm::GlobalVariable::ExternalWeakLinkage,
3207 GlobalDecl(), FI, cast<llvm::Function>(Init),
false);
3211 Init->setVisibility(Var->getVisibility());
3213 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3214 Init->setDSOLocal(Var->isDSOLocal());
3217 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3225 isEmittedWithConstantInitializer(VD,
true) &&
3226 !mayNeedDestruction(VD)) {
3231 assert(Init ==
nullptr &&
"Expected Init to be null.");
3233 llvm::Function *
Func = llvm::Function::Create(
3234 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3237 cast<llvm::Function>(Func),
3240 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Func);
3242 Builder.CreateRetVoid();
3245 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3247 if (HasConstantInitialization) {
3249 }
else if (InitIsInitFunc) {
3251 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy, Init);
3253 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3254 llvm::Function *
Fn =
3255 cast<llvm::Function>(cast<llvm::GlobalAlias>(Init)->getAliasee());
3256 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3267 Builder.CreateCall(InitFnTy, Init);
3270 llvm::Value *Have = Builder.CreateIsNotNull(Init);
3271 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3272 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3273 Builder.CreateCondBr(Have, InitBB, ExitBB);
3275 Builder.SetInsertPoint(InitBB);
3276 Builder.CreateCall(InitFnTy, Init);
3277 Builder.CreateBr(ExitBB);
3279 Builder.SetInsertPoint(ExitBB);
3284 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3288 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3291 Builder.CreateRet(Val);
3299 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3301 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
3302 CallVal->setCallingConv(Wrapper->getCallingConv());
3316 bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
3335 ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3337 llvm::raw_svector_ostream Out(MethodName);
3338 getMangleContext().mangleCXXName(MD, Out);
3339 MethodName +=
"_vfpthunk_";
3340 StringRef ThunkName = MethodName.str();
3341 llvm::Function *ThunkFn;
3342 if ((ThunkFn = cast_or_null<llvm::Function>(
3343 CGM.
getModule().getNamedValue(ThunkName))))
3348 llvm::GlobalValue::LinkageTypes
Linkage =
3350 : llvm::GlobalValue::InternalLinkage;
3353 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3355 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3361 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3362 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3363 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3376 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3377 setCXXABIThisValue(CGF, ThisVal);
3380 for (
const VarDecl *VD : FunctionArgs)
3388 getThisAddress(CGF), ThunkTy);
3389 llvm::CallBase *CallOrInvoke;
3392 auto *
Call = cast<llvm::CallInst>(CallOrInvoke);
3393 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3394 if (
Call->getType()->isVoidTy())
3407 class ItaniumRTTIBuilder {
3409 llvm::LLVMContext &VMContext;
3410 const ItaniumCXXABI &
CXXABI;
3416 llvm::GlobalVariable *
3417 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3421 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
3424 void BuildVTablePointer(
const Type *Ty);
3437 void BuildPointerTypeInfo(
QualType PointeeTy);
3448 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3449 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3463 PTI_Incomplete = 0x8,
3467 PTI_ContainingClassIncomplete = 0x10,
3473 PTI_Noexcept = 0x40,
3479 VMI_NonDiamondRepeat = 0x1,
3482 VMI_DiamondShaped = 0x2
3496 llvm::Constant *BuildTypeInfo(
QualType Ty);
3499 llvm::Constant *BuildTypeInfo(
3501 llvm::GlobalVariable::LinkageTypes
Linkage,
3502 llvm::GlobalValue::VisibilityTypes
Visibility,
3503 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3507 llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3510 llvm::raw_svector_ostream Out(Name);
3516 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
3523 GV->setInitializer(Init);
3529 ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
3532 llvm::raw_svector_ostream Out(Name);
3536 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3543 GV =
new llvm::GlobalVariable(
3545 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3551 if (RD && CXXRecordNonInlineHasAttr<DLLImportAttr>(RD)) {
3552 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3579 case BuiltinType::Void:
3580 case BuiltinType::NullPtr:
3581 case BuiltinType::Bool:
3582 case BuiltinType::WChar_S:
3583 case BuiltinType::WChar_U:
3584 case BuiltinType::Char_U:
3585 case BuiltinType::Char_S:
3586 case BuiltinType::UChar:
3587 case BuiltinType::SChar:
3588 case BuiltinType::Short:
3589 case BuiltinType::UShort:
3590 case BuiltinType::Int:
3591 case BuiltinType::UInt:
3592 case BuiltinType::Long:
3593 case BuiltinType::ULong:
3594 case BuiltinType::LongLong:
3595 case BuiltinType::ULongLong:
3596 case BuiltinType::Half:
3598 case BuiltinType::Double:
3599 case BuiltinType::LongDouble:
3600 case BuiltinType::Float16:
3601 case BuiltinType::Float128:
3602 case BuiltinType::Ibm128:
3603 case BuiltinType::Char8:
3604 case BuiltinType::Char16:
3605 case BuiltinType::Char32:
3606 case BuiltinType::Int128:
3607 case BuiltinType::UInt128:
3610 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3611 case BuiltinType::Id:
3612 #include "clang/Basic/OpenCLImageTypes.def"
3613 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3614 case BuiltinType::Sampled##Id:
3615 #define IMAGE_WRITE_TYPE(Type, Id, Ext)
3616 #define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
3617 #include "clang/Basic/OpenCLImageTypes.def"
3618 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3619 case BuiltinType::Id:
3620 #include "clang/Basic/OpenCLExtensionTypes.def"
3621 case BuiltinType::OCLSampler:
3622 case BuiltinType::OCLEvent:
3623 case BuiltinType::OCLClkEvent:
3624 case BuiltinType::OCLQueue:
3625 case BuiltinType::OCLReserveID:
3626 #define SVE_TYPE(Name, Id, SingletonId) \
3627 case BuiltinType::Id:
3628 #include "clang/Basic/AArch64SVEACLETypes.def"
3629 #define PPC_VECTOR_TYPE(Name, Id, Size) \
3630 case BuiltinType::Id:
3631 #include "clang/Basic/PPCTypes.def"
3632 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3633 #include "clang/Basic/RISCVVTypes.def"
3634 #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3635 #include "clang/Basic/WebAssemblyReferenceTypes.def"
3636 #define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3637 #include "clang/Basic/AMDGPUTypes.def"
3638 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3639 #include "clang/Basic/HLSLIntangibleTypes.def"
3640 case BuiltinType::ShortAccum:
3641 case BuiltinType::Accum:
3642 case BuiltinType::LongAccum:
3643 case BuiltinType::UShortAccum:
3644 case BuiltinType::UAccum:
3645 case BuiltinType::ULongAccum:
3646 case BuiltinType::ShortFract:
3647 case BuiltinType::Fract:
3648 case BuiltinType::LongFract:
3649 case BuiltinType::UShortFract:
3650 case BuiltinType::UFract:
3651 case BuiltinType::ULongFract:
3652 case BuiltinType::SatShortAccum:
3653 case BuiltinType::SatAccum:
3654 case BuiltinType::SatLongAccum:
3655 case BuiltinType::SatUShortAccum:
3656 case BuiltinType::SatUAccum:
3657 case BuiltinType::SatULongAccum:
3658 case BuiltinType::SatShortFract:
3659 case BuiltinType::SatFract:
3660 case BuiltinType::SatLongFract:
3661 case BuiltinType::SatUShortFract:
3662 case BuiltinType::SatUFract:
3663 case BuiltinType::SatULongFract:
3664 case BuiltinType::BFloat16:
3667 case BuiltinType::Dependent:
3668 #define BUILTIN_TYPE(Id, SingletonId)
3669 #define PLACEHOLDER_TYPE(Id, SingletonId) \
3670 case BuiltinType::Id:
3671 #include "clang/AST/BuiltinTypes.def"
3672 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3674 case BuiltinType::ObjCId:
3675 case BuiltinType::ObjCClass:
3676 case BuiltinType::ObjCSel:
3677 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3680 llvm_unreachable(
"Invalid BuiltinType Kind!");
3685 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3703 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3708 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3726 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3727 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
3738 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3741 if (CGM.
getTriple().isWindowsGNUEnvironment())
3748 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3776 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3781 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3785 dyn_cast<MemberPointerType>(Ty)) {
3787 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
3809 if (
Base->isVirtual())
3819 if (!BaseDecl->isEmpty() &&
3826 void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
3828 static const char *
const ClassTypeInfo =
3829 "_ZTVN10__cxxabiv117__class_type_infoE";
3831 static const char *
const SIClassTypeInfo =
3832 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3834 static const char *
const VMIClassTypeInfo =
3835 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3837 const char *VTableName =
nullptr;
3840 #define TYPE(Class, Base)
3841 #define ABSTRACT_TYPE(Class, Base)
3842 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3843 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3844 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
3845 #include "clang/AST/TypeNodes.inc"
3846 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3848 case Type::LValueReference:
3849 case Type::RValueReference:
3850 llvm_unreachable(
"References shouldn't get here");
3853 case Type::DeducedTemplateSpecialization:
3854 llvm_unreachable(
"Undeduced type shouldn't get here");
3857 llvm_unreachable(
"Pipe types shouldn't get here");
3859 case Type::ArrayParameter:
3860 llvm_unreachable(
"Array Parameter types should not get here.");
3866 case Type::ExtVector:
3867 case Type::ConstantMatrix:
3871 case Type::BlockPointer:
3873 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3876 case Type::ConstantArray:
3877 case Type::IncompleteArray:
3878 case Type::VariableArray:
3880 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3883 case Type::FunctionNoProto:
3884 case Type::FunctionProto:
3886 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3891 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3896 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3899 VTableName = ClassTypeInfo;
3901 VTableName = SIClassTypeInfo;
3903 VTableName = VMIClassTypeInfo;
3909 case Type::ObjCObject:
3911 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3914 if (isa<BuiltinType>(Ty)) {
3915 VTableName = ClassTypeInfo;
3919 assert(isa<ObjCInterfaceType>(Ty));
3922 case Type::ObjCInterface:
3923 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3924 VTableName = SIClassTypeInfo;
3926 VTableName = ClassTypeInfo;
3930 case Type::ObjCObjectPointer:
3933 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3936 case Type::MemberPointer:
3938 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3942 llvm::Constant *VTable =
nullptr;
3946 VTable = CGM.
getModule().getNamedAlias(VTableName);
3949 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
3952 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3954 llvm::Type *PtrDiffTy =
3961 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
3963 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8Ty, VTable, Eight);
3965 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3966 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
3974 Fields.push_back(VTable);
3991 return llvm::GlobalValue::InternalLinkage;
3995 llvm_unreachable(
"Linkage hasn't been computed!");
4000 return llvm::GlobalValue::InternalLinkage;
4008 return llvm::GlobalValue::LinkOnceODRLinkage;
4013 return llvm::GlobalValue::WeakODRLinkage;
4014 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4015 if (RD->
hasAttr<DLLImportAttr>() &&
4017 return llvm::GlobalValue::ExternalLinkage;
4023 .isWindowsGNUEnvironment())
4027 return llvm::GlobalValue::LinkOnceODRLinkage;
4030 llvm_unreachable(
"Invalid linkage!");
4033 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
4039 llvm::raw_svector_ostream Out(Name);
4042 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4043 if (OldGV && !OldGV->isDeclaration()) {
4044 assert(!OldGV->hasAvailableExternallyLinkage() &&
4045 "available_externally typeinfos not yet implemented");
4053 return GetAddrOfExternalRTTIDescriptor(Ty);
4060 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4061 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4065 ItaniumCXXABI::RUK_NonUniqueHidden)
4070 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4071 llvm::GlobalValue::DefaultStorageClass;
4073 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4074 RD->
hasAttr<DLLExportAttr>()) ||
4076 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4078 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4080 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass);
4083 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4085 llvm::GlobalVariable::LinkageTypes
Linkage,
4086 llvm::GlobalValue::VisibilityTypes
Visibility,
4087 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4089 BuildVTablePointer(cast<Type>(Ty));
4093 llvm::Constant *TypeNameField;
4097 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4099 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4102 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4103 llvm::Constant *flag =
4105 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4111 Fields.push_back(TypeNameField);
4114 #define TYPE(Class, Base)
4115 #define ABSTRACT_TYPE(Class, Base)
4116 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4117 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4118 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
4119 #include "clang/AST/TypeNodes.inc"
4120 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4125 case Type::ExtVector:
4126 case Type::ConstantMatrix:
4128 case Type::BlockPointer:
4133 case Type::LValueReference:
4134 case Type::RValueReference:
4135 llvm_unreachable(
"References shouldn't get here");
4138 case Type::DeducedTemplateSpecialization:
4139 llvm_unreachable(
"Undeduced type shouldn't get here");
4147 case Type::ConstantArray:
4148 case Type::IncompleteArray:
4149 case Type::VariableArray:
4150 case Type::ArrayParameter:
4155 case Type::FunctionNoProto:
4156 case Type::FunctionProto:
4168 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
4175 BuildSIClassTypeInfo(RD);
4177 BuildVMIClassTypeInfo(RD);
4182 case Type::ObjCObject:
4183 case Type::ObjCInterface:
4184 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
4187 case Type::ObjCObjectPointer:
4188 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->
getPointeeType());
4195 case Type::MemberPointer:
4196 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
4204 llvm::Constant *
Init = llvm::ConstantStruct::getAnon(Fields);
4207 llvm::raw_svector_ostream Out(Name);
4210 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4211 llvm::GlobalVariable *GV =
4212 new llvm::GlobalVariable(M,
Init->getType(),
4216 auto GVDLLStorageClass = DLLStorageClass;
4218 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
4219 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
4220 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
4221 if (RD->
hasAttr<DLLExportAttr>() ||
4222 CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
4223 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
4229 GV->takeName(OldGV);
4230 OldGV->replaceAllUsesWith(GV);
4231 OldGV->eraseFromParent();
4235 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4262 TypeName->setDLLStorageClass(DLLStorageClass);
4263 GV->setDLLStorageClass(GVDLLStorageClass);
4273 void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4276 assert(isa<BuiltinType>(
T) || isa<ObjCInterfaceType>(
T));
4280 if (isa<BuiltinType>(
T))
return;
4291 llvm::Constant *BaseTypeInfo =
4292 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4293 Fields.push_back(BaseTypeInfo);
4298 void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4302 llvm::Constant *BaseTypeInfo =
4304 Fields.push_back(BaseTypeInfo);
4327 if (
Base->isVirtual()) {
4329 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4332 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4334 if (Bases.NonVirtualBases.count(BaseDecl))
4335 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4339 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4342 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4344 if (Bases.VirtualBases.count(BaseDecl))
4345 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4350 for (
const auto &I : BaseDecl->bases())
4361 for (
const auto &I : RD->
bases())
4370 void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4371 llvm::Type *UnsignedIntLTy =
4379 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4384 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4417 llvm::Type *OffsetFlagsLTy =
4422 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4434 if (
Base.isVirtual())
4446 if (
Base.isVirtual())
4447 OffsetFlags |= BCTI_Virtual;
4449 OffsetFlags |= BCTI_Public;
4451 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
4460 if (
Type.isConstQualified())
4461 Flags |= ItaniumRTTIBuilder::PTI_Const;
4462 if (
Type.isVolatileQualified())
4463 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4464 if (
Type.isRestrictQualified())
4465 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4472 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4475 if (Proto->isNothrow()) {
4476 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4486 void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
4492 llvm::Type *UnsignedIntLTy =
4494 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4499 llvm::Constant *PointeeTypeInfo =
4500 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4501 Fields.push_back(PointeeTypeInfo);
4517 Flags |= PTI_ContainingClassIncomplete;
4519 llvm::Type *UnsignedIntLTy =
4521 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4526 llvm::Constant *PointeeTypeInfo =
4527 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4528 Fields.push_back(PointeeTypeInfo);
4535 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
4538 llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
4539 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4542 void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4545 getContext().VoidTy, getContext().NullPtrTy,
4546 getContext().BoolTy, getContext().WCharTy,
4547 getContext().CharTy, getContext().UnsignedCharTy,
4548 getContext().SignedCharTy, getContext().ShortTy,
4549 getContext().UnsignedShortTy, getContext().IntTy,
4550 getContext().UnsignedIntTy, getContext().LongTy,
4551 getContext().UnsignedLongTy, getContext().LongLongTy,
4552 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4553 getContext().UnsignedInt128Ty, getContext().HalfTy,
4554 getContext().FloatTy, getContext().DoubleTy,
4555 getContext().LongDoubleTy, getContext().Float128Ty,
4556 getContext().Char8Ty, getContext().Char16Ty,
4557 getContext().Char32Ty
4559 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4561 ? llvm::GlobalValue::DLLExportStorageClass
4562 : llvm::GlobalValue::DefaultStorageClass;
4563 llvm::GlobalValue::VisibilityTypes
Visibility =
4565 for (
const QualType &FundamentalType : FundamentalTypes) {
4567 QualType PointerTypeConst = getContext().getPointerType(
4568 FundamentalType.withConst());
4570 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4571 Type, llvm::GlobalValue::ExternalLinkage,
4578 ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4580 if (shouldRTTIBeUnique())
4584 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4585 Linkage != llvm::GlobalValue::WeakODRLinkage)
4593 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4594 return RUK_NonUniqueHidden;
4599 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4600 return RUK_NonUniqueVisible;
4605 enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4610 return StructorCodegen::Emit;
4615 return StructorCodegen::Emit;
4618 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4621 const auto *CD = cast<CXXConstructorDecl>(MD);
4626 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4627 return StructorCodegen::RAUW;
4630 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4631 return StructorCodegen::RAUW;
4633 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4637 return StructorCodegen::COMDAT;
4638 return StructorCodegen::Emit;
4641 return StructorCodegen::Alias;
4651 if (Entry && !Entry->isDeclaration())
4654 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
4660 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4664 assert(Entry->getType() == Aliasee->getType() &&
4665 "declaration exists with different type");
4666 Alias->takeName(Entry);
4667 Entry->replaceAllUsesWith(Alias);
4668 Entry->eraseFromParent();
4670 Alias->setName(MangledName);
4677 void ItaniumCXXABI::emitCXXStructor(
GlobalDecl GD) {
4678 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
4679 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4692 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4697 if (CGType == StructorCodegen::RAUW) {
4710 CGType != StructorCodegen::COMDAT &&
4728 if (CGType == StructorCodegen::COMDAT) {
4730 llvm::raw_svector_ostream Out(Buffer);
4732 getMangleContext().mangleCXXDtorComdat(DD, Out);
4734 getMangleContext().mangleCXXCtorComdat(CD, Out);
4735 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(Out.str());
4744 llvm::FunctionType *FTy = llvm::FunctionType::get(
4752 llvm::FunctionType *FTy =
4753 llvm::FunctionType::get(CGM.
VoidTy,
false);
4760 llvm::FunctionType *FTy = llvm::FunctionType::get(
4780 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4802 bool EndMightThrow) {
4803 llvm::CallInst *call =
4806 CGF.
EHStack.pushCleanup<CallEndCatch>(
4808 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4828 if (isa<ReferenceType>(CatchType)) {
4833 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4838 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4847 unsigned HeaderSize =
4850 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
4873 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
4881 llvm::Value *ExnCast =
4882 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
4894 if (CatchType->hasPointerRepresentation()) {
4895 llvm::Value *CastExn =
4896 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
4913 llvm_unreachable(
"bad ownership qualifier!");
4931 llvm_unreachable(
"evaluation kind filtered out!");
4933 llvm_unreachable(
"bad evaluation kind");
4936 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
4937 auto catchRD = CatchType->getAsCXXRecordDecl();
4948 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4949 LLVMCatchTy, caughtExnAlignment);
4958 llvm::CallInst *rawAdjustedExn =
4962 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4963 LLVMCatchTy, caughtExnAlignment);
5019 VarDecl *CatchParam = S->getExceptionDecl();
5038 C.VoidTy, {C.getPointerType(C.CharTy)});
5041 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5042 llvm::Function *fn =
5043 cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
5047 fn->setDoesNotThrow();
5048 fn->setDoesNotReturn();
5053 fn->addFnAttr(llvm::Attribute::NoInline);
5057 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5060 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5063 llvm::BasicBlock *entry =
5068 llvm::Value *exn = &*fn->arg_begin();
5071 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5072 catchCall->setDoesNotThrow();
5076 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5077 termCall->setDoesNotThrow();
5078 termCall->setDoesNotReturn();
5082 builder.CreateUnreachable();
5088 ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5098 std::pair<llvm::Value *, const CXXRecordDecl *>
5105 ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5110 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5121 ItaniumCXXABI::emitBeginCatch(CGF, C);
5125 WebAssemblyCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5138 llvm::FunctionCallee Dtor,
5139 llvm::Constant *Addr) {
5141 llvm::PointerType *PtrTy =
5145 llvm::FunctionType *AtExitTy =
5146 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5149 llvm::FunctionCallee
AtExit =
5157 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5165 llvm::Function *DtorStub =
5173 emitCXXStermFinalizer(
D, DtorStub, Addr);
5176 void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &
D, llvm::Function *dtorStub,
5177 llvm::Constant *addr) {
5178 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5181 llvm::raw_svector_ostream Out(FnName);
5182 getMangleContext().mangleDynamicStermFinalizer(&
D, Out);
5194 D.getInit()->getExprLoc());
5204 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5209 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5214 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5217 CI->setCallingConv(dtorStub->getCallingConv());
5223 if (
auto *IPA =
D.
getAttr<InitPriorityAttr>()) {
5225 IPA->getPriority());
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
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 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::Constant * pointerAuthResignConstant(llvm::Value *Ptr, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, CodeGenModule &CGM)
static llvm::FunctionCallee getBadCastFn(CodeGenFunction &CGF)
static llvm::FunctionCallee getBeginCatchFn(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::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM)
static bool IsStandardLibraryRTTIDescriptor(QualType Ty)
IsStandardLibraryRTTIDescriptor - Returns whether the type information for the given type exists in t...
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 llvm::Value * performTypeAdjustment(CodeGenFunction &CGF, Address InitialPtr, const CXXRecordDecl *UnadjustedClass, int64_t NonVirtualAdjustment, int64_t VirtualAdjustment, bool IsReturnAdjustment)
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::Function * createGlobalInitOrCleanupFn(CodeGen::CodeGenModule &CGM, StringRef FnName)
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::Constant * pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType, QualType SrcType, CodeGenModule &CGM)
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 void emitConstructorDestructorAlias(CodeGenModule &CGM, GlobalDecl AliasDecl, GlobalDecl TargetDecl)
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 const RecordType * getRecordType(QualType QT)
Checks that the passed in QualType either is of RecordType or points to RecordType.
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.
__DEVICE__ int max(int __a, int __b)
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.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
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 ...
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
const LangOptions & getLangOpts() const
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.
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 ...
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 call to a member function that may be written either with member call syntax (e....
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.
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
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, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
unsigned getAddressSpace() const
Return the address space that this address resides in.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ...
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual llvm::CallInst * emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn)
MangleContext & getMangleContext()
Gets the mangle context.
All available information about a concrete callee.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
CanQualType getReturnType() const
ABIArgInfo & getReturnInfo()
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.
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
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.
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask >> Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
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::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
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::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::LLVMContext & getLLVMContext()
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,...
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
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.
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
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.
ASTContext & getContext() 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 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.
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...
const TargetInfo & getTarget() const
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::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 * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
llvm::Type * ConvertTypeForMem(QualType T)
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...
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
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.
CodeGenTypes & getTypes() const
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...
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.
const TargetInfo & getTarget() const
llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const
Get LLVM TLS mode from CodeGenOptions.
void setDSOLocal(llvm::GlobalValue *GV) 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.
CodeGenTypes & getTypes()
const llvm::DataLayout & getDataLayout() const
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.
llvm::Module & getModule() const
CodeGenVTables & getVTables()
CGPointerAuthInfo getMemberFunctionPointerAuthInfo(QualType FT)
bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const
const LangOptions & getLangOpts() const
const llvm::Triple & getTriple() const
llvm::LLVMContext & getLLVMContext()
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.
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.
CGCXXABI & getCXXABI() const
ItaniumVTableContext & getItaniumVTableContext()
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)
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()
StringRef getMangledName(GlobalDecl GD)
ASTContext & getContext() const
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::GlobalValue * GetGlobalValue(StringRef Ref)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
const CodeGenOptions & getCodeGenOpts() const
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.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
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)
const Decl * getDecl() const
CXXDtorType getDtorType() 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
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...
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
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.
const Type * getClass() const
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.
Visibility getVisibility() const
Determines the visibility of this entity.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() 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.
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
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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.
const Type * getTypeForDecl() const
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...
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...
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
CGCXXABI * CreateItaniumCXXABI(CodeGenModule &CGM)
Creates an Itanium-family ABI.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
constexpr Variable var(Literal L)
Returns the variable of L.
bool Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool Init(InterpState &S, CodePtr OpPC)
bool InRange(InterpState &S, CodePtr OpPC)
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
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...
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.
@ CXXVTT
Parameter for C++ virtual table pointers.
@ EST_None
no exception specification
Visibility
Describes the different kinds of visibility that a declaration may have.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
Represents an element in a path from a derived class to a base class.
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
CharUnits getPointerAlign() const
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
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ReturnAdjustment::VirtualAdjustment::@189 Itanium
struct clang::ThisAdjustment::VirtualAdjustment::@191 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.