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:
586 == llvm::Triple::le32) {
590 return new ItaniumCXXABI(CGM,
true);
592 return new ItaniumCXXABI(CGM);
594 case TargetCXXABI::Microsoft:
595 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
597 llvm_unreachable(
"bad ABI kind");
603 return CGM.PtrDiffTy;
604 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
627CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
629 llvm::Value *&ThisPtrForCall,
638 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
645 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
648 llvm::Value *Adj = RawAdj;
649 if (UseARMMethodPtrABI)
650 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
655 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(), This, Adj);
656 ThisPtrForCall = This;
659 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
663 llvm::Value *IsVirtual;
664 if (UseARMMethodPtrABI)
665 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
667 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
668 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
669 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
687 llvm::Value *VTableOffset = FnAsInt;
688 if (!UseARMMethodPtrABI)
689 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
690 if (Use32BitVTableOffsetABI) {
691 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
692 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
697 llvm::Constant *CheckSourceLocation;
698 llvm::Constant *CheckTypeDesc;
699 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
700 CGM.HasHiddenLTOVisibility(RD);
701 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
702 CGM.HasHiddenLTOVisibility(RD);
703 bool ShouldEmitWPDInfo =
704 CGM.getCodeGenOpts().WholeProgramVTables &&
706 !CGM.AlwaysHasLTOVisibilityPublic(RD);
707 llvm::Value *VirtualFn =
nullptr;
710 CodeGenFunction::SanitizerScope SanScope(&CGF);
711 llvm::Value *TypeId =
nullptr;
712 llvm::Value *CheckResult =
nullptr;
714 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
718 CGM.CreateMetadataIdentifierForVirtualMemPtrType(
QualType(MPT, 0));
722 if (ShouldEmitVFEInfo) {
723 llvm::Value *VFPAddr =
724 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
731 llvm::Value *CheckedLoad = Builder.CreateCall(
732 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
733 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
734 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
735 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
739 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
740 llvm::Value *VFPAddr =
741 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
742 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
743 ? llvm::Intrinsic::type_test
744 : llvm::Intrinsic::public_type_test;
747 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
750 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
751 VirtualFn = CGF.
Builder.CreateCall(
752 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
753 {VTableOffset->getType()}),
754 {VTable, VTableOffset});
756 llvm::Value *VFPAddr =
763 assert(VirtualFn &&
"Virtual fuction pointer not created!");
764 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
766 "Check result required but not created!");
768 if (ShouldEmitCFICheck) {
772 llvm::Constant *StaticData[] = {
773 llvm::ConstantInt::get(CGF.
Int8Ty, CodeGenFunction::CFITCK_VMFCall),
778 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
779 CGF.
EmitTrapCheck(CheckResult, SanitizerHandler::CFICheckFail);
781 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
782 CGM.getLLVMContext(),
783 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
784 llvm::Value *ValidVtable = Builder.CreateCall(
785 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
786 CGF.
EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIMFCall),
787 SanitizerHandler::CFICheckFail, StaticData,
788 {VTable, ValidVtable});
791 FnVirtual = Builder.GetInsertBlock();
800 llvm::Value *NonVirtualFn =
801 Builder.CreateIntToPtr(FnAsInt, CGF.
UnqualPtrTy,
"memptr.nonvirtualfn");
804 if (ShouldEmitCFICheck) {
807 CodeGenFunction::SanitizerScope SanScope(&CGF);
809 llvm::Constant *StaticData[] = {
810 llvm::ConstantInt::get(CGF.
Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
815 llvm::Value *Bit = Builder.getFalse();
817 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
818 getContext().getMemberPointerType(
821 llvm::Value *TypeId =
824 llvm::Value *TypeTest =
825 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
826 {NonVirtualFn, TypeId});
827 Bit = Builder.CreateOr(Bit, TypeTest);
830 CGF.
EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
831 SanitizerHandler::CFICheckFail, StaticData,
832 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
834 FnNonVirtual = Builder.GetInsertBlock();
840 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
UnqualPtrTy, 2);
841 CalleePtr->addIncoming(VirtualFn, FnVirtual);
842 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
846 if (
const auto &Schema =
847 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers) {
848 llvm::PHINode *DiscriminatorPHI = Builder.CreatePHI(CGF.
IntPtrTy, 2);
849 DiscriminatorPHI->addIncoming(llvm::ConstantInt::get(CGF.
IntPtrTy, 0),
851 const auto &AuthInfo =
852 CGM.getMemberFunctionPointerAuthInfo(
QualType(MPT, 0));
853 assert(Schema.getKey() == AuthInfo.getKey() &&
854 "Keys for virtual and non-virtual member functions must match");
855 auto *NonVirtualDiscriminator = AuthInfo.getDiscriminator();
856 DiscriminatorPHI->addIncoming(NonVirtualDiscriminator, FnNonVirtual);
858 Schema.getKey(), Schema.getAuthenticationMode(), Schema.isIsaPointer(),
859 Schema.authenticatesNullValues(), DiscriminatorPHI);
868llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
871 assert(MemPtr->getType() == CGM.PtrDiffTy);
876 return Builder.CreateInBoundsGEP(CGF.
Int8Ty,
Base.emitRawPointer(CGF), MemPtr,
884 const auto *CPA = dyn_cast<llvm::ConstantPtrAuth>(Ptr);
889 assert(CPA->getKey()->getZExtValue() == CurAuthInfo.
getKey() &&
890 CPA->getAddrDiscriminator()->isZeroValue() &&
892 "unexpected key or discriminators");
895 CPA->getPointer(), NewAuthInfo.
getKey(),
nullptr,
927 if (isa<llvm::Constant>(src))
928 return EmitMemberPointerConversion(
E, cast<llvm::Constant>(src));
930 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
931 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
932 E->getCastKind() == CK_ReinterpretMemberPointer);
938 if (
const auto &NewAuthInfo =
939 CGM.getMemberFunctionPointerAuthInfo(DstType)) {
942 const auto &CurAuthInfo = CGM.getMemberFunctionPointerAuthInfo(SrcType);
943 llvm::Value *MemFnPtr = Builder.CreateExtractValue(src, 0,
"memptr.ptr");
944 llvm::Type *OrigTy = MemFnPtr->getType();
946 llvm::BasicBlock *StartBB = Builder.GetInsertBlock();
951 assert(UseARMMethodPtrABI &&
"ARM ABI expected");
952 llvm::Value *Adj = Builder.CreateExtractValue(src, 1,
"memptr.adj");
953 llvm::Constant *Ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
954 llvm::Value *AndVal = Builder.CreateAnd(Adj, Ptrdiff_1);
955 llvm::Value *IsVirtualOffset =
956 Builder.CreateIsNotNull(AndVal,
"is.virtual.offset");
957 Builder.CreateCondBr(IsVirtualOffset, MergeBB, ResignBB);
960 llvm::Type *PtrTy = llvm::PointerType::getUnqual(CGM.Int8Ty);
961 MemFnPtr = Builder.CreateIntToPtr(MemFnPtr, PtrTy);
964 isa<llvm::Constant>(src));
965 MemFnPtr = Builder.CreatePtrToInt(MemFnPtr, OrigTy);
966 llvm::Value *ResignedVal = Builder.CreateInsertValue(src, MemFnPtr, 0);
967 ResignBB = Builder.GetInsertBlock();
970 llvm::PHINode *NewSrc = Builder.CreatePHI(src->getType(), 2);
971 NewSrc->addIncoming(src, StartBB);
972 NewSrc->addIncoming(ResignedVal, ResignBB);
978 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
980 llvm::Constant *adj = getMemberPointerAdjustment(
E);
981 if (!adj)
return src;
983 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
993 dst = Builder.CreateNSWSub(src, adj,
"adj");
995 dst = Builder.CreateNSWAdd(src, adj,
"adj");
998 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
999 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
1000 return Builder.CreateSelect(isNull, src, dst);
1004 if (UseARMMethodPtrABI) {
1005 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1007 adj = llvm::ConstantInt::get(adj->getType(), offset);
1010 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
1011 llvm::Value *dstAdj;
1012 if (isDerivedToBase)
1013 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
1015 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
1017 return Builder.CreateInsertValue(src, dstAdj, 1);
1020static llvm::Constant *
1025 "member function pointers expected");
1026 if (DestType == SrcType)
1032 if (!NewAuthInfo && !CurAuthInfo)
1035 llvm::Constant *MemFnPtr = Src->getAggregateElement(0u);
1036 if (MemFnPtr->getNumOperands() == 0) {
1038 assert(isa<llvm::ConstantInt>(MemFnPtr) &&
"constant int expected");
1043 cast<llvm::User>(MemFnPtr)->getOperand(0), CurAuthInfo, NewAuthInfo, CGM);
1044 ConstPtr = llvm::ConstantExpr::getPtrToInt(ConstPtr, MemFnPtr->getType());
1045 return ConstantFoldInsertValueInstruction(Src, ConstPtr, 0);
1049ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *
E,
1050 llvm::Constant *src) {
1051 assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
1052 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
1053 E->getCastKind() == CK_ReinterpretMemberPointer);
1059 src, DstType,
E->getSubExpr()->
getType(), CGM);
1062 if (
E->getCastKind() == CK_ReinterpretMemberPointer)
return src;
1065 llvm::Constant *adj = getMemberPointerAdjustment(
E);
1066 if (!adj)
return src;
1068 bool isDerivedToBase = (
E->getCastKind() == CK_DerivedToBaseMemberPointer);
1077 if (src->isAllOnesValue())
return src;
1079 if (isDerivedToBase)
1080 return llvm::ConstantExpr::getNSWSub(src, adj);
1082 return llvm::ConstantExpr::getNSWAdd(src, adj);
1086 if (UseARMMethodPtrABI) {
1087 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
1089 adj = llvm::ConstantInt::get(adj->getType(), offset);
1092 llvm::Constant *srcAdj = src->getAggregateElement(1);
1093 llvm::Constant *dstAdj;
1094 if (isDerivedToBase)
1095 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
1097 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
1099 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
1100 assert(res !=
nullptr &&
"Folding must succeed");
1109 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
1111 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
1112 llvm::Constant *Values[2] = {
Zero,
Zero };
1113 return llvm::ConstantStruct::getAnon(Values);
1122 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1126ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1130llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1132 assert(MD->
isInstance() &&
"Member function must not be static!");
1137 llvm::Constant *MemPtr[2];
1139 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1141 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1143 VTableOffset = Index * 4;
1148 VTableOffset = Index * PointerWidth.
getQuantity();
1151 if (UseARMMethodPtrABI) {
1173 const auto &Schema =
1174 CGM.getCodeGenOpts().PointerAuth.CXXMemberFunctionPointers;
1176 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(
1177 getSignedVirtualMemberFunctionPointer(MD), CGM.PtrDiffTy);
1179 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1182 MemPtr[1] = llvm::ConstantInt::get(
1189 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1190 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1197 if (Types.isFuncTypeConvertible(FPT)) {
1199 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
1205 llvm::Constant *addr = CGM.getMemberFunctionPointer(MD, Ty);
1207 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1208 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1209 (UseARMMethodPtrABI ? 2 : 1) *
1213 return llvm::ConstantStruct::getAnon(MemPtr);
1216llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1221 return EmitNullMemberPointer(MPT);
1225 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
1227 QualType SrcType = getContext().getMemberPointerType(
1233 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1249 llvm::ICmpInst::Predicate
Eq;
1250 llvm::Instruction::BinaryOps
And,
Or;
1252 Eq = llvm::ICmpInst::ICMP_NE;
1253 And = llvm::Instruction::Or;
1254 Or = llvm::Instruction::And;
1256 Eq = llvm::ICmpInst::ICMP_EQ;
1257 And = llvm::Instruction::And;
1258 Or = llvm::Instruction::Or;
1264 return Builder.CreateICmp(
Eq, L, R);
1276 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1277 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1281 llvm::Value *PtrEq = Builder.CreateICmp(
Eq, LPtr, RPtr,
"cmp.ptr");
1286 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1287 llvm::Value *EqZero = Builder.CreateICmp(
Eq, LPtr, Zero,
"cmp.ptr.null");
1291 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1292 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1293 llvm::Value *AdjEq = Builder.CreateICmp(
Eq, LAdj, RAdj,
"cmp.adj");
1297 if (UseARMMethodPtrABI) {
1298 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1301 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1302 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1303 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(
Eq, OrAdjAnd1, Zero,
1305 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1309 llvm::Value *Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1310 Result = Builder.CreateBinOp(
And, PtrEq, Result,
1311 Inequality ?
"memptr.ne" :
"memptr.eq");
1317 llvm::Value *MemPtr,
1323 assert(MemPtr->getType() == CGM.PtrDiffTy);
1324 llvm::Value *NegativeOne =
1325 llvm::Constant::getAllOnesValue(MemPtr->getType());
1326 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1330 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1332 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1333 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
1337 if (UseARMMethodPtrABI) {
1338 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1339 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1340 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1341 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1342 "memptr.isvirtual");
1343 Result = Builder.CreateOr(Result, IsVirtual);
1349bool ItaniumCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1356 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1377 if (UseGlobalDelete) {
1387 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1388 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1406 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
1408 if (UseGlobalDelete)
1412void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1415 llvm::FunctionType *FTy =
1416 llvm::FunctionType::get(CGM.VoidTy,
false);
1418 llvm::FunctionCallee
Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1429 llvm::FunctionType *FTy =
1440 llvm::FunctionType *FTy =
1441 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1449 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1450 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1454 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1458 E->getSubExpr(),
Address(ExceptionPtr, CGM.Int8Ty, ExnAlign));
1461 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1466 llvm::Constant *Dtor =
nullptr;
1469 if (!
Record->hasTrivialDestructor()) {
1479 Dtor = CGM.getFunctionPointer(Dtor, DtorTy);
1482 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1484 llvm::Value *args[] = { ExceptionPtr,
TypeInfo, Dtor };
1496 llvm::Type *PtrDiffTy =
1499 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1501 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1505 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1506 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1507 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1508 llvm::AttributeList Attrs = llvm::AttributeList::get(
1509 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1516 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1533 unsigned NumPublicPaths = 0;
1546 if (PathElement.Base->isVirtual())
1549 if (NumPublicPaths > 1)
1555 PathElement.Base->getType()->getAsCXXRecordDecl());
1560 if (NumPublicPaths == 0)
1564 if (NumPublicPaths > 1)
1574 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1579bool ItaniumCXXABI::shouldTypeidBeNullChecked(
QualType SrcRecordTy) {
1586 Call->setDoesNotReturn();
1587 CGF.
Builder.CreateUnreachable();
1593 llvm::Type *StdTypeInfoPtrTy) {
1599 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1602 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1603 {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});
1607 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1613bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1618llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1621 llvm::Type *PtrDiffLTy =
1624 llvm::Value *SrcRTTI =
1626 llvm::Value *DestRTTI =
1632 llvm::Value *OffsetHint = llvm::ConstantInt::get(
1638 if (CGM.getCodeGenOpts().PointerAuth.CXXVTablePointers) {
1644 llvm::Value *Vtable =
1646 CodeGenFunction::VTableAuthMode::MustTrap);
1651 llvm::Value *args[] = {
Value, SrcRTTI, DestRTTI, OffsetHint};
1657 llvm::BasicBlock *BadCastBlock =
1664 EmitBadCastCall(CGF);
1670llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1673 llvm::BasicBlock *CastFail) {
1685 std::optional<CharUnits> Offset;
1695 PathElement.Base->getType()->getAsCXXRecordDecl();
1696 if (PathElement.Base->isVirtual()) {
1709 Offset = PathOffset;
1710 else if (Offset != PathOffset) {
1715 ThisAddr =
Address(emitDynamicCastToVoid(CGF, ThisAddr, SrcRecordTy),
1726 return llvm::PoisonValue::get(CGF.
VoidPtrTy);
1735 CGM.DecorateInstructionWithTBAA(
1736 VPtr, CGM.getTBAAVTablePtrAccessInfo(CGF.
VoidPtrPtrTy));
1738 VPtr, getVTableAddressPoint(
BaseSubobject(SrcDecl, *Offset), DestDecl));
1740 if (!Offset->isZero())
1743 {llvm::ConstantInt::get(CGF.PtrDiffTy, -Offset->getQuantity())});
1748llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(
CodeGenFunction &CGF,
1753 llvm::Value *OffsetToTop;
1754 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1756 llvm::Value *VTable =
1761 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1765 llvm::Type *PtrDiffLTy =
1769 llvm::Value *VTable =
1774 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1786 Call->setDoesNotReturn();
1787 CGF.
Builder.CreateUnreachable();
1796 llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1798 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1800 llvm::Value *VBaseOffsetPtr =
1801 CGF.
Builder.CreateConstGEP1_64(
1803 "vbase.offset.ptr");
1805 llvm::Value *VBaseOffset;
1806 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1812 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1819 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1827 if (!
D->getParent()->isAbstract()) {
1834ItaniumCXXABI::buildStructorSignature(
GlobalDecl GD,
1844 cast<CXXMethodDecl>(GD.
getDecl())->getParent()->getNumVBases() != 0) {
1845 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1847 ArgTys.insert(ArgTys.begin() + 1,
1849 return AddedStructorArgCounts::prefix(1);
1851 return AddedStructorArgCounts{};
1874 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1877 if (NeedsVTTParameter(CGF.
CurGD)) {
1881 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1886 T, ImplicitParamKind::CXXVTT);
1887 Params.insert(Params.begin() + 1, VTTDecl);
1888 getStructorImplicitParamDecl(CGF) = VTTDecl;
1899 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1902 if (getStructorImplicitParamDecl(CGF)) {
1915 if (HasThisReturn(CGF.
CurGD))
1923 return AddedStructorArgs{};
1930 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1931 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
1932 QualType VTTTy = getContext().getPointerType(Q);
1933 return AddedStructorArgs::prefix({{VTT, VTTTy}});
1936llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
1951 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1954 if (getContext().getLangOpts().AppleKext &&
1961 ThisTy, VTT, VTTTy,
nullptr);
1965template <
typename T>
1968 if (
const auto *FD = dyn_cast<FunctionDecl>(
D)) {
1969 if (FD->isInlined() || FD->doesThisDeclarationHaveABody() ||
1970 FD->isPureVirtual())
1981 llvm::GlobalVariable *VTable,
1983 if (VTable->getDLLStorageClass() !=
1984 llvm::GlobalVariable::DefaultStorageClass ||
1989 if (CXXRecordNonInlineHasAttr<DLLImportAttr>(RD))
1990 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1991 }
else if (CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
1992 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1997 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1998 if (VTable->hasInitializer())
2003 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2004 llvm::Constant *RTTI =
2005 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
2009 auto components = builder.beginStruct();
2011 llvm::GlobalValue::isLocalLinkage(
Linkage));
2012 components.finishAndSetAsInitializer(VTable);
2017 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
2018 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
2020 if (CGM.getTarget().hasPS4DLLImportExport())
2024 CGM.setGVProperties(VTable, RD);
2032 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
2033 cast<NamespaceDecl>(DC)->getIdentifier()->isStr(
"__cxxabiv1") &&
2035 EmitFundamentalRTTIDescriptors(RD);
2042 if (!VTable->isDeclarationForLinker() ||
2043 CGM.getCodeGenOpts().WholeProgramVTables) {
2044 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
2048 if (VTable->isDeclarationForLinker()) {
2049 assert(CGM.getCodeGenOpts().WholeProgramVTables);
2050 CGM.addCompilerUsedGlobal(VTable);
2056 if (!VTable->isDSOLocal())
2061bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2063 if (Vptr.NearestVBase ==
nullptr)
2065 return NeedsVTTParameter(CGF.
CurGD);
2068llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
2072 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2073 NeedsVTTParameter(CGF.
CurGD)) {
2074 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass,
Base,
2077 return getVTableAddressPoint(
Base, VTableClass);
2083 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
2088 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
2091 llvm::Value *Indices[] = {
2092 llvm::ConstantInt::get(CGM.Int32Ty, 0),
2093 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
2099 unsigned ComponentSize =
2100 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
2101 unsigned VTableSize =
2104 llvm::ConstantRange
InRange(llvm::APInt(32, -Offset,
true),
2105 llvm::APInt(32, VTableSize - Offset,
true));
2106 return llvm::ConstantExpr::getGetElementPtr(
2107 VTable->getValueType(), VTable, Indices,
true, InRange);
2110llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2113 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
2114 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
2118 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass,
Base);
2122 if (VirtualPointerIndex)
2124 VirtualPointerIndex);
2141llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
2143 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
2145 llvm::GlobalVariable *&VTable = VTables[RD];
2150 CGM.addDeferredVTable(RD);
2153 llvm::raw_svector_ostream Out(Name);
2154 getMangleContext().mangleCXXVTable(RD, Out);
2157 CGM.getItaniumVTableContext().getVTableLayout(RD);
2158 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
2163 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
2164 unsigned PAlign = CGM.getItaniumVTableContext().isRelativeLayout()
2166 : CGM.getTarget().getPointerAlign(AS);
2168 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
2169 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
2170 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
2171 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2173 if (CGM.getTarget().hasPS4DLLImportExport())
2176 CGM.setGVProperties(VTable, RD);
2185 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2186 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
2187 llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
2189 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2190 llvm::Value *VFunc, *VTableSlotPtr =
nullptr;
2191 auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXVirtualFunctionPointers;
2194 MethodDecl->getParent(), VTable, PtrTy,
2196 CGM.getContext().getTargetInfo().getPointerWidth(LangAS::Default) /
2201 llvm::Value *VFuncLoad;
2202 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
2203 VFuncLoad = CGF.
Builder.CreateCall(
2204 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2205 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, 4 * VTableIndex)});
2207 VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2208 PtrTy, VTable, VTableIndex,
"vfn");
2219 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2220 CGM.getCodeGenOpts().StrictVTablePointers) {
2221 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2222 VFuncLoadInstr->setMetadata(
2223 llvm::LLVMContext::MD_invariant_load,
2224 llvm::MDNode::get(CGM.getLLVMContext(),
2233 assert(VTableSlotPtr &&
"virtual function pointer not set");
2234 GD = CGM.getItaniumVTableContext().findOriginalMethod(GD.
getCanonicalDecl());
2241llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2243 Address This, DeleteOrMemberCallExpr
E) {
2246 assert((CE !=
nullptr) ^ (
D !=
nullptr));
2247 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
2252 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2258 ThisTy = CE->getObjectType();
2260 ThisTy =
D->getDestroyedType();
2268void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2274bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2278 if (CGM.getLangOpts().AppleKext)
2283 if (isVTableHidden(RD))
2286 if (CGM.getCodeGenOpts().ForceEmitVTables)
2293 if (hasAnyUnusedVirtualInlineFunction(RD))
2301 for (
const auto &B : RD->
bases()) {
2302 auto *BRD = B.getType()->getAsCXXRecordDecl();
2303 assert(BRD &&
"no class for base specifier");
2304 if (B.isVirtual() || !BRD->isDynamicClass())
2306 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2314bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2315 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2320 for (
const auto &B : RD->
vbases()) {
2321 auto *BRD = B.getType()->getAsCXXRecordDecl();
2322 assert(BRD &&
"no class for base specifier");
2323 if (!BRD->isDynamicClass())
2325 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2334 int64_t NonVirtualAdjustment,
2335 int64_t VirtualAdjustment,
2336 bool IsReturnAdjustment) {
2337 if (!NonVirtualAdjustment && !VirtualAdjustment)
2343 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2349 llvm::Value *ResultPtr;
2350 if (VirtualAdjustment) {
2351 llvm::Value *VTablePtr =
2354 llvm::Value *Offset;
2355 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2356 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2363 llvm::Type *PtrDiffTy =
2372 V.emitRawPointer(CGF), Offset);
2374 ResultPtr =
V.emitRawPointer(CGF);
2379 if (NonVirtualAdjustment && IsReturnAdjustment) {
2380 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2381 NonVirtualAdjustment);
2408 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2413 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2422 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2427 llvm::Value *NumElements,
2430 assert(requiresArrayCookie(
expr));
2440 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2444 CharUnits CookieOffset = CookieSize - SizeSize;
2445 if (!CookieOffset.
isZero())
2453 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2454 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2455 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2457 SI->setNoSanitizeMetadata();
2458 llvm::FunctionType *FTy =
2459 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2460 llvm::FunctionCallee F =
2461 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2474 Address numElementsPtr = allocPtr;
2476 if (!numElementsOffset.
isZero())
2482 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2489 llvm::FunctionType *FTy =
2491 llvm::FunctionCallee F =
2492 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2506 CGM.getContext().getTypeAlignInChars(elementType));
2511 llvm::Value *numElements,
2514 assert(requiresArrayCookie(
expr));
2521 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2522 getContext().getTypeSizeInChars(elementType).getQuantity());
2531 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2550 llvm::PointerType *GuardPtrTy) {
2552 llvm::FunctionType *FTy =
2556 FTy,
"__cxa_guard_acquire",
2558 llvm::AttributeList::FunctionIndex,
2559 llvm::Attribute::NoUnwind));
2563 llvm::PointerType *GuardPtrTy) {
2565 llvm::FunctionType *FTy =
2566 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2568 FTy,
"__cxa_guard_release",
2570 llvm::AttributeList::FunctionIndex,
2571 llvm::Attribute::NoUnwind));
2575 llvm::PointerType *GuardPtrTy) {
2577 llvm::FunctionType *FTy =
2578 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2580 FTy,
"__cxa_guard_abort",
2582 llvm::AttributeList::FunctionIndex,
2583 llvm::Attribute::NoUnwind));
2588 llvm::GlobalVariable *Guard;
2589 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2602 llvm::GlobalVariable *var,
2603 bool shouldPerformInit) {
2608 bool NonTemplateInline =
2615 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2616 (
D.isLocalVarDecl() || NonTemplateInline) &&
2621 bool useInt8GuardVariable = !threadsafe &&
var->hasInternalLinkage();
2623 llvm::IntegerType *guardTy;
2625 if (useInt8GuardVariable) {
2631 if (UseARMGuardVarABI) {
2640 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2646 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&
D);
2651 llvm::raw_svector_ostream out(guardName);
2652 getMangleContext().mangleStaticGuardVariable(&
D, out);
2658 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2659 false,
var->getLinkage(),
2660 llvm::ConstantInt::get(guardTy, 0),
2662 guard->setDSOLocal(
var->isDSOLocal());
2663 guard->setVisibility(
var->getVisibility());
2664 guard->setDLLStorageClass(
var->getDLLStorageClass());
2666 guard->setThreadLocalMode(
var->getThreadLocalMode());
2667 guard->setAlignment(guardAlignment.
getAsAlign());
2672 llvm::Comdat *
C =
var->getComdat();
2673 if (!
D.isLocalVarDecl() &&
C &&
2674 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2675 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2676 guard->setComdat(
C);
2677 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2678 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2681 CGM.setStaticLocalDeclGuardAddress(&
D, guard);
2684 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2709 if (!threadsafe || MaxInlineWidthInBits) {
2711 llvm::LoadInst *LI =
2721 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2744 (UseARMGuardVarABI && !useInt8GuardVariable)
2745 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2747 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2753 CodeGenFunction::GuardKind::VariableGuard, &
D);
2781 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2782 InitBlock, EndBlock);
2788 }
else if (!
D.isLocalVarDecl()) {
2792 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2806 }
else if (
D.isLocalVarDecl()) {
2810 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2819 llvm::FunctionCallee dtor,
2820 llvm::Constant *addr,
bool TLS) {
2822 "unexpected call to emitGlobalDtorWithCXAAtExit");
2824 "__cxa_atexit is disabled");
2825 const char *Name =
"__cxa_atexit";
2828 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2836 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2837 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2841 llvm::Constant *handle =
2843 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2844 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2847 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2848 llvm::FunctionType *atexitTy =
2849 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2853 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2854 fn->setDoesNotThrow();
2861 llvm::Constant *dtorCallee = cast<llvm::Constant>(dtor.getCallee());
2869 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2871 llvm::Value *args[] = {dtorCallee, addr, handle};
2879 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2883 return GlobalInitOrCleanupFn;
2886void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
2887 for (
const auto &I : DtorsUsingAtExit) {
2889 std::string GlobalCleanupFnName =
2890 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
2892 llvm::Function *GlobalCleanupFn =
2902 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
2906 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2907 auto itv = Dtors.rbegin();
2908 while (itv != Dtors.rend()) {
2909 llvm::Function *Dtor = *itv;
2914 llvm::Value *NeedsDestruct =
2917 llvm::BasicBlock *DestructCallBlock =
2920 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
2923 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
2928 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
2930 CI->setCallingConv(Dtor->getCallingConv());
2942void CodeGenModule::registerGlobalDtorsWithAtExit() {
2943 for (
const auto &I : DtorsUsingAtExit) {
2945 std::string GlobalInitFnName =
2946 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
2947 llvm::Function *GlobalInitFn =
2961 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2962 for (
auto *Dtor : Dtors) {
2979 unregisterGlobalDtorsWithUnAtExit();
2984 llvm::FunctionCallee dtor,
2985 llvm::Constant *addr) {
2986 if (
D.isNoDestroy(CGM.getContext()))
2994 if (!CGM.getLangOpts().hasAtExit() && !
D.isStaticLocal())
3001 if (CGM.getCodeGenOpts().CXAAtExit ||
D.getTLSKind())
3006 if (CGM.getLangOpts().AppleKext) {
3008 return CGM.AddCXXDtorEntry(dtor, addr);
3016 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
3026static llvm::GlobalValue::LinkageTypes
3028 llvm::GlobalValue::LinkageTypes VarLinkage =
3032 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
3037 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
3038 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
3040 return llvm::GlobalValue::WeakODRLinkage;
3044ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
3049 llvm::raw_svector_ostream Out(WrapperName);
3050 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
3055 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
3056 return cast<llvm::Function>(
V);
3062 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
3065 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
3066 llvm::Function *Wrapper =
3068 WrapperName.str(), &CGM.getModule());
3070 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
3071 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
3073 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, Wrapper,
false);
3076 if (!Wrapper->hasLocalLinkage())
3078 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
3079 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
3081 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
3084 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3085 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
3088 ThreadWrappers.push_back({VD, Wrapper});
3092void ItaniumCXXABI::EmitThreadLocalInitFuncs(
3096 llvm::Function *InitFunc =
nullptr;
3101 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
3102 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
3105 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
3106 CXXThreadLocalInits[I];
3108 OrderedInits.push_back(CXXThreadLocalInits[I]);
3111 if (!OrderedInits.empty()) {
3113 llvm::FunctionType *FTy =
3114 llvm::FunctionType::get(CGM.
VoidTy,
false);
3119 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
3121 llvm::GlobalVariable::InternalLinkage,
3122 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
3123 Guard->setThreadLocal(
true);
3127 Guard->setAlignment(GuardAlign.
getAsAlign());
3133 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3134 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
3140 for (
const VarDecl *VD : CXXThreadLocals) {
3144 getOrCreateThreadLocalWrapper(VD, GV);
3149 for (
auto VDAndWrapper : ThreadWrappers) {
3150 const VarDecl *VD = VDAndWrapper.first;
3151 llvm::GlobalVariable *Var =
3153 llvm::Function *Wrapper = VDAndWrapper.second;
3160 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
3166 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
3167 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
3175 llvm::raw_svector_ostream Out(InitFnName);
3176 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
3179 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
3184 llvm::GlobalValue *
Init =
nullptr;
3185 bool InitIsInitFunc =
false;
3186 bool HasConstantInitialization =
false;
3187 if (!usesThreadWrapperFunction(VD)) {
3188 HasConstantInitialization =
true;
3190 InitIsInitFunc =
true;
3191 llvm::Function *InitFuncToUse = InitFunc;
3195 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3202 Init = llvm::Function::Create(InitFnTy,
3203 llvm::GlobalVariable::ExternalWeakLinkage,
3211 Init->setVisibility(Var->getVisibility());
3213 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3214 Init->setDSOLocal(Var->isDSOLocal());
3217 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3225 isEmittedWithConstantInitializer(VD,
true) &&
3226 !mayNeedDestruction(VD)) {
3231 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3233 llvm::Function *
Func = llvm::Function::Create(
3234 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3237 cast<llvm::Function>(
Func),
3240 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3242 Builder.CreateRetVoid();
3245 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3247 if (HasConstantInitialization) {
3249 }
else if (InitIsInitFunc) {
3251 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3253 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3254 llvm::Function *
Fn =
3255 cast<llvm::Function>(cast<llvm::GlobalAlias>(
Init)->getAliasee());
3256 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3267 Builder.CreateCall(InitFnTy,
Init);
3270 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3271 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3272 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3273 Builder.CreateCondBr(Have, InitBB, ExitBB);
3275 Builder.SetInsertPoint(InitBB);
3276 Builder.CreateCall(InitFnTy,
Init);
3277 Builder.CreateBr(ExitBB);
3279 Builder.SetInsertPoint(ExitBB);
3284 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3288 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3291 Builder.CreateRet(Val);
3299 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3301 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
3302 CallVal->setCallingConv(Wrapper->getCallingConv());
3316bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
3335ItaniumCXXABI::getOrCreateVirtualFunctionPointerThunk(
const CXXMethodDecl *MD) {
3337 llvm::raw_svector_ostream Out(MethodName);
3338 getMangleContext().mangleCXXName(MD, Out);
3339 MethodName +=
"_vfpthunk_";
3340 StringRef ThunkName = MethodName.str();
3341 llvm::Function *ThunkFn;
3342 if ((ThunkFn = cast_or_null<llvm::Function>(
3343 CGM.
getModule().getNamedValue(ThunkName))))
3348 llvm::GlobalValue::LinkageTypes
Linkage =
3350 : llvm::GlobalValue::InternalLinkage;
3353 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3354 ThunkFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
3355 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
3361 ThunkFn->removeFnAttr(llvm::Attribute::StackProtect);
3362 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectStrong);
3363 ThunkFn->removeFnAttr(llvm::Attribute::StackProtectReq);
3376 llvm::Value *ThisVal = loadIncomingCXXThis(CGF);
3377 setCXXABIThisValue(CGF, ThisVal);
3380 for (
const VarDecl *VD : FunctionArgs)
3388 getThisAddress(CGF), ThunkTy);
3389 llvm::CallBase *CallOrInvoke;
3392 auto *
Call = cast<llvm::CallInst>(CallOrInvoke);
3393 Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
3394 if (
Call->getType()->isVoidTy())
3407class ItaniumRTTIBuilder {
3409 llvm::LLVMContext &VMContext;
3410 const ItaniumCXXABI &
CXXABI;
3416 llvm::GlobalVariable *
3417 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3421 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
3424 void BuildVTablePointer(
const Type *Ty);
3437 void BuildPointerTypeInfo(
QualType PointeeTy);
3448 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3449 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3463 PTI_Incomplete = 0x8,
3467 PTI_ContainingClassIncomplete = 0x10,
3473 PTI_Noexcept = 0x40,
3479 VMI_NonDiamondRepeat = 0x1,
3482 VMI_DiamondShaped = 0x2
3496 llvm::Constant *BuildTypeInfo(
QualType Ty);
3499 llvm::Constant *BuildTypeInfo(
3501 llvm::GlobalVariable::LinkageTypes
Linkage,
3502 llvm::GlobalValue::VisibilityTypes
Visibility,
3503 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3507llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3510 llvm::raw_svector_ostream Out(Name);
3516 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
3523 GV->setInitializer(
Init);
3529ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
3532 llvm::raw_svector_ostream Out(Name);
3536 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3543 GV =
new llvm::GlobalVariable(
3545 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3551 if (RD && CXXRecordNonInlineHasAttr<DLLImportAttr>(RD)) {
3552 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3579 case BuiltinType::Void:
3580 case BuiltinType::NullPtr:
3581 case BuiltinType::Bool:
3582 case BuiltinType::WChar_S:
3583 case BuiltinType::WChar_U:
3584 case BuiltinType::Char_U:
3585 case BuiltinType::Char_S:
3586 case BuiltinType::UChar:
3587 case BuiltinType::SChar:
3588 case BuiltinType::Short:
3589 case BuiltinType::UShort:
3590 case BuiltinType::Int:
3591 case BuiltinType::UInt:
3592 case BuiltinType::Long:
3593 case BuiltinType::ULong:
3594 case BuiltinType::LongLong:
3595 case BuiltinType::ULongLong:
3596 case BuiltinType::Half:
3597 case BuiltinType::Float:
3598 case BuiltinType::Double:
3599 case BuiltinType::LongDouble:
3600 case BuiltinType::Float16:
3601 case BuiltinType::Float128:
3602 case BuiltinType::Ibm128:
3603 case BuiltinType::Char8:
3604 case BuiltinType::Char16:
3605 case BuiltinType::Char32:
3606 case BuiltinType::Int128:
3607 case BuiltinType::UInt128:
3610#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3611 case BuiltinType::Id:
3612#include "clang/Basic/OpenCLImageTypes.def"
3613#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3614 case BuiltinType::Id:
3615#include "clang/Basic/OpenCLExtensionTypes.def"
3616 case BuiltinType::OCLSampler:
3617 case BuiltinType::OCLEvent:
3618 case BuiltinType::OCLClkEvent:
3619 case BuiltinType::OCLQueue:
3620 case BuiltinType::OCLReserveID:
3621#define SVE_TYPE(Name, Id, SingletonId) \
3622 case BuiltinType::Id:
3623#include "clang/Basic/AArch64SVEACLETypes.def"
3624#define PPC_VECTOR_TYPE(Name, Id, Size) \
3625 case BuiltinType::Id:
3626#include "clang/Basic/PPCTypes.def"
3627#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3628#include "clang/Basic/RISCVVTypes.def"
3629#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3630#include "clang/Basic/WebAssemblyReferenceTypes.def"
3631#define AMDGPU_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3632#include "clang/Basic/AMDGPUTypes.def"
3633 case BuiltinType::ShortAccum:
3634 case BuiltinType::Accum:
3635 case BuiltinType::LongAccum:
3636 case BuiltinType::UShortAccum:
3637 case BuiltinType::UAccum:
3638 case BuiltinType::ULongAccum:
3639 case BuiltinType::ShortFract:
3640 case BuiltinType::Fract:
3641 case BuiltinType::LongFract:
3642 case BuiltinType::UShortFract:
3643 case BuiltinType::UFract:
3644 case BuiltinType::ULongFract:
3645 case BuiltinType::SatShortAccum:
3646 case BuiltinType::SatAccum:
3647 case BuiltinType::SatLongAccum:
3648 case BuiltinType::SatUShortAccum:
3649 case BuiltinType::SatUAccum:
3650 case BuiltinType::SatULongAccum:
3651 case BuiltinType::SatShortFract:
3652 case BuiltinType::SatFract:
3653 case BuiltinType::SatLongFract:
3654 case BuiltinType::SatUShortFract:
3655 case BuiltinType::SatUFract:
3656 case BuiltinType::SatULongFract:
3657 case BuiltinType::BFloat16:
3660 case BuiltinType::Dependent:
3661#define BUILTIN_TYPE(Id, SingletonId)
3662#define PLACEHOLDER_TYPE(Id, SingletonId) \
3663 case BuiltinType::Id:
3664#include "clang/AST/BuiltinTypes.def"
3665 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3667 case BuiltinType::ObjCId:
3668 case BuiltinType::ObjCClass:
3669 case BuiltinType::ObjCSel:
3670 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3673 llvm_unreachable(
"Invalid BuiltinType Kind!");
3678 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3696 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3701 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3719 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3720 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
3731 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3734 if (CGM.
getTriple().isWindowsGNUEnvironment())
3741 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3769 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3774 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3778 dyn_cast<MemberPointerType>(Ty)) {
3780 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
3802 if (
Base->isVirtual())
3812 if (!BaseDecl->isEmpty() &&
3819void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
3821 static const char *
const ClassTypeInfo =
3822 "_ZTVN10__cxxabiv117__class_type_infoE";
3824 static const char *
const SIClassTypeInfo =
3825 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3827 static const char *
const VMIClassTypeInfo =
3828 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3830 const char *VTableName =
nullptr;
3833#define TYPE(Class, Base)
3834#define ABSTRACT_TYPE(Class, Base)
3835#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3836#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3837#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3838#include "clang/AST/TypeNodes.inc"
3839 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3841 case Type::LValueReference:
3842 case Type::RValueReference:
3843 llvm_unreachable(
"References shouldn't get here");
3846 case Type::DeducedTemplateSpecialization:
3847 llvm_unreachable(
"Undeduced type shouldn't get here");
3850 llvm_unreachable(
"Pipe types shouldn't get here");
3852 case Type::ArrayParameter:
3853 llvm_unreachable(
"Array Parameter types should not get here.");
3859 case Type::ExtVector:
3860 case Type::ConstantMatrix:
3864 case Type::BlockPointer:
3866 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3869 case Type::ConstantArray:
3870 case Type::IncompleteArray:
3871 case Type::VariableArray:
3873 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3876 case Type::FunctionNoProto:
3877 case Type::FunctionProto:
3879 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3884 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3887 case Type::Record: {
3889 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3892 VTableName = ClassTypeInfo;
3894 VTableName = SIClassTypeInfo;
3896 VTableName = VMIClassTypeInfo;
3902 case Type::ObjCObject:
3904 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3907 if (isa<BuiltinType>(Ty)) {
3908 VTableName = ClassTypeInfo;
3912 assert(isa<ObjCInterfaceType>(Ty));
3915 case Type::ObjCInterface:
3916 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3917 VTableName = SIClassTypeInfo;
3919 VTableName = ClassTypeInfo;
3923 case Type::ObjCObjectPointer:
3926 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3929 case Type::MemberPointer:
3931 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3935 llvm::Constant *VTable =
nullptr;
3939 VTable = CGM.
getModule().getNamedAlias(VTableName);
3942 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
3945 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3947 llvm::Type *PtrDiffTy =
3954 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
3956 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8Ty, VTable, Eight);
3958 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3959 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
3967 Fields.push_back(VTable);
3984 return llvm::GlobalValue::InternalLinkage;
3988 llvm_unreachable(
"Linkage hasn't been computed!");
3993 return llvm::GlobalValue::InternalLinkage;
4001 return llvm::GlobalValue::LinkOnceODRLinkage;
4006 return llvm::GlobalValue::WeakODRLinkage;
4007 if (CGM.
getTriple().isWindowsItaniumEnvironment())
4008 if (RD->
hasAttr<DLLImportAttr>() &&
4010 return llvm::GlobalValue::ExternalLinkage;
4016 .isWindowsGNUEnvironment())
4020 return llvm::GlobalValue::LinkOnceODRLinkage;
4023 llvm_unreachable(
"Invalid linkage!");
4026llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
4032 llvm::raw_svector_ostream Out(Name);
4035 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
4036 if (OldGV && !OldGV->isDeclaration()) {
4037 assert(!OldGV->hasAvailableExternallyLinkage() &&
4038 "available_externally typeinfos not yet implemented");
4046 return GetAddrOfExternalRTTIDescriptor(Ty);
4053 llvm::GlobalValue::VisibilityTypes llvmVisibility;
4054 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
4056 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
4058 ItaniumCXXABI::RUK_NonUniqueHidden)
4059 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
4063 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4064 llvm::GlobalValue::DefaultStorageClass;
4066 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
4067 RD->
hasAttr<DLLExportAttr>()) ||
4069 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
4070 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
4071 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
4073 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass);
4076llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
4078 llvm::GlobalVariable::LinkageTypes
Linkage,
4079 llvm::GlobalValue::VisibilityTypes
Visibility,
4080 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
4082 BuildVTablePointer(cast<Type>(Ty));
4086 llvm::Constant *TypeNameField;
4090 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
4092 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
4095 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
4096 llvm::Constant *flag =
4097 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
4098 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
4104 Fields.push_back(TypeNameField);
4107#define TYPE(Class, Base)
4108#define ABSTRACT_TYPE(Class, Base)
4109#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
4110#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
4111#define DEPENDENT_TYPE(Class, Base) case Type::Class:
4112#include "clang/AST/TypeNodes.inc"
4113 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
4118 case Type::ExtVector:
4119 case Type::ConstantMatrix:
4121 case Type::BlockPointer:
4126 case Type::LValueReference:
4127 case Type::RValueReference:
4128 llvm_unreachable(
"References shouldn't get here");
4131 case Type::DeducedTemplateSpecialization:
4132 llvm_unreachable(
"Undeduced type shouldn't get here");
4140 case Type::ConstantArray:
4141 case Type::IncompleteArray:
4142 case Type::VariableArray:
4143 case Type::ArrayParameter:
4148 case Type::FunctionNoProto:
4149 case Type::FunctionProto:
4159 case Type::Record: {
4161 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
4168 BuildSIClassTypeInfo(RD);
4170 BuildVMIClassTypeInfo(RD);
4175 case Type::ObjCObject:
4176 case Type::ObjCInterface:
4177 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
4180 case Type::ObjCObjectPointer:
4181 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->
getPointeeType());
4188 case Type::MemberPointer:
4189 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
4197 llvm::Constant *
Init = llvm::ConstantStruct::getAnon(Fields);
4200 llvm::raw_svector_ostream Out(Name);
4203 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
4204 llvm::GlobalVariable *GV =
4205 new llvm::GlobalVariable(M,
Init->getType(),
4209 auto GVDLLStorageClass = DLLStorageClass;
4211 GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
4212 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
4213 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
4214 if (RD->
hasAttr<DLLExportAttr>() ||
4215 CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
4216 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
4222 GV->takeName(OldGV);
4223 OldGV->replaceAllUsesWith(GV);
4224 OldGV->eraseFromParent();
4228 GV->setComdat(M.getOrInsertComdat(GV->getName()));
4255 TypeName->setDLLStorageClass(DLLStorageClass);
4256 GV->setDLLStorageClass(GVDLLStorageClass);
4266void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4269 assert(isa<BuiltinType>(
T) || isa<ObjCInterfaceType>(
T));
4273 if (isa<BuiltinType>(
T))
return;
4284 llvm::Constant *BaseTypeInfo =
4285 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4286 Fields.push_back(BaseTypeInfo);
4291void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4295 llvm::Constant *BaseTypeInfo =
4297 Fields.push_back(BaseTypeInfo);
4320 if (
Base->isVirtual()) {
4322 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4325 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4327 if (Bases.NonVirtualBases.count(BaseDecl))
4328 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4332 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4335 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4337 if (Bases.VirtualBases.count(BaseDecl))
4338 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4343 for (
const auto &I : BaseDecl->bases())
4354 for (
const auto &I : RD->
bases())
4363void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4364 llvm::Type *UnsignedIntLTy =
4372 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4377 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4410 llvm::Type *OffsetFlagsLTy =
4415 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4427 if (
Base.isVirtual())
4435 OffsetFlags =
uint64_t(Offset.getQuantity()) << 8;
4439 if (
Base.isVirtual())
4440 OffsetFlags |= BCTI_Virtual;
4442 OffsetFlags |= BCTI_Public;
4444 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
4453 if (
Type.isConstQualified())
4454 Flags |= ItaniumRTTIBuilder::PTI_Const;
4455 if (
Type.isVolatileQualified())
4456 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4457 if (
Type.isRestrictQualified())
4458 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4465 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4468 if (Proto->isNothrow()) {
4469 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4479void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
4485 llvm::Type *UnsignedIntLTy =
4487 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4492 llvm::Constant *PointeeTypeInfo =
4493 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4494 Fields.push_back(PointeeTypeInfo);
4510 Flags |= PTI_ContainingClassIncomplete;
4512 llvm::Type *UnsignedIntLTy =
4514 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4519 llvm::Constant *PointeeTypeInfo =
4520 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4521 Fields.push_back(PointeeTypeInfo);
4528 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
4531llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
4532 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4535void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4538 getContext().VoidTy, getContext().NullPtrTy,
4539 getContext().BoolTy, getContext().WCharTy,
4540 getContext().CharTy, getContext().UnsignedCharTy,
4541 getContext().SignedCharTy, getContext().ShortTy,
4542 getContext().UnsignedShortTy, getContext().IntTy,
4543 getContext().UnsignedIntTy, getContext().LongTy,
4544 getContext().UnsignedLongTy, getContext().LongLongTy,
4545 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4546 getContext().UnsignedInt128Ty, getContext().HalfTy,
4547 getContext().FloatTy, getContext().DoubleTy,
4548 getContext().LongDoubleTy, getContext().Float128Ty,
4549 getContext().Char8Ty, getContext().Char16Ty,
4550 getContext().Char32Ty
4552 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4554 ? llvm::GlobalValue::DLLExportStorageClass
4555 : llvm::GlobalValue::DefaultStorageClass;
4556 llvm::GlobalValue::VisibilityTypes
Visibility =
4558 for (
const QualType &FundamentalType : FundamentalTypes) {
4560 QualType PointerTypeConst = getContext().getPointerType(
4561 FundamentalType.withConst());
4563 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4564 Type, llvm::GlobalValue::ExternalLinkage,
4571ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4573 if (shouldRTTIBeUnique())
4577 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4578 Linkage != llvm::GlobalValue::WeakODRLinkage)
4586 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4587 return RUK_NonUniqueHidden;
4592 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4593 return RUK_NonUniqueVisible;
4598enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4603 return StructorCodegen::Emit;
4608 return StructorCodegen::Emit;
4611 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4614 const auto *CD = cast<CXXConstructorDecl>(MD);
4619 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4620 return StructorCodegen::RAUW;
4623 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4624 return StructorCodegen::RAUW;
4626 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4630 return StructorCodegen::COMDAT;
4631 return StructorCodegen::Emit;
4634 return StructorCodegen::Alias;
4644 if (Entry && !Entry->isDeclaration())
4647 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
4650 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4653 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4657 assert(Entry->getType() == Aliasee->getType() &&
4658 "declaration exists with different type");
4659 Alias->takeName(Entry);
4660 Entry->replaceAllUsesWith(Alias);
4661 Entry->eraseFromParent();
4663 Alias->setName(MangledName);
4670void ItaniumCXXABI::emitCXXStructor(
GlobalDecl GD) {
4671 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
4672 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4685 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4690 if (CGType == StructorCodegen::RAUW) {
4703 CGType != StructorCodegen::COMDAT &&
4721 if (CGType == StructorCodegen::COMDAT) {
4723 llvm::raw_svector_ostream Out(Buffer);
4725 getMangleContext().mangleCXXDtorComdat(DD, Out);
4727 getMangleContext().mangleCXXCtorComdat(CD, Out);
4728 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(Out.str());
4737 llvm::FunctionType *FTy = llvm::FunctionType::get(
4745 llvm::FunctionType *FTy =
4746 llvm::FunctionType::get(CGM.
VoidTy,
false);
4753 llvm::FunctionType *FTy = llvm::FunctionType::get(
4773 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4795 bool EndMightThrow) {
4796 llvm::CallInst *call =
4799 CGF.
EHStack.pushCleanup<CallEndCatch>(
4801 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4821 if (isa<ReferenceType>(CatchType)) {
4826 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4831 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4840 unsigned HeaderSize =
4843 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
4866 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
4874 llvm::Value *ExnCast =
4875 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
4887 if (CatchType->hasPointerRepresentation()) {
4888 llvm::Value *CastExn =
4889 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
4906 llvm_unreachable(
"bad ownership qualifier!");
4924 llvm_unreachable(
"evaluation kind filtered out!");
4926 llvm_unreachable(
"bad evaluation kind");
4929 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
4930 auto catchRD = CatchType->getAsCXXRecordDecl();
4940 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4941 LLVMCatchTy, caughtExnAlignment);
4950 llvm::CallInst *rawAdjustedExn =
4954 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4955 LLVMCatchTy, caughtExnAlignment);
4959 CodeGenFunction::OpaqueValueMapping
5011 VarDecl *CatchParam = S->getExceptionDecl();
5030 C.VoidTy, {C.getPointerType(C.CharTy)});
5033 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
5034 llvm::Function *fn =
5035 cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
5039 fn->setDoesNotThrow();
5040 fn->setDoesNotReturn();
5045 fn->addFnAttr(llvm::Attribute::NoInline);
5049 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
5050 fn->setVisibility(llvm::Function::HiddenVisibility);
5052 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
5055 llvm::BasicBlock *entry =
5060 llvm::Value *exn = &*fn->arg_begin();
5063 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
5064 catchCall->setDoesNotThrow();
5068 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
5069 termCall->setDoesNotThrow();
5070 termCall->setDoesNotReturn();
5074 builder.CreateUnreachable();
5080ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5090std::pair<llvm::Value *, const CXXRecordDecl *>
5097ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(
const CXXMethodDecl *MD) {
5102 llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
5113 ItaniumCXXABI::emitBeginCatch(CGF,
C);
5117WebAssemblyCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
5130 llvm::FunctionCallee Dtor,
5131 llvm::Constant *Addr) {
5136 llvm::FunctionType *AtExitTy =
5137 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
5140 llvm::FunctionCallee
AtExit =
5148 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
5156 llvm::Function *DtorStub =
5164 emitCXXStermFinalizer(
D, DtorStub, Addr);
5167void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &
D, llvm::Function *dtorStub,
5168 llvm::Constant *addr) {
5169 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
5172 llvm::raw_svector_ostream Out(FnName);
5173 getMangleContext().mangleDynamicStermFinalizer(&
D, Out);
5185 D.getInit()->getExprLoc());
5195 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
5200 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
5205 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
5208 CI->setCallingConv(dtorStub->getCallingConv());
5214 if (
auto *IPA =
D.
getAttr<InitPriorityAttr>()) {
5216 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()
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
struct clang::ReturnAdjustment::VirtualAdjustment::@191 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@193 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.