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