33#include "llvm/IR/DataLayout.h"
34#include "llvm/IR/GlobalValue.h"
35#include "llvm/IR/Instructions.h"
36#include "llvm/IR/Intrinsics.h"
37#include "llvm/IR/Value.h"
38#include "llvm/Support/ScopedPrinter.h"
43using namespace CodeGen;
48 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
55 bool UseARMMethodPtrABI;
56 bool UseARMGuardVarABI;
57 bool Use32BitVTableOffsetABI;
65 bool UseARMMethodPtrABI =
false,
66 bool UseARMGuardVarABI =
false) :
67 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
68 UseARMGuardVarABI(UseARMGuardVarABI),
69 Use32BitVTableOffsetABI(
false) { }
83 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
93 llvm_unreachable(
"emitting dtor comdat as function?");
95 llvm_unreachable(
"bad dtor kind");
97 if (isa<CXXConstructorDecl>(GD.
getDecl())) {
107 llvm_unreachable(
"closure ctors in Itanium ABI?");
110 llvm_unreachable(
"emitting ctor comdat as function?");
112 llvm_unreachable(
"bad dtor kind");
127 llvm::Value *&ThisPtrForCall,
128 llvm::Value *MemFnPtr,
139 llvm::Value *Src)
override;
141 llvm::Constant *Src)
override;
153 llvm::Value *L, llvm::Value *R,
155 bool Inequality)
override;
172 llvm::Value *Exn)
override;
174 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
178 QualType CatchHandlerType)
override {
186 llvm::Type *StdTypeInfoPtrTy)
override;
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)))
220 llvm::GlobalValue::DefaultVisibility)
227 return hasUniqueVTablePointer(DestRecordTy);
233 llvm::BasicBlock *CastEnd)
override;
238 llvm::BasicBlock *CastSuccess,
239 llvm::BasicBlock *CastFail)
override;
253 AddedStructorArgCounts
293 CodeGenFunction::VPtr Vptr)
override;
307 llvm::Value *getVTableAddressPointInStructorWithVTT(
321 DeleteOrMemberCallExpr
E)
override;
326 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
332 if (ForVTable && !Thunk->hasLocalLinkage())
333 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
334 CGM.setGVProperties(Thunk, GD);
349 assert(!Args.empty() &&
"expected the arglist to not be empty!");
350 return Args.size() - 1;
355 {
return "__cxa_deleted_virtual"; }
360 llvm::Value *NumElements,
368 llvm::GlobalVariable *DeclPtr,
369 bool PerformInit)
override;
371 llvm::FunctionCallee dtor,
372 llvm::Constant *addr)
override;
374 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
392 getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD);
399 virtual bool shouldRTTIBeUnique()
const {
return true; }
403 enum RTTIUniquenessKind {
421 classifyRTTIUniqueness(
QualType CanTy,
422 llvm::GlobalValue::LinkageTypes
Linkage)
const;
423 friend class ItaniumRTTIBuilder;
427 std::pair<llvm::Value *, const CXXRecordDecl *>
433 getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD);
435 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
436 const auto &VtableLayout =
437 CGM.getItaniumVTableContext().getVTableLayout(RD);
439 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
441 if (!VtableComponent.isUsedFunctionPointerKind())
444 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
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();
468 if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
470 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
471 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
472 if (Method->
getVisibility() == Visibility::HiddenVisibility &&
481class ARMCXXABI :
public ItaniumCXXABI {
484 ItaniumCXXABI(CGM,
true,
487 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
495 llvm::Value *NumElements,
502class AppleARM64CXXABI :
public ARMCXXABI {
505 Use32BitVTableOffsetABI =
true;
509 bool shouldRTTIBeUnique()
const override {
return false; }
512class FuchsiaCXXABI final :
public ItaniumCXXABI {
515 : ItaniumCXXABI(CGM) {}
518 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
521class 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; }
536class 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);
620CGCallee 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;
703 CodeGenFunction::SanitizerScope SanScope(&CGF);
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);
735 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
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[] = {
766 llvm::ConstantInt::get(CGF.
Int8Ty, CodeGenFunction::CFITCK_VMFCall),
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 =
794 Builder.CreateIntToPtr(FnAsInt, CGF.
UnqualPtrTy,
"memptr.nonvirtualfn");
797 if (ShouldEmitCFICheck) {
800 CodeGenFunction::SanitizerScope SanScope(&CGF);
802 llvm::Constant *StaticData[] = {
803 llvm::ConstantInt::get(CGF.
Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
808 llvm::Value *Bit = Builder.getFalse();
810 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
811 getContext().getMemberPointerType(
814 llvm::Value *TypeId =
817 llvm::Value *TypeTest =
818 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
819 {NonVirtualFn, TypeId});
820 Bit = Builder.CreateOr(Bit, TypeTest);
823 CGF.
EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
824 SanitizerHandler::CFICheckFail, StaticData,
825 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
827 FnNonVirtual = Builder.GetInsertBlock();
833 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
UnqualPtrTy, 2);
834 CalleePtr->addIncoming(VirtualFn, FnVirtual);
835 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
839 if (
const auto &Schema =
840 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
841 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
842 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
844 const auto &AuthInfo =
845 CGM.getMemberFunctionPointerAuthInfo(
QualType(MPT, 0));
846 assert(Schema.getKey() == AuthInfo.getKey() &&
847 "Keys for virtual and non-virtual member functions must match");
848 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
849 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
851 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
852 Schema.authenticatesNullValues(), DiscriminatorPHI);
861llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
864 assert(MemPtr->getType() == CGM.PtrDiffTy);
869 return Builder.CreateInBoundsGEP(CGF.
Int8Ty,
Base.emitRawPointer(CGF), MemPtr,
877 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
882 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
883 CPA->getAddrDiscriminator()->isZeroValue() &&
885 "unexpected key or discriminators");
888 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
920 if (isa<llvm::Constant>(src))
921 return EmitMemberPointerConversion(
E, cast<llvm::Constant>(src));
923 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
924 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
925 E->getCastKind() == CK_ReinterpretMemberPointer);
931 if (
const auto &NewAuthInfo =
932 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
935 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
936 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
937 llvm::Type *OrigTy = MemFnPtr->getType();
939 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
944 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
945 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
946 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
947 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
948 llvm::Value *IsVirtualOffset =
949 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
950 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
953 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.Int8Ty);
954 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
957 isa<llvm::Constant>(src));
958 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
959 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
960 ResignBB = Builder.GetInsertBlock();
963 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
964 NewSrc->addIncoming(src, StartBB);
965 NewSrc->addIncoming(ResignedVal, ResignBB);
971 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
973 llvm::Constant *adj = getMemberPointerAdjustment(
E);
974 if (!adj)
return src;
976 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
986 dst = Builder.CreateNSWSub(src, adj,
"adj");
988 dst = Builder.CreateNSWAdd(src, adj,
"adj");
991 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
992 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
993 return Builder.CreateSelect(isNull, src, dst);
997 if (UseARMMethodPtrABI) {
998 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1000 adj = llvm::ConstantInt::get(adj->getType(), offset);
1003 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1004 llvm::Value *dstAdj;
1005 if (isDerivedToBase)
1006 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1008 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1010 return Builder.CreateInsertValue(src, dstAdj, 1);
1013static llvm::Constant *
1018 "member function pointers expected");
1019 if (DestType == SrcType)
1025 if (!NewAuthInfo && !CurAuthInfo)
1028 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1029 if (MemFnPtr->getNumOperands() == 0) {
1031 assert(isa<llvm::ConstantInt>(MemFnPtr) &&
"constant int expected");
1036 cast<llvm::User>(MemFnPtr)->getOperand(0), CurAuthInfo, NewAuthInfo, CGM);
1037 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1038 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1042ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *
E,
1043 llvm::Constant *src) {
1044 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
1045 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
1046 E->getCastKind() == CK_ReinterpretMemberPointer);
1052 src, DstType,
E->getSubExpr()->
getType(), CGM);
1055 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
1058 llvm::Constant *adj = getMemberPointerAdjustment(
E);
1059 if (!adj)
return src;
1061 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
1070 if (src->isAllOnesValue())
return src;
1072 if (isDerivedToBase)
1073 return llvm::ConstantExpr::getNSWSub(src, adj);
1075 return llvm::ConstantExpr::getNSWAdd(src, adj);
1079 if (UseARMMethodPtrABI) {
1080 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1082 adj = llvm::ConstantInt::get(adj->getType(), offset);
1085 llvm::Constant *srcAdj = src->getAggregateElement(1);
1086 llvm::Constant *dstAdj;
1087 if (isDerivedToBase)
1088 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1090 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1092 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1093 assert(res !=
nullptr &&
"Folding must succeed");
1102 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1104 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1105 llvm::Constant *Values[2] = {
Zero,
Zero };
1106 return llvm::ConstantStruct::getAnon(Values);
1115 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1119ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1123llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1125 assert(MD->
isInstance() &&
"Member function must not be static!");
1130 llvm::Constant *MemPtr[2];
1132 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1134 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1136 VTableOffset = Index * 4;
1141 VTableOffset = Index * PointerWidth.
getQuantity();
1144 if (UseARMMethodPtrABI) {
1166 const auto &Schema =
1167 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1169 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1170 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1172 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1175 MemPtr[1] = llvm::ConstantInt::get(
1182 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1183 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1190 if (Types.isFuncTypeConvertible(FPT)) {
1192 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
1198 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1200 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1201 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1202 (UseARMMethodPtrABI ? 2 : 1) *
1206 return llvm::ConstantStruct::getAnon(MemPtr);
1209llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1214 return EmitNullMemberPointer(MPT);
1218 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1220 QualType SrcType = getContext().getMemberPointerType(
1226 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1242 llvm::ICmpInst::Predicate
Eq;
1243 llvm::Instruction::BinaryOps
And,
Or;
1245 Eq = llvm::ICmpInst::ICMP_NE;
1246 And = llvm::Instruction::Or;
1247 Or = llvm::Instruction::And;
1249 Eq = llvm::ICmpInst::ICMP_EQ;
1250 And = llvm::Instruction::And;
1251 Or = llvm::Instruction::Or;
1257 return Builder.CreateICmp(
Eq, L, R);
1269 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1270 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1274 llvm::Value *PtrEq = Builder.CreateICmp(
Eq, LPtr, RPtr,
"cmp.ptr");
1279 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1280 llvm::Value *EqZero = Builder.CreateICmp(
Eq, LPtr, Zero,
"cmp.ptr.null");
1284 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1285 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1286 llvm::Value *AdjEq = Builder.CreateICmp(
Eq, LAdj, RAdj,
"cmp.adj");
1290 if (UseARMMethodPtrABI) {
1291 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1294 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1295 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1296 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(
Eq, OrAdjAnd1, Zero,
1298 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1302 llvm::Value *Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1303 Result = Builder.CreateBinOp(
And, PtrEq, Result,
1304 Inequality ?
"memptr.ne" :
"memptr.eq");
1310 llvm::Value *MemPtr,
1316 assert(MemPtr->getType() == CGM.PtrDiffTy);
1317 llvm::Value *NegativeOne =
1318 llvm::Constant::getAllOnesValue(MemPtr->getType());
1319 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1323 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1325 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1326 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
1330 if (UseARMMethodPtrABI) {
1331 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1332 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1333 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1334 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1335 "memptr.isvirtual");
1336 Result = Builder.CreateOr(Result, IsVirtual);
1342bool ItaniumCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1349 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1370 if (UseGlobalDelete) {
1380 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1381 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1399 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
1401 if (UseGlobalDelete)
1405void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1408 llvm::FunctionType *FTy =
1409 llvm::FunctionType::get(CGM.VoidTy,
false);
1411 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1422 llvm::FunctionType *FTy =
1433 llvm::FunctionType *FTy =
1434 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1442 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1443 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1447 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1451 E->getSubExpr(),
Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));
1454 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1459 llvm::Constant *Dtor =
nullptr;
1462 if (!
Record->hasTrivialDestructor()) {
1472 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1475 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1477 llvm::Value *args[] = { ExceptionPtr,
TypeInfo, Dtor };
1489 llvm::Type *PtrDiffTy =
1492 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1494 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1498 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1499 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1500 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1501 llvm::AttributeList Attrs = llvm::AttributeList::get(
1502 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1509 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1526 unsigned NumPublicPaths = 0;
1539 if (PathElement.Base->isVirtual())
1542 if (NumPublicPaths > 1)
1548 PathElement.Base->getType()->getAsCXXRecordDecl());
1553 if (NumPublicPaths == 0)
1557 if (NumPublicPaths > 1)
1567 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1572bool ItaniumCXXABI::shouldTypeidBeNullChecked(
QualType SrcRecordTy) {
1579 Call->setDoesNotReturn();
1580 CGF.
Builder.CreateUnreachable();
1586 llvm::Type *StdTypeInfoPtrTy) {
1592 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1595 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1596 {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});
1600 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1606bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1611llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1614 llvm::Type *PtrDiffLTy =
1617 llvm::Value *SrcRTTI =
1619 llvm::Value *DestRTTI =
1625 llvm::Value *OffsetHint = llvm::ConstantInt::get(
1631 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1637 llvm::Value *Vtable =
1639 CodeGenFunction::VTableAuthMode::MustTrap);
1644 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1650 llvm::BasicBlock *BadCastBlock =
1657 EmitBadCastCall(CGF);
1663llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1666 llvm::BasicBlock *CastFail) {
1678 std::optional<CharUnits> Offset;
1688 PathElement.Base->getType()->getAsCXXRecordDecl();
1689 if (PathElement.Base->isVirtual()) {
1702 Offset = PathOffset;
1703 else if (Offset != PathOffset) {
1708 ThisAddr =
Address(emitDynamicCastToVoid(CGF, ThisAddr, SrcRecordTy),
1719 return llvm::PoisonValue::get(CGF.
VoidPtrTy);
1728 CGM.DecorateInstructionWithTBAA(
1729 VPtr, CGM.getTBAAVTablePtrAccessInfo(CGF.
VoidPtrPtrTy));
1731 VPtr, getVTableAddressPoint(
BaseSubobject(SrcDecl, *Offset), DestDecl));
1733 if (!Offset->isZero())
1736 {llvm::ConstantInt::get(CGF.PtrDiffTy, -Offset->getQuantity())});
1741llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(
CodeGenFunction &CGF,
1746 llvm::Value *OffsetToTop;
1747 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1749 llvm::Value *VTable =
1754 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1758 llvm::Type *PtrDiffLTy =
1762 llvm::Value *VTable =
1767 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1779 Call->setDoesNotReturn();
1780 CGF.
Builder.CreateUnreachable();
1789 llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1791 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1793 llvm::Value *VBaseOffsetPtr =
1794 CGF.
Builder.CreateConstGEP1_64(
1796 "vbase.offset.ptr");
1798 llvm::Value *VBaseOffset;
1799 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1805 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1812 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1820 if (!
D->getParent()->isAbstract()) {
1827ItaniumCXXABI::buildStructorSignature(
GlobalDecl GD,
1837 cast<CXXMethodDecl>(GD.
getDecl())->getParent()->getNumVBases() != 0) {
1838 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1840 ArgTys.insert(ArgTys.begin() + 1,
1842 return AddedStructorArgCounts::prefix(1);
1844 return AddedStructorArgCounts{};
1867 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1870 if (NeedsVTTParameter(CGF.
CurGD)) {
1874 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1879 T, ImplicitParamKind::CXXVTT);
1880 Params.insert(Params.begin() + 1, VTTDecl);
1881 getStructorImplicitParamDecl(CGF) = VTTDecl;
1892 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1895 if (getStructorImplicitParamDecl(CGF)) {
1908 if (HasThisReturn(CGF.
CurGD))
1916 return AddedStructorArgs{};
1923 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1924 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
1925 QualType VTTTy = getContext().getPointerType(Q);
1926 return AddedStructorArgs::prefix({{VTT, VTTTy}});
1929llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
1944 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1947 if (getContext().getLangOpts().AppleKext &&
1954 ThisTy, VTT, VTTTy,
nullptr);
1958template <
typename T>
1961 if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
1962 if (FD->isInlined() || FD->doesThisDeclarationHaveABody() ||
1963 FD->isPureVirtual())
1974 llvm::GlobalVariable *VTable,
1976 if (VTable->getDLLStorageClass() !=
1977 llvm::GlobalVariable::DefaultStorageClass ||
1982 if (CXXRecordNonInlineHasAttr<DLLImportAttr>(RD))
1983 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1984 }
else if (CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
1985 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1990 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1991 if (VTable->hasInitializer())
1996 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
1997 llvm::Constant *RTTI =
1998 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
2002 auto components = builder.beginStruct();
2004 llvm::GlobalValue::isLocalLinkage(
Linkage));
2005 components.finishAndSetAsInitializer(VTable);
2010 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2011 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2013 if (CGM.getTarget().hasPS4DLLImportExport())
2017 CGM.setGVProperties(VTable, RD);
2025 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
2026 cast<NamespaceDecl>(DC)->getIdentifier()->isStr(
"__cxxabiv1") &&
2028 EmitFundamentalRTTIDescriptors(RD);
2035 if (!VTable->isDeclarationForLinker() ||
2036 CGM.getCodeGenOpts().WholeProgramVTables) {
2037 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2041 if (VTable->isDeclarationForLinker()) {
2042 assert(CGM.getCodeGenOpts().WholeProgramVTables);
2043 CGM.addCompilerUsedGlobal(VTable);
2049 if (!VTable->isDSOLocal())
2054bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2056 if (Vptr.NearestVBase ==
nullptr)
2058 return NeedsVTTParameter(CGF.
CurGD);
2061llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2065 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2066 NeedsVTTParameter(CGF.
CurGD)) {
2067 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass,
Base,
2070 return getVTableAddressPoint(
Base, VTableClass);
2076 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
2081 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2084 llvm::Value *Indices[] = {
2085 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2086 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2092 unsigned ComponentSize =
2093 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2094 unsigned VTableSize =
2097 llvm::ConstantRange
InRange(llvm::APInt(32, -Offset,
true),
2098 llvm::APInt(32, VTableSize - Offset,
true));
2099 return llvm::ConstantExpr::getGetElementPtr(
2100 VTable->getValueType(), VTable, Indices,
true, InRange);
2103llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2106 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2107 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2111 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass,
Base);
2115 if (VirtualPointerIndex)
2117 VirtualPointerIndex);
2134llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2136 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2138 llvm::GlobalVariable *&VTable = VTables[RD];
2143 CGM.addDeferredVTable(RD);
2146 llvm::raw_svector_ostream Out(Name);
2147 getMangleContext().mangleCXXVTable(RD, Out);
2150 CGM.getItaniumVTableContext().getVTableLayout(RD);
2151 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2156 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
2157 unsigned PAlign = CGM.getItaniumVTableContext().isRelativeLayout()
2159 : CGM.getTarget().getPointerAlign(AS);
2161 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2162 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2163 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2164 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2166 if (CGM.getTarget().hasPS4DLLImportExport())
2169 CGM.setGVProperties(VTable, RD);
2178 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2179 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
2180 llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
2182 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2183 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2184 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2187 MethodDecl->getParent(), VTable, PtrTy,
2189 CGM.getContext().getTargetInfo().getPointerWidth(LangAS::Default) /
2194 llvm::Value *VFuncLoad;
2195 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
2196 VFuncLoad = CGF.
Builder.CreateCall(
2197 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2198 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, 4 * VTableIndex)});
2200 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2201 PtrTy, VTable, VTableIndex,
"vfn");
2212 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2213 CGM.getCodeGenOpts().StrictVTablePointers) {
2214 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2215 VFuncLoadInstr->setMetadata(
2216 llvm::LLVMContext::MD_invariant_load,
2217 llvm::MDNode::get(CGM.getLLVMContext(),
2226 assert(VTableSlotPtr &&
"virtual function pointer not set");
2227 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2234llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2236 Address This, DeleteOrMemberCallExpr
E) {
2239 assert((CE !=
nullptr) ^ (
D !=
nullptr));
2240 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
2245 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2251 ThisTy = CE->getObjectType();
2253 ThisTy =
D->getDestroyedType();
2261void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2267bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2271 if (CGM.getLangOpts().AppleKext)
2276 if (isVTableHidden(RD))
2279 if (CGM.getCodeGenOpts().ForceEmitVTables)
2286 if (hasAnyUnusedVirtualInlineFunction(RD))
2294 for (
const auto &B : RD->
bases()) {
2295 auto *BRD = B.getType()->getAsCXXRecordDecl();
2296 assert(BRD &&
"no class for base specifier");
2297 if (B.isVirtual() || !BRD->isDynamicClass())
2299 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2307bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2308 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2316 for (
const auto &B : RD->
vbases()) {
2317 auto *BRD = B.getType()->getAsCXXRecordDecl();
2318 assert(BRD &&
"no class for base specifier");
2319 if (!BRD->isDynamicClass())
2321 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2330 int64_t NonVirtualAdjustment,
2331 int64_t VirtualAdjustment,
2332 bool IsReturnAdjustment) {
2333 if (!NonVirtualAdjustment && !VirtualAdjustment)
2339 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2345 llvm::Value *ResultPtr;
2346 if (VirtualAdjustment) {
2347 llvm::Value *VTablePtr =
2350 llvm::Value *Offset;
2351 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2352 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2359 llvm::Type *PtrDiffTy =
2368 V.emitRawPointer(CGF), Offset);
2370 ResultPtr =
V.emitRawPointer(CGF);
2375 if (NonVirtualAdjustment && IsReturnAdjustment) {
2376 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2377 NonVirtualAdjustment);
2404 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2409 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2418 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2423 llvm::Value *NumElements,
2426 assert(requiresArrayCookie(
expr));
2436 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2440 CharUnits CookieOffset = CookieSize - SizeSize;
2441 if (!CookieOffset.
isZero())
2449 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2450 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2451 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2453 SI->setNoSanitizeMetadata();
2454 llvm::FunctionType *FTy =
2455 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2456 llvm::FunctionCallee F =
2457 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2470 Address numElementsPtr = allocPtr;
2472 if (!numElementsOffset.
isZero())
2478 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2485 llvm::FunctionType *FTy =
2487 llvm::FunctionCallee F =
2488 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2502 CGM.getContext().getTypeAlignInChars(elementType));
2507 llvm::Value *numElements,
2510 assert(requiresArrayCookie(
expr));
2517 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2518 getContext().getTypeSizeInChars(elementType).getQuantity());
2527 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2546 llvm::PointerType *GuardPtrTy) {
2548 llvm::FunctionType *FTy =
2552 FTy,
"__cxa_guard_acquire",
2554 llvm::AttributeList::FunctionIndex,
2555 llvm::Attribute::NoUnwind));
2559 llvm::PointerType *GuardPtrTy) {
2561 llvm::FunctionType *FTy =
2562 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2564 FTy,
"__cxa_guard_release",
2566 llvm::AttributeList::FunctionIndex,
2567 llvm::Attribute::NoUnwind));
2571 llvm::PointerType *GuardPtrTy) {
2573 llvm::FunctionType *FTy =
2574 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2576 FTy,
"__cxa_guard_abort",
2578 llvm::AttributeList::FunctionIndex,
2579 llvm::Attribute::NoUnwind));
2584 llvm::GlobalVariable *Guard;
2585 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2598 llvm::GlobalVariable *var,
2599 bool shouldPerformInit) {
2604 bool NonTemplateInline =
2611 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2612 (
D.isLocalVarDecl() || NonTemplateInline) &&
2617 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2619 llvm::IntegerType *guardTy;
2621 if (useInt8GuardVariable) {
2627 if (UseARMGuardVarABI) {
2636 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2642 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&
D);
2647 llvm::raw_svector_ostream out(guardName);
2648 getMangleContext().mangleStaticGuardVariable(&
D, out);
2654 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2655 false,
var->getLinkage(),
2656 llvm::ConstantInt::get(guardTy, 0),
2658 guard->setDSOLocal(
var->isDSOLocal());
2659 guard->setVisibility(
var->getVisibility());
2660 guard->setDLLStorageClass(
var->getDLLStorageClass());
2662 guard->setThreadLocalMode(
var->getThreadLocalMode());
2663 guard->setAlignment(guardAlignment.
getAsAlign());
2668 llvm::Comdat *
C =
var->getComdat();
2669 if (!
D.isLocalVarDecl() &&
C &&
2670 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2671 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2672 guard->setComdat(
C);
2673 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2674 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2677 CGM.setStaticLocalDeclGuardAddress(&
D, guard);
2680 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2705 if (!threadsafe || MaxInlineWidthInBits) {
2707 llvm::LoadInst *LI =
2717 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2740 (UseARMGuardVarABI && !useInt8GuardVariable)
2741 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2743 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2749 CodeGenFunction::GuardKind::VariableGuard, &
D);
2777 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2778 InitBlock, EndBlock);
2784 }
else if (!
D.isLocalVarDecl()) {
2788 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2802 }
else if (
D.isLocalVarDecl()) {
2806 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2815 llvm::FunctionCallee dtor,
2816 llvm::Constant *addr,
bool TLS) {
2818 "unexpected call to emitGlobalDtorWithCXAAtExit");
2820 "__cxa_atexit is disabled");
2821 const char *Name =
"__cxa_atexit";
2824 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2832 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2833 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2837 llvm::Constant *handle =
2839 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2840 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2843 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2844 llvm::FunctionType *atexitTy =
2845 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2849 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2850 fn->setDoesNotThrow();
2857 llvm::Constant *dtorCallee = cast<llvm::Constant>(dtor.getCallee());
2865 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2867 llvm::Value *args[] = {dtorCallee, addr, handle};
2875 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2879 return GlobalInitOrCleanupFn;
2882void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
2883 for (
const auto &I : DtorsUsingAtExit) {
2885 std::string GlobalCleanupFnName =
2886 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
2888 llvm::Function *GlobalCleanupFn =
2898 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
2902 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2903 auto itv = Dtors.rbegin();
2904 while (itv != Dtors.rend()) {
2905 llvm::Function *Dtor = *itv;
2910 llvm::Value *NeedsDestruct =
2913 llvm::BasicBlock *DestructCallBlock =
2916 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
2919 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
2924 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
2926 CI->setCallingConv(Dtor->getCallingConv());
2938void CodeGenModule::registerGlobalDtorsWithAtExit() {
2939 for (
const auto &I : DtorsUsingAtExit) {
2941 std::string GlobalInitFnName =
2942 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
2943 llvm::Function *GlobalInitFn =
2957 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2958 for (
auto *Dtor : Dtors) {
2975 unregisterGlobalDtorsWithUnAtExit();
2980 llvm::FunctionCallee dtor,
2981 llvm::Constant *addr) {
2982 if (
D.isNoDestroy(CGM.getContext()))
2990 if (!CGM.getLangOpts().hasAtExit() && !
D.isStaticLocal())
2997 if (CGM.getCodeGenOpts().CXAAtExit ||
D.getTLSKind())
3002 if (CGM.getLangOpts().AppleKext) {
3004 return CGM.AddCXXDtorEntry(dtor, addr);
3012 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3022static llvm::GlobalValue::LinkageTypes
3024 llvm::GlobalValue::LinkageTypes VarLinkage =
3028 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3033 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3034 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3036 return llvm::GlobalValue::WeakODRLinkage;
3040ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3045 llvm::raw_svector_ostream Out(WrapperName);
3046 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3051 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3052 return cast<llvm::Function>(
V);
3058 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3061 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3062 llvm::Function *Wrapper =
3064 WrapperName.str(), &CGM.getModule());
3066 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3067 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3069 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, Wrapper,
false);
3072 if (!Wrapper->hasLocalLinkage())
3074 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3075 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3077 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
3080 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3081 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3084 ThreadWrappers.push_back({VD, Wrapper});
3088void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3092 llvm::Function *InitFunc =
nullptr;
3097 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3098 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3101 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3102 CXXThreadLocalInits[I];
3104 OrderedInits.push_back(CXXThreadLocalInits[I]);
3107 if (!OrderedInits.empty()) {
3109 llvm::FunctionType *FTy =
3110 llvm::FunctionType::get(CGM.
VoidTy,
false);
3115 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3117 llvm::GlobalVariable::InternalLinkage,
3118 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3119 Guard->setThreadLocal(
true);
3123 Guard->setAlignment(GuardAlign.
getAsAlign());
3129 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3130 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3136 for (
const VarDecl *VD : CXXThreadLocals) {
3140 getOrCreateThreadLocalWrapper(VD, GV);
3145 for (
auto VDAndWrapper : ThreadWrappers) {
3146 const VarDecl *VD = VDAndWrapper.first;
3147 llvm::GlobalVariable *Var =
3149 llvm::Function *Wrapper = VDAndWrapper.second;
3156 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3162 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3163 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3171 llvm::raw_svector_ostream Out(InitFnName);
3172 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3175 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3180 llvm::GlobalValue *
Init =
nullptr;
3181 bool InitIsInitFunc =
false;
3182 bool HasConstantInitialization =
false;
3183 if (!usesThreadWrapperFunction(VD)) {
3184 HasConstantInitialization =
true;
3186 InitIsInitFunc =
true;
3187 llvm::Function *InitFuncToUse = InitFunc;
3191 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3198 Init = llvm::Function::Create(InitFnTy,
3199 llvm::GlobalVariable::ExternalWeakLinkage,
3207 Init->setVisibility(Var->getVisibility());
3209 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3210 Init->setDSOLocal(Var->isDSOLocal());
3213 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3221 isEmittedWithConstantInitializer(VD,
true) &&
3222 !mayNeedDestruction(VD)) {
3227 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3229 llvm::Function *
Func = llvm::Function::Create(
3230 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3233 cast<llvm::Function>(
Func),
3236 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3238 Builder.CreateRetVoid();
3241 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3243 if (HasConstantInitialization) {
3245 }
else if (InitIsInitFunc) {
3247 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3249 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3250 llvm::Function *
Fn =
3251 cast<llvm::Function>(cast<llvm::GlobalAlias>(
Init)->getAliasee());
3252 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3263 Builder.CreateCall(InitFnTy,
Init);
3266 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3267 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3268 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3269 Builder.CreateCondBr(Have, InitBB, ExitBB);
3271 Builder.SetInsertPoint(InitBB);
3272 Builder.CreateCall(InitFnTy,
Init);
3273 Builder.CreateBr(ExitBB);
3275 Builder.SetInsertPoint(ExitBB);
3280 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3284 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3287 Builder.CreateRet(Val);
3295 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3297 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
3298 CallVal->setCallingConv(Wrapper->getCallingConv());
3312bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
3331ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3333 llvm::raw_svector_ostream Out(MethodName);
3334 getMangleContext().mangleCXXName(MD, Out);
3335 MethodName +=
"_vfpthunk_";
3336 StringRef ThunkName = MethodName.str();
3337 llvm::Function *ThunkFn;
3338 if ((ThunkFn = cast_or_null<llvm::Function>(
3339 CGM.
getModule().getNamedValue(ThunkName))))
3344 llvm::GlobalValue::LinkageTypes
Linkage =
3346 : llvm::GlobalValue::InternalLinkage;
3349 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3350 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
3351 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3357 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3358 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3359 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3372 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3373 setCXXABIThisValue(CGF, ThisVal);
3376 for (
const VarDecl *VD : FunctionArgs)
3384 getThisAddress(CGF), ThunkTy);
3385 llvm::CallBase *CallOrInvoke;
3388 auto *
Call = cast<llvm::CallInst>(CallOrInvoke);
3389 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3390 if (
Call->getType()->isVoidTy())
3403class ItaniumRTTIBuilder {
3405 llvm::LLVMContext &VMContext;
3406 const ItaniumCXXABI &
CXXABI;
3412 llvm::GlobalVariable *
3413 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3417 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
3420 void BuildVTablePointer(
const Type *Ty);
3433 void BuildPointerTypeInfo(
QualType PointeeTy);
3444 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3445 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3459 PTI_Incomplete = 0x8,
3463 PTI_ContainingClassIncomplete = 0x10,
3469 PTI_Noexcept = 0x40,
3475 VMI_NonDiamondRepeat = 0x1,
3478 VMI_DiamondShaped = 0x2
3492 llvm::Constant *BuildTypeInfo(
QualType Ty);
3495 llvm::Constant *BuildTypeInfo(
3497 llvm::GlobalVariable::LinkageTypes
Linkage,
3498 llvm::GlobalValue::VisibilityTypes
Visibility,
3499 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3503llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3506 llvm::raw_svector_ostream Out(Name);
3512 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
3519 GV->setInitializer(
Init);
3525ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
3528 llvm::raw_svector_ostream Out(Name);
3532 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3539 GV =
new llvm::GlobalVariable(
3541 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3547 if (RD && CXXRecordNonInlineHasAttr<DLLImportAttr>(RD)) {
3548 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3575 case BuiltinType::Void:
3576 case BuiltinType::NullPtr:
3577 case BuiltinType::Bool:
3578 case BuiltinType::WChar_S:
3579 case BuiltinType::WChar_U:
3580 case BuiltinType::Char_U:
3581 case BuiltinType::Char_S:
3582 case BuiltinType::UChar:
3583 case BuiltinType::SChar:
3584 case BuiltinType::Short:
3585 case BuiltinType::UShort:
3586 case BuiltinType::Int:
3587 case BuiltinType::UInt:
3588 case BuiltinType::Long:
3589 case BuiltinType::ULong:
3590 case BuiltinType::LongLong:
3591 case BuiltinType::ULongLong:
3592 case BuiltinType::Half:
3593 case BuiltinType::Float:
3594 case BuiltinType::Double:
3595 case BuiltinType::LongDouble:
3596 case BuiltinType::Float16:
3597 case BuiltinType::Float128:
3598 case BuiltinType::Ibm128:
3599 case BuiltinType::Char8:
3600 case BuiltinType::Char16:
3601 case BuiltinType::Char32:
3602 case BuiltinType::Int128:
3603 case BuiltinType::UInt128:
3606#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3607 case BuiltinType::Id:
3608#include "clang/Basic/OpenCLImageTypes.def"
3609#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3610 case BuiltinType::Id:
3611#include "clang/Basic/OpenCLExtensionTypes.def"
3612 case BuiltinType::OCLSampler:
3613 case BuiltinType::OCLEvent:
3614 case BuiltinType::OCLClkEvent:
3615 case BuiltinType::OCLQueue:
3616 case BuiltinType::OCLReserveID:
3617#define SVE_TYPE(Name, Id, SingletonId) \
3618 case BuiltinType::Id:
3619#include "clang/Basic/AArch64SVEACLETypes.def"
3620#define PPC_VECTOR_TYPE(Name, Id, Size) \
3621 case BuiltinType::Id:
3622#include "clang/Basic/PPCTypes.def"
3623#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3624#include "clang/Basic/RISCVVTypes.def"
3625#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3626#include "clang/Basic/WebAssemblyReferenceTypes.def"
3627#define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3628#include "clang/Basic/AMDGPUTypes.def"
3629#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3630#include "clang/Basic/HLSLIntangibleTypes.def"
3631 case BuiltinType::ShortAccum:
3632 case BuiltinType::Accum:
3633 case BuiltinType::LongAccum:
3634 case BuiltinType::UShortAccum:
3635 case BuiltinType::UAccum:
3636 case BuiltinType::ULongAccum:
3637 case BuiltinType::ShortFract:
3638 case BuiltinType::Fract:
3639 case BuiltinType::LongFract:
3640 case BuiltinType::UShortFract:
3641 case BuiltinType::UFract:
3642 case BuiltinType::ULongFract:
3643 case BuiltinType::SatShortAccum:
3644 case BuiltinType::SatAccum:
3645 case BuiltinType::SatLongAccum:
3646 case BuiltinType::SatUShortAccum:
3647 case BuiltinType::SatUAccum:
3648 case BuiltinType::SatULongAccum:
3649 case BuiltinType::SatShortFract:
3650 case BuiltinType::SatFract:
3651 case BuiltinType::SatLongFract:
3652 case BuiltinType::SatUShortFract:
3653 case BuiltinType::SatUFract:
3654 case BuiltinType::SatULongFract:
3655 case BuiltinType::BFloat16:
3658 case BuiltinType::Dependent:
3659#define BUILTIN_TYPE(Id, SingletonId)
3660#define PLACEHOLDER_TYPE(Id, SingletonId) \
3661 case BuiltinType::Id:
3662#include "clang/AST/BuiltinTypes.def"
3663 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3665 case BuiltinType::ObjCId:
3666 case BuiltinType::ObjCClass:
3667 case BuiltinType::ObjCSel:
3668 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3671 llvm_unreachable(
"Invalid BuiltinType Kind!");
3676 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3694 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3699 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3717 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3718 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
3729 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3732 if (CGM.
getTriple().isWindowsGNUEnvironment())
3739 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3767 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3772 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3776 dyn_cast<MemberPointerType>(Ty)) {
3778 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
3800 if (
Base->isVirtual())
3810 if (!BaseDecl->isEmpty() &&
3817void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
3819 static const char *
const ClassTypeInfo =
3820 "_ZTVN10__cxxabiv117__class_type_infoE";
3822 static const char *
const SIClassTypeInfo =
3823 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3825 static const char *
const VMIClassTypeInfo =
3826 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3828 const char *VTableName =
nullptr;
3831#define TYPE(Class, Base)
3832#define ABSTRACT_TYPE(Class, Base)
3833#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3834#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3835#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3836#include "clang/AST/TypeNodes.inc"
3837 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3839 case Type::LValueReference:
3840 case Type::RValueReference:
3841 llvm_unreachable(
"References shouldn't get here");
3844 case Type::DeducedTemplateSpecialization:
3845 llvm_unreachable(
"Undeduced type shouldn't get here");
3848 llvm_unreachable(
"Pipe types shouldn't get here");
3850 case Type::ArrayParameter:
3851 llvm_unreachable(
"Array Parameter types should not get here.");
3857 case Type::ExtVector:
3858 case Type::ConstantMatrix:
3862 case Type::BlockPointer:
3864 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3867 case Type::ConstantArray:
3868 case Type::IncompleteArray:
3869 case Type::VariableArray:
3871 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3874 case Type::FunctionNoProto:
3875 case Type::FunctionProto:
3877 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3882 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3885 case Type::Record: {
3887 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3890 VTableName = ClassTypeInfo;
3892 VTableName = SIClassTypeInfo;
3894 VTableName = VMIClassTypeInfo;
3900 case Type::ObjCObject:
3902 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3905 if (isa<BuiltinType>(Ty)) {
3906 VTableName = ClassTypeInfo;
3910 assert(isa<ObjCInterfaceType>(Ty));
3913 case Type::ObjCInterface:
3914 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3915 VTableName = SIClassTypeInfo;
3917 VTableName = ClassTypeInfo;
3921 case Type::ObjCObjectPointer:
3924 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3927 case Type::MemberPointer:
3929 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3933 llvm::Constant *VTable =
nullptr;
3937 VTable = CGM.
getModule().getNamedAlias(VTableName);
3940 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
3943 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3945 llvm::Type *PtrDiffTy =
3952 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
3954 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8Ty, VTable, Eight);
3956 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3957 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
3965 Fields.push_back(VTable);
3982 return llvm::GlobalValue::InternalLinkage;
3986 llvm_unreachable(
"Linkage hasn't been computed!");
3991 return llvm::GlobalValue::InternalLinkage;
3999 return llvm::GlobalValue::LinkOnceODRLinkage;
4004 return llvm::GlobalValue::WeakODRLinkage;
4005 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4006 if (RD->
hasAttr<DLLImportAttr>() &&
4008 return llvm::GlobalValue::ExternalLinkage;
4014 .isWindowsGNUEnvironment())
4018 return llvm::GlobalValue::LinkOnceODRLinkage;
4021 llvm_unreachable(
"Invalid linkage!");
4024llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
4030 llvm::raw_svector_ostream Out(Name);
4033 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4034 if (OldGV && !OldGV->isDeclaration()) {
4035 assert(!OldGV->hasAvailableExternallyLinkage() &&
4036 "available_externally typeinfos not yet implemented");
4044 return GetAddrOfExternalRTTIDescriptor(Ty);
4051 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4052 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4054 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
4056 ItaniumCXXABI::RUK_NonUniqueHidden)
4057 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
4061 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4062 llvm::GlobalValue::DefaultStorageClass;
4064 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4065 RD->
hasAttr<DLLExportAttr>()) ||
4067 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4068 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
4069 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4071 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass);
4074llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4076 llvm::GlobalVariable::LinkageTypes
Linkage,
4077 llvm::GlobalValue::VisibilityTypes
Visibility,
4078 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4080 BuildVTablePointer(cast<Type>(Ty));
4084 llvm::Constant *TypeNameField;
4088 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4090 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4093 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4094 llvm::Constant *flag =
4095 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
4096 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4102 Fields.push_back(TypeNameField);
4105#define TYPE(Class, Base)
4106#define ABSTRACT_TYPE(Class, Base)
4107#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4108#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4109#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4110#include "clang/AST/TypeNodes.inc"
4111 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4116 case Type::ExtVector:
4117 case Type::ConstantMatrix:
4119 case Type::BlockPointer:
4124 case Type::LValueReference:
4125 case Type::RValueReference:
4126 llvm_unreachable(
"References shouldn't get here");
4129 case Type::DeducedTemplateSpecialization:
4130 llvm_unreachable(
"Undeduced type shouldn't get here");
4138 case Type::ConstantArray:
4139 case Type::IncompleteArray:
4140 case Type::VariableArray:
4141 case Type::ArrayParameter:
4146 case Type::FunctionNoProto:
4147 case Type::FunctionProto:
4157 case Type::Record: {
4159 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
4166 BuildSIClassTypeInfo(RD);
4168 BuildVMIClassTypeInfo(RD);
4173 case Type::ObjCObject:
4174 case Type::ObjCInterface:
4175 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
4178 case Type::ObjCObjectPointer:
4179 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->
getPointeeType());
4186 case Type::MemberPointer:
4187 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
4195 llvm::Constant *
Init = llvm::ConstantStruct::getAnon(Fields);
4198 llvm::raw_svector_ostream Out(Name);
4201 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4202 llvm::GlobalVariable *GV =
4203 new llvm::GlobalVariable(M,
Init->getType(),
4207 auto GVDLLStorageClass = DLLStorageClass;
4209 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
4210 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
4211 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
4212 if (RD->
hasAttr<DLLExportAttr>() ||
4213 CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
4214 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
4220 GV->takeName(OldGV);
4221 OldGV->replaceAllUsesWith(GV);
4222 OldGV->eraseFromParent();
4226 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4253 TypeName->setDLLStorageClass(DLLStorageClass);
4254 GV->setDLLStorageClass(GVDLLStorageClass);
4264void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4267 assert(isa<BuiltinType>(
T) || isa<ObjCInterfaceType>(
T));
4271 if (isa<BuiltinType>(
T))
return;
4282 llvm::Constant *BaseTypeInfo =
4283 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4284 Fields.push_back(BaseTypeInfo);
4289void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4293 llvm::Constant *BaseTypeInfo =
4295 Fields.push_back(BaseTypeInfo);
4318 if (
Base->isVirtual()) {
4320 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4323 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4325 if (Bases.NonVirtualBases.count(BaseDecl))
4326 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4330 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4333 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4335 if (Bases.VirtualBases.count(BaseDecl))
4336 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4341 for (
const auto &I : BaseDecl->bases())
4352 for (
const auto &I : RD->
bases())
4361void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4362 llvm::Type *UnsignedIntLTy =
4370 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4375 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4408 llvm::Type *OffsetFlagsLTy =
4413 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4425 if (
Base.isVirtual())
4433 OffsetFlags =
uint64_t(Offset.getQuantity()) << 8;
4437 if (
Base.isVirtual())
4438 OffsetFlags |= BCTI_Virtual;
4440 OffsetFlags |= BCTI_Public;
4442 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
4451 if (
Type.isConstQualified())
4452 Flags |= ItaniumRTTIBuilder::PTI_Const;
4453 if (
Type.isVolatileQualified())
4454 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4455 if (
Type.isRestrictQualified())
4456 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4463 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4466 if (Proto->isNothrow()) {
4467 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4477void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
4483 llvm::Type *UnsignedIntLTy =
4485 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4490 llvm::Constant *PointeeTypeInfo =
4491 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4492 Fields.push_back(PointeeTypeInfo);
4508 Flags |= PTI_ContainingClassIncomplete;
4510 llvm::Type *UnsignedIntLTy =
4512 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4517 llvm::Constant *PointeeTypeInfo =
4518 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4519 Fields.push_back(PointeeTypeInfo);
4526 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
4529llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
4530 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4533void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4536 getContext().VoidTy, getContext().NullPtrTy,
4537 getContext().BoolTy, getContext().WCharTy,
4538 getContext().CharTy, getContext().UnsignedCharTy,
4539 getContext().SignedCharTy, getContext().ShortTy,
4540 getContext().UnsignedShortTy, getContext().IntTy,
4541 getContext().UnsignedIntTy, getContext().LongTy,
4542 getContext().UnsignedLongTy, getContext().LongLongTy,
4543 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4544 getContext().UnsignedInt128Ty, getContext().HalfTy,
4545 getContext().FloatTy, getContext().DoubleTy,
4546 getContext().LongDoubleTy, getContext().Float128Ty,
4547 getContext().Char8Ty, getContext().Char16Ty,
4548 getContext().Char32Ty
4550 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4552 ? llvm::GlobalValue::DLLExportStorageClass
4553 : llvm::GlobalValue::DefaultStorageClass;
4554 llvm::GlobalValue::VisibilityTypes
Visibility =
4556 for (
const QualType &FundamentalType : FundamentalTypes) {
4558 QualType PointerTypeConst = getContext().getPointerType(
4559 FundamentalType.withConst());
4561 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4562 Type, llvm::GlobalValue::ExternalLinkage,
4569ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4571 if (shouldRTTIBeUnique())
4575 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4576 Linkage != llvm::GlobalValue::WeakODRLinkage)
4584 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4585 return RUK_NonUniqueHidden;
4590 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4591 return RUK_NonUniqueVisible;
4596enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4601 return StructorCodegen::Emit;
4606 return StructorCodegen::Emit;
4609 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4612 const auto *CD = cast<CXXConstructorDecl>(MD);
4617 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4618 return StructorCodegen::RAUW;
4621 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4622 return StructorCodegen::RAUW;
4624 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4628 return StructorCodegen::COMDAT;
4629 return StructorCodegen::Emit;
4632 return StructorCodegen::Alias;
4642 if (Entry && !Entry->isDeclaration())
4645 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
4648 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4651 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4655 assert(Entry->getType() == Aliasee->getType() &&
4656 "declaration exists with different type");
4657 Alias->takeName(Entry);
4658 Entry->replaceAllUsesWith(Alias);
4659 Entry->eraseFromParent();
4661 Alias->setName(MangledName);
4668void ItaniumCXXABI::emitCXXStructor(
GlobalDecl GD) {
4669 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
4670 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4683 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4688 if (CGType == StructorCodegen::RAUW) {
4701 CGType != StructorCodegen::COMDAT &&
4719 if (CGType == StructorCodegen::COMDAT) {
4721 llvm::raw_svector_ostream Out(Buffer);
4723 getMangleContext().mangleCXXDtorComdat(DD, Out);
4725 getMangleContext().mangleCXXCtorComdat(CD, Out);
4726 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(Out.str());
4735 llvm::FunctionType *FTy = llvm::FunctionType::get(
4743 llvm::FunctionType *FTy =
4744 llvm::FunctionType::get(CGM.
VoidTy,
false);
4751 llvm::FunctionType *FTy = llvm::FunctionType::get(
4771 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4793 bool EndMightThrow) {
4794 llvm::CallInst *call =
4797 CGF.
EHStack.pushCleanup<CallEndCatch>(
4799 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4819 if (isa<ReferenceType>(CatchType)) {
4824 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4829 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4838 unsigned HeaderSize =
4841 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
4864 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
4872 llvm::Value *ExnCast =
4873 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
4885 if (CatchType->hasPointerRepresentation()) {
4886 llvm::Value *CastExn =
4887 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
4904 llvm_unreachable(
"bad ownership qualifier!");
4922 llvm_unreachable(
"evaluation kind filtered out!");
4924 llvm_unreachable(
"bad evaluation kind");
4927 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
4928 auto catchRD = CatchType->getAsCXXRecordDecl();
4938 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4939 LLVMCatchTy, caughtExnAlignment);
4948 llvm::CallInst *rawAdjustedExn =
4952 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4953 LLVMCatchTy, caughtExnAlignment);
4957 CodeGenFunction::OpaqueValueMapping
5009 VarDecl *CatchParam = S->getExceptionDecl();
5028 C.VoidTy, {C.getPointerType(C.CharTy)});
5031 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5032 llvm::Function *fn =
5033 cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
5037 fn->setDoesNotThrow();
5038 fn->setDoesNotReturn();
5043 fn->addFnAttr(llvm::Attribute::NoInline);
5047 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5048 fn->setVisibility(llvm::Function::HiddenVisibility);
5050 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5053 llvm::BasicBlock *entry =
5058 llvm::Value *exn = &*fn->arg_begin();
5061 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5062 catchCall->setDoesNotThrow();
5066 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5067 termCall->setDoesNotThrow();
5068 termCall->setDoesNotReturn();
5072 builder.CreateUnreachable();
5078ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5088std::pair<llvm::Value *, const CXXRecordDecl *>
5095ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5100 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5111 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5115WebAssemblyCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5128 llvm::FunctionCallee Dtor,
5129 llvm::Constant *Addr) {
5134 llvm::FunctionType *AtExitTy =
5135 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5138 llvm::FunctionCallee
AtExit =
5146 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5154 llvm::Function *DtorStub =
5162 emitCXXStermFinalizer(
D, DtorStub, Addr);
5165void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &
D, llvm::Function *dtorStub,
5166 llvm::Constant *addr) {
5167 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5170 llvm::raw_svector_ostream Out(FnName);
5171 getMangleContext().mangleDynamicStermFinalizer(&
D, Out);
5183 D.getInit()->getExprLoc());
5193 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5198 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5203 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5206 CI->setCallingConv(dtorStub->getCallingConv());
5212 if (
auto *IPA =
D.
getAttr<InitPriorityAttr>()) {
5214 IPA->getPriority());
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF)
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void @__clang_call_terminate(i8* exn) nounwind noreturn This co...
static bool CXXRecordNonInlineHasAttr(const CXXRecordDecl *RD)
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF)
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::FunctionCallee dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
static llvm::FunctionCallee getBadCastFn(CodeGenFunction &CGF)
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM)
static llvm::Constant * pointerAuthResignMemberFunctionPointer(llvm::Constant *Src, QualType DestType, QualType SrcType, CodeGenModule &CGM)
static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty)
Return the linkage that the type info and type info name constants should have for the given type.
static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static llvm::Value * performTypeAdjustment(CodeGenFunction &CGF, Address InitialPtr, const CXXRecordDecl *UnadjustedClass, int64_t NonVirtualAdjustment, int64_t VirtualAdjustment, bool IsReturnAdjustment)
static llvm::Function * createGlobalInitOrCleanupFn(CodeGen::CodeGenModule &CGM, StringRef FnName)
static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM)
static bool IsStandardLibraryRTTIDescriptor(QualType Ty)
IsStandardLibraryRTTIDescriptor - Returns whether the type information for the given type exists in t...
static llvm::Value * CallBeginCatch(CodeGenFunction &CGF, llvm::Value *Exn, bool EndMightThrow)
Emits a call to __cxa_begin_catch and enters a cleanup to call __cxa_end_catch.
static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static CharUnits computeOffsetHint(ASTContext &Context, const CXXRecordDecl *Src, const CXXRecordDecl *Dst)
Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7].
static bool isThreadWrapperReplaceable(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
static void InitCatchParam(CodeGenFunction &CGF, const VarDecl &CatchParam, Address ParamAddr, SourceLocation Loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty)
TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type info for that type is de...
static bool CanUseSingleInheritance(const CXXRecordDecl *RD)
static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM)
static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
Get the appropriate linkage for the wrapper function.
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void setVTableSelectiveDLLImportExport(CodeGenModule &CGM, llvm::GlobalVariable *VTable, const CXXRecordDecl *RD)
static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static bool ContainsIncompleteClassType(QualType Ty)
ContainsIncompleteClassType - Returns whether the given type contains an incomplete class type.
static llvm::Constant * pointerAuthResignConstant(llvm::Value *Ptr, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, CodeGenModule &CGM)
static 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.
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.
const LangOptions & getLangOpts() const
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
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.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ... produce name = getelementptr inbounds addr, i64 index where i64 is actually the t...
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual bool shouldEmitExactDynamicCast(QualType DestRecordTy)=0
virtual void EmitCXXConstructors(const CXXConstructorDecl *D)=0
Emit constructor variants required by this ABI.
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual llvm::Value * getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, const CXXRecordDecl *NearestVBase)=0
Get the address point of the vtable for the given base subobject while building a constructor or a de...
virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0
virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn)=0
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
virtual bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr)=0
Checks if ABI requires extra virtual offset for vtable field.
virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)=0
Emits the guarded initializer and destructor setup for the given variable, given that it couldn't be ...
virtual void EmitCXXDestructors(const CXXDestructorDecl *D)=0
Emit destructor variants required by this ABI.
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, CXXDtorType DT) const =0
Returns true if the given destructor type should be emitted as a linkonce delegating thunk,...
virtual bool NeedsVTTParameter(GlobalDecl GD)
Return whether the given global decl needs a VTT parameter.
virtual llvm::CallInst * emitTerminateForUnexpectedException(CodeGenFunction &CGF, llvm::Value *Exn)
@ RAA_Default
Pass it using the normal C aggregate rules for the ABI, potentially introducing extra copies and pass...
@ RAA_Indirect
Pass it as a pointer to temporary memory.
virtual bool shouldTypeidBeNullChecked(QualType SrcRecordTy)=0
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const CXXRecordDecl *UnadjustedClass, const ThunkInfo &TI)=0
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual StringRef GetPureVirtualCallName()=0
Gets the pure virtual member call function.
virtual CharUnits getArrayCookieSizeImpl(QualType elementType)
Returns the extra size required in order to store the array cookie for the given type.
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const =0
Determine whether it's possible to emit a vtable for RD, even though we do not know that the vtable h...
virtual StringRef GetDeletedVirtualCallName()=0
Gets the deleted virtual member call name.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const CXXRecordDecl *UnadjustedClass, const ReturnAdjustment &RA)=0
virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType)=0
Emit a reference to a non-local thread_local variable (including triggering the initialization of all...
bool isEmittedWithConstantInitializer(const VarDecl *VD, bool InspectInitForWeakDef=false) const
Determine whether we will definitely emit this variable with a constant initializer,...
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Constant * EmitMemberPointer(const APValue &MP, QualType MPT)
Create a member pointer for the given member pointer constant.
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
virtual llvm::Value * readArrayCookieImpl(CodeGenFunction &IGF, Address ptr, CharUnits cookieSize)
Reads the array cookie for an allocation which is known to have one.
virtual llvm::Value * EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, const MemberPointerType *MPT)
Calculate an l-value from an object and a data member pointer.
virtual llvm::Value * getCXXDestructorImplicitParam(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating)=0
Get the implicit (second) parameter that comes after the "this" pointer, or nullptr if there is isn't...
virtual std::pair< llvm::Value *, const CXXRecordDecl * > LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD)=0
Load a vtable from This, an object of polymorphic type RD, or from one of its virtual bases if it doe...
virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment)=0
virtual llvm::Value * EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E)=0
Emit the ABI-specific virtual destructor call.
bool mayNeedDestruction(const VarDecl *VD) const
virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)=0
Checks if ABI requires to initialize vptrs for given dynamic class.
virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0
virtual llvm::Value * GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl)=0
virtual bool isThisCompleteObject(GlobalDecl GD) const =0
Determine whether there's something special about the rules of the ABI tell us that 'this' is a compl...
virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, Address This, llvm::Type *Ty, SourceLocation Loc)=0
Build a virtual function pointer in the ABI-specific way.
virtual bool classifyReturnType(CGFunctionInfo &FI) const =0
If the C++ ABI requires the given type be returned in a particular way, this method sets RetAI and re...
virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0
virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0
virtual void EmitThreadLocalInitFuncs(CodeGenModule &CGM, ArrayRef< const VarDecl * > CXXThreadLocals, ArrayRef< llvm::Function * > CXXThreadLocalInits, ArrayRef< const VarDecl * > CXXThreadLocalInitVars)=0
Emits ABI-required functions necessary to initialize thread_local variables in this translation unit.
virtual bool usesThreadWrapperFunction(const VarDecl *VD) const =0
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
virtual llvm::Value * emitExactDynamicCast(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastSuccess, llvm::BasicBlock *CastFail)=0
Emit a dynamic_cast from SrcRecordTy to DestRecordTy.
virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)=0
Emit the destructor call.
virtual llvm::GlobalVariable * getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset)=0
Get the address of the vtable for the given record decl which should be used for the vptr at the give...
virtual bool EmitBadCastCall(CodeGenFunction &CGF)=0
virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)
Create a member pointer for the given field.
virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD)=0
Emit any tables needed to implement virtual inheritance.
virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD)=0
Emits the VTable definitions required for the given record type.
virtual CGCallee EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, Address This, llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr, const MemberPointerType *MPT)
Load a member function from an object and a member function pointer.
virtual void emitCXXStructor(GlobalDecl GD)=0
Emit a single constructor/destructor with the given type from a C++ constructor Decl.
virtual bool exportThunk()=0
virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0
virtual llvm::Value * emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy)=0
virtual bool isZeroInitializable(const MemberPointerType *MPT)
Return true if the given member pointer can be zero-initialized (in the C++ sense) with an LLVM zeroi...
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)
Create a member pointer for the given method.
virtual llvm::Value * emitDynamicCastCall(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd)=0
virtual Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType)
Initialize the array cookie for the given allocation.
virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, QualType SrcRecordTy)=0
virtual AddedStructorArgCounts buildStructorSignature(GlobalDecl GD, SmallVectorImpl< CanQualType > &ArgTys)=0
Build the signature of the given constructor or destructor variant by adding any required parameters.
MangleContext & getMangleContext()
Gets the mangle context.
virtual AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating)=0
All available information about a concrete callee.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
llvm::Value * getDiscriminator() const
CallArgList - Type for representing both the value and type of arguments in a call.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
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.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
SanitizerSet SanOpts
Sanitizers enabled for this function.
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitAnyExprToExn(const Expr *E, Address Addr)
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
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...
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
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,...
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Function * createTLSAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr, llvm::FunctionCallee &AtExit)
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...
const TargetInfo & getTarget() const
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
llvm::Value * emitPointerAuthResign(llvm::Value *Pointer, QualType PointerType, const CGPointerAuthInfo &CurAuthInfo, const CGPointerAuthInfo &NewAuthInfo, bool IsKnownNonNull)
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...
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, const CXXRecordDecl *RD)
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 EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
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.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
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.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
llvm::Value * unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub)
Call unatexit() with function dtorStub.
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
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::Type * ConvertType(QualType T)
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
CodeGenTypes & getTypes() const
void EmitARCInitWeak(Address addr, llvm::Value *value)
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Instruction * CurrentFuncletPad
llvm::LLVMContext & getLLVMContext()
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
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...
CGPointerAuthInfo EmitPointerAuthInfo(const PointerAuthSchema &Schema, llvm::Value *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
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.
This class organizes the cross-function state that is used while generating LLVM code.
void AddCXXPrioritizedStermFinalizerEntry(llvm::Function *StermFinalizer, int Priority)
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
void AddCXXStermFinalizerToGlobalDtor(llvm::Function *StermFinalizer, int Priority)
Add an sterm finalizer to its own llvm.global_dtors entry.
llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const
Get LLVM TLS mode from CodeGenOptions.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenVTables & getVTables()
void AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn)
Add an sterm finalizer to the C++ global cleanup function.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
llvm::Constant * getFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return the ABI-correct function pointer value for a reference to the given function.
CGPointerAuthInfo getMemberFunctionPointerAuthInfo(QualType FT)
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const
const TargetInfo & getTarget() const
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD)
Returns LLVM linkage for a declarator.
const llvm::DataLayout & getDataLayout() const
CGCXXABI & getCXXABI() const
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V)
llvm::Constant * getMemberFunctionPointer(const FunctionDecl *FD, llvm::Type *Ty=nullptr)
llvm::Function * codegenCXXStructor(GlobalDecl GD)
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const llvm::Triple & getTriple() const
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD)
void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535, bool IsDtorAttrFunc=false)
AddGlobalDtor - Add a function to the list that will be called when the module is unloaded.
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, const CXXRecordDecl *Class, CharUnits ExpectedTargetAlign)
Given a class pointer with an actual known alignment, and the expected alignment of an object at a dy...
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
ItaniumVTableContext & getItaniumVTableContext()
ASTContext & getContext() const
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
bool supportsCOMDAT() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, llvm::Align Alignment)
Will return a global variable of the given type.
llvm::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
llvm::LLVMContext & getLLVMContext()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void addReplacement(StringRef Name, llvm::Constant *C)
llvm::Constant * getConstantSignedPointer(llvm::Constant *Pointer, const PointerAuthSchema &Schema, llvm::Constant *StorageAddress, GlobalDecl SchemaDecl, QualType SchemaType)
Sign a constant pointer using the given scheme, producing a constant with the same IR type.
void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535, unsigned LexOrder=~0U, llvm::Constant *AssociatedData=nullptr)
AddGlobalCtor - Add a function to the list that will be called before main() runs.
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Function * CreateGlobalInitOrCleanUpFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false, llvm::GlobalVariable::LinkageTypes Linkage=llvm::GlobalVariable::InternalLinkage)
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
const CodeGenOptions & getCodeGenOpts() const
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)
Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
llvm::GlobalVariable * GetAddrOfVTT(const CXXRecordDecl *RD)
GetAddrOfVTT - Get the address of the VTT for the given record decl.
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
void GenerateRelativeVTableAlias(llvm::GlobalVariable *VTable, llvm::StringRef AliasNameRef)
Generate a public facing alias for the vtable and make the vtable either hidden or private.
bool isVTableExternal(const CXXRecordDecl *RD)
At this point in the translation unit, does it appear that can we rely on the vtable being defined el...
void RemoveHwasanMetadata(llvm::GlobalValue *GV) const
Specify a global should not be instrumented with hwasan.
void EmitVTTDefinition(llvm::GlobalVariable *VTT, llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD)
EmitVTTDefinition - Emit the definition of the given vtable.
A specialization of Address that requires the address to be an LLVM Constant.
The standard implementation of ConstantInitBuilder used in Clang.
Information for lazily generating a cleanup.
void popTerminate()
Pops a terminate handler off the stack.
void pushTerminate()
Push a terminate handler on the stack.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
A class for recording the number of arguments that a function signature requires.
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
decl_range noload_decls() const
noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...
SourceLocation getLocation() const
DeclContext * getDeclContext()
bool shouldEmitInExternalSource() const
Whether the definition of the declaration should be emitted in external sources.
This represents one expression.
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)
CXXDtorType getDtorType() const
const Decl * getDecl() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
bool isRelativeLayout() const
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
GlobalDecl findOriginalMethod(GlobalDecl GD)
Return the method that added the v-table slot that will be used to call the given method.
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
A pointer to member type per C++ 8.3.3 - Pointers to members.
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.
const Type * getClass() const
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
bool isExternallyVisible() const
Represents an ObjC class declaration.
Represents a class type in Objective C.
QualType getBaseType() const
Gets the base type of this object type.
static const OpaqueValueExpr * findInCopyConstruct(const Expr *expr)
Given an expression which invokes a copy constructor — i.e.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
The collection of all-type qualifiers we support.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
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.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getMaxAtomicInlineWidth() const
Return the maximum width lock-free atomic operation which can be inlined given the supported features...
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool hasPS4DLLImportExport() const
uint64_t getPointerAlign(LangAS AddrSpace) const
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
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...
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
CGCXXABI * CreateItaniumCXXABI(CodeGenModule &CGM)
Creates an Itanium-family ABI.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
constexpr Variable var(Literal L)
Returns the variable of L.
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool InRange(InterpState &S, CodePtr OpPC)
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
@ Success
Template argument deduction was successful.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ EST_None
no exception specification
Visibility
Describes the different kinds of visibility that a declaration may have.
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
Represents an element in a path from a derived class to a base class.
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,...
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
llvm::PointerType * GlobalsVoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * CharTy
char
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * SizeTy
llvm::PointerType * VoidPtrPtrTy
llvm::PointerType * GlobalsInt8PtrTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
CharUnits getSizeSize() const
CharUnits getSizeAlign() const
llvm::PointerType * Int8PtrTy
llvm::PointerType * UnqualPtrTy
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.