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" 39 using namespace clang;
40 using namespace CodeGen;
45 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
52 bool UseARMMethodPtrABI;
53 bool UseARMGuardVarABI;
54 bool Use32BitVTableOffsetABI;
62 bool UseARMMethodPtrABI =
false,
63 bool UseARMGuardVarABI =
false) :
64 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
65 UseARMGuardVarABI(UseARMGuardVarABI),
66 Use32BitVTableOffsetABI(
false) { }
77 bool isThisCompleteObject(
GlobalDecl GD)
const override {
80 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
90 llvm_unreachable(
"emitting dtor comdat as function?");
92 llvm_unreachable(
"bad dtor kind");
94 if (isa<CXXConstructorDecl>(GD.
getDecl())) {
104 llvm_unreachable(
"closure ctors in Itanium ABI?");
107 llvm_unreachable(
"emitting ctor comdat as function?");
109 llvm_unreachable(
"bad dtor kind");
137 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
138 llvm::Constant *Src)
override;
142 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
145 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
152 bool Inequality)
override;
171 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
172 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
174 getAddrOfCXXCatchHandlerType(
QualType Ty,
175 QualType CatchHandlerType)
override {
179 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
185 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
191 llvm::BasicBlock *CastEnd)
override;
241 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
253 llvm::Value *getVTableAddressPointInStructorWithVTT(
261 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
271 DeleteOrMemberCallExpr E)
override;
273 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
275 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
276 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
278 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
GlobalDecl GD,
282 if (ForVTable && !Thunk->hasLocalLinkage())
283 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
284 CGM.setGVProperties(Thunk, GD);
287 bool exportThunk()
override {
return true; }
293 const ReturnAdjustment &RA)
override;
297 assert(!Args.empty() &&
"expected the arglist to not be empty!");
298 return Args.size() - 1;
301 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
302 StringRef GetDeletedVirtualCallName()
override 303 {
return "__cxa_deleted_virtual"; }
316 llvm::GlobalVariable *DeclPtr,
317 bool PerformInit)
override;
319 llvm::FunctionCallee dtor,
320 llvm::Constant *addr)
override;
322 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
324 void EmitThreadLocalInitFuncs(
333 bool isEmittedWithConstantInitializer(
const VarDecl *VD)
const {
335 if (VD->
hasAttr<ConstInitAttr>())
363 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
364 return !isEmittedWithConstantInitializer(VD) ||
370 bool NeedsVTTParameter(
GlobalDecl GD)
override;
377 virtual bool shouldRTTIBeUnique()
const {
return true; }
381 enum RTTIUniquenessKind {
399 classifyRTTIUniqueness(
QualType CanTy,
400 llvm::GlobalValue::LinkageTypes
Linkage)
const;
401 friend class ItaniumRTTIBuilder;
405 std::pair<llvm::Value *, const CXXRecordDecl *>
410 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
411 const auto &VtableLayout =
412 CGM.getItaniumVTableContext().getVTableLayout(RD);
414 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
416 if (!VtableComponent.isUsedFunctionPointerKind())
419 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
423 StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
424 auto *Entry = CGM.GetGlobalValue(Name);
430 if (!Entry || Entry->isDeclaration())
437 const auto &VtableLayout =
438 CGM.getItaniumVTableContext().getVTableLayout(RD);
440 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
441 if (VtableComponent.isRTTIKind()) {
442 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
445 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
446 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
456 class ARMCXXABI :
public ItaniumCXXABI {
459 ItaniumCXXABI(CGM,
true,
462 bool HasThisReturn(
GlobalDecl GD)
const override {
463 return (isa<CXXConstructorDecl>(GD.
getDecl()) || (
464 isa<CXXDestructorDecl>(GD.
getDecl()) &&
481 class iOS64CXXABI :
public ARMCXXABI {
484 Use32BitVTableOffsetABI =
true;
488 bool shouldRTTIBeUnique()
const override {
return false; }
491 class FuchsiaCXXABI final :
public ItaniumCXXABI {
494 : ItaniumCXXABI(CGM) {}
497 bool HasThisReturn(
GlobalDecl GD)
const override {
498 return isa<CXXConstructorDecl>(GD.
getDecl()) ||
499 (isa<CXXDestructorDecl>(GD.
getDecl()) &&
504 class WebAssemblyCXXABI final :
public ItaniumCXXABI {
507 : ItaniumCXXABI(CGM,
true,
512 bool HasThisReturn(
GlobalDecl GD)
const override {
513 return isa<CXXConstructorDecl>(GD.
getDecl()) ||
514 (isa<CXXDestructorDecl>(GD.
getDecl()) &&
517 bool canCallMismatchedFunctionType()
const override {
return false; }
528 return new ARMCXXABI(CGM);
531 return new iOS64CXXABI(CGM);
534 return new FuchsiaCXXABI(CGM);
540 return new ItaniumCXXABI(CGM,
true,
544 return new ItaniumCXXABI(CGM,
true);
547 return new WebAssemblyCXXABI(CGM);
551 == llvm::Triple::le32) {
555 return new ItaniumCXXABI(CGM,
true);
557 return new ItaniumCXXABI(CGM);
560 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
562 llvm_unreachable(
"bad ABI kind");
568 return CGM.PtrDiffTy;
569 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
592 CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
603 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
604 CGM.getTypes().arrangeCXXMethodType(RD, FPT,
nullptr));
606 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
613 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
617 if (UseARMMethodPtrABI)
618 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
624 Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
625 This = Builder.
CreateBitCast(Ptr, This->getType(),
"this.adjusted");
626 ThisPtrForCall =
This;
629 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
634 if (UseARMMethodPtrABI)
635 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
637 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
638 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
639 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
647 llvm::Type *VTableTy = Builder.getInt8PtrTy();
658 if (!UseARMMethodPtrABI)
659 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
660 if (Use32BitVTableOffsetABI) {
661 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
662 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
667 llvm::Constant *CheckSourceLocation;
668 llvm::Constant *CheckTypeDesc;
669 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
670 CGM.HasHiddenLTOVisibility(RD);
671 bool ShouldEmitVFEInfo = CGM.getCodeGenOpts().VirtualFunctionElimination &&
672 CGM.HasHiddenLTOVisibility(RD);
680 if (ShouldEmitCFICheck || ShouldEmitVFEInfo) {
683 CGM.CreateMetadataIdentifierForVirtualMemPtrType(
QualType(MPT, 0));
687 llvm::Value *VFPAddr = Builder.CreateGEP(VTable, VTableOffset);
689 if (ShouldEmitVFEInfo) {
696 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
697 {VFPAddr, llvm::ConstantInt::get(CGM.Int32Ty, 0), TypeId});
698 CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
699 VirtualFn = Builder.CreateExtractValue(CheckedLoad, 0);
700 VirtualFn = Builder.
CreateBitCast(VirtualFn, FTy->getPointerTo(),
705 if (ShouldEmitCFICheck) {
706 CheckResult = Builder.CreateCall(
707 CGM.getIntrinsic(llvm::Intrinsic::type_test),
711 Builder.
CreateBitCast(VFPAddr, FTy->getPointerTo()->getPointerTo());
715 assert(VirtualFn &&
"Virtual fuction pointer not created!");
716 assert((!ShouldEmitCFICheck || !ShouldEmitVFEInfo || CheckResult) &&
717 "Check result required but not created!");
719 if (ShouldEmitCFICheck) {
723 llvm::Constant *StaticData[] = {
729 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
732 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
733 CGM.getLLVMContext(),
734 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
736 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
737 CGF.
EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIMFCall),
738 SanitizerHandler::CFICheckFail, StaticData,
739 {VTable, ValidVtable});
742 FnVirtual = Builder.GetInsertBlock();
752 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(),
"memptr.nonvirtualfn");
755 if (ShouldEmitCFICheck) {
760 llvm::Constant *StaticData[] = {
770 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
771 getContext().getMemberPointerType(
778 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
779 {CastedNonVirtualFn, TypeId});
780 Bit = Builder.CreateOr(Bit, TypeTest);
783 CGF.
EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
784 SanitizerHandler::CFICheckFail, StaticData,
785 {CastedNonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
787 FnNonVirtual = Builder.GetInsertBlock();
793 llvm::PHINode *CalleePtr = Builder.CreatePHI(FTy->getPointerTo(), 2);
794 CalleePtr->addIncoming(VirtualFn, FnVirtual);
795 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
803 llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
806 assert(MemPtr->getType() == CGM.PtrDiffTy);
811 Base = Builder.CreateElementBitCast(Base, CGF.
Int8Ty);
815 Builder.CreateInBoundsGEP(Base.
getPointer(), MemPtr,
"memptr.offset");
821 return Builder.CreateBitCast(Addr, PType);
851 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
852 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
856 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
859 if (isa<llvm::Constant>(src))
860 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
862 llvm::Constant *adj = getMemberPointerAdjustment(E);
863 if (!adj)
return src;
866 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
876 dst = Builder.CreateNSWSub(src, adj,
"adj");
878 dst = Builder.CreateNSWAdd(src, adj,
"adj");
881 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
882 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
883 return Builder.CreateSelect(isNull, src, dst);
887 if (UseARMMethodPtrABI) {
888 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
890 adj = llvm::ConstantInt::get(adj->getType(), offset);
893 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
896 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
898 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
900 return Builder.CreateInsertValue(src, dstAdj, 1);
904 ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
905 llvm::Constant *src) {
906 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
907 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
911 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
914 llvm::Constant *adj = getMemberPointerAdjustment(E);
915 if (!adj)
return src;
917 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
926 if (src->isAllOnesValue())
return src;
929 return llvm::ConstantExpr::getNSWSub(src, adj);
931 return llvm::ConstantExpr::getNSWAdd(src, adj);
935 if (UseARMMethodPtrABI) {
936 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
938 adj = llvm::ConstantInt::get(adj->getType(), offset);
941 llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
942 llvm::Constant *dstAdj;
944 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
946 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
948 return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
956 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
958 llvm::Constant *
Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
959 llvm::Constant *Values[2] = {
Zero, Zero };
960 return llvm::ConstantStruct::getAnon(Values);
969 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
973 ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
977 llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
979 assert(MD->
isInstance() &&
"Member function must not be static!");
984 llvm::Constant *MemPtr[2];
986 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
991 uint64_t VTableOffset = (Index * PointerWidth.
getQuantity());
993 if (UseARMMethodPtrABI) {
1000 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
1001 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1008 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
1009 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1016 if (Types.isFuncTypeConvertible(FPT)) {
1018 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
1024 llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
1026 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
1027 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
1028 (UseARMMethodPtrABI ? 2 : 1) *
1032 return llvm::ConstantStruct::getAnon(MemPtr);
1035 llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
1040 return EmitNullMemberPointer(MPT);
1042 CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
1045 return BuildMemberPointer(MD, ThisAdjustment);
1048 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
1049 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
1064 llvm::ICmpInst::Predicate Eq;
1065 llvm::Instruction::BinaryOps
And, Or;
1067 Eq = llvm::ICmpInst::ICMP_NE;
1068 And = llvm::Instruction::Or;
1071 Eq = llvm::ICmpInst::ICMP_EQ;
1073 Or = llvm::Instruction::Or;
1079 return Builder.CreateICmp(Eq, L, R);
1091 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1092 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1096 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1102 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero,
"cmp.ptr.null");
1106 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1107 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1108 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1112 if (UseARMMethodPtrABI) {
1113 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1116 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1117 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1118 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
1120 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
1124 llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
1125 Result = Builder.CreateBinOp(And, PtrEq, Result,
1126 Inequality ?
"memptr.ne" :
"memptr.eq");
1138 assert(MemPtr->getType() == CGM.PtrDiffTy);
1140 llvm::Constant::getAllOnesValue(MemPtr->getType());
1141 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1145 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1147 llvm::Constant *
Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1148 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
1152 if (UseARMMethodPtrABI) {
1153 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1154 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1155 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1156 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1157 "memptr.isvirtual");
1158 Result = Builder.CreateOr(Result, IsVirtual);
1171 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1192 if (UseGlobalDelete) {
1204 VTable, -2,
"complete-offset.ptr");
1211 CompletePtr = CGF.
Builder.CreateInBoundsGEP(CompletePtr, Offset);
1222 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
1224 if (UseGlobalDelete)
1228 void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1231 llvm::FunctionType *FTy =
1232 llvm::FunctionType::get(CGM.VoidTy,
false);
1234 llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1245 llvm::FunctionType *FTy =
1256 llvm::FunctionType *FTy =
1257 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1266 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1270 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1276 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1281 llvm::Constant *Dtor =
nullptr;
1283 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
1287 Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy);
1290 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1292 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
1306 llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
1308 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1311 llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
1312 llvm::Attribute::ReadOnly };
1313 llvm::AttributeList Attrs = llvm::AttributeList::get(
1314 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1321 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1338 unsigned NumPublicPaths = 0;
1351 if (PathElement.Base->isVirtual())
1354 if (NumPublicPaths > 1)
1360 PathElement.Base->getType()->getAsCXXRecordDecl());
1365 if (NumPublicPaths == 0)
1369 if (NumPublicPaths > 1)
1379 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1384 bool ItaniumCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
1392 Call->setDoesNotReturn();
1393 CGF.
Builder.CreateUnreachable();
1403 CGF.
GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo(), ClassDecl);
1406 Value = CGF.
Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
1410 bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1445 llvm::BasicBlock *BadCastBlock =
1449 CGF.
Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1452 EmitBadCastCall(CGF);
1474 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
1482 Value = CGF.
Builder.CreateInBoundsGEP(Value, OffsetToTop);
1490 Call->setDoesNotReturn();
1491 CGF.
Builder.CreateUnreachable();
1502 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1507 "vbase.offset.ptr");
1509 CGM.PtrDiffTy->getPointerTo());
1520 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1535 ItaniumCXXABI::buildStructorSignature(
GlobalDecl GD,
1545 cast<CXXMethodDecl>(GD.
getDecl())->getParent()->getNumVBases() != 0) {
1546 ArgTys.insert(ArgTys.begin() + 1,
1548 return AddedStructorArgs::prefix(1);
1550 return AddedStructorArgs{};
1573 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1576 if (NeedsVTTParameter(CGF.
CurGD)) {
1584 Params.insert(Params.begin() + 1, VTTDecl);
1585 getStructorImplicitParamDecl(CGF) = VTTDecl;
1589 void ItaniumCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1596 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1599 if (getStructorImplicitParamDecl(CGF)) {
1612 if (HasThisReturn(CGF.
CurGD))
1618 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1620 return AddedStructorArgs{};
1625 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1627 return AddedStructorArgs::prefix(1);
1633 bool Delegating,
Address This,
1637 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1640 if (getContext().getLangOpts().AppleKext &&
1652 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1653 if (VTable->hasInitializer())
1658 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
1659 llvm::Constant *RTTI =
1660 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1666 Components.finishAndSetAsInitializer(VTable);
1669 VTable->setLinkage(Linkage);
1671 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1672 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1675 CGM.setGVProperties(VTable, RD);
1683 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1684 cast<NamespaceDecl>(DC)->
getIdentifier()->isStr(
"__cxxabiv1") &&
1686 EmitFundamentalRTTIDescriptors(RD);
1688 if (!VTable->isDeclarationForLinker())
1689 CGM.EmitVTableTypeMetadata(RD, VTable, VTLayout);
1692 bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1696 return NeedsVTTParameter(CGF.
CurGD);
1699 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1704 NeedsVTTParameter(CGF.
CurGD)) {
1705 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
1708 return getVTableAddressPoint(Base, VTableClass);
1714 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
1719 CGM.getItaniumVTableContext()
1720 .getVTableLayout(VTableClass)
1721 .getAddressPoint(Base);
1723 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1724 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
1728 return llvm::ConstantExpr::getGetElementPtr(VTable->getValueType(), VTable,
1733 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1737 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
1740 uint64_t VirtualPointerIndex =
1741 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
1745 if (VirtualPointerIndex)
1746 VTT = CGF.
Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
1752 llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
1754 return getVTableAddressPoint(Base, VTableClass);
1757 llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1759 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1761 llvm::GlobalVariable *&VTable = VTables[RD];
1766 CGM.addDeferredVTable(RD);
1769 llvm::raw_svector_ostream Out(Name);
1770 getMangleContext().mangleCXXVTable(RD, Out);
1773 CGM.getItaniumVTableContext().getVTableLayout(RD);
1774 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1779 unsigned PAlign = CGM.getTarget().getPointerAlign(0);
1781 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1783 getContext().toCharUnitsFromBits(PAlign).getQuantity());
1784 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1786 CGM.setGVProperties(VTable, RD);
1796 Ty = Ty->getPointerTo()->getPointerTo();
1797 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1800 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
1804 MethodDecl->getParent(), VTable,
1805 VTableIndex * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1810 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex,
"vfn");
1820 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1821 CGM.getCodeGenOpts().StrictVTablePointers)
1822 VFuncLoad->setMetadata(
1823 llvm::LLVMContext::MD_invariant_load,
1824 llvm::MDNode::get(CGM.getLLVMContext(),
1833 llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
1835 Address This, DeleteOrMemberCallExpr E) {
1838 assert((CE !=
nullptr) ^ (D !=
nullptr));
1839 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
1844 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
1850 ThisTy = CE->getObjectType();
1852 ThisTy = D->getDestroyedType();
1860 void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1866 bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
1870 if (CGM.getLangOpts().AppleKext)
1875 if (isVTableHidden(RD))
1878 if (CGM.getCodeGenOpts().ForceEmitVTables)
1885 if (hasAnyUnusedVirtualInlineFunction(RD))
1893 for (
const auto &B : RD->
bases()) {
1894 auto *BRD = B.getType()->getAsCXXRecordDecl();
1895 assert(BRD &&
"no class for base specifier");
1896 if (B.isVirtual() || !BRD->isDynamicClass())
1898 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
1906 bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
1907 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
1912 for (
const auto &B : RD->
vbases()) {
1913 auto *BRD = B.getType()->getAsCXXRecordDecl();
1914 assert(BRD &&
"no class for base specifier");
1915 if (!BRD->isDynamicClass())
1917 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
1925 int64_t NonVirtualAdjustment,
1926 int64_t VirtualAdjustment,
1927 bool IsReturnAdjustment) {
1928 if (!NonVirtualAdjustment && !VirtualAdjustment)
1934 if (NonVirtualAdjustment && !IsReturnAdjustment) {
1941 if (VirtualAdjustment) {
1949 CGF.
Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
1965 if (NonVirtualAdjustment && IsReturnAdjustment) {
1966 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(ResultPtr,
1967 NonVirtualAdjustment);
1976 const ThisAdjustment &TA) {
1984 const ReturnAdjustment &RA) {
1993 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
1998 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
2007 CGM.getContext().getTypeAlignInChars(elementType));
2015 assert(requiresArrayCookie(expr));
2025 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
2029 CharUnits CookieOffset = CookieSize - SizeSize;
2030 if (!CookieOffset.
isZero())
2039 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
2041 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
2043 CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
2044 llvm::FunctionType *FTy =
2045 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
2046 llvm::FunctionCallee F =
2047 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
2060 Address numElementsPtr = allocPtr;
2062 if (!numElementsOffset.
isZero())
2068 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
2075 llvm::FunctionType *FTy =
2076 llvm::FunctionType::get(CGF.
SizeTy, CGF.
SizeTy->getPointerTo(0),
false);
2077 llvm::FunctionCallee F =
2078 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2092 CGM.getContext().getTypeAlignInChars(elementType));
2100 assert(requiresArrayCookie(expr));
2108 getContext().getTypeSizeInChars(elementType).getQuantity());
2117 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2136 llvm::PointerType *GuardPtrTy) {
2138 llvm::FunctionType *FTy =
2142 FTy,
"__cxa_guard_acquire",
2144 llvm::AttributeList::FunctionIndex,
2145 llvm::Attribute::NoUnwind));
2149 llvm::PointerType *GuardPtrTy) {
2151 llvm::FunctionType *FTy =
2152 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2154 FTy,
"__cxa_guard_release",
2156 llvm::AttributeList::FunctionIndex,
2157 llvm::Attribute::NoUnwind));
2161 llvm::PointerType *GuardPtrTy) {
2163 llvm::FunctionType *FTy =
2164 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2166 FTy,
"__cxa_guard_abort",
2168 llvm::AttributeList::FunctionIndex,
2169 llvm::Attribute::NoUnwind));
2174 llvm::GlobalVariable *Guard;
2175 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2188 llvm::GlobalVariable *var,
2189 bool shouldPerformInit) {
2194 bool NonTemplateInline =
2201 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2207 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
2209 llvm::IntegerType *guardTy;
2211 if (useInt8GuardVariable) {
2217 if (UseARMGuardVarABI) {
2223 CGM.getDataLayout().getABITypeAlignment(guardTy));
2226 llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
2230 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2235 llvm::raw_svector_ostream out(guardName);
2236 getMangleContext().mangleStaticGuardVariable(&D, out);
2241 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2242 false, var->getLinkage(),
2243 llvm::ConstantInt::get(guardTy, 0),
2245 guard->setDSOLocal(var->isDSOLocal());
2246 guard->setVisibility(var->getVisibility());
2248 guard->setThreadLocalMode(var->getThreadLocalMode());
2249 guard->setAlignment(guardAlignment.
getAsAlign());
2254 llvm::Comdat *C = var->getComdat();
2256 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2257 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2258 guard->setComdat(C);
2262 if (!NonTemplateInline)
2263 CGF.
CurFn->setComdat(C);
2264 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2265 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2268 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2291 llvm::LoadInst *LI =
2301 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2324 (UseARMGuardVarABI && !useInt8GuardVariable)
2325 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2327 llvm::Value *NeedsInit = Builder.CreateIsNull(V,
"guard.uninitialized");
2346 Builder.CreateCondBr(Builder.CreateIsNotNull(V,
"tobool"),
2347 InitBlock, EndBlock);
2366 Builder.
CreateStore(llvm::ConstantInt::get(guardTy, 1), guardAddr);
2374 llvm::FunctionCallee dtor,
2375 llvm::Constant *addr,
bool TLS) {
2377 "__cxa_atexit is disabled");
2378 const char *Name =
"__cxa_atexit";
2381 Name = T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2388 llvm::FunctionType::get(CGF.
VoidTy, CGF.
Int8PtrTy,
false)->getPointerTo();
2391 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2392 auto AddrInt8PtrTy =
2396 llvm::Constant *handle =
2398 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2403 llvm::FunctionType *atexitTy =
2404 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2408 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2409 fn->setDoesNotThrow();
2416 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2418 llvm::Value *args[] = {llvm::ConstantExpr::getBitCast(
2419 cast<llvm::Constant>(dtor.getCallee()), dtorTy),
2420 llvm::ConstantExpr::getBitCast(addr, AddrInt8PtrTy),
2425 void CodeGenModule::registerGlobalDtorsWithAtExit() {
2426 for (
const auto &I : DtorsUsingAtExit) {
2428 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2438 std::string GlobalInitFnName =
2439 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
2440 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
false);
2441 llvm::Function *GlobalInitFn = CreateGlobalInitOrDestructFunction(
2442 FTy, GlobalInitFnName, getTypes().arrangeNullaryFunction(),
2455 for (
auto *Dtor : Dtors) {
2458 if (getCodeGenOpts().CXAAtExit)
2465 AddGlobalCtor(GlobalInitFn, Priority,
nullptr);
2471 llvm::FunctionCallee dtor,
2472 llvm::Constant *addr) {
2480 if (CGM.getCodeGenOpts().CXAAtExit || D.
getTLSKind())
2485 if (CGM.getLangOpts().AppleKext) {
2487 return CGM.AddCXXDtorEntry(dtor, addr);
2495 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
2505 static llvm::GlobalValue::LinkageTypes
2507 llvm::GlobalValue::LinkageTypes VarLinkage =
2511 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
2516 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
2517 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
2519 return llvm::GlobalValue::WeakODRLinkage;
2523 ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
2528 llvm::raw_svector_ostream Out(WrapperName);
2529 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
2534 if (
llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
2535 return cast<llvm::Function>(
V);
2541 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
2544 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
2545 llvm::Function *Wrapper =
2547 WrapperName.str(), &CGM.getModule());
2549 if (CGM.supportsCOMDAT() && Wrapper->isWeakForLinker())
2550 Wrapper->setComdat(CGM.getModule().getOrInsertComdat(Wrapper->getName()));
2552 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, Wrapper);
2555 if (!Wrapper->hasLocalLinkage())
2557 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
2558 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
2563 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2564 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
2567 ThreadWrappers.push_back({VD, Wrapper});
2571 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2575 llvm::Function *InitFunc =
nullptr;
2580 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
2581 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
2585 CXXThreadLocalInits[I];
2587 OrderedInits.push_back(CXXThreadLocalInits[I]);
2590 if (!OrderedInits.empty()) {
2592 llvm::FunctionType *FTy =
2593 llvm::FunctionType::get(CGM.
VoidTy,
false);
2598 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
2601 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
2602 Guard->setThreadLocal(
true);
2605 Guard->setAlignment(GuardAlign.
getAsAlign());
2611 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2612 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
2618 for (
const VarDecl *VD : CXXThreadLocals) {
2622 getOrCreateThreadLocalWrapper(VD, GV);
2627 for (
auto VDAndWrapper : ThreadWrappers) {
2628 const VarDecl *VD = VDAndWrapper.first;
2629 llvm::GlobalVariable *Var =
2631 llvm::Function *Wrapper = VDAndWrapper.second;
2644 if (Wrapper->getLinkage() == llvm::Function::WeakODRLinkage)
2645 Wrapper->setLinkage(llvm::Function::LinkOnceODRLinkage);
2653 llvm::raw_svector_ostream Out(InitFnName);
2654 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
2657 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2662 llvm::GlobalValue *Init =
nullptr;
2663 bool InitIsInitFunc =
false;
2664 bool HasConstantInitialization =
false;
2665 if (!usesThreadWrapperFunction(VD)) {
2666 HasConstantInitialization =
true;
2668 InitIsInitFunc =
true;
2669 llvm::Function *InitFuncToUse = InitFunc;
2681 llvm::GlobalVariable::ExternalWeakLinkage,
2685 cast<llvm::Function>(Init));
2689 Init->setVisibility(Var->getVisibility());
2691 if (!CGM.
getTriple().isOSWindows() || !Init->hasExternalWeakLinkage())
2692 Init->setDSOLocal(Var->isDSOLocal());
2695 llvm::LLVMContext &Context = CGM.
getModule().getContext();
2698 if (HasConstantInitialization) {
2700 }
else if (InitIsInitFunc) {
2702 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy, Init);
2704 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2705 llvm::Function *Fn =
2706 cast<llvm::Function>(cast<llvm::GlobalAlias>(Init)->getAliasee());
2707 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2712 llvm::Value *Have = Builder.CreateIsNotNull(Init);
2715 Builder.CreateCondBr(Have, InitBB, ExitBB);
2717 Builder.SetInsertPoint(InitBB);
2718 Builder.CreateCall(InitFnTy, Init);
2719 Builder.CreateBr(ExitBB);
2721 Builder.SetInsertPoint(ExitBB);
2731 if (Val->getType() != Wrapper->getReturnType())
2733 Val, Wrapper->getReturnType(),
"");
2734 Builder.CreateRet(Val);
2742 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
2744 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
2745 CallVal->setCallingConv(Wrapper->getCallingConv());
2759 bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
2778 class ItaniumRTTIBuilder {
2780 llvm::LLVMContext &VMContext;
2781 const ItaniumCXXABI &
CXXABI;
2787 llvm::GlobalVariable *
2788 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
2792 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
2795 void BuildVTablePointer(
const Type *Ty);
2808 void BuildPointerTypeInfo(
QualType PointeeTy);
2819 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
2820 : CGM(ABI.CGM), VMContext(CGM.
getModule().getContext()), CXXABI(ABI) {}
2834 PTI_Incomplete = 0x8,
2838 PTI_ContainingClassIncomplete = 0x10,
2844 PTI_Noexcept = 0x40,
2850 VMI_NonDiamondRepeat = 0x1,
2853 VMI_DiamondShaped = 0x2
2867 llvm::Constant *BuildTypeInfo(
QualType Ty);
2870 llvm::Constant *BuildTypeInfo(
2872 llvm::GlobalVariable::LinkageTypes Linkage,
2873 llvm::GlobalValue::VisibilityTypes
Visibility,
2874 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
2878 llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
2881 llvm::raw_svector_ostream Out(Name);
2887 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
2892 Name, Init->getType(),
Linkage, Align.getQuantity());
2894 GV->setInitializer(Init);
2900 ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
2903 llvm::raw_svector_ostream Out(Name);
2907 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
2922 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
2943 case BuiltinType::Void:
2944 case BuiltinType::NullPtr:
2945 case BuiltinType::Bool:
2946 case BuiltinType::WChar_S:
2947 case BuiltinType::WChar_U:
2948 case BuiltinType::Char_U:
2949 case BuiltinType::Char_S:
2950 case BuiltinType::UChar:
2951 case BuiltinType::SChar:
2952 case BuiltinType::Short:
2953 case BuiltinType::UShort:
2954 case BuiltinType::Int:
2955 case BuiltinType::UInt:
2956 case BuiltinType::Long:
2957 case BuiltinType::ULong:
2958 case BuiltinType::LongLong:
2959 case BuiltinType::ULongLong:
2960 case BuiltinType::Half:
2961 case BuiltinType::Float:
2962 case BuiltinType::Double:
2963 case BuiltinType::LongDouble:
2964 case BuiltinType::Float16:
2965 case BuiltinType::Float128:
2966 case BuiltinType::Char8:
2967 case BuiltinType::Char16:
2968 case BuiltinType::Char32:
2969 case BuiltinType::Int128:
2970 case BuiltinType::UInt128:
2973 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 2974 case BuiltinType::Id: 2975 #include "clang/Basic/OpenCLImageTypes.def" 2976 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 2977 case BuiltinType::Id: 2978 #include "clang/Basic/OpenCLExtensionTypes.def" 2979 case BuiltinType::OCLSampler:
2980 case BuiltinType::OCLEvent:
2981 case BuiltinType::OCLClkEvent:
2982 case BuiltinType::OCLQueue:
2983 case BuiltinType::OCLReserveID:
2984 #define SVE_TYPE(Name, Id, SingletonId) \ 2985 case BuiltinType::Id: 2986 #include "clang/Basic/AArch64SVEACLETypes.def" 2987 case BuiltinType::ShortAccum:
2988 case BuiltinType::Accum:
2989 case BuiltinType::LongAccum:
2990 case BuiltinType::UShortAccum:
2991 case BuiltinType::UAccum:
2992 case BuiltinType::ULongAccum:
2993 case BuiltinType::ShortFract:
2994 case BuiltinType::Fract:
2995 case BuiltinType::LongFract:
2996 case BuiltinType::UShortFract:
2997 case BuiltinType::UFract:
2998 case BuiltinType::ULongFract:
2999 case BuiltinType::SatShortAccum:
3000 case BuiltinType::SatAccum:
3001 case BuiltinType::SatLongAccum:
3002 case BuiltinType::SatUShortAccum:
3003 case BuiltinType::SatUAccum:
3004 case BuiltinType::SatULongAccum:
3005 case BuiltinType::SatShortFract:
3006 case BuiltinType::SatFract:
3007 case BuiltinType::SatLongFract:
3008 case BuiltinType::SatUShortFract:
3009 case BuiltinType::SatUFract:
3010 case BuiltinType::SatULongFract:
3013 case BuiltinType::Dependent:
3014 #define BUILTIN_TYPE(Id, SingletonId) 3015 #define PLACEHOLDER_TYPE(Id, SingletonId) \ 3016 case BuiltinType::Id: 3017 #include "clang/AST/BuiltinTypes.def" 3018 llvm_unreachable(
"asking for RRTI for a placeholder type!");
3020 case BuiltinType::ObjCId:
3021 case BuiltinType::ObjCClass:
3022 case BuiltinType::ObjCSel:
3023 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
3026 llvm_unreachable(
"Invalid BuiltinType Kind!");
3049 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
3054 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3072 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3073 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
3084 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
3087 if (CGM.
getTriple().isWindowsGNUEnvironment())
3091 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
3119 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3124 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3128 dyn_cast<MemberPointerType>(Ty)) {
3130 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
3162 if (!BaseDecl->isEmpty() &&
3169 void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
3171 static const char *
const ClassTypeInfo =
3172 "_ZTVN10__cxxabiv117__class_type_infoE";
3174 static const char *
const SIClassTypeInfo =
3175 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3177 static const char *
const VMIClassTypeInfo =
3178 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3180 const char *VTableName =
nullptr;
3183 #define TYPE(Class, Base) 3184 #define ABSTRACT_TYPE(Class, Base) 3185 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 3186 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 3187 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 3188 #include "clang/AST/TypeNodes.inc" 3189 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3191 case Type::LValueReference:
3192 case Type::RValueReference:
3193 llvm_unreachable(
"References shouldn't get here");
3196 case Type::DeducedTemplateSpecialization:
3197 llvm_unreachable(
"Undeduced type shouldn't get here");
3200 llvm_unreachable(
"Pipe types shouldn't get here");
3205 case Type::ExtVector:
3209 case Type::BlockPointer:
3211 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3214 case Type::ConstantArray:
3215 case Type::IncompleteArray:
3216 case Type::VariableArray:
3218 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3221 case Type::FunctionNoProto:
3222 case Type::FunctionProto:
3224 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3229 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3232 case Type::Record: {
3234 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3237 VTableName = ClassTypeInfo;
3239 VTableName = SIClassTypeInfo;
3241 VTableName = VMIClassTypeInfo;
3247 case Type::ObjCObject:
3249 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3252 if (isa<BuiltinType>(Ty)) {
3253 VTableName = ClassTypeInfo;
3257 assert(isa<ObjCInterfaceType>(Ty));
3260 case Type::ObjCInterface:
3261 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3262 VTableName = SIClassTypeInfo;
3264 VTableName = ClassTypeInfo;
3268 case Type::ObjCObjectPointer:
3271 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3274 case Type::MemberPointer:
3276 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3280 llvm::Constant *VTable =
3282 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3288 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3290 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8PtrTy, VTable, Two);
3291 VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.
Int8PtrTy);
3293 Fields.push_back(VTable);
3325 return llvm::GlobalValue::LinkOnceODRLinkage;
3327 if (
const RecordType *Record = dyn_cast<RecordType>(Ty)) {
3328 const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
3330 return llvm::GlobalValue::WeakODRLinkage;
3331 if (CGM.
getTriple().isWindowsItaniumEnvironment())
3332 if (RD->
hasAttr<DLLImportAttr>() &&
3340 .isWindowsGNUEnvironment())
3344 return llvm::GlobalValue::LinkOnceODRLinkage;
3347 llvm_unreachable(
"Invalid linkage!");
3350 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
3356 llvm::raw_svector_ostream Out(Name);
3359 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
3360 if (OldGV && !OldGV->isDeclaration()) {
3361 assert(!OldGV->hasAvailableExternallyLinkage() &&
3362 "available_externally typeinfos not yet implemented");
3364 return llvm::ConstantExpr::getBitCast(OldGV, CGM.
Int8PtrTy);
3370 return GetAddrOfExternalRTTIDescriptor(Ty);
3377 llvm::GlobalValue::VisibilityTypes llvmVisibility;
3378 if (llvm::GlobalValue::isLocalLinkage(Linkage))
3381 else if (
CXXABI.classifyRTTIUniqueness(Ty, Linkage) ==
3382 ItaniumCXXABI::RUK_NonUniqueHidden)
3387 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3388 llvm::GlobalValue::DefaultStorageClass;
3389 if (CGM.
getTriple().isWindowsItaniumEnvironment()) {
3391 if (RD && RD->
hasAttr<DLLExportAttr>())
3392 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
3395 return BuildTypeInfo(Ty, Linkage, llvmVisibility, DLLStorageClass);
3398 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
3400 llvm::GlobalVariable::LinkageTypes Linkage,
3401 llvm::GlobalValue::VisibilityTypes
Visibility,
3402 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
3404 BuildVTablePointer(cast<Type>(Ty));
3407 llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
3408 llvm::Constant *TypeNameField;
3412 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
3413 CXXABI.classifyRTTIUniqueness(Ty, Linkage);
3414 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
3417 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
3418 llvm::Constant *flag =
3419 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
3420 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
3422 llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.
Int8PtrTy);
3424 TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.
Int8PtrTy);
3426 Fields.push_back(TypeNameField);
3429 #define TYPE(Class, Base) 3430 #define ABSTRACT_TYPE(Class, Base) 3431 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 3432 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 3433 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 3434 #include "clang/AST/TypeNodes.inc" 3435 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3440 case Type::ExtVector:
3442 case Type::BlockPointer:
3447 case Type::LValueReference:
3448 case Type::RValueReference:
3449 llvm_unreachable(
"References shouldn't get here");
3452 case Type::DeducedTemplateSpecialization:
3453 llvm_unreachable(
"Undeduced type shouldn't get here");
3456 llvm_unreachable(
"Pipe type shouldn't get here");
3458 case Type::ConstantArray:
3459 case Type::IncompleteArray:
3460 case Type::VariableArray:
3465 case Type::FunctionNoProto:
3466 case Type::FunctionProto:
3476 case Type::Record: {
3478 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3485 BuildSIClassTypeInfo(RD);
3487 BuildVMIClassTypeInfo(RD);
3492 case Type::ObjCObject:
3493 case Type::ObjCInterface:
3494 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
3497 case Type::ObjCObjectPointer:
3498 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
3502 BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
3505 case Type::MemberPointer:
3506 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
3514 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
3517 llvm::raw_svector_ostream Out(Name);
3520 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
3521 llvm::GlobalVariable *GV =
3522 new llvm::GlobalVariable(M, Init->getType(),
3527 GV->takeName(OldGV);
3528 llvm::Constant *NewPtr =
3529 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
3530 OldGV->replaceAllUsesWith(NewPtr);
3531 OldGV->eraseFromParent();
3535 GV->setComdat(M.getOrInsertComdat(GV->getName()));
3556 TypeName->setVisibility(Visibility);
3559 GV->setVisibility(Visibility);
3562 TypeName->setDLLStorageClass(DLLStorageClass);
3563 GV->setDLLStorageClass(DLLStorageClass);
3568 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3573 void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
3576 assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
3580 if (isa<BuiltinType>(T))
return;
3591 llvm::Constant *BaseTypeInfo =
3592 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
3593 Fields.push_back(BaseTypeInfo);
3598 void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
3602 llvm::Constant *BaseTypeInfo =
3604 Fields.push_back(BaseTypeInfo);
3611 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
3612 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
3629 if (!Bases.VirtualBases.insert(BaseDecl).second) {
3632 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
3634 if (Bases.NonVirtualBases.count(BaseDecl))
3635 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3639 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
3642 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3644 if (Bases.VirtualBases.count(BaseDecl))
3645 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3650 for (
const auto &I : BaseDecl->bases())
3661 for (
const auto &I : RD->
bases())
3670 void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
3679 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3684 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
3719 for (
const auto &Base : RD->
bases()) {
3721 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(Base.getType()));
3724 cast<CXXRecordDecl>(Base.getType()->castAs<
RecordType>()->getDecl());
3726 int64_t OffsetFlags = 0;
3733 if (Base.isVirtual())
3741 OffsetFlags = uint64_t(Offset.
getQuantity()) << 8;
3745 if (Base.isVirtual())
3746 OffsetFlags |= BCTI_Virtual;
3747 if (Base.getAccessSpecifier() ==
AS_public)
3748 OffsetFlags |= BCTI_Public;
3750 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
3760 Flags |= ItaniumRTTIBuilder::PTI_Const;
3762 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
3764 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
3771 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
3774 if (Proto->isNothrow()) {
3775 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
3785 void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
3793 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3798 llvm::Constant *PointeeTypeInfo =
3799 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
3800 Fields.push_back(PointeeTypeInfo);
3816 Flags |= PTI_ContainingClassIncomplete;
3820 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3825 llvm::Constant *PointeeTypeInfo =
3826 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
3827 Fields.push_back(PointeeTypeInfo);
3834 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
3837 llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
3838 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
3841 void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
3844 getContext().VoidTy, getContext().NullPtrTy,
3845 getContext().BoolTy, getContext().WCharTy,
3846 getContext().CharTy, getContext().UnsignedCharTy,
3847 getContext().SignedCharTy, getContext().ShortTy,
3848 getContext().UnsignedShortTy, getContext().IntTy,
3849 getContext().UnsignedIntTy, getContext().LongTy,
3850 getContext().UnsignedLongTy, getContext().LongLongTy,
3851 getContext().UnsignedLongLongTy, getContext().Int128Ty,
3852 getContext().UnsignedInt128Ty, getContext().HalfTy,
3853 getContext().FloatTy, getContext().DoubleTy,
3854 getContext().LongDoubleTy, getContext().Float128Ty,
3855 getContext().Char8Ty, getContext().Char16Ty,
3856 getContext().Char32Ty
3858 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3860 ? llvm::GlobalValue::DLLExportStorageClass
3861 : llvm::GlobalValue::DefaultStorageClass;
3862 llvm::GlobalValue::VisibilityTypes Visibility =
3864 for (
const QualType &FundamentalType : FundamentalTypes) {
3866 QualType PointerTypeConst = getContext().getPointerType(
3867 FundamentalType.withConst());
3868 for (
QualType Type : {FundamentalType, PointerType, PointerTypeConst})
3869 ItaniumRTTIBuilder(*this).BuildTypeInfo(
3871 Visibility, DLLStorageClass);
3877 ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
3878 QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage)
const {
3879 if (shouldRTTIBeUnique())
3883 if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
3884 Linkage != llvm::GlobalValue::WeakODRLinkage)
3892 if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3893 return RUK_NonUniqueHidden;
3898 assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
3899 return RUK_NonUniqueVisible;
3909 return StructorCodegen::Emit;
3914 return StructorCodegen::Emit;
3917 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
3920 const auto *CD = cast<CXXConstructorDecl>(MD);
3925 if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
3926 return StructorCodegen::RAUW;
3929 if (!llvm::GlobalAlias::isValidLinkage(Linkage))
3930 return StructorCodegen::RAUW;
3932 if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
3936 return StructorCodegen::COMDAT;
3937 return StructorCodegen::Emit;
3940 return StructorCodegen::Alias;
3950 if (Entry && !Entry->isDeclaration())
3953 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
3959 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3963 assert(Entry->getType() == Aliasee->getType() &&
3964 "declaration exists with different type");
3965 Alias->takeName(Entry);
3966 Entry->replaceAllUsesWith(Alias);
3967 Entry->eraseFromParent();
3969 Alias->setName(MangledName);
3976 void ItaniumCXXABI::emitCXXStructor(
GlobalDecl GD) {
3977 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
3991 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
3996 if (CGType == StructorCodegen::RAUW) {
4009 CGType != StructorCodegen::COMDAT &&
4027 if (CGType == StructorCodegen::COMDAT) {
4029 llvm::raw_svector_ostream Out(Buffer);
4031 getMangleContext().mangleCXXDtorComdat(DD, Out);
4033 getMangleContext().mangleCXXCtorComdat(CD, Out);
4034 llvm::Comdat *C = CGM.
getModule().getOrInsertComdat(Out.str());
4043 llvm::FunctionType *FTy = llvm::FunctionType::get(
4051 llvm::FunctionType *FTy =
4052 llvm::FunctionType::get(CGM.
VoidTy,
false);
4059 llvm::FunctionType *FTy = llvm::FunctionType::get(
4079 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
4099 bool EndMightThrow) {
4100 llvm::CallInst *call =
4123 if (isa<ReferenceType>(CatchType)) {
4124 QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
4133 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4142 unsigned HeaderSize =
4144 AdjustedExn = CGF.
Builder.CreateConstGEP1_32(Exn, HeaderSize);
4163 cast<llvm::PointerType>(LLVMCatchTy)->getElementType();
4189 if (CatchType->hasPointerRepresentation()) {
4208 llvm_unreachable(
"bad ownership qualifier!");
4213 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
4229 llvm_unreachable(
"evaluation kind filtered out!");
4231 llvm_unreachable(
"bad evaluation kind");
4234 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
4235 auto catchRD = CatchType->getAsCXXRecordDecl();
4238 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
4246 caughtExnAlignment);
4255 llvm::CallInst *rawAdjustedExn =
4260 caughtExnAlignment);
4333 llvm::FunctionType *fnTy =
4336 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
4337 llvm::Function *fn =
4338 cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
4340 fn->setDoesNotThrow();
4341 fn->setDoesNotReturn();
4346 fn->addFnAttr(llvm::Attribute::NoInline);
4350 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
4353 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
4356 llvm::BasicBlock *entry =
4364 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
4365 catchCall->setDoesNotThrow();
4369 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
4370 termCall->setDoesNotThrow();
4371 termCall->setDoesNotReturn();
4375 builder.CreateUnreachable();
4381 ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
4391 std::pair<llvm::Value *, const CXXRecordDecl *>
4402 ItaniumCXXABI::emitBeginCatch(CGF, C);
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
void pushTerminate()
Push a terminate handler on the stack.
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ...
The generic AArch64 ABI is also a modified version of the Itanium ABI, but it has fewer divergences t...
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.
void EmitVTTDefinition(llvm::GlobalVariable *VTT, llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD)
EmitVTTDefinition - Emit the definition of the given vtable.
static const Decl * getCanonicalDecl(const Decl *D)
Represents a function declaration or definition.
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...
llvm::IntegerType * IntTy
int
static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
Get the appropriate linkage for the wrapper function.
bool Cast(InterpState &S, CodePtr OpPC)
External linkage, which indicates that the entity can be referred to from other translation units...
static void InitCatchParam(CodeGenFunction &CGF, const VarDecl &CatchParam, Address ParamAddr, SourceLocation Loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
no exception specification
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F)
Set the LLVM function attributes (sext, zext, etc).
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
The iOS 64-bit ABI is follows ARM's published 64-bit ABI more closely, but we don't guarantee to foll...
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
const CodeGenOptions & getCodeGenOpts() const
unsigned getNumBases() const
Retrieves the number of base classes of this class.
Internal linkage according to the Modules TS, but can be referred to from other translation units ind...
const Expr * getSubExpr() const
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target...
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler...
llvm::LLVMContext & getLLVMContext()
The COMDAT used for ctors.
CXXDtorType getDtorType() const
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
The standard implementation of ConstantInitBuilder used in Clang.
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
No linkage, which means that the entity is unique and can only be referred to from within its scope...
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
C Language Family Type Representation.
bool isRecordType() const
bool isInitICE() const
Determines whether the initializer is an integral constant expression, or in C++11, whether the initializer is a constant expression.
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D)
Determine what kind of template specialization the given declaration is.
bool isDiscardableGVALinkage(GVALinkage L)
FunctionDecl * getOperatorNew() const
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
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...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
The base class of the type hierarchy.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
bool isZero() const
isZero - Test whether the quantity equals zero.
const TargetInfo & getTargetInfo() const
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=CSK_unspecified, Expr *TrailingRequiresClause=nullptr)
Linkage getLinkage() const
Determine the linkage of this type.
bool isDefined(const FunctionDecl *&Definition) const
Returns true if the function has a definition that does not need to be instantiated.
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
static llvm::FunctionCallee getBadTypeidFn(CodeGenFunction &CGF)
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V)
Default closure variant of a ctor.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
static const OpaqueValueExpr * findInCopyConstruct(const Expr *expr)
Given an expression which invokes a copy constructor — i.e.
GlobalDecl getWithCtorType(CXXCtorType Type)
Represents a variable declaration or definition.
Address getObjectAddress(CodeGenFunction &CGF) const
Returns the address of the object within this declaration.
Objects with "hidden" visibility are not seen by the dynamic linker.
unsigned AddressPointIndex
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const T * getAs() const
Member-template getAs<specific type>'.
bool This(InterpState &S, CodePtr OpPC)
bool supportsCOMDAT() const
A this pointer adjustment.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
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::FunctionCallee getTerminateFn()
Get the declaration of std::terminate for the platform.
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * getPointer() const
A C++ throw-expression (C++ [except.throw]).
bool hasDefinition() const
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
static llvm::FunctionCallee getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
unsigned getAddressSpace() const
Return the address space that this address resides in.
The collection of all-type qualifiers we support.
const ValueDecl * getMemberPointerDecl() const
Qualifiers getQualifiers() const
Retrieve all qualifiers.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
const TargetInfo & getTarget() const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
static llvm::FunctionCallee getBadCastFn(CodeGenFunction &CGF)
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Represents a class type in Objective C.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const CXXRecordDecl * NearestVBase
llvm::IntegerType * Int64Ty
CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, const CXXRecordDecl *RD)
BuildVirtualCall - This routine makes indirect vtable call for call to virtual destructors.
SourceLocation getBeginLoc() const LLVM_READONLY
The generic Mips ABI is a modified version of the Itanium ABI.
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM)
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
Parameter for C++ virtual table pointers.
llvm::IntegerType * SizeTy
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
CharUnits getSizeAlign() const
bool Zero(InterpState &S, CodePtr OpPC)
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isReferenceType() const
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
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 CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
__DEVICE__ int max(int __a, int __b)
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.
static llvm::FunctionCallee getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
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...
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
Objects with "default" visibility are seen by the dynamic linker and act like normal objects...
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...
bool isReplaceableGlobalAllocationFunction(bool *IsAligned=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type...
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void (i8* exn) nounwind noreturn This code is used only in C++...
FunctionDecl * getOperatorDelete() const
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
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...
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
The Microsoft ABI is the ABI used by Microsoft Visual Studio (and compatible compilers).
Visibility
Describes the different kinds of visibility that a declaration may have.
CharUnits getAlignment() const
Return the alignment of this pointer.
Visibility getVisibility() const
Determine the visibility of this type.
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].
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
CXXCtorType getCtorType() const
static void dtorTy(Block *, char *Ptr, Descriptor *)
const Type * getClass() const
static llvm::FunctionCallee getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
base_class_iterator bases_begin()
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getPointerAlign() const
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
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...
Represents an ObjC class declaration.
bool isAbstract() const
Determine whether this class has a pure virtual function.
GlobalDecl getWithDtorType(CXXDtorType Type)
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...
The iOS ABI is a partial implementation of the ARM ABI.
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
This object can be modified without requiring retains or releases.
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...
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
CanQualType getReturnType() const
QualType getBaseType() const
Gets the base type of this object type.
static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty)
TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type info for that type is de...
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
static CharUnits One()
One - Construct a CharUnits quantity of one.
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ASTContext & getContext() const
Represents a prototype with parameter type info, e.g.
The generic ARM ABI is a modified version of the Itanium ABI proposed by ARM for use on ARM-based pla...
bool isDynamicClass() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
SourceLocation getBeginLoc() const LLVM_READONLY
union clang::ReturnAdjustment::VirtualAdjustment Virtual
Module linkage, which indicates that the entity can be referred to from other translation units withi...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
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...
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::CallingConv::ID getRuntimeCC() const
Exposes information about the current target.
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
CXXDtorType
C++ destructor types.
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
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.
const T * castAs() const
Member-template castAs<specific type>.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Represents a C++ destructor within a class.
VarDecl * getExceptionDecl() const
llvm::PointerType * getType() const
Return the type of the pointer value.
ObjCLifetime getObjCLifetime() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
DeclContext * getDeclContext()
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
ObjCInterfaceDecl * getSuperClass() const
TLSKind getTLSKind() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
CharUnits getSizeSize() const
static bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
llvm::LLVMContext & getLLVMContext()
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
llvm::IntegerType * Int32Ty
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant)
Returns LLVM linkage for a declarator.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
const CodeGenOptions & getCodeGenOpts() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD)
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI)
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function *> CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units. ...
Implements C++ ABI-specific semantic analysis functions.
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
const TargetInfo & getTarget() const
void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV)
Set attributes which are common to any form of a global definition (alias, Objective-C method...
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
const LangOptions & getLangOpts() const
ASTContext & getContext() const
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
The COMDAT used for dtors.
static StringRef getIdentifier(const Token &Tok)
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
GlobalDecl - represents a global declaration.
WatchOS is a modernisation of the iOS ABI, which roughly means it's the iOS64 ABI ported to 32-bits...
bool isConstQualified() const
Determine whether this type is const-qualified.
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
static llvm::Value * performTypeAdjustment(CodeGenFunction &CGF, Address InitialPtr, int64_t NonVirtualAdjustment, int64_t VirtualAdjustment, bool IsReturnAdjustment)
There is no lifetime qualification on this type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Assigning into this object requires the old value to be released and the new value to be retained...
QualType getCanonicalType() const
virtual void mangleCXXRTTIName(QualType T, raw_ostream &)=0
Encodes a location in the source.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
static bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
CastKind getCastKind() const
struct clang::ReturnAdjustment::VirtualAdjustment::@135 Itanium
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
Represents a call to a member function that may be written either with member call syntax (e...
const Decl * getDecl() const
llvm::GlobalVariable * GetAddrOfVTT(const CXXRecordDecl *RD)
GetAddrOfVTT - Get the address of the VTT for the given record decl.
Represents a static or instance method of a struct/union/class.
SanitizerSet SanOpts
Sanitizers enabled for this function.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti)
Add vtable components for the given vtable layout to the given global initializer.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
The generic Itanium ABI is the standard ABI of most open-source and Unix-like platforms.
All available information about a concrete callee.
TypeClass getTypeClass() const
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset. ...
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
MangleContext & getMangleContext()
Gets the mangle context.
llvm::Instruction * CurrentFuncletPad
ItaniumVTableContext & getItaniumVTableContext()
Assigning into this object requires a lifetime extension.
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler...
static llvm::FunctionCallee getAllocateExceptionFn(CodeGenModule &CGM)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
CXXCtorType
C++ constructor types.
The WebAssembly ABI is a modified version of the Itanium ABI.
void addReplacement(StringRef Name, llvm::Constant *C)
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
FunctionArgList - Type for representing both the decl and type of parameters to a function...
Represents an element in a path from a derived class to a base class.
TLS with a dynamic initializer.
VarDecl * getInitializingDeclaration()
Get the initializing declaration of this variable, if any.
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
bool isUniqueGVALinkage(GVALinkage L)
Do we know that this will be the only definition of this symbol (excluding inlining-only definitions)...
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
Dataflow Directional Tag Classes.
External linkage within a unique namespace.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
bool isInitKnownICE() const
Determines whether it is already known whether the initializer is an integral constant expression or ...
static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF)
void EmitAnyExprToExn(const Expr *E, Address Addr)
std::string SymbolPartition
The name of the partition that symbols are assigned to, specified with -fsymbol-partition (see https:...
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
const Expr * getInit() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
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.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined...
The Fuchsia ABI is a modified version of the Itanium ABI.
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
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. ...
A pointer to member type per C++ 8.3.3 - Pointers to members.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
union clang::ThisAdjustment::VirtualAdjustment Virtual
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type. ...
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class...
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value *> args)
Emits a call or invoke to the given noreturn runtime function.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
CodeGenTypes & getTypes() const
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
static bool isThreadWrapperReplaceable(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
Implements C++ ABI-specific code generation functions.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
llvm::PointerType * Int8PtrTy
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
StringRef getMangledName(GlobalDecl GD)
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitARCInitWeak(Address addr, llvm::Value *value)
i8* @objc_initWeak(i8** addr, i8* value) Returns value.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
ABIArgInfo & getReturnInfo()
Represents a base class of a C++ class.
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases...
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Reading or writing from this object requires a barrier call.
TranslationUnitDecl * getTranslationUnitDecl() const
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
true
A convenience builder class for complex constant initializers, especially for anonymous global struct...
Represents a C++ struct/union/class.
CGCXXABI * CreateItaniumCXXABI(CodeGenModule &CGM)
Creates an Itanium-family ABI.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block, taking care to avoid creation of branches from dummy blocks.
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
static bool ContainsIncompleteClassType(QualType Ty)
ContainsIncompleteClassType - Returns whether the given type contains an incomplete class type...
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false)
CXXCatchStmt - This represents a C++ catch block.
llvm::Type * ConvertType(QualType T)
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
A specialization of Address that requires the address to be an LLVM Constant.
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::FunctionCallee dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EmitTrapCheck(llvm::Value *Checked)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it...
void popTerminate()
Pops a terminate handler off the stack.
No linkage according to the standard, but is visible from other translation units because of types de...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
This class is used for builtin types like 'int'.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
bool isGlobalDelete() const
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
uint64_t getPointerAlign(unsigned AddrSpace) const
Copying closure variant of a ctor.
static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM)
static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM)
CGCXXABI & getCXXABI() const
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, unsigned Alignment)
Will return a global variable of the given type.
Struct with all information about dynamic [sub]class needed to set vptr.
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
llvm::Function * codegenCXXStructor(GlobalDecl GD)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
static RValue get(llvm::Value *V)
Visibility getVisibility() const
Determines the visibility of this entity.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
CodeGenVTables & getVTables()
static void emitConstructorDestructorAlias(CodeGenModule &CGM, GlobalDecl AliasDecl, GlobalDecl TargetDecl)
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
bool isTranslationUnit() const
bool isInline() const
Whether this variable is (C++1z) inline.
Notes how many arguments were added to the beginning (Prefix) and ending (Suffix) of an arg list...
static bool IsStandardLibraryRTTIDescriptor(QualType Ty)
IsStandardLibraryRTTIDescriptor - Returns whether the type information for the given type exists in t...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
static bool CanUseSingleInheritance(const CXXRecordDecl *RD)
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
CallArgList - Type for representing both the value and type of arguments in a call.
const LangOptions & getLangOpts() const
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
base_class_range vbases()
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
struct clang::ThisAdjustment::VirtualAdjustment::@137 Itanium
SourceLocation getLocation() const
QualType getPointeeType() const
CanQualType UnsignedIntTy
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed? If so, the variable need not have a usable destr...
QualType getType() const
Retrieves the type of the base class.
const llvm::Triple & getTriple() const