32#include "llvm/IR/DataLayout.h"
33#include "llvm/IR/GlobalValue.h"
34#include "llvm/IR/Instructions.h"
35#include "llvm/IR/Intrinsics.h"
36#include "llvm/IR/Value.h"
37#include "llvm/Support/ScopedPrinter.h"
42using namespace CodeGen;
47 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
54 bool UseARMMethodPtrABI;
55 bool UseARMGuardVarABI;
56 bool Use32BitVTableOffsetABI;
64 bool UseARMMethodPtrABI =
false,
65 bool UseARMGuardVarABI =
false) :
66 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
67 UseARMGuardVarABI(UseARMGuardVarABI),
68 Use32BitVTableOffsetABI(
false) { }
82 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
92 llvm_unreachable(
"emitting dtor comdat as function?");
94 llvm_unreachable(
"bad dtor kind");
96 if (isa<CXXConstructorDecl>(GD.
getDecl())) {
106 llvm_unreachable(
"closure ctors in Itanium ABI?");
109 llvm_unreachable(
"emitting ctor comdat as function?");
111 llvm_unreachable(
"bad dtor kind");
126 llvm::Value *&ThisPtrForCall,
127 llvm::Value *MemFnPtr,
138 llvm::Value *Src)
override;
140 llvm::Constant *Src)
override;
152 llvm::Value *L, llvm::Value *R,
154 bool Inequality)
override;
171 llvm::Value *Exn)
override;
173 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
177 QualType CatchHandlerType)
override {
185 llvm::Type *StdTypeInfoPtrTy)
override;
194 bool hasUniqueVTablePointer(
QualType RecordTy) {
199 if (!CGM.getCodeGenOpts().AssumeUniqueVTables ||
200 getContext().getLangOpts().AppleKext)
205 if (!CGM.shouldEmitRTTI())
210 if (!llvm::GlobalValue::isWeakForLinker(CGM.getVTableLinkage(RD)))
219 llvm::GlobalValue::DefaultVisibility)
226 return hasUniqueVTablePointer(DestRecordTy);
232 llvm::BasicBlock *CastEnd)
override;
237 llvm::BasicBlock *CastSuccess,
238 llvm::BasicBlock *CastFail)
override;
252 AddedStructorArgCounts
292 CodeGenFunction::VPtr Vptr)
override;
306 llvm::Value *getVTableAddressPointInStructorWithVTT(
320 DeleteOrMemberCallExpr E)
override;
325 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
331 if (ForVTable && !Thunk->hasLocalLinkage())
332 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
333 CGM.setGVProperties(Thunk, GD);
346 assert(!Args.empty() &&
"expected the arglist to not be empty!");
347 return Args.size() - 1;
352 {
return "__cxa_deleted_virtual"; }
357 llvm::Value *NumElements,
365 llvm::GlobalVariable *DeclPtr,
366 bool PerformInit)
override;
368 llvm::FunctionCallee dtor,
369 llvm::Constant *addr)
override;
371 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
393 virtual bool shouldRTTIBeUnique()
const {
return true; }
397 enum RTTIUniquenessKind {
415 classifyRTTIUniqueness(
QualType CanTy,
416 llvm::GlobalValue::LinkageTypes
Linkage)
const;
417 friend class ItaniumRTTIBuilder;
421 std::pair<llvm::Value *, const CXXRecordDecl *>
426 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
427 const auto &VtableLayout =
428 CGM.getItaniumVTableContext().getVTableLayout(RD);
430 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
432 if (!VtableComponent.isUsedFunctionPointerKind())
435 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
439 StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
440 auto *Entry = CGM.GetGlobalValue(Name);
446 if (!Entry || Entry->isDeclaration())
453 const auto &VtableLayout =
454 CGM.getItaniumVTableContext().getVTableLayout(RD);
456 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
457 if (VtableComponent.isRTTIKind()) {
458 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
459 if (RTTIDecl->
getVisibility() == Visibility::HiddenVisibility)
461 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
462 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
463 if (Method->
getVisibility() == Visibility::HiddenVisibility &&
472class ARMCXXABI :
public ItaniumCXXABI {
475 ItaniumCXXABI(CGM,
true,
478 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
486 llvm::Value *NumElements,
493class AppleARM64CXXABI :
public ARMCXXABI {
496 Use32BitVTableOffsetABI =
true;
500 bool shouldRTTIBeUnique()
const override {
return false; }
503class FuchsiaCXXABI final :
public ItaniumCXXABI {
506 : ItaniumCXXABI(CGM) {}
509 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
512class WebAssemblyCXXABI final :
public ItaniumCXXABI {
515 : ItaniumCXXABI(CGM,
true,
520 llvm::Value *Exn)
override;
523 bool constructorsAndDestructorsReturnThis()
const override {
return true; }
524 bool canCallMismatchedFunctionType()
const override {
return false; }
527class XLCXXABI final :
public ItaniumCXXABI {
530 : ItaniumCXXABI(CGM) {}
533 llvm::FunctionCallee dtor,
534 llvm::Constant *addr)
override;
536 bool useSinitAndSterm()
const override {
return true; }
539 void emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
540 llvm::Constant *addr);
548 case TargetCXXABI::GenericARM:
549 case TargetCXXABI::iOS:
550 case TargetCXXABI::WatchOS:
551 return new ARMCXXABI(CGM);
553 case TargetCXXABI::AppleARM64:
554 return new AppleARM64CXXABI(CGM);
556 case TargetCXXABI::Fuchsia:
557 return new FuchsiaCXXABI(CGM);
562 case TargetCXXABI::GenericAArch64:
563 return new ItaniumCXXABI(CGM,
true,
566 case TargetCXXABI::GenericMIPS:
567 return new ItaniumCXXABI(CGM,
true);
569 case TargetCXXABI::WebAssembly:
570 return new WebAssemblyCXXABI(CGM);
572 case TargetCXXABI::XL:
573 return new XLCXXABI(CGM);
575 case TargetCXXABI::GenericItanium:
577 == llvm::Triple::le32) {
581 return new ItaniumCXXABI(CGM,
true);
583 return new ItaniumCXXABI(CGM);
585 case TargetCXXABI::Microsoft:
586 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
588 llvm_unreachable(
"bad ABI kind");
594 return CGM.PtrDiffTy;
595 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
618CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
620 llvm::Value *&ThisPtrForCall,
629 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
636 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
639 llvm::Value *Adj = RawAdj;
640 if (UseARMMethodPtrABI)
641 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
646 This = Builder.CreateInBoundsGEP(Builder.getInt8Ty(), This, Adj);
647 ThisPtrForCall = This;
650 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
654 llvm::Value *IsVirtual;
655 if (UseARMMethodPtrABI)
656 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
658 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
659 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
660 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
678 llvm::Value *VTableOffset = FnAsInt;
679 if (!UseARMMethodPtrABI)
680 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
681 if (Use32BitVTableOffsetABI) {
682 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
683 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
688 llvm::Constant *CheckSourceLocation;
689 llvm::Constant *CheckTypeDesc;
690 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
691 CGM.HasHiddenLTOVisibility(RD);
692 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
693 CGM.HasHiddenLTOVisibility(RD);
694 bool ShouldEmitWPDInfo =
695 CGM.getCodeGenOpts().WholeProgramVTables &&
697 !CGM.AlwaysHasLTOVisibilityPublic(RD);
698 llvm::Value *VirtualFn =
nullptr;
701 CodeGenFunction::SanitizerScope SanScope(&CGF);
702 llvm::Value *TypeId =
nullptr;
703 llvm::Value *CheckResult =
nullptr;
705 if (ShouldEmitCFICheck || ShouldEmitVFEInfo || ShouldEmitWPDInfo) {
709 CGM.CreateMetadataIdentifierForVirtualMemPtrType(
QualType(MPT, 0));
713 if (ShouldEmitVFEInfo) {
714 llvm::Value *VFPAddr =
715 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
722 llvm::Value *CheckedLoad = Builder.CreateCall(
723 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
724 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
725 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
726 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
730 if (ShouldEmitCFICheck || ShouldEmitWPDInfo) {
731 llvm::Value *VFPAddr =
732 Builder.CreateGEP(CGF.
Int8Ty, VTable, VTableOffset);
733 llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
734 ? llvm::Intrinsic::type_test
735 : llvm::Intrinsic::public_type_test;
738 Builder.CreateCall(CGM.getIntrinsic(IID), {VFPAddr, TypeId});
741 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
742 VirtualFn = CGF.
Builder.CreateCall(
743 CGM.getIntrinsic(llvm::Intrinsic::load_relative,
744 {VTableOffset->getType()}),
745 {VTable, VTableOffset});
747 llvm::Value *VFPAddr =
754 assert(VirtualFn &&
"Virtual fuction pointer not created!");
755 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || !ShouldEmitWPDInfo ||
757 "Check result required but not created!");
759 if (ShouldEmitCFICheck) {
763 llvm::Constant *StaticData[] = {
764 llvm::ConstantInt::get(CGF.
Int8Ty, CodeGenFunction::CFITCK_VMFCall),
769 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
770 CGF.
EmitTrapCheck(CheckResult, SanitizerHandler::CFICheckFail);
772 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
773 CGM.getLLVMContext(),
774 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
775 llvm::Value *ValidVtable = Builder.CreateCall(
776 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
777 CGF.
EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIMFCall),
778 SanitizerHandler::CFICheckFail, StaticData,
779 {VTable, ValidVtable});
782 FnVirtual = Builder.GetInsertBlock();
791 llvm::Value *NonVirtualFn =
792 Builder.CreateIntToPtr(FnAsInt, CGF.
UnqualPtrTy,
"memptr.nonvirtualfn");
795 if (ShouldEmitCFICheck) {
798 CodeGenFunction::SanitizerScope SanScope(&CGF);
800 llvm::Constant *StaticData[] = {
801 llvm::ConstantInt::get(CGF.
Int8Ty, CodeGenFunction::CFITCK_NVMFCall),
806 llvm::Value *Bit = Builder.getFalse();
808 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
809 getContext().getMemberPointerType(
812 llvm::Value *TypeId =
815 llvm::Value *TypeTest =
816 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
817 {NonVirtualFn, TypeId});
818 Bit = Builder.CreateOr(Bit, TypeTest);
821 CGF.
EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
822 SanitizerHandler::CFICheckFail, StaticData,
823 {NonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
825 FnNonVirtual = Builder.GetInsertBlock();
831 llvm::PHINode *CalleePtr = Builder.CreatePHI(CGF.
UnqualPtrTy, 2);
832 CalleePtr->addIncoming(VirtualFn, FnVirtual);
833 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
841llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
844 assert(MemPtr->getType() == CGM.PtrDiffTy);
849 return Builder.CreateInBoundsGEP(CGF.
Int8Ty,
Base.emitRawPointer(CGF), MemPtr,
880 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
881 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
885 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
888 if (isa<llvm::Constant>(src))
889 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
891 llvm::Constant *adj = getMemberPointerAdjustment(E);
892 if (!adj)
return src;
895 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
905 dst = Builder.CreateNSWSub(src, adj,
"adj");
907 dst = Builder.CreateNSWAdd(src, adj,
"adj");
910 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
911 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
912 return Builder.CreateSelect(isNull, src, dst);
916 if (UseARMMethodPtrABI) {
917 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
919 adj = llvm::ConstantInt::get(adj->getType(), offset);
922 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
925 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
927 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
929 return Builder.CreateInsertValue(src, dstAdj, 1);
933ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
934 llvm::Constant *src) {
935 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
936 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
940 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
943 llvm::Constant *adj = getMemberPointerAdjustment(E);
944 if (!adj)
return src;
946 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
955 if (src->isAllOnesValue())
return src;
958 return llvm::ConstantExpr::getNSWSub(src, adj);
960 return llvm::ConstantExpr::getNSWAdd(src, adj);
964 if (UseARMMethodPtrABI) {
965 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
967 adj = llvm::ConstantInt::get(adj->getType(), offset);
970 llvm::Constant *srcAdj = src->getAggregateElement(1);
971 llvm::Constant *dstAdj;
973 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
975 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
977 llvm::Constant *res = ConstantFoldInsertValueInstruction(src, dstAdj, 1);
978 assert(res !=
nullptr &&
"Folding must succeed");
987 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
989 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
990 llvm::Constant *Values[2] = {
Zero,
Zero };
991 return llvm::ConstantStruct::getAnon(Values);
1000 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
1004ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
1008llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
1010 assert(MD->
isInstance() &&
"Member function must not be static!");
1015 llvm::Constant *MemPtr[2];
1017 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
1019 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1021 VTableOffset = Index * 4;
1026 VTableOffset = Index * PointerWidth.
getQuantity();
1029 if (UseARMMethodPtrABI) {
1036 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1037 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1044 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1045 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1052 if (Types.isFuncTypeConvertible(FPT)) {
1054 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
1060 llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
1062 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1063 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1064 (UseARMMethodPtrABI ? 2 : 1) *
1068 return llvm::ConstantStruct::getAnon(MemPtr);
1071llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1076 return EmitNullMemberPointer(MPT);
1084 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1100 llvm::ICmpInst::Predicate
Eq;
1101 llvm::Instruction::BinaryOps
And,
Or;
1103 Eq = llvm::ICmpInst::ICMP_NE;
1104 And = llvm::Instruction::Or;
1105 Or = llvm::Instruction::And;
1107 Eq = llvm::ICmpInst::ICMP_EQ;
1108 And = llvm::Instruction::And;
1109 Or = llvm::Instruction::Or;
1115 return Builder.CreateICmp(
Eq, L, R);
1127 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1128 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1132 llvm::Value *PtrEq = Builder.CreateICmp(
Eq, LPtr, RPtr,
"cmp.ptr");
1137 llvm::Value *
Zero = llvm::Constant::getNullValue(LPtr->getType());
1138 llvm::Value *EqZero = Builder.CreateICmp(
Eq, LPtr, Zero,
"cmp.ptr.null");
1142 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1143 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1144 llvm::Value *AdjEq = Builder.CreateICmp(
Eq, LAdj, RAdj,
"cmp.adj");
1148 if (UseARMMethodPtrABI) {
1149 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1152 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1153 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1154 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(
Eq, OrAdjAnd1, Zero,
1156 EqZero = Builder.CreateBinOp(
And, EqZero, OrAdjAnd1EqZero);
1160 llvm::Value *Result = Builder.CreateBinOp(
Or, EqZero, AdjEq);
1161 Result = Builder.CreateBinOp(
And, PtrEq, Result,
1162 Inequality ?
"memptr.ne" :
"memptr.eq");
1168 llvm::Value *MemPtr,
1174 assert(MemPtr->getType() == CGM.PtrDiffTy);
1175 llvm::Value *NegativeOne =
1176 llvm::Constant::getAllOnesValue(MemPtr->getType());
1177 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1181 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1183 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1184 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
1188 if (UseARMMethodPtrABI) {
1189 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1190 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1191 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1192 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1193 "memptr.isvirtual");
1194 Result = Builder.CreateOr(Result, IsVirtual);
1200bool ItaniumCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1207 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1228 if (UseGlobalDelete) {
1238 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
1239 CGF.
IntPtrTy, VTable, -2,
"complete-offset.ptr");
1257 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
1259 if (UseGlobalDelete)
1263void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1266 llvm::FunctionType *FTy =
1267 llvm::FunctionType::get(CGM.VoidTy,
false);
1269 llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1280 llvm::FunctionType *FTy =
1291 llvm::FunctionType *FTy =
1292 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1300 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
1301 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1305 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1312 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1317 llvm::Constant *Dtor =
nullptr;
1320 if (!
Record->hasTrivialDestructor()) {
1325 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1327 llvm::Value *args[] = { ExceptionPtr,
TypeInfo, Dtor };
1339 llvm::Type *PtrDiffTy =
1342 llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
1344 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1348 FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1349 FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
1350 FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
1351 llvm::AttributeList Attrs = llvm::AttributeList::get(
1352 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1359 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1376 unsigned NumPublicPaths = 0;
1389 if (PathElement.Base->isVirtual())
1392 if (NumPublicPaths > 1)
1398 PathElement.Base->getType()->getAsCXXRecordDecl());
1403 if (NumPublicPaths == 0)
1407 if (NumPublicPaths > 1)
1417 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1422bool ItaniumCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
1430 Call->setDoesNotReturn();
1431 CGF.
Builder.CreateUnreachable();
1437 llvm::Type *StdTypeInfoPtrTy) {
1443 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1446 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
1447 {Value, llvm::ConstantInt::get(CGM.Int32Ty, -4)});
1451 CGF.
Builder.CreateConstInBoundsGEP1_64(StdTypeInfoPtrTy,
Value, -1ULL);
1457bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1462llvm::Value *ItaniumCXXABI::emitDynamicCastCall(
1465 llvm::Type *PtrDiffLTy =
1468 llvm::Value *SrcRTTI =
1470 llvm::Value *DestRTTI =
1476 llvm::Value *OffsetHint = llvm::ConstantInt::get(
1481 llvm::Value *Args[] = {ThisAddr.
emitRawPointer(CGF), SrcRTTI, DestRTTI,
1483 llvm::Value *
Value =
1489 llvm::BasicBlock *BadCastBlock =
1496 EmitBadCastCall(CGF);
1502llvm::Value *ItaniumCXXABI::emitExactDynamicCast(
1505 llvm::BasicBlock *CastFail) {
1517 std::optional<CharUnits> Offset;
1527 PathElement.Base->getType()->getAsCXXRecordDecl();
1528 if (PathElement.Base->isVirtual()) {
1541 Offset = PathOffset;
1542 else if (Offset != PathOffset) {
1547 ThisAddr =
Address(emitDynamicCastToVoid(CGF, ThisAddr, SrcRecordTy),
1558 return llvm::PoisonValue::get(CGF.
VoidPtrTy);
1567 CGM.DecorateInstructionWithTBAA(
1568 VPtr, CGM.getTBAAVTablePtrAccessInfo(CGF.
VoidPtrPtrTy));
1570 VPtr, getVTableAddressPoint(
BaseSubobject(SrcDecl, *Offset), DestDecl));
1572 if (!Offset->isZero())
1575 {llvm::ConstantInt::get(CGF.PtrDiffTy, -Offset->getQuantity())});
1580llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(
CodeGenFunction &CGF,
1585 llvm::Value *OffsetToTop;
1586 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1588 llvm::Value *VTable =
1593 CGF.
Builder.CreateConstInBoundsGEP1_32(CGM.Int32Ty, VTable, -2U);
1597 llvm::Type *PtrDiffLTy =
1601 llvm::Value *VTable =
1606 CGF.
Builder.CreateConstInBoundsGEP1_64(PtrDiffLTy, VTable, -2ULL);
1618 Call->setDoesNotReturn();
1619 CGF.
Builder.CreateUnreachable();
1628 llvm::Value *VTablePtr = CGF.
GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
1630 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1632 llvm::Value *VBaseOffsetPtr =
1633 CGF.
Builder.CreateConstGEP1_64(
1635 "vbase.offset.ptr");
1637 llvm::Value *VBaseOffset;
1638 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
1644 CGM.PtrDiffTy, VBaseOffsetPtr, CGF.
getPointerAlign(),
"vbase.offset");
1651 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1666ItaniumCXXABI::buildStructorSignature(
GlobalDecl GD,
1676 cast<CXXMethodDecl>(GD.
getDecl())->getParent()->getNumVBases() != 0) {
1677 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1679 ArgTys.insert(ArgTys.begin() + 1,
1681 return AddedStructorArgCounts::prefix(1);
1683 return AddedStructorArgCounts{};
1706 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1709 if (NeedsVTTParameter(CGF.
CurGD)) {
1713 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1718 T, ImplicitParamKind::CXXVTT);
1719 Params.insert(Params.begin() + 1, VTTDecl);
1720 getStructorImplicitParamDecl(CGF) = VTTDecl;
1731 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1734 if (getStructorImplicitParamDecl(CGF)) {
1747 if (HasThisReturn(CGF.
CurGD))
1755 return AddedStructorArgs{};
1762 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1763 QualType Q = getContext().getAddrSpaceQualType(getContext().VoidPtrTy, AS);
1764 QualType VTTTy = getContext().getPointerType(Q);
1765 return AddedStructorArgs::prefix({{VTT, VTTTy}});
1768llvm::Value *ItaniumCXXABI::getCXXDestructorImplicitParam(
1783 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1786 if (getContext().getLangOpts().AppleKext &&
1793 ThisTy, VTT, VTTTy,
nullptr);
1798 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1799 if (VTable->hasInitializer())
1804 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
1805 llvm::Constant *RTTI =
1806 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1810 auto components = builder.beginStruct();
1812 llvm::GlobalValue::isLocalLinkage(
Linkage));
1813 components.finishAndSetAsInitializer(VTable);
1818 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1819 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1822 CGM.setGVProperties(VTable, RD);
1830 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1831 cast<NamespaceDecl>(DC)->getIdentifier()->isStr(
"__cxxabiv1") &&
1833 EmitFundamentalRTTIDescriptors(RD);
1840 if (!VTable->isDeclarationForLinker() ||
1841 CGM.getCodeGenOpts().WholeProgramVTables) {
1842 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
1846 if (VTable->isDeclarationForLinker()) {
1847 assert(CGM.getCodeGenOpts().WholeProgramVTables);
1848 CGM.addCompilerUsedGlobal(VTable);
1854 if (!VTable->isDSOLocal())
1859bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1861 if (Vptr.NearestVBase ==
nullptr)
1863 return NeedsVTTParameter(CGF.
CurGD);
1866llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1870 if ((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
1871 NeedsVTTParameter(CGF.
CurGD)) {
1872 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass,
Base,
1875 return getVTableAddressPoint(
Base, VTableClass);
1881 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
1886 CGM.getItaniumVTableContext().getVTableLayout(VTableClass);
1889 llvm::Value *Indices[] = {
1890 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1891 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
1897 unsigned ComponentSize =
1898 CGM.getDataLayout().getTypeAllocSize(CGM.getVTableComponentType());
1899 unsigned VTableSize =
1902 llvm::ConstantRange
InRange(llvm::APInt(32, -Offset,
true),
1903 llvm::APInt(32, VTableSize - Offset,
true));
1904 return llvm::ConstantExpr::getGetElementPtr(
1905 VTable->getValueType(), VTable, Indices,
true, InRange);
1910template <
typename T>
1912 bool FoundNonInlineVirtualMethodWithAttr =
false;
1914 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
1915 if (!FD->isVirtualAsWritten() || FD->isInlineSpecified() ||
1916 FD->doesThisDeclarationHaveABody())
1920 FoundNonInlineVirtualMethodWithAttr =
true;
1928 return FoundNonInlineVirtualMethodWithAttr;
1931llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1934 assert((
Base.getBase()->getNumVBases() || NearestVBase !=
nullptr) &&
1935 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
1939 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass,
Base);
1943 if (VirtualPointerIndex)
1945 VirtualPointerIndex);
1952llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1954 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1956 llvm::GlobalVariable *&VTable = VTables[RD];
1961 CGM.addDeferredVTable(RD);
1964 llvm::raw_svector_ostream Out(Name);
1965 getMangleContext().mangleCXXVTable(RD, Out);
1968 CGM.getItaniumVTableContext().getVTableLayout(RD);
1969 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1974 LangAS AS = CGM.GetGlobalVarAddressSpace(
nullptr);
1975 unsigned PAlign = CGM.getItaniumVTableContext().isRelativeLayout()
1977 : CGM.getTarget().getPointerAlign(AS);
1979 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1980 Name, VTableType, llvm::GlobalValue::ExternalLinkage,
1981 getContext().toCharUnitsFromBits(PAlign).getAsAlign());
1982 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1991 if (CGM.getTarget().hasPS4DLLImportExport()) {
1992 if ((!RD->
hasAttr<DLLImportAttr>()) && (!RD->
hasAttr<DLLExportAttr>())) {
1993 if (CGM.getVTables().isVTableExternal(RD)) {
1994 if (CXXRecordAllNonInlineVirtualsHaveAttr<DLLImportAttr>(RD))
1995 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1997 if (CXXRecordAllNonInlineVirtualsHaveAttr<DLLExportAttr>(RD))
1998 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2002 CGM.setGVProperties(VTable, RD);
2012 llvm::Type *PtrTy = CGM.GlobalsInt8PtrTy;
2013 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
2014 llvm::Value *VTable = CGF.
GetVTablePtr(This, PtrTy, MethodDecl->getParent());
2016 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
2020 MethodDecl->getParent(), VTable, PtrTy,
2022 CGM.getContext().getTargetInfo().getPointerWidth(LangAS::Default) /
2027 llvm::Value *VFuncLoad;
2028 if (CGM.getItaniumVTableContext().isRelativeLayout()) {
2029 VFuncLoad = CGF.
Builder.CreateCall(
2030 CGM.getIntrinsic(llvm::Intrinsic::load_relative, {CGM.Int32Ty}),
2031 {VTable, llvm::ConstantInt::get(CGM.Int32Ty, 4 * VTableIndex)});
2033 llvm::Value *VTableSlotPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2034 PtrTy, VTable, VTableIndex,
"vfn");
2045 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2046 CGM.getCodeGenOpts().StrictVTablePointers) {
2047 if (
auto *VFuncLoadInstr = dyn_cast<llvm::Instruction>(VFuncLoad)) {
2048 VFuncLoadInstr->setMetadata(
2049 llvm::LLVMContext::MD_invariant_load,
2050 llvm::MDNode::get(CGM.getLLVMContext(),
2061llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
2063 Address This, DeleteOrMemberCallExpr E) {
2066 assert((CE !=
nullptr) ^ (D !=
nullptr));
2067 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
2072 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
2078 ThisTy = CE->getObjectType();
2080 ThisTy = D->getDestroyedType();
2088void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2094bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2098 if (CGM.getLangOpts().AppleKext)
2103 if (isVTableHidden(RD))
2106 if (CGM.getCodeGenOpts().ForceEmitVTables)
2113 if (hasAnyUnusedVirtualInlineFunction(RD))
2121 for (
const auto &B : RD->
bases()) {
2122 auto *BRD = B.getType()->getAsCXXRecordDecl();
2123 assert(BRD &&
"no class for base specifier");
2124 if (B.isVirtual() || !BRD->isDynamicClass())
2126 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2134bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
2135 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
2140 for (
const auto &B : RD->
vbases()) {
2141 auto *BRD = B.getType()->getAsCXXRecordDecl();
2142 assert(BRD &&
"no class for base specifier");
2143 if (!BRD->isDynamicClass())
2145 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
2153 int64_t NonVirtualAdjustment,
2154 int64_t VirtualAdjustment,
2155 bool IsReturnAdjustment) {
2156 if (!NonVirtualAdjustment && !VirtualAdjustment)
2162 if (NonVirtualAdjustment && !IsReturnAdjustment) {
2168 llvm::Value *ResultPtr;
2169 if (VirtualAdjustment) {
2173 llvm::Value *Offset;
2174 llvm::Value *OffsetPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2175 CGF.
Int8Ty, VTablePtr, VirtualAdjustment);
2182 llvm::Type *PtrDiffTy =
2191 V.emitRawPointer(CGF), Offset);
2193 ResultPtr =
V.emitRawPointer(CGF);
2198 if (NonVirtualAdjustment && IsReturnAdjustment) {
2199 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CGF.
Int8Ty, ResultPtr,
2200 NonVirtualAdjustment);
2206llvm::Value *ItaniumCXXABI::performThisAdjustment(
CodeGenFunction &CGF,
2225 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
2230 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2239 CGM.getContext().getPreferredTypeAlignInChars(elementType));
2244 llvm::Value *NumElements,
2247 assert(requiresArrayCookie(
expr));
2257 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2261 CharUnits CookieOffset = CookieSize - SizeSize;
2262 if (!CookieOffset.
isZero())
2270 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2271 (
expr->getOperatorNew()->isReplaceableGlobalAllocationFunction() ||
2272 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2274 SI->setNoSanitizeMetadata();
2275 llvm::FunctionType *FTy =
2276 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2277 llvm::FunctionCallee F =
2278 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2291 Address numElementsPtr = allocPtr;
2293 if (!numElementsOffset.
isZero())
2299 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2306 llvm::FunctionType *FTy =
2308 llvm::FunctionCallee F =
2309 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2323 CGM.getContext().getTypeAlignInChars(elementType));
2328 llvm::Value *numElements,
2331 assert(requiresArrayCookie(
expr));
2338 llvm::Value *elementSize = llvm::ConstantInt::get(CGF.
SizeTy,
2339 getContext().getTypeSizeInChars(elementType).getQuantity());
2348 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2367 llvm::PointerType *GuardPtrTy) {
2369 llvm::FunctionType *FTy =
2373 FTy,
"__cxa_guard_acquire",
2375 llvm::AttributeList::FunctionIndex,
2376 llvm::Attribute::NoUnwind));
2380 llvm::PointerType *GuardPtrTy) {
2382 llvm::FunctionType *FTy =
2383 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2385 FTy,
"__cxa_guard_release",
2387 llvm::AttributeList::FunctionIndex,
2388 llvm::Attribute::NoUnwind));
2392 llvm::PointerType *GuardPtrTy) {
2394 llvm::FunctionType *FTy =
2395 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2397 FTy,
"__cxa_guard_abort",
2399 llvm::AttributeList::FunctionIndex,
2400 llvm::Attribute::NoUnwind));
2405 llvm::GlobalVariable *Guard;
2406 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2419 llvm::GlobalVariable *var,
2420 bool shouldPerformInit) {
2425 bool NonTemplateInline =
2432 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2438 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
2440 llvm::IntegerType *guardTy;
2442 if (useInt8GuardVariable) {
2448 if (UseARMGuardVarABI) {
2457 llvm::PointerType *guardPtrTy = llvm::PointerType::get(
2463 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2468 llvm::raw_svector_ostream out(guardName);
2469 getMangleContext().mangleStaticGuardVariable(&D, out);
2475 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2476 false, var->getLinkage(),
2477 llvm::ConstantInt::get(guardTy, 0),
2479 guard->setDSOLocal(var->isDSOLocal());
2480 guard->setVisibility(var->getVisibility());
2481 guard->setDLLStorageClass(var->getDLLStorageClass());
2483 guard->setThreadLocalMode(var->getThreadLocalMode());
2484 guard->setAlignment(guardAlignment.
getAsAlign());
2489 llvm::Comdat *
C = var->getComdat();
2491 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2492 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2493 guard->setComdat(
C);
2494 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2495 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2498 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2501 Address guardAddr =
Address(guard, guard->getValueType(), guardAlignment);
2526 if (!threadsafe || MaxInlineWidthInBits) {
2528 llvm::LoadInst *LI =
2538 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2561 (UseARMGuardVarABI && !useInt8GuardVariable)
2562 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2564 llvm::Value *NeedsInit = Builder.CreateIsNull(
V,
"guard.uninitialized");
2570 CodeGenFunction::GuardKind::VariableGuard, &D);
2598 Builder.CreateCondBr(Builder.CreateIsNotNull(
V,
"tobool"),
2599 InitBlock, EndBlock);
2609 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2627 Builder.CreateStore(llvm::ConstantInt::get(CGM.Int8Ty, 1),
2636 llvm::FunctionCallee dtor,
2637 llvm::Constant *addr,
bool TLS) {
2639 "unexpected call to emitGlobalDtorWithCXAAtExit");
2641 "__cxa_atexit is disabled");
2642 const char *Name =
"__cxa_atexit";
2645 Name =
T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2653 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2654 auto AddrPtrTy = AddrAS ? llvm::PointerType::get(CGF.
getLLVMContext(), AddrAS)
2658 llvm::Constant *handle =
2660 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2661 GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
2664 llvm::Type *paramTys[] = {
dtorTy, AddrPtrTy, handle->getType()};
2665 llvm::FunctionType *atexitTy =
2666 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2670 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2671 fn->setDoesNotThrow();
2678 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2680 llvm::Value *args[] = {dtor.getCallee(), addr, handle};
2688 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2692 return GlobalInitOrCleanupFn;
2695void CodeGenModule::unregisterGlobalDtorsWithUnAtExit() {
2696 for (
const auto &I : DtorsUsingAtExit) {
2698 std::string GlobalCleanupFnName =
2699 std::string(
"__GLOBAL_cleanup_") + llvm::to_string(Priority);
2701 llvm::Function *GlobalCleanupFn =
2711 llvm::FunctionType *dtorFuncTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
2715 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2716 auto itv = Dtors.rbegin();
2717 while (itv != Dtors.rend()) {
2718 llvm::Function *Dtor = *itv;
2723 llvm::Value *NeedsDestruct =
2726 llvm::BasicBlock *DestructCallBlock =
2729 (itv + 1) != Dtors.rend() ?
"unatexit.call" :
"destruct.end");
2732 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
2737 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorFuncTy, Dtor);
2739 CI->setCallingConv(Dtor->getCallingConv());
2751void CodeGenModule::registerGlobalDtorsWithAtExit() {
2752 for (
const auto &I : DtorsUsingAtExit) {
2754 std::string GlobalInitFnName =
2755 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
2756 llvm::Function *GlobalInitFn =
2770 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2771 for (
auto *Dtor : Dtors) {
2788 unregisterGlobalDtorsWithUnAtExit();
2793 llvm::FunctionCallee dtor,
2794 llvm::Constant *addr) {
2810 if (CGM.getCodeGenOpts().CXAAtExit || D.
getTLSKind())
2815 if (CGM.getLangOpts().AppleKext) {
2817 return CGM.AddCXXDtorEntry(dtor, addr);
2825 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
2835static llvm::GlobalValue::LinkageTypes
2837 llvm::GlobalValue::LinkageTypes VarLinkage =
2841 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
2846 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
2847 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
2849 return llvm::GlobalValue::WeakODRLinkage;
2853ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
2858 llvm::raw_svector_ostream Out(WrapperName);
2859 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
2864 if (llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
2865 return cast<llvm::Function>(
V);
2871 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
2874 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
2875 llvm::Function *Wrapper =
2877 WrapperName.str(), &CGM.getModule());
2879 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
2880 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
2882 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, Wrapper,
false);
2885 if (!Wrapper->hasLocalLinkage())
2887 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
2888 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
2890 Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
2893 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2894 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
2897 ThreadWrappers.push_back({VD, Wrapper});
2901void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2905 llvm::Function *InitFunc =
nullptr;
2910 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
2911 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
2914 UnorderedInits[CXXThreadLocalInitVars[I]->getCanonicalDecl()] =
2915 CXXThreadLocalInits[I];
2917 OrderedInits.push_back(CXXThreadLocalInits[I]);
2920 if (!OrderedInits.empty()) {
2922 llvm::FunctionType *FTy =
2923 llvm::FunctionType::get(CGM.
VoidTy,
false);
2928 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
2930 llvm::GlobalVariable::InternalLinkage,
2931 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
2932 Guard->setThreadLocal(
true);
2936 Guard->setAlignment(GuardAlign.
getAsAlign());
2942 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2943 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
2949 for (
const VarDecl *VD : CXXThreadLocals) {
2953 getOrCreateThreadLocalWrapper(VD, GV);
2958 for (
auto VDAndWrapper : ThreadWrappers) {
2959 const VarDecl *VD = VDAndWrapper.first;
2960 llvm::GlobalVariable *Var =
2962 llvm::Function *Wrapper = VDAndWrapper.second;
2969 Wrapper->setLinkage(llvm::Function::ExternalLinkage);
2975 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
2976 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
2984 llvm::raw_svector_ostream Out(InitFnName);
2985 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
2988 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2993 llvm::GlobalValue *
Init =
nullptr;
2994 bool InitIsInitFunc =
false;
2995 bool HasConstantInitialization =
false;
2996 if (!usesThreadWrapperFunction(VD)) {
2997 HasConstantInitialization =
true;
2999 InitIsInitFunc =
true;
3000 llvm::Function *InitFuncToUse = InitFunc;
3004 Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
3011 Init = llvm::Function::Create(InitFnTy,
3012 llvm::GlobalVariable::ExternalWeakLinkage,
3020 Init->setVisibility(Var->getVisibility());
3022 if (!CGM.
getTriple().isOSWindows() || !
Init->hasExternalWeakLinkage())
3023 Init->setDSOLocal(Var->isDSOLocal());
3026 llvm::LLVMContext &Context = CGM.
getModule().getContext();
3034 isEmittedWithConstantInitializer(VD,
true) &&
3035 !mayNeedDestruction(VD)) {
3040 assert(
Init ==
nullptr &&
"Expected Init to be null.");
3042 llvm::Function *
Func = llvm::Function::Create(
3043 InitFnTy, Var->getLinkage(), InitFnName.str(), &CGM.
getModule());
3046 cast<llvm::Function>(
Func),
3049 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"",
Func);
3051 Builder.CreateRetVoid();
3054 llvm::BasicBlock *Entry = llvm::BasicBlock::Create(Context,
"", Wrapper);
3056 if (HasConstantInitialization) {
3058 }
else if (InitIsInitFunc) {
3060 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy,
Init);
3062 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3063 llvm::Function *Fn =
3064 cast<llvm::Function>(cast<llvm::GlobalAlias>(
Init)->getAliasee());
3065 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
3076 Builder.CreateCall(InitFnTy,
Init);
3079 llvm::Value *Have = Builder.CreateIsNotNull(
Init);
3080 llvm::BasicBlock *InitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3081 llvm::BasicBlock *ExitBB = llvm::BasicBlock::Create(Context,
"", Wrapper);
3082 Builder.CreateCondBr(Have, InitBB, ExitBB);
3084 Builder.SetInsertPoint(InitBB);
3085 Builder.CreateCall(InitFnTy,
Init);
3086 Builder.CreateBr(ExitBB);
3088 Builder.SetInsertPoint(ExitBB);
3093 llvm::Value *Val = Builder.CreateThreadLocalAddress(Var);
3097 Val = Builder.CreateAlignedLoad(Var->getValueType(), Val, Align);
3100 Builder.CreateRet(Val);
3108 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
3110 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
3111 CallVal->setCallingConv(Wrapper->getCallingConv());
3125bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
3144class ItaniumRTTIBuilder {
3146 llvm::LLVMContext &VMContext;
3147 const ItaniumCXXABI &
CXXABI;
3153 llvm::GlobalVariable *
3154 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
3158 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
3161 void BuildVTablePointer(
const Type *Ty);
3174 void BuildPointerTypeInfo(
QualType PointeeTy);
3185 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
3186 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
3200 PTI_Incomplete = 0x8,
3204 PTI_ContainingClassIncomplete = 0x10,
3210 PTI_Noexcept = 0x40,
3216 VMI_NonDiamondRepeat = 0x1,
3219 VMI_DiamondShaped = 0x2
3233 llvm::Constant *BuildTypeInfo(
QualType Ty);
3236 llvm::Constant *BuildTypeInfo(
3238 llvm::GlobalVariable::LinkageTypes
Linkage,
3239 llvm::GlobalValue::VisibilityTypes
Visibility,
3240 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
3244llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
3247 llvm::raw_svector_ostream Out(Name);
3253 llvm::Constant *
Init = llvm::ConstantDataArray::getString(VMContext,
3260 GV->setInitializer(
Init);
3266ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
3269 llvm::raw_svector_ostream Out(Name);
3273 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
3280 GV =
new llvm::GlobalVariable(
3282 true, llvm::GlobalValue::ExternalLinkage,
nullptr, Name);
3288 if (RD && CXXRecordAllNonInlineVirtualsHaveAttr<DLLImportAttr>(RD)) {
3289 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
3316 case BuiltinType::Void:
3317 case BuiltinType::NullPtr:
3318 case BuiltinType::Bool:
3319 case BuiltinType::WChar_S:
3320 case BuiltinType::WChar_U:
3321 case BuiltinType::Char_U:
3322 case BuiltinType::Char_S:
3323 case BuiltinType::UChar:
3324 case BuiltinType::SChar:
3325 case BuiltinType::Short:
3326 case BuiltinType::UShort:
3327 case BuiltinType::Int:
3328 case BuiltinType::UInt:
3329 case BuiltinType::Long:
3330 case BuiltinType::ULong:
3331 case BuiltinType::LongLong:
3332 case BuiltinType::ULongLong:
3333 case BuiltinType::Half:
3334 case BuiltinType::Float:
3335 case BuiltinType::Double:
3336 case BuiltinType::LongDouble:
3337 case BuiltinType::Float16:
3338 case BuiltinType::Float128:
3339 case BuiltinType::Ibm128:
3340 case BuiltinType::Char8:
3341 case BuiltinType::Char16:
3342 case BuiltinType::Char32:
3343 case BuiltinType::Int128:
3344 case BuiltinType::UInt128:
3347#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
3348 case BuiltinType::Id:
3349#include "clang/Basic/OpenCLImageTypes.def"
3350#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
3351 case BuiltinType::Id:
3352#include "clang/Basic/OpenCLExtensionTypes.def"
3353 case BuiltinType::OCLSampler:
3354 case BuiltinType::OCLEvent:
3355 case BuiltinType::OCLClkEvent:
3356 case BuiltinType::OCLQueue:
3357 case BuiltinType::OCLReserveID:
3358#define SVE_TYPE(Name, Id, SingletonId) \
3359 case BuiltinType::Id:
3360#include "clang/Basic/AArch64SVEACLETypes.def"
3361#define PPC_VECTOR_TYPE(Name, Id, Size) \
3362 case BuiltinType::Id:
3363#include "clang/Basic/PPCTypes.def"
3364#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3365#include "clang/Basic/RISCVVTypes.def"
3366#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
3367#include "clang/Basic/WebAssemblyReferenceTypes.def"
3368 case BuiltinType::ShortAccum:
3369 case BuiltinType::Accum:
3370 case BuiltinType::LongAccum:
3371 case BuiltinType::UShortAccum:
3372 case BuiltinType::UAccum:
3373 case BuiltinType::ULongAccum:
3374 case BuiltinType::ShortFract:
3375 case BuiltinType::Fract:
3376 case BuiltinType::LongFract:
3377 case BuiltinType::UShortFract:
3378 case BuiltinType::UFract:
3379 case BuiltinType::ULongFract:
3380 case BuiltinType::SatShortAccum:
3381 case BuiltinType::SatAccum:
3382 case BuiltinType::SatLongAccum:
3383 case BuiltinType::SatUShortAccum:
3384 case BuiltinType::SatUAccum:
3385 case BuiltinType::SatULongAccum:
3386 case BuiltinType::SatShortFract:
3387 case BuiltinType::SatFract:
3388 case BuiltinType::SatLongFract:
3389 case BuiltinType::SatUShortFract:
3390 case BuiltinType::SatUFract:
3391 case BuiltinType::SatULongFract:
3392 case BuiltinType::BFloat16:
3395 case BuiltinType::Dependent:
3396#define BUILTIN_TYPE(Id, SingletonId)
3397#define PLACEHOLDER_TYPE(Id, SingletonId) \
3398 case BuiltinType::Id:
3399#include "clang/AST/BuiltinTypes.def"
3400 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3402 case BuiltinType::ObjCId:
3403 case BuiltinType::ObjCClass:
3404 case BuiltinType::ObjCSel:
3405 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3408 llvm_unreachable(
"Invalid BuiltinType Kind!");
3413 const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
3431 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3436 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3454 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3455 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
3466 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3469 if (CGM.
getTriple().isWindowsGNUEnvironment())
3476 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3504 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3509 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3513 dyn_cast<MemberPointerType>(Ty)) {
3515 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
3537 if (
Base->isVirtual())
3547 if (!BaseDecl->isEmpty() &&
3554void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
3556 static const char *
const ClassTypeInfo =
3557 "_ZTVN10__cxxabiv117__class_type_infoE";
3559 static const char *
const SIClassTypeInfo =
3560 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3562 static const char *
const VMIClassTypeInfo =
3563 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3565 const char *VTableName =
nullptr;
3568#define TYPE(Class, Base)
3569#define ABSTRACT_TYPE(Class, Base)
3570#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3571#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3572#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3573#include "clang/AST/TypeNodes.inc"
3574 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3576 case Type::LValueReference:
3577 case Type::RValueReference:
3578 llvm_unreachable(
"References shouldn't get here");
3581 case Type::DeducedTemplateSpecialization:
3582 llvm_unreachable(
"Undeduced type shouldn't get here");
3585 llvm_unreachable(
"Pipe types shouldn't get here");
3587 case Type::ArrayParameter:
3588 llvm_unreachable(
"Array Parameter types should not get here.");
3594 case Type::ExtVector:
3595 case Type::ConstantMatrix:
3599 case Type::BlockPointer:
3601 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3604 case Type::ConstantArray:
3605 case Type::IncompleteArray:
3606 case Type::VariableArray:
3608 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3611 case Type::FunctionNoProto:
3612 case Type::FunctionProto:
3614 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3619 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3622 case Type::Record: {
3624 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3627 VTableName = ClassTypeInfo;
3629 VTableName = SIClassTypeInfo;
3631 VTableName = VMIClassTypeInfo;
3637 case Type::ObjCObject:
3639 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3642 if (isa<BuiltinType>(Ty)) {
3643 VTableName = ClassTypeInfo;
3647 assert(isa<ObjCInterfaceType>(Ty));
3650 case Type::ObjCInterface:
3651 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3652 VTableName = SIClassTypeInfo;
3654 VTableName = ClassTypeInfo;
3658 case Type::ObjCObjectPointer:
3661 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3664 case Type::MemberPointer:
3666 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3670 llvm::Constant *VTable =
nullptr;
3674 VTable = CGM.
getModule().getNamedAlias(VTableName);
3677 VTable = CGM.
getModule().getOrInsertGlobal(VTableName, Ty);
3680 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3682 llvm::Type *PtrDiffTy =
3689 llvm::Constant *Eight = llvm::ConstantInt::get(CGM.
Int32Ty, 8);
3691 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8Ty, VTable, Eight);
3693 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3694 VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
GlobalsInt8PtrTy,
3698 Fields.push_back(VTable);
3715 return llvm::GlobalValue::InternalLinkage;
3719 llvm_unreachable(
"Linkage hasn't been computed!");
3724 return llvm::GlobalValue::InternalLinkage;
3732 return llvm::GlobalValue::LinkOnceODRLinkage;
3737 return llvm::GlobalValue::WeakODRLinkage;
3738 if (CGM.
getTriple().isWindowsItaniumEnvironment())
3739 if (RD->
hasAttr<DLLImportAttr>() &&
3741 return llvm::GlobalValue::ExternalLinkage;
3747 .isWindowsGNUEnvironment())
3751 return llvm::GlobalValue::LinkOnceODRLinkage;
3754 llvm_unreachable(
"Invalid linkage!");
3757llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
3763 llvm::raw_svector_ostream Out(Name);
3766 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
3767 if (OldGV && !OldGV->isDeclaration()) {
3768 assert(!OldGV->hasAvailableExternallyLinkage() &&
3769 "available_externally typeinfos not yet implemented");
3777 return GetAddrOfExternalRTTIDescriptor(Ty);
3784 llvm::GlobalValue::VisibilityTypes llvmVisibility;
3785 if (llvm::GlobalValue::isLocalLinkage(
Linkage))
3787 llvmVisibility = llvm::GlobalValue::DefaultVisibility;
3789 ItaniumCXXABI::RUK_NonUniqueHidden)
3790 llvmVisibility = llvm::GlobalValue::HiddenVisibility;
3794 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3795 llvm::GlobalValue::DefaultStorageClass;
3797 if ((CGM.
getTriple().isWindowsItaniumEnvironment() &&
3798 RD->
hasAttr<DLLExportAttr>()) ||
3800 !llvm::GlobalValue::isLocalLinkage(
Linkage) &&
3801 llvmVisibility == llvm::GlobalValue::DefaultVisibility))
3802 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
3804 return BuildTypeInfo(Ty,
Linkage, llvmVisibility, DLLStorageClass);
3807llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
3809 llvm::GlobalVariable::LinkageTypes
Linkage,
3810 llvm::GlobalValue::VisibilityTypes
Visibility,
3811 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
3813 BuildVTablePointer(cast<Type>(Ty));
3817 llvm::Constant *TypeNameField;
3821 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
3823 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
3826 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
3827 llvm::Constant *flag =
3828 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
3829 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
3835 Fields.push_back(TypeNameField);
3838#define TYPE(Class, Base)
3839#define ABSTRACT_TYPE(Class, Base)
3840#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
3841#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
3842#define DEPENDENT_TYPE(Class, Base) case Type::Class:
3843#include "clang/AST/TypeNodes.inc"
3844 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3849 case Type::ExtVector:
3850 case Type::ConstantMatrix:
3852 case Type::BlockPointer:
3857 case Type::LValueReference:
3858 case Type::RValueReference:
3859 llvm_unreachable(
"References shouldn't get here");
3862 case Type::DeducedTemplateSpecialization:
3863 llvm_unreachable(
"Undeduced type shouldn't get here");
3871 case Type::ConstantArray:
3872 case Type::IncompleteArray:
3873 case Type::VariableArray:
3874 case Type::ArrayParameter:
3879 case Type::FunctionNoProto:
3880 case Type::FunctionProto:
3890 case Type::Record: {
3892 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3899 BuildSIClassTypeInfo(RD);
3901 BuildVMIClassTypeInfo(RD);
3906 case Type::ObjCObject:
3907 case Type::ObjCInterface:
3908 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
3911 case Type::ObjCObjectPointer:
3912 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
3916 BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
3919 case Type::MemberPointer:
3920 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
3928 llvm::Constant *
Init = llvm::ConstantStruct::getAnon(Fields);
3931 llvm::raw_svector_ostream Out(Name);
3934 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
3935 llvm::GlobalVariable *GV =
3936 new llvm::GlobalVariable(M,
Init->getType(),
3940 auto GVDLLStorageClass = DLLStorageClass;
3942 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3943 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
3944 if (RD->
hasAttr<DLLExportAttr>() ||
3945 CXXRecordAllNonInlineVirtualsHaveAttr<DLLExportAttr>(RD)) {
3946 GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
3953 GV->takeName(OldGV);
3954 OldGV->replaceAllUsesWith(GV);
3955 OldGV->eraseFromParent();
3959 GV->setComdat(M.getOrInsertComdat(GV->getName()));
3986 TypeName->setDLLStorageClass(DLLStorageClass);
3999void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
4002 assert(isa<BuiltinType>(
T) || isa<ObjCInterfaceType>(
T));
4006 if (isa<BuiltinType>(
T))
return;
4017 llvm::Constant *BaseTypeInfo =
4018 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
4019 Fields.push_back(BaseTypeInfo);
4024void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
4028 llvm::Constant *BaseTypeInfo =
4030 Fields.push_back(BaseTypeInfo);
4053 if (
Base->isVirtual()) {
4055 if (!Bases.VirtualBases.insert(BaseDecl).second) {
4058 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
4060 if (Bases.NonVirtualBases.count(BaseDecl))
4061 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4065 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
4068 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4070 if (Bases.VirtualBases.count(BaseDecl))
4071 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
4076 for (
const auto &I : BaseDecl->bases())
4087 for (
const auto &I : RD->
bases())
4096void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
4097 llvm::Type *UnsignedIntLTy =
4105 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4110 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
4143 llvm::Type *OffsetFlagsLTy =
4148 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
Base.getType()));
4160 if (
Base.isVirtual())
4168 OffsetFlags =
uint64_t(Offset.getQuantity()) << 8;
4172 if (
Base.isVirtual())
4173 OffsetFlags |= BCTI_Virtual;
4175 OffsetFlags |= BCTI_Public;
4177 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
4186 if (
Type.isConstQualified())
4187 Flags |= ItaniumRTTIBuilder::PTI_Const;
4188 if (
Type.isVolatileQualified())
4189 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
4190 if (
Type.isRestrictQualified())
4191 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
4198 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
4201 if (Proto->isNothrow()) {
4202 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
4212void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
4218 llvm::Type *UnsignedIntLTy =
4220 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4225 llvm::Constant *PointeeTypeInfo =
4226 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4227 Fields.push_back(PointeeTypeInfo);
4243 Flags |= PTI_ContainingClassIncomplete;
4245 llvm::Type *UnsignedIntLTy =
4247 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
4252 llvm::Constant *PointeeTypeInfo =
4253 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
4254 Fields.push_back(PointeeTypeInfo);
4261 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
4264llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
4265 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
4268void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
4271 getContext().VoidTy, getContext().NullPtrTy,
4272 getContext().BoolTy, getContext().WCharTy,
4273 getContext().CharTy, getContext().UnsignedCharTy,
4274 getContext().SignedCharTy, getContext().ShortTy,
4275 getContext().UnsignedShortTy, getContext().IntTy,
4276 getContext().UnsignedIntTy, getContext().LongTy,
4277 getContext().UnsignedLongTy, getContext().LongLongTy,
4278 getContext().UnsignedLongLongTy, getContext().Int128Ty,
4279 getContext().UnsignedInt128Ty, getContext().HalfTy,
4280 getContext().FloatTy, getContext().DoubleTy,
4281 getContext().LongDoubleTy, getContext().Float128Ty,
4282 getContext().Char8Ty, getContext().Char16Ty,
4283 getContext().Char32Ty
4285 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
4287 ? llvm::GlobalValue::DLLExportStorageClass
4288 : llvm::GlobalValue::DefaultStorageClass;
4289 llvm::GlobalValue::VisibilityTypes
Visibility =
4291 for (
const QualType &FundamentalType : FundamentalTypes) {
4293 QualType PointerTypeConst = getContext().getPointerType(
4294 FundamentalType.withConst());
4296 ItaniumRTTIBuilder(*this).BuildTypeInfo(
4297 Type, llvm::GlobalValue::ExternalLinkage,
4304ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
4306 if (shouldRTTIBeUnique())
4310 if (
Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
4311 Linkage != llvm::GlobalValue::WeakODRLinkage)
4319 if (
Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
4320 return RUK_NonUniqueHidden;
4325 assert(
Linkage == llvm::GlobalValue::WeakODRLinkage);
4326 return RUK_NonUniqueVisible;
4331enum class StructorCodegen { Emit, RAUW, Alias, COMDAT };
4336 return StructorCodegen::Emit;
4341 return StructorCodegen::Emit;
4344 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
4347 const auto *CD = cast<CXXConstructorDecl>(MD);
4352 if (llvm::GlobalValue::isDiscardableIfUnused(
Linkage))
4353 return StructorCodegen::RAUW;
4356 if (!llvm::GlobalAlias::isValidLinkage(
Linkage))
4357 return StructorCodegen::RAUW;
4359 if (llvm::GlobalValue::isWeakForLinker(
Linkage)) {
4363 return StructorCodegen::COMDAT;
4364 return StructorCodegen::Emit;
4367 return StructorCodegen::Alias;
4377 if (Entry && !Entry->isDeclaration())
4380 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
4383 auto *Alias = llvm::GlobalAlias::create(
Linkage,
"", Aliasee);
4386 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4390 assert(Entry->getType() == Aliasee->getType() &&
4391 "declaration exists with different type");
4392 Alias->takeName(Entry);
4393 Entry->replaceAllUsesWith(Alias);
4394 Entry->eraseFromParent();
4396 Alias->setName(MangledName);
4403void ItaniumCXXABI::emitCXXStructor(
GlobalDecl GD) {
4404 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
4405 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
4418 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
4423 if (CGType == StructorCodegen::RAUW) {
4436 CGType != StructorCodegen::COMDAT &&
4454 if (CGType == StructorCodegen::COMDAT) {
4456 llvm::raw_svector_ostream Out(Buffer);
4458 getMangleContext().mangleCXXDtorComdat(DD, Out);
4460 getMangleContext().mangleCXXCtorComdat(CD, Out);
4461 llvm::Comdat *
C = CGM.
getModule().getOrInsertComdat(Out.str());
4470 llvm::FunctionType *FTy = llvm::FunctionType::get(
4478 llvm::FunctionType *FTy =
4479 llvm::FunctionType::get(CGM.
VoidTy,
false);
4486 llvm::FunctionType *FTy = llvm::FunctionType::get(
4506 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4528 bool EndMightThrow) {
4529 llvm::CallInst *call =
4532 CGF.
EHStack.pushCleanup<CallEndCatch>(
4534 EndMightThrow && !CGF.
CGM.
getLangOpts().AssumeNothrowExceptionDtor);
4554 if (isa<ReferenceType>(CatchType)) {
4559 llvm::Value *AdjustedExn =
CallBeginCatch(CGF, Exn, EndCatchMightThrow);
4564 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4573 unsigned HeaderSize =
4576 CGF.
Builder.CreateConstGEP1_32(CGF.
Int8Ty, Exn, HeaderSize);
4599 llvm::Value *Casted = CGF.
Builder.CreateBitCast(AdjustedExn, PtrTy);
4607 llvm::Value *ExnCast =
4608 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
4620 if (CatchType->hasPointerRepresentation()) {
4621 llvm::Value *CastExn =
4622 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
4639 llvm_unreachable(
"bad ownership qualifier!");
4657 llvm_unreachable(
"evaluation kind filtered out!");
4659 llvm_unreachable(
"bad evaluation kind");
4662 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
4663 auto catchRD = CatchType->getAsCXXRecordDecl();
4673 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4674 LLVMCatchTy, caughtExnAlignment);
4683 llvm::CallInst *rawAdjustedExn =
4687 Address adjustedExn(CGF.
Builder.CreateBitCast(rawAdjustedExn, PtrTy),
4688 LLVMCatchTy, caughtExnAlignment);
4692 CodeGenFunction::OpaqueValueMapping
4744 VarDecl *CatchParam = S->getExceptionDecl();
4753 InitCatchParam(CGF, *CatchParam, var.getObjectAddress(CGF), S->getBeginLoc());
4763 C.VoidTy, {C.getPointerType(C.CharTy)});
4766 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
4767 llvm::Function *fn =
4768 cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
4772 fn->setDoesNotThrow();
4773 fn->setDoesNotReturn();
4778 fn->addFnAttr(llvm::Attribute::NoInline);
4782 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
4783 fn->setVisibility(llvm::Function::HiddenVisibility);
4785 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
4788 llvm::BasicBlock *entry =
4793 llvm::Value *exn = &*fn->arg_begin();
4796 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
4797 catchCall->setDoesNotThrow();
4801 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
4802 termCall->setDoesNotThrow();
4803 termCall->setDoesNotReturn();
4807 builder.CreateUnreachable();
4813ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
4823std::pair<llvm::Value *, const CXXRecordDecl *>
4834 ItaniumCXXABI::emitBeginCatch(CGF,
C);
4838WebAssemblyCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
4851 llvm::FunctionCallee Dtor,
4852 llvm::Constant *Addr) {
4857 llvm::FunctionType *AtExitTy =
4858 llvm::FunctionType::get(CGM.
IntTy, {CGM.IntTy, PtrTy},
true);
4861 llvm::FunctionCallee
AtExit =
4869 llvm::Value *NV = llvm::Constant::getNullValue(CGM.
IntTy);
4884 emitCXXStermFinalizer(D, DtorStub, Addr);
4887void XLCXXABI::emitCXXStermFinalizer(
const VarDecl &D, llvm::Function *dtorStub,
4888 llvm::Constant *addr) {
4889 llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
4892 llvm::raw_svector_ostream Out(FnName);
4893 getMangleContext().mangleDynamicStermFinalizer(&D, Out);
4915 llvm::BasicBlock *DestructCallBlock = CGF.
createBasicBlock(
"destruct.call");
4920 CGF.
Builder.CreateCondBr(NeedsDestruct, DestructCallBlock, EndBlock);
4925 llvm::CallInst *CI = CGF.
Builder.CreateCall(dtorStub);
4928 CI->setCallingConv(dtorStub->getCallingConv());
4934 if (
auto *IPA = D.
getAttr<InitPriorityAttr>()) {
4936 IPA->getPriority());
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF)
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void @__clang_call_terminate(i8* exn) nounwind noreturn This co...
static llvm::Value * performTypeAdjustment(CodeGenFunction &CGF, Address InitialPtr, int64_t NonVirtualAdjustment, int64_t VirtualAdjustment, bool IsReturnAdjustment)
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::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::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 bool CXXRecordAllNonInlineVirtualsHaveAttr(const CXXRecordDecl *RD)
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 llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static bool ContainsIncompleteClassType(QualType Ty)
ContainsIncompleteClassType - Returns whether the given type contains an incomplete class type.
static void emitConstructorDestructorAlias(CodeGenModule &CGM, GlobalDecl AliasDecl, GlobalDecl TargetDecl)
static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM)
static void dtorTy(Block *, std::byte *Ptr, const Descriptor *)
llvm::MachO::Record Record
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
static const RecordType * getRecordType(QualType QT)
Checks that the passed in QualType either is of RecordType or points to RecordType.
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D)
Determine what kind of template specialization the given declaration is.
#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.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
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
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 isAbstract() const
Determine whether this class has a pure virtual function.
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]).
const Expr * getSubExpr() const
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...
CastKind getCastKind() const
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.
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 * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const ReturnAdjustment &RA)=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 llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
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 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType)=0
Emit a reference to a non-local thread_local variable (including triggering the initialization of all...
bool isEmittedWithConstantInitializer(const VarDecl *VD, bool InspectInitForWeakDef=false) const
Determine whether we will definitely emit this variable with a constant initializer,...
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Constant * EmitMemberPointer(const APValue &MP, QualType MPT)
Create a member pointer for the given member pointer constant.
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
virtual llvm::Value * readArrayCookieImpl(CodeGenFunction &IGF, Address ptr, CharUnits cookieSize)
Reads the array cookie for an allocation which is known to have one.
virtual llvm::Value * EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, const MemberPointerType *MPT)
Calculate an l-value from an object and a data member pointer.
virtual llvm::Value * getCXXDestructorImplicitParam(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating)=0
Get the implicit (second) parameter that comes after the "this" pointer, or nullptr if there is isn't...
virtual std::pair< llvm::Value *, const CXXRecordDecl * > LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD)=0
Load a vtable from This, an object of polymorphic type RD, or from one of its virtual bases if it doe...
virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment)=0
virtual llvm::Value * EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E)=0
Emit the ABI-specific virtual destructor call.
bool mayNeedDestruction(const VarDecl *VD) const
virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)=0
Checks if ABI requires to initialize vptrs for given dynamic class.
virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0
virtual llvm::Value * GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl)=0
virtual bool isThisCompleteObject(GlobalDecl GD) const =0
Determine whether there's something special about the rules of the ABI tell us that 'this' is a compl...
virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, Address This, llvm::Type *Ty, SourceLocation Loc)=0
Build a virtual function pointer in the ABI-specific way.
virtual bool classifyReturnType(CGFunctionInfo &FI) const =0
If the C++ ABI requires the given type be returned in a particular way, this method sets RetAI and re...
virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0
virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0
virtual void EmitThreadLocalInitFuncs(CodeGenModule &CGM, ArrayRef< const VarDecl * > CXXThreadLocals, ArrayRef< llvm::Function * > CXXThreadLocalInits, ArrayRef< const VarDecl * > CXXThreadLocalInitVars)=0
Emits ABI-required functions necessary to initialize thread_local variables in this translation unit.
virtual bool usesThreadWrapperFunction(const VarDecl *VD) const =0
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
virtual llvm::Value * emitExactDynamicCast(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastSuccess, llvm::BasicBlock *CastFail)=0
Emit a dynamic_cast from SrcRecordTy to DestRecordTy.
virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)=0
Emit the destructor call.
virtual llvm::GlobalVariable * getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset)=0
Get the address of the vtable for the given record decl which should be used for the vptr at the give...
virtual bool EmitBadCastCall(CodeGenFunction &CGF)=0
virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)
Create a member pointer for the given field.
virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD)=0
Emit any tables needed to implement virtual inheritance.
virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD)=0
Emits the VTable definitions required for the given record type.
virtual CGCallee EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, Address This, llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr, const MemberPointerType *MPT)
Load a member function from an object and a member function pointer.
virtual void emitCXXStructor(GlobalDecl GD)=0
Emit a single constructor/destructor with the given type from a C++ constructor Decl.
virtual bool exportThunk()=0
virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0
virtual llvm::Value * emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy)=0
virtual bool isZeroInitializable(const MemberPointerType *MPT)
Return true if the given member pointer can be zero-initialized (in the C++ sense) with an LLVM zeroi...
virtual bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy)=0
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)
Create a member pointer for the given method.
virtual llvm::Value * emitDynamicCastCall(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd)=0
virtual Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType)
Initialize the array cookie for the given allocation.
virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, QualType SrcRecordTy)=0
virtual AddedStructorArgCounts buildStructorSignature(GlobalDecl GD, SmallVectorImpl< CanQualType > &ArgTys)=0
Build the signature of the given constructor or destructor variant by adding any required parameters.
virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA)=0
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
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.
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.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitAnyExprToExn(const Expr *E, Address Addr)
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
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.
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, const CXXRecordDecl *RD)
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
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...
llvm::Function * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source=AlignmentSource::Type)
Same as MakeAddrLValue above except that the pointer is known to be unsigned.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
llvm::Value * unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub)
Call unatexit() with function dtorStub.
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void 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="")
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
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.
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::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
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...
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.
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::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)
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 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 & 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)
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
decl_range noload_decls() const
noload_decls_begin/end - Iterate over the declarations stored in this context that are currently load...
SourceLocation getLocation() const
DeclContext * getDeclContext()
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Represents a prototype with parameter type info, e.g.
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
CXXCtorType getCtorType() const
GlobalDecl 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...
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.
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.
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.
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 isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed? If so, the variable need not have a usable destr...
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
bool isInline() const
Whether this variable is (C++1z) inline.
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.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
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.
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
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.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@186 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@188 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.