31 #include "llvm/IR/DataLayout.h" 32 #include "llvm/IR/GlobalValue.h" 33 #include "llvm/IR/Instructions.h" 34 #include "llvm/IR/Intrinsics.h" 35 #include "llvm/IR/Value.h" 36 #include "llvm/Support/ScopedPrinter.h" 38 using namespace clang;
39 using namespace CodeGen;
44 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
47 bool UseARMMethodPtrABI;
48 bool UseARMGuardVarABI;
49 bool Use32BitVTableOffsetABI;
57 bool UseARMMethodPtrABI =
false,
58 bool UseARMGuardVarABI =
false) :
59 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
60 UseARMGuardVarABI(UseARMGuardVarABI),
61 Use32BitVTableOffsetABI(
false) { }
72 bool isThisCompleteObject(
GlobalDecl GD)
const override {
75 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
85 llvm_unreachable(
"emitting dtor comdat as function?");
87 llvm_unreachable(
"bad dtor kind");
89 if (isa<CXXConstructorDecl>(GD.
getDecl())) {
99 llvm_unreachable(
"closure ctors in Itanium ABI?");
102 llvm_unreachable(
"emitting ctor comdat as function?");
104 llvm_unreachable(
"bad dtor kind");
132 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
133 llvm::Constant *Src)
override;
137 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
140 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
147 bool Inequality)
override;
166 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
167 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
169 getAddrOfCXXCatchHandlerType(
QualType Ty,
170 QualType CatchHandlerType)
override {
174 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
180 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
186 llvm::BasicBlock *CastEnd)
override;
236 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
248 llvm::Value *getVTableAddressPointInStructorWithVTT(
256 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
266 DeleteOrMemberCallExpr E)
override;
268 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
270 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
271 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
273 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
GlobalDecl GD,
277 if (ForVTable && !Thunk->hasLocalLinkage())
278 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
279 CGM.setGVProperties(Thunk, GD);
282 bool exportThunk()
override {
return true; }
288 const ReturnAdjustment &RA)
override;
292 assert(!Args.empty() &&
"expected the arglist to not be empty!");
293 return Args.size() - 1;
296 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
297 StringRef GetDeletedVirtualCallName()
override 298 {
return "__cxa_deleted_virtual"; }
311 llvm::GlobalVariable *DeclPtr,
312 bool PerformInit)
override;
314 llvm::FunctionCallee dtor,
315 llvm::Constant *addr)
override;
317 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
319 void EmitThreadLocalInitFuncs(
325 bool usesThreadWrapperFunction()
const override {
return true; }
329 bool NeedsVTTParameter(
GlobalDecl GD)
override;
336 virtual bool shouldRTTIBeUnique()
const {
return true; }
340 enum RTTIUniquenessKind {
358 classifyRTTIUniqueness(
QualType CanTy,
359 llvm::GlobalValue::LinkageTypes
Linkage)
const;
360 friend class ItaniumRTTIBuilder;
364 std::pair<llvm::Value *, const CXXRecordDecl *>
369 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
370 const auto &VtableLayout =
371 CGM.getItaniumVTableContext().getVTableLayout(RD);
373 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
375 if (!VtableComponent.isUsedFunctionPointerKind())
378 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
382 StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
383 auto *Entry = CGM.GetGlobalValue(Name);
389 if (!Entry || Entry->isDeclaration())
396 const auto &VtableLayout =
397 CGM.getItaniumVTableContext().getVTableLayout(RD);
399 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
400 if (VtableComponent.isRTTIKind()) {
401 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
404 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
405 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
415 class ARMCXXABI :
public ItaniumCXXABI {
418 ItaniumCXXABI(CGM,
true,
421 bool HasThisReturn(
GlobalDecl GD)
const override {
422 return (isa<CXXConstructorDecl>(GD.
getDecl()) || (
423 isa<CXXDestructorDecl>(GD.
getDecl()) &&
440 class iOS64CXXABI :
public ARMCXXABI {
443 Use32BitVTableOffsetABI =
true;
447 bool shouldRTTIBeUnique()
const override {
return false; }
450 class WebAssemblyCXXABI final :
public ItaniumCXXABI {
453 : ItaniumCXXABI(CGM,
true,
458 bool HasThisReturn(
GlobalDecl GD)
const override {
459 return isa<CXXConstructorDecl>(GD.
getDecl()) ||
460 (isa<CXXDestructorDecl>(GD.
getDecl()) &&
463 bool canCallMismatchedFunctionType()
const override {
return false; }
474 return new ARMCXXABI(CGM);
477 return new iOS64CXXABI(CGM);
483 return new ItaniumCXXABI(CGM,
true,
487 return new ItaniumCXXABI(CGM,
true);
490 return new WebAssemblyCXXABI(CGM);
494 == llvm::Triple::le32) {
498 return new ItaniumCXXABI(CGM,
true,
501 return new ItaniumCXXABI(CGM);
504 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
506 llvm_unreachable(
"bad ABI kind");
512 return CGM.PtrDiffTy;
513 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
536 CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
547 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
548 CGM.getTypes().arrangeCXXMethodType(RD, FPT,
nullptr));
550 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
557 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
561 if (UseARMMethodPtrABI)
562 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
568 Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
569 This = Builder.
CreateBitCast(Ptr, This->getType(),
"this.adjusted");
570 ThisPtrForCall = This;
573 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
578 if (UseARMMethodPtrABI)
579 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
581 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
582 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
583 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
591 llvm::Type *VTableTy = Builder.getInt8PtrTy();
602 if (!UseARMMethodPtrABI)
603 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
604 if (Use32BitVTableOffsetABI) {
605 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
606 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
609 llvm::Value *VFPAddr = Builder.CreateGEP(VTable, VTableOffset);
613 llvm::Constant *CheckSourceLocation;
614 llvm::Constant *CheckTypeDesc;
615 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
616 CGM.HasHiddenLTOVisibility(RD);
617 if (ShouldEmitCFICheck) {
622 llvm::Constant *StaticData[] = {
629 CGM.CreateMetadataIdentifierForVirtualMemPtrType(
QualType(MPT, 0));
633 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VFPAddr, TypeId});
635 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
638 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
639 CGM.getLLVMContext(),
640 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
642 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
643 CGF.
EmitCheck(std::make_pair(TypeTest, SanitizerKind::CFIMFCall),
644 SanitizerHandler::CFICheckFail, StaticData,
645 {VTable, ValidVtable});
648 FnVirtual = Builder.GetInsertBlock();
652 VFPAddr = Builder.
CreateBitCast(VFPAddr, FTy->getPointerTo()->getPointerTo());
661 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(),
"memptr.nonvirtualfn");
664 if (ShouldEmitCFICheck) {
669 llvm::Constant *StaticData[] = {
679 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
680 getContext().getMemberPointerType(
687 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
688 {CastedNonVirtualFn, TypeId});
689 Bit = Builder.CreateOr(Bit, TypeTest);
692 CGF.
EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
693 SanitizerHandler::CFICheckFail, StaticData,
694 {CastedNonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
696 FnNonVirtual = Builder.GetInsertBlock();
702 llvm::PHINode *CalleePtr = Builder.CreatePHI(FTy->getPointerTo(), 2);
703 CalleePtr->addIncoming(VirtualFn, FnVirtual);
704 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
712 llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
715 assert(MemPtr->getType() == CGM.PtrDiffTy);
720 Base = Builder.CreateElementBitCast(Base, CGF.
Int8Ty);
724 Builder.CreateInBoundsGEP(Base.
getPointer(), MemPtr,
"memptr.offset");
730 return Builder.CreateBitCast(Addr, PType);
760 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
761 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
765 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
768 if (isa<llvm::Constant>(src))
769 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
771 llvm::Constant *adj = getMemberPointerAdjustment(E);
772 if (!adj)
return src;
775 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
785 dst = Builder.CreateNSWSub(src, adj,
"adj");
787 dst = Builder.CreateNSWAdd(src, adj,
"adj");
790 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
791 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
792 return Builder.CreateSelect(isNull, src, dst);
796 if (UseARMMethodPtrABI) {
797 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
799 adj = llvm::ConstantInt::get(adj->getType(), offset);
802 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
805 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
807 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
809 return Builder.CreateInsertValue(src, dstAdj, 1);
813 ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
814 llvm::Constant *src) {
815 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
816 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
820 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
823 llvm::Constant *adj = getMemberPointerAdjustment(E);
824 if (!adj)
return src;
826 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
835 if (src->isAllOnesValue())
return src;
838 return llvm::ConstantExpr::getNSWSub(src, adj);
840 return llvm::ConstantExpr::getNSWAdd(src, adj);
844 if (UseARMMethodPtrABI) {
845 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
847 adj = llvm::ConstantInt::get(adj->getType(), offset);
850 llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
851 llvm::Constant *dstAdj;
853 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
855 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
857 return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
865 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
867 llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
868 llvm::Constant *Values[2] = { Zero, Zero };
869 return llvm::ConstantStruct::getAnon(Values);
878 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
882 ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
886 llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
888 assert(MD->
isInstance() &&
"Member function must not be static!");
893 llvm::Constant *MemPtr[2];
895 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
900 uint64_t VTableOffset = (Index * PointerWidth.
getQuantity());
902 if (UseARMMethodPtrABI) {
909 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
910 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
917 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
918 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
925 if (Types.isFuncTypeConvertible(FPT)) {
927 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
933 llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
935 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
936 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
937 (UseARMMethodPtrABI ? 2 : 1) *
941 return llvm::ConstantStruct::getAnon(MemPtr);
944 llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
949 return EmitNullMemberPointer(MPT);
951 CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
954 return BuildMemberPointer(MD, ThisAdjustment);
957 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
958 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
973 llvm::ICmpInst::Predicate Eq;
974 llvm::Instruction::BinaryOps
And, Or;
976 Eq = llvm::ICmpInst::ICMP_NE;
977 And = llvm::Instruction::Or;
980 Eq = llvm::ICmpInst::ICMP_EQ;
982 Or = llvm::Instruction::Or;
988 return Builder.CreateICmp(Eq, L, R);
1000 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1001 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1005 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1010 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
1011 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero,
"cmp.ptr.null");
1015 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1016 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1017 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1021 if (UseARMMethodPtrABI) {
1022 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1025 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1026 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1027 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
1029 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
1033 llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
1034 Result = Builder.CreateBinOp(And, PtrEq, Result,
1035 Inequality ?
"memptr.ne" :
"memptr.eq");
1047 assert(MemPtr->getType() == CGM.PtrDiffTy);
1049 llvm::Constant::getAllOnesValue(MemPtr->getType());
1050 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1054 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1056 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1057 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
1061 if (UseARMMethodPtrABI) {
1062 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1063 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1064 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1065 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1066 "memptr.isvirtual");
1067 Result = Builder.CreateOr(Result, IsVirtual);
1080 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1101 if (UseGlobalDelete) {
1113 VTable, -2,
"complete-offset.ptr");
1120 CompletePtr = CGF.
Builder.CreateInBoundsGEP(CompletePtr, Offset);
1131 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
1133 if (UseGlobalDelete)
1137 void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1140 llvm::FunctionType *FTy =
1141 llvm::FunctionType::get(CGM.VoidTy,
false);
1143 llvm::FunctionCallee Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1154 llvm::FunctionType *FTy =
1165 llvm::FunctionType *FTy =
1166 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1175 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1179 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1185 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1190 llvm::Constant *Dtor =
nullptr;
1192 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
1196 Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy);
1199 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1201 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
1215 llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
1217 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1220 llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
1221 llvm::Attribute::ReadOnly };
1222 llvm::AttributeList Attrs = llvm::AttributeList::get(
1223 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1230 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1247 unsigned NumPublicPaths = 0;
1260 if (PathElement.Base->isVirtual())
1263 if (NumPublicPaths > 1)
1269 PathElement.Base->getType()->getAsCXXRecordDecl());
1274 if (NumPublicPaths == 0)
1278 if (NumPublicPaths > 1)
1288 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1293 bool ItaniumCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
1301 Call->setDoesNotReturn();
1302 CGF.
Builder.CreateUnreachable();
1312 CGF.
GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo(), ClassDecl);
1315 Value = CGF.
Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
1319 bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1354 llvm::BasicBlock *BadCastBlock =
1358 CGF.
Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1361 EmitBadCastCall(CGF);
1383 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
1391 Value = CGF.
Builder.CreateInBoundsGEP(Value, OffsetToTop);
1399 Call->setDoesNotReturn();
1400 CGF.
Builder.CreateUnreachable();
1411 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1416 "vbase.offset.ptr");
1418 CGM.PtrDiffTy->getPointerTo());
1429 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1444 ItaniumCXXABI::buildStructorSignature(
GlobalDecl GD,
1454 cast<CXXMethodDecl>(GD.
getDecl())->getParent()->getNumVBases() != 0) {
1455 ArgTys.insert(ArgTys.begin() + 1,
1457 return AddedStructorArgs::prefix(1);
1459 return AddedStructorArgs{};
1482 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1485 if (NeedsVTTParameter(CGF.
CurGD)) {
1493 Params.insert(Params.begin() + 1, VTTDecl);
1494 getStructorImplicitParamDecl(CGF) = VTTDecl;
1498 void ItaniumCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1505 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1508 if (getStructorImplicitParamDecl(CGF)) {
1521 if (HasThisReturn(CGF.
CurGD))
1527 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1529 return AddedStructorArgs{};
1534 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1536 return AddedStructorArgs::prefix(1);
1542 bool Delegating,
Address This,
1546 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1549 if (getContext().getLangOpts().AppleKext &&
1561 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1562 if (VTable->hasInitializer())
1567 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
1568 llvm::Constant *RTTI =
1569 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1575 Components.finishAndSetAsInitializer(VTable);
1578 VTable->setLinkage(Linkage);
1580 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1581 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1584 CGM.setGVProperties(VTable, RD);
1592 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1593 cast<NamespaceDecl>(DC)->
getIdentifier()->isStr(
"__cxxabiv1") &&
1595 EmitFundamentalRTTIDescriptors(RD);
1597 if (!VTable->isDeclarationForLinker())
1598 CGM.EmitVTableTypeMetadata(VTable, VTLayout);
1601 bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1605 return NeedsVTTParameter(CGF.
CurGD);
1608 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1613 NeedsVTTParameter(CGF.
CurGD)) {
1614 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
1617 return getVTableAddressPoint(Base, VTableClass);
1623 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
1628 CGM.getItaniumVTableContext()
1629 .getVTableLayout(VTableClass)
1630 .getAddressPoint(Base);
1632 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1633 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
1637 return llvm::ConstantExpr::getGetElementPtr(VTable->getValueType(), VTable,
1642 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1646 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
1649 uint64_t VirtualPointerIndex =
1650 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
1654 if (VirtualPointerIndex)
1655 VTT = CGF.
Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
1661 llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
1663 return getVTableAddressPoint(Base, VTableClass);
1666 llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1668 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1670 llvm::GlobalVariable *&VTable = VTables[RD];
1675 CGM.addDeferredVTable(RD);
1678 llvm::raw_svector_ostream Out(Name);
1679 getMangleContext().mangleCXXVTable(RD, Out);
1682 CGM.getItaniumVTableContext().getVTableLayout(RD);
1683 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1688 unsigned PAlign = CGM.getTarget().getPointerAlign(0);
1690 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1692 getContext().toCharUnitsFromBits(PAlign).getQuantity());
1693 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1695 CGM.setGVProperties(VTable, RD);
1705 Ty = Ty->getPointerTo()->getPointerTo();
1706 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1709 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
1713 MethodDecl->getParent(), VTable,
1714 VTableIndex * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1719 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex,
"vfn");
1729 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1730 CGM.getCodeGenOpts().StrictVTablePointers)
1731 VFuncLoad->setMetadata(
1732 llvm::LLVMContext::MD_invariant_load,
1733 llvm::MDNode::get(CGM.getLLVMContext(),
1742 llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
1744 Address This, DeleteOrMemberCallExpr E) {
1747 assert((CE !=
nullptr) ^ (D !=
nullptr));
1748 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
1753 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
1759 ThisTy = CE->getObjectType();
1761 ThisTy = D->getDestroyedType();
1769 void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1775 bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
1779 if (CGM.getLangOpts().AppleKext)
1784 if (isVTableHidden(RD))
1787 if (CGM.getCodeGenOpts().ForceEmitVTables)
1794 if (hasAnyUnusedVirtualInlineFunction(RD))
1802 for (
const auto &B : RD->
bases()) {
1803 auto *BRD = B.getType()->getAsCXXRecordDecl();
1804 assert(BRD &&
"no class for base specifier");
1805 if (B.isVirtual() || !BRD->isDynamicClass())
1807 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
1815 bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
1816 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
1821 for (
const auto &B : RD->
vbases()) {
1822 auto *BRD = B.getType()->getAsCXXRecordDecl();
1823 assert(BRD &&
"no class for base specifier");
1824 if (!BRD->isDynamicClass())
1826 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
1834 int64_t NonVirtualAdjustment,
1835 int64_t VirtualAdjustment,
1836 bool IsReturnAdjustment) {
1837 if (!NonVirtualAdjustment && !VirtualAdjustment)
1843 if (NonVirtualAdjustment && !IsReturnAdjustment) {
1850 if (VirtualAdjustment) {
1858 CGF.
Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
1874 if (NonVirtualAdjustment && IsReturnAdjustment) {
1875 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(ResultPtr,
1876 NonVirtualAdjustment);
1885 const ThisAdjustment &TA) {
1893 const ReturnAdjustment &RA) {
1902 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
1907 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
1916 CGM.getContext().getTypeAlignInChars(elementType));
1924 assert(requiresArrayCookie(expr));
1934 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
1938 CharUnits CookieOffset = CookieSize - SizeSize;
1939 if (!CookieOffset.
isZero())
1948 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
1950 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
1952 CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
1953 llvm::FunctionType *FTy =
1954 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
1955 llvm::FunctionCallee F =
1956 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
1969 Address numElementsPtr = allocPtr;
1971 if (!numElementsOffset.
isZero())
1977 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
1984 llvm::FunctionType *FTy =
1985 llvm::FunctionType::get(CGF.
SizeTy, CGF.
SizeTy->getPointerTo(0),
false);
1986 llvm::FunctionCallee F =
1987 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2001 CGM.getContext().getTypeAlignInChars(elementType));
2009 assert(requiresArrayCookie(expr));
2017 getContext().getTypeSizeInChars(elementType).getQuantity());
2026 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2045 llvm::PointerType *GuardPtrTy) {
2047 llvm::FunctionType *FTy =
2051 FTy,
"__cxa_guard_acquire",
2053 llvm::AttributeList::FunctionIndex,
2054 llvm::Attribute::NoUnwind));
2058 llvm::PointerType *GuardPtrTy) {
2060 llvm::FunctionType *FTy =
2061 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2063 FTy,
"__cxa_guard_release",
2065 llvm::AttributeList::FunctionIndex,
2066 llvm::Attribute::NoUnwind));
2070 llvm::PointerType *GuardPtrTy) {
2072 llvm::FunctionType *FTy =
2073 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2075 FTy,
"__cxa_guard_abort",
2077 llvm::AttributeList::FunctionIndex,
2078 llvm::Attribute::NoUnwind));
2083 llvm::GlobalVariable *Guard;
2084 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2097 llvm::GlobalVariable *var,
2098 bool shouldPerformInit) {
2103 bool NonTemplateInline =
2110 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2116 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
2118 llvm::IntegerType *guardTy;
2120 if (useInt8GuardVariable) {
2126 if (UseARMGuardVarABI) {
2132 CGM.getDataLayout().getABITypeAlignment(guardTy));
2135 llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
2139 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2144 llvm::raw_svector_ostream out(guardName);
2145 getMangleContext().mangleStaticGuardVariable(&D, out);
2150 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2151 false, var->getLinkage(),
2152 llvm::ConstantInt::get(guardTy, 0),
2154 guard->setDSOLocal(var->isDSOLocal());
2155 guard->setVisibility(var->getVisibility());
2157 guard->setThreadLocalMode(var->getThreadLocalMode());
2158 guard->setAlignment(guardAlignment.
getQuantity());
2163 llvm::Comdat *C = var->getComdat();
2165 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2166 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2167 guard->setComdat(C);
2171 if (!NonTemplateInline)
2172 CGF.
CurFn->setComdat(C);
2173 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2174 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2177 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2200 llvm::LoadInst *LI =
2210 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2233 (UseARMGuardVarABI && !useInt8GuardVariable)
2234 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2236 llvm::Value *NeedsInit = Builder.CreateIsNull(V,
"guard.uninitialized");
2255 Builder.CreateCondBr(Builder.CreateIsNotNull(V,
"tobool"),
2256 InitBlock, EndBlock);
2275 Builder.
CreateStore(llvm::ConstantInt::get(guardTy, 1), guardAddr);
2283 llvm::FunctionCallee dtor,
2284 llvm::Constant *addr,
bool TLS) {
2286 "__cxa_atexit is disabled");
2287 const char *Name =
"__cxa_atexit";
2290 Name = T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2297 llvm::FunctionType::get(CGF.
VoidTy, CGF.
Int8PtrTy,
false)->getPointerTo();
2300 auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
2301 auto AddrInt8PtrTy =
2305 llvm::Constant *handle =
2307 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2311 llvm::Type *paramTys[] = {dtorTy, AddrInt8PtrTy, handle->getType()};
2312 llvm::FunctionType *atexitTy =
2313 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2317 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
2318 fn->setDoesNotThrow();
2325 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2327 llvm::Value *args[] = {llvm::ConstantExpr::getBitCast(
2328 cast<llvm::Constant>(dtor.getCallee()), dtorTy),
2329 llvm::ConstantExpr::getBitCast(addr, AddrInt8PtrTy),
2334 void CodeGenModule::registerGlobalDtorsWithAtExit() {
2335 for (
const auto I : DtorsUsingAtExit) {
2336 int Priority = I.first;
2337 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2347 std::string GlobalInitFnName =
2348 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
2349 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
false);
2350 llvm::Function *GlobalInitFn = CreateGlobalInitOrDestructFunction(
2351 FTy, GlobalInitFnName, getTypes().arrangeNullaryFunction(),
2364 for (
auto *Dtor : Dtors) {
2367 if (getCodeGenOpts().CXAAtExit)
2374 AddGlobalCtor(GlobalInitFn, Priority,
nullptr);
2380 llvm::FunctionCallee dtor,
2381 llvm::Constant *addr) {
2389 if (CGM.getCodeGenOpts().CXAAtExit || D.
getTLSKind())
2394 if (CGM.getLangOpts().AppleKext) {
2396 return CGM.AddCXXDtorEntry(dtor, addr);
2404 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
2414 static llvm::GlobalValue::LinkageTypes
2416 llvm::GlobalValue::LinkageTypes VarLinkage =
2420 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
2425 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
2426 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
2428 return llvm::GlobalValue::WeakODRLinkage;
2432 ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
2437 llvm::raw_svector_ostream Out(WrapperName);
2438 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
2443 if (
llvm::Value *
V = CGM.getModule().getNamedValue(WrapperName))
2444 return cast<llvm::Function>(
V);
2450 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
2453 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
2454 llvm::Function *Wrapper =
2456 WrapperName.str(), &CGM.getModule());
2458 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, Wrapper);
2461 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, Wrapper);
2464 if (!Wrapper->hasLocalLinkage())
2466 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
2467 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
2472 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2473 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
2478 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2482 llvm::Function *InitFunc =
nullptr;
2487 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
2488 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
2492 CXXThreadLocalInits[I];
2494 OrderedInits.push_back(CXXThreadLocalInits[I]);
2497 if (!OrderedInits.empty()) {
2499 llvm::FunctionType *FTy =
2500 llvm::FunctionType::get(CGM.
VoidTy,
false);
2505 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
2508 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
2509 Guard->setThreadLocal(
true);
2518 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2519 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
2524 for (
const VarDecl *VD : CXXThreadLocals) {
2525 llvm::GlobalVariable *Var =
2527 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
2540 llvm::raw_svector_ostream Out(InitFnName);
2541 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
2544 llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2549 llvm::GlobalValue *Init =
nullptr;
2550 bool InitIsInitFunc =
false;
2552 InitIsInitFunc =
true;
2553 llvm::Function *InitFuncToUse = InitFunc;
2565 llvm::GlobalVariable::ExternalWeakLinkage,
2569 cast<llvm::Function>(Init));
2573 Init->setVisibility(Var->getVisibility());
2574 Init->setDSOLocal(Var->isDSOLocal());
2577 llvm::LLVMContext &Context = CGM.
getModule().getContext();
2580 if (InitIsInitFunc) {
2582 llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy, Init);
2584 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2585 llvm::Function *Fn =
2586 cast<llvm::Function>(cast<llvm::GlobalAlias>(Init)->getAliasee());
2587 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2592 llvm::Value *Have = Builder.CreateIsNotNull(Init);
2595 Builder.CreateCondBr(Have, InitBB, ExitBB);
2597 Builder.SetInsertPoint(InitBB);
2598 Builder.CreateCall(InitFnTy, Init);
2599 Builder.CreateBr(ExitBB);
2601 Builder.SetInsertPoint(ExitBB);
2611 if (Val->getType() != Wrapper->getReturnType())
2613 Val, Wrapper->getReturnType(),
"");
2614 Builder.CreateRet(Val);
2622 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
2624 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
2625 CallVal->setCallingConv(Wrapper->getCallingConv());
2639 bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
2658 class ItaniumRTTIBuilder {
2660 llvm::LLVMContext &VMContext;
2661 const ItaniumCXXABI &
CXXABI;
2667 llvm::GlobalVariable *
2668 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
2672 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
2675 void BuildVTablePointer(
const Type *Ty);
2688 void BuildPointerTypeInfo(
QualType PointeeTy);
2699 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
2700 : CGM(ABI.CGM), VMContext(CGM.
getModule().getContext()), CXXABI(ABI) {}
2714 PTI_Incomplete = 0x8,
2718 PTI_ContainingClassIncomplete = 0x10,
2724 PTI_Noexcept = 0x40,
2730 VMI_NonDiamondRepeat = 0x1,
2733 VMI_DiamondShaped = 0x2
2747 llvm::Constant *BuildTypeInfo(
QualType Ty);
2750 llvm::Constant *BuildTypeInfo(
2752 llvm::GlobalVariable::LinkageTypes Linkage,
2753 llvm::GlobalValue::VisibilityTypes
Visibility,
2754 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
2758 llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
2761 llvm::raw_svector_ostream Out(Name);
2767 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
2772 Name, Init->getType(),
Linkage, Align.getQuantity());
2774 GV->setInitializer(Init);
2780 ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
2783 llvm::raw_svector_ostream Out(Name);
2787 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
2802 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
2823 case BuiltinType::Void:
2824 case BuiltinType::NullPtr:
2825 case BuiltinType::Bool:
2826 case BuiltinType::WChar_S:
2827 case BuiltinType::WChar_U:
2828 case BuiltinType::Char_U:
2829 case BuiltinType::Char_S:
2830 case BuiltinType::UChar:
2831 case BuiltinType::SChar:
2832 case BuiltinType::Short:
2833 case BuiltinType::UShort:
2834 case BuiltinType::Int:
2835 case BuiltinType::UInt:
2836 case BuiltinType::Long:
2837 case BuiltinType::ULong:
2838 case BuiltinType::LongLong:
2839 case BuiltinType::ULongLong:
2840 case BuiltinType::Half:
2841 case BuiltinType::Float:
2842 case BuiltinType::Double:
2843 case BuiltinType::LongDouble:
2844 case BuiltinType::Float16:
2845 case BuiltinType::Float128:
2846 case BuiltinType::Char8:
2847 case BuiltinType::Char16:
2848 case BuiltinType::Char32:
2849 case BuiltinType::Int128:
2850 case BuiltinType::UInt128:
2853 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 2854 case BuiltinType::Id: 2855 #include "clang/Basic/OpenCLImageTypes.def" 2856 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 2857 case BuiltinType::Id: 2858 #include "clang/Basic/OpenCLExtensionTypes.def" 2859 case BuiltinType::OCLSampler:
2860 case BuiltinType::OCLEvent:
2861 case BuiltinType::OCLClkEvent:
2862 case BuiltinType::OCLQueue:
2863 case BuiltinType::OCLReserveID:
2864 case BuiltinType::ShortAccum:
2865 case BuiltinType::Accum:
2866 case BuiltinType::LongAccum:
2867 case BuiltinType::UShortAccum:
2868 case BuiltinType::UAccum:
2869 case BuiltinType::ULongAccum:
2870 case BuiltinType::ShortFract:
2871 case BuiltinType::Fract:
2872 case BuiltinType::LongFract:
2873 case BuiltinType::UShortFract:
2874 case BuiltinType::UFract:
2875 case BuiltinType::ULongFract:
2876 case BuiltinType::SatShortAccum:
2877 case BuiltinType::SatAccum:
2878 case BuiltinType::SatLongAccum:
2879 case BuiltinType::SatUShortAccum:
2880 case BuiltinType::SatUAccum:
2881 case BuiltinType::SatULongAccum:
2882 case BuiltinType::SatShortFract:
2883 case BuiltinType::SatFract:
2884 case BuiltinType::SatLongFract:
2885 case BuiltinType::SatUShortFract:
2886 case BuiltinType::SatUFract:
2887 case BuiltinType::SatULongFract:
2890 case BuiltinType::Dependent:
2891 #define BUILTIN_TYPE(Id, SingletonId) 2892 #define PLACEHOLDER_TYPE(Id, SingletonId) \ 2893 case BuiltinType::Id: 2894 #include "clang/AST/BuiltinTypes.def" 2895 llvm_unreachable(
"asking for RRTI for a placeholder type!");
2897 case BuiltinType::ObjCId:
2898 case BuiltinType::ObjCClass:
2899 case BuiltinType::ObjCSel:
2900 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
2903 llvm_unreachable(
"Invalid BuiltinType Kind!");
2926 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
2931 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2949 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2950 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2961 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
2964 if (CGM.
getTriple().isWindowsGNUEnvironment())
2968 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
2996 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3001 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3005 dyn_cast<MemberPointerType>(Ty)) {
3007 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
3046 void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
3048 static const char *
const ClassTypeInfo =
3049 "_ZTVN10__cxxabiv117__class_type_infoE";
3051 static const char *
const SIClassTypeInfo =
3052 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3054 static const char *
const VMIClassTypeInfo =
3055 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3057 const char *VTableName =
nullptr;
3060 #define TYPE(Class, Base) 3061 #define ABSTRACT_TYPE(Class, Base) 3062 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 3063 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 3064 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 3065 #include "clang/AST/TypeNodes.def" 3066 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3068 case Type::LValueReference:
3069 case Type::RValueReference:
3070 llvm_unreachable(
"References shouldn't get here");
3073 case Type::DeducedTemplateSpecialization:
3074 llvm_unreachable(
"Undeduced type shouldn't get here");
3077 llvm_unreachable(
"Pipe types shouldn't get here");
3082 case Type::ExtVector:
3086 case Type::BlockPointer:
3088 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3091 case Type::ConstantArray:
3092 case Type::IncompleteArray:
3093 case Type::VariableArray:
3095 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3098 case Type::FunctionNoProto:
3099 case Type::FunctionProto:
3101 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3106 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3109 case Type::Record: {
3111 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3114 VTableName = ClassTypeInfo;
3116 VTableName = SIClassTypeInfo;
3118 VTableName = VMIClassTypeInfo;
3124 case Type::ObjCObject:
3126 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3129 if (isa<BuiltinType>(Ty)) {
3130 VTableName = ClassTypeInfo;
3134 assert(isa<ObjCInterfaceType>(Ty));
3137 case Type::ObjCInterface:
3138 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3139 VTableName = SIClassTypeInfo;
3141 VTableName = ClassTypeInfo;
3145 case Type::ObjCObjectPointer:
3148 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3151 case Type::MemberPointer:
3153 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3157 llvm::Constant *VTable =
3159 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3165 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3167 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8PtrTy, VTable, Two);
3168 VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.
Int8PtrTy);
3170 Fields.push_back(VTable);
3202 return llvm::GlobalValue::LinkOnceODRLinkage;
3204 if (
const RecordType *Record = dyn_cast<RecordType>(Ty)) {
3205 const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
3207 return llvm::GlobalValue::WeakODRLinkage;
3208 if (CGM.
getTriple().isWindowsItaniumEnvironment())
3209 if (RD->
hasAttr<DLLImportAttr>() &&
3217 .isWindowsGNUEnvironment())
3221 return llvm::GlobalValue::LinkOnceODRLinkage;
3224 llvm_unreachable(
"Invalid linkage!");
3227 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
3233 llvm::raw_svector_ostream Out(Name);
3236 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
3237 if (OldGV && !OldGV->isDeclaration()) {
3238 assert(!OldGV->hasAvailableExternallyLinkage() &&
3239 "available_externally typeinfos not yet implemented");
3241 return llvm::ConstantExpr::getBitCast(OldGV, CGM.
Int8PtrTy);
3247 return GetAddrOfExternalRTTIDescriptor(Ty);
3254 llvm::GlobalValue::VisibilityTypes llvmVisibility;
3255 if (llvm::GlobalValue::isLocalLinkage(Linkage))
3258 else if (
CXXABI.classifyRTTIUniqueness(Ty, Linkage) ==
3259 ItaniumCXXABI::RUK_NonUniqueHidden)
3264 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3265 llvm::GlobalValue::DefaultStorageClass;
3266 if (CGM.
getTriple().isWindowsItaniumEnvironment()) {
3268 if (RD && RD->
hasAttr<DLLExportAttr>())
3269 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
3272 return BuildTypeInfo(Ty, Linkage, llvmVisibility, DLLStorageClass);
3275 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
3277 llvm::GlobalVariable::LinkageTypes Linkage,
3278 llvm::GlobalValue::VisibilityTypes
Visibility,
3279 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
3281 BuildVTablePointer(cast<Type>(Ty));
3284 llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
3285 llvm::Constant *TypeNameField;
3289 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
3290 CXXABI.classifyRTTIUniqueness(Ty, Linkage);
3291 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
3294 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
3295 llvm::Constant *flag =
3296 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
3297 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
3299 llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.
Int8PtrTy);
3301 TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.
Int8PtrTy);
3303 Fields.push_back(TypeNameField);
3306 #define TYPE(Class, Base) 3307 #define ABSTRACT_TYPE(Class, Base) 3308 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 3309 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 3310 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 3311 #include "clang/AST/TypeNodes.def" 3312 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3317 case Type::ExtVector:
3319 case Type::BlockPointer:
3324 case Type::LValueReference:
3325 case Type::RValueReference:
3326 llvm_unreachable(
"References shouldn't get here");
3329 case Type::DeducedTemplateSpecialization:
3330 llvm_unreachable(
"Undeduced type shouldn't get here");
3333 llvm_unreachable(
"Pipe type shouldn't get here");
3335 case Type::ConstantArray:
3336 case Type::IncompleteArray:
3337 case Type::VariableArray:
3342 case Type::FunctionNoProto:
3343 case Type::FunctionProto:
3353 case Type::Record: {
3355 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3362 BuildSIClassTypeInfo(RD);
3364 BuildVMIClassTypeInfo(RD);
3369 case Type::ObjCObject:
3370 case Type::ObjCInterface:
3371 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
3374 case Type::ObjCObjectPointer:
3375 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
3379 BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
3382 case Type::MemberPointer:
3383 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
3391 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
3394 llvm::raw_svector_ostream Out(Name);
3397 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
3398 llvm::GlobalVariable *GV =
3399 new llvm::GlobalVariable(M, Init->getType(),
3404 GV->takeName(OldGV);
3405 llvm::Constant *NewPtr =
3406 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
3407 OldGV->replaceAllUsesWith(NewPtr);
3408 OldGV->eraseFromParent();
3412 GV->setComdat(M.getOrInsertComdat(GV->getName()));
3433 TypeName->setVisibility(Visibility);
3436 GV->setVisibility(Visibility);
3439 TypeName->setDLLStorageClass(DLLStorageClass);
3440 GV->setDLLStorageClass(DLLStorageClass);
3445 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3450 void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
3453 assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
3457 if (isa<BuiltinType>(T))
return;
3468 llvm::Constant *BaseTypeInfo =
3469 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
3470 Fields.push_back(BaseTypeInfo);
3475 void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
3479 llvm::Constant *BaseTypeInfo =
3481 Fields.push_back(BaseTypeInfo);
3488 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
3489 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
3506 if (!Bases.VirtualBases.insert(BaseDecl).second) {
3509 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
3511 if (Bases.NonVirtualBases.count(BaseDecl))
3512 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3516 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
3519 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3521 if (Bases.VirtualBases.count(BaseDecl))
3522 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3527 for (
const auto &I : BaseDecl->
bases())
3538 for (
const auto &I : RD->
bases())
3547 void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
3556 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3561 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
3596 for (
const auto &Base : RD->
bases()) {
3598 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(Base.getType()));
3601 cast<CXXRecordDecl>(Base.getType()->getAs<
RecordType>()->getDecl());
3603 int64_t OffsetFlags = 0;
3610 if (Base.isVirtual())
3618 OffsetFlags = uint64_t(Offset.
getQuantity()) << 8;
3622 if (Base.isVirtual())
3623 OffsetFlags |= BCTI_Virtual;
3624 if (Base.getAccessSpecifier() ==
AS_public)
3625 OffsetFlags |= BCTI_Public;
3627 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
3637 Flags |= ItaniumRTTIBuilder::PTI_Const;
3639 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
3641 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
3648 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
3651 if (Proto->isNothrow()) {
3652 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
3662 void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
3670 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3675 llvm::Constant *PointeeTypeInfo =
3676 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
3677 Fields.push_back(PointeeTypeInfo);
3693 Flags |= PTI_ContainingClassIncomplete;
3697 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3702 llvm::Constant *PointeeTypeInfo =
3703 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
3704 Fields.push_back(PointeeTypeInfo);
3711 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
3714 llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
3715 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
3718 void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
3721 getContext().VoidTy, getContext().NullPtrTy,
3722 getContext().BoolTy, getContext().WCharTy,
3723 getContext().CharTy, getContext().UnsignedCharTy,
3724 getContext().SignedCharTy, getContext().ShortTy,
3725 getContext().UnsignedShortTy, getContext().IntTy,
3726 getContext().UnsignedIntTy, getContext().LongTy,
3727 getContext().UnsignedLongTy, getContext().LongLongTy,
3728 getContext().UnsignedLongLongTy, getContext().Int128Ty,
3729 getContext().UnsignedInt128Ty, getContext().HalfTy,
3730 getContext().FloatTy, getContext().DoubleTy,
3731 getContext().LongDoubleTy, getContext().Float128Ty,
3732 getContext().Char8Ty, getContext().Char16Ty,
3733 getContext().Char32Ty
3735 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3737 ? llvm::GlobalValue::DLLExportStorageClass
3738 : llvm::GlobalValue::DefaultStorageClass;
3739 llvm::GlobalValue::VisibilityTypes Visibility =
3741 for (
const QualType &FundamentalType : FundamentalTypes) {
3743 QualType PointerTypeConst = getContext().getPointerType(
3744 FundamentalType.withConst());
3745 for (
QualType Type : {FundamentalType, PointerType, PointerTypeConst})
3746 ItaniumRTTIBuilder(*this).BuildTypeInfo(
3748 Visibility, DLLStorageClass);
3754 ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
3755 QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage)
const {
3756 if (shouldRTTIBeUnique())
3760 if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
3761 Linkage != llvm::GlobalValue::WeakODRLinkage)
3769 if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3770 return RUK_NonUniqueHidden;
3775 assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
3776 return RUK_NonUniqueVisible;
3786 return StructorCodegen::Emit;
3791 return StructorCodegen::Emit;
3794 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
3797 const auto *CD = cast<CXXConstructorDecl>(MD);
3802 if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
3803 return StructorCodegen::RAUW;
3806 if (!llvm::GlobalAlias::isValidLinkage(Linkage))
3807 return StructorCodegen::RAUW;
3809 if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
3813 return StructorCodegen::COMDAT;
3814 return StructorCodegen::Emit;
3817 return StructorCodegen::Alias;
3827 if (Entry && !Entry->isDeclaration())
3830 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
3836 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3840 assert(Entry->getType() == Aliasee->getType() &&
3841 "declaration exists with different type");
3842 Alias->takeName(Entry);
3843 Entry->replaceAllUsesWith(Alias);
3844 Entry->eraseFromParent();
3846 Alias->setName(MangledName);
3853 void ItaniumCXXABI::emitCXXStructor(
GlobalDecl GD) {
3854 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
3868 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
3873 if (CGType == StructorCodegen::RAUW) {
3886 CGType != StructorCodegen::COMDAT &&
3904 if (CGType == StructorCodegen::COMDAT) {
3906 llvm::raw_svector_ostream Out(Buffer);
3908 getMangleContext().mangleCXXDtorComdat(DD, Out);
3910 getMangleContext().mangleCXXCtorComdat(CD, Out);
3911 llvm::Comdat *C = CGM.
getModule().getOrInsertComdat(Out.str());
3920 llvm::FunctionType *FTy = llvm::FunctionType::get(
3928 llvm::FunctionType *FTy =
3929 llvm::FunctionType::get(CGM.
VoidTy,
false);
3936 llvm::FunctionType *FTy = llvm::FunctionType::get(
3956 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
3976 bool EndMightThrow) {
3977 llvm::CallInst *call =
4000 if (isa<ReferenceType>(CatchType)) {
4001 QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
4010 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
4019 unsigned HeaderSize =
4021 AdjustedExn = CGF.
Builder.CreateConstGEP1_32(Exn, HeaderSize);
4040 cast<llvm::PointerType>(LLVMCatchTy)->getElementType();
4066 if (CatchType->hasPointerRepresentation()) {
4085 llvm_unreachable(
"bad ownership qualifier!");
4090 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
4106 llvm_unreachable(
"evaluation kind filtered out!");
4108 llvm_unreachable(
"bad evaluation kind");
4111 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
4112 auto catchRD = CatchType->getAsCXXRecordDecl();
4115 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
4123 caughtExnAlignment);
4132 llvm::CallInst *rawAdjustedExn =
4137 caughtExnAlignment);
4210 llvm::FunctionType *fnTy =
4213 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
4214 llvm::Function *fn =
4215 cast<llvm::Function>(fnRef.getCallee()->stripPointerCasts());
4217 fn->setDoesNotThrow();
4218 fn->setDoesNotReturn();
4223 fn->addFnAttr(llvm::Attribute::NoInline);
4227 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
4230 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
4233 llvm::BasicBlock *entry =
4241 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
4242 catchCall->setDoesNotThrow();
4246 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
4247 termCall->setDoesNotThrow();
4248 termCall->setDoesNotReturn();
4252 builder.CreateUnreachable();
4258 ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
4268 std::pair<llvm::Value *, const CXXRecordDecl *>
4279 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.
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.
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)
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
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D)
Determine what kind of template specialization the given declaration is.
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
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 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
struct clang::ThisAdjustment::VirtualAdjustment::@135 Itanium
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.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
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)
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
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
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
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.
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.
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.
struct clang::ReturnAdjustment::VirtualAdjustment::@133 Itanium
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.
CastKind getCastKind() const
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.
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.
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
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. ...
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...
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
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...
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create or return a runtime function declaration with the specified type and name. ...
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.
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.
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
Do we need to emit an exit-time destructor for this variable?
QualType getType() const
Retrieves the type of the base class.
const llvm::Triple & getTriple() const