32 #include "llvm/IR/CallSite.h" 33 #include "llvm/IR/DataLayout.h" 34 #include "llvm/IR/GlobalValue.h" 35 #include "llvm/IR/Instructions.h" 36 #include "llvm/IR/Intrinsics.h" 37 #include "llvm/IR/Value.h" 38 #include "llvm/Support/ScopedPrinter.h" 40 using namespace clang;
41 using namespace CodeGen;
46 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
49 bool UseARMMethodPtrABI;
50 bool UseARMGuardVarABI;
51 bool Use32BitVTableOffsetABI;
59 bool UseARMMethodPtrABI =
false,
60 bool UseARMGuardVarABI =
false) :
61 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
62 UseARMGuardVarABI(UseARMGuardVarABI),
63 Use32BitVTableOffsetABI(
false) { }
68 return !canCopyArgument(RD);
73 if (passClassIndirect(RD))
78 bool isThisCompleteObject(
GlobalDecl GD)
const override {
81 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
91 llvm_unreachable(
"emitting dtor comdat as function?");
93 llvm_unreachable(
"bad dtor kind");
95 if (isa<CXXConstructorDecl>(GD.
getDecl())) {
105 llvm_unreachable(
"closure ctors in Itanium ABI?");
108 llvm_unreachable(
"emitting ctor comdat as function?");
110 llvm_unreachable(
"bad dtor kind");
138 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
139 llvm::Constant *Src)
override;
143 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
146 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
153 bool Inequality)
override;
172 auto align = CGM.getContext().getTargetDefaultAlignForAttributeAligned();
173 return CGM.getContext().toCharUnitsFromBits(align);
185 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
186 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
188 getAddrOfCXXCatchHandlerType(
QualType Ty,
189 QualType CatchHandlerType)
override {
193 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
199 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
205 llvm::BasicBlock *CastEnd)
override;
246 bool Delegating,
Address This)
override;
254 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
266 llvm::Value *getVTableAddressPointInStructorWithVTT(
274 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
287 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
289 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
290 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
292 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
GlobalDecl GD,
296 if (ForVTable && !Thunk->hasLocalLinkage())
297 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
298 CGM.setGVProperties(Thunk, GD);
301 bool exportThunk()
override {
return true; }
307 const ReturnAdjustment &RA)
override;
311 assert(!Args.empty() &&
"expected the arglist to not be empty!");
312 return Args.size() - 1;
315 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
316 StringRef GetDeletedVirtualCallName()
override 317 {
return "__cxa_deleted_virtual"; }
330 llvm::GlobalVariable *DeclPtr,
331 bool PerformInit)
override;
333 llvm::Constant *dtor, llvm::Constant *addr)
override;
335 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
337 void EmitThreadLocalInitFuncs(
343 bool usesThreadWrapperFunction()
const override {
return true; }
347 bool NeedsVTTParameter(
GlobalDecl GD)
override;
354 virtual bool shouldRTTIBeUnique()
const {
return true; }
358 enum RTTIUniquenessKind {
376 classifyRTTIUniqueness(
QualType CanTy,
377 llvm::GlobalValue::LinkageTypes
Linkage)
const;
378 friend class ItaniumRTTIBuilder;
382 std::pair<llvm::Value *, const CXXRecordDecl *>
387 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
388 const auto &VtableLayout =
389 CGM.getItaniumVTableContext().getVTableLayout(RD);
391 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
393 if (!VtableComponent.isUsedFunctionPointerKind())
396 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
400 StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
401 auto *Entry = CGM.GetGlobalValue(Name);
407 if (!Entry || Entry->isDeclaration())
414 const auto &VtableLayout =
415 CGM.getItaniumVTableContext().getVTableLayout(RD);
417 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
418 if (VtableComponent.isRTTIKind()) {
419 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
422 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
423 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
433 class ARMCXXABI :
public ItaniumCXXABI {
436 ItaniumCXXABI(CGM,
true,
439 bool HasThisReturn(
GlobalDecl GD)
const override {
440 return (isa<CXXConstructorDecl>(GD.
getDecl()) || (
441 isa<CXXDestructorDecl>(GD.
getDecl()) &&
458 class iOS64CXXABI :
public ARMCXXABI {
461 Use32BitVTableOffsetABI =
true;
465 bool shouldRTTIBeUnique()
const override {
return false; }
468 class WebAssemblyCXXABI final :
public ItaniumCXXABI {
471 : ItaniumCXXABI(CGM,
true,
476 bool HasThisReturn(
GlobalDecl GD)
const override {
477 return isa<CXXConstructorDecl>(GD.
getDecl()) ||
478 (isa<CXXDestructorDecl>(GD.
getDecl()) &&
481 bool canCallMismatchedFunctionType()
const override {
return false; }
492 return new ARMCXXABI(CGM);
495 return new iOS64CXXABI(CGM);
501 return new ItaniumCXXABI(CGM,
true,
505 return new ItaniumCXXABI(CGM,
true);
508 return new WebAssemblyCXXABI(CGM);
512 == llvm::Triple::le32) {
516 return new ItaniumCXXABI(CGM,
true,
519 return new ItaniumCXXABI(CGM);
522 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
524 llvm_unreachable(
"bad ABI kind");
530 return CGM.PtrDiffTy;
531 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
554 CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
565 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
566 CGM.getTypes().arrangeCXXMethodType(RD, FPT,
nullptr));
568 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
575 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
579 if (UseARMMethodPtrABI)
580 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
586 Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
587 This = Builder.
CreateBitCast(Ptr, This->getType(),
"this.adjusted");
588 ThisPtrForCall = This;
591 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
596 if (UseARMMethodPtrABI)
597 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
599 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
600 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
601 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
609 llvm::Type *VTableTy = Builder.getInt8PtrTy();
620 if (!UseARMMethodPtrABI)
621 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
622 if (Use32BitVTableOffsetABI) {
623 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
624 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
627 llvm::Value *VFPAddr = Builder.CreateGEP(VTable, VTableOffset);
631 llvm::Constant *CheckSourceLocation;
632 llvm::Constant *CheckTypeDesc;
633 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
634 CGM.HasHiddenLTOVisibility(RD);
635 if (ShouldEmitCFICheck) {
640 llvm::Constant *StaticData[] = {
647 CGM.CreateMetadataIdentifierForVirtualMemPtrType(
QualType(MPT, 0));
651 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VFPAddr, TypeId});
653 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
656 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
657 CGM.getLLVMContext(),
658 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
660 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
661 CGF.
EmitCheck(std::make_pair(TypeTest, SanitizerKind::CFIMFCall),
662 SanitizerHandler::CFICheckFail, StaticData,
663 {VTable, ValidVtable});
666 FnVirtual = Builder.GetInsertBlock();
670 VFPAddr = Builder.
CreateBitCast(VFPAddr, FTy->getPointerTo()->getPointerTo());
679 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(),
"memptr.nonvirtualfn");
682 if (ShouldEmitCFICheck) {
687 llvm::Constant *StaticData[] = {
697 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
698 getContext().getMemberPointerType(
705 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
706 {CastedNonVirtualFn, TypeId});
707 Bit = Builder.CreateOr(Bit, TypeTest);
710 CGF.
EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
711 SanitizerHandler::CFICheckFail, StaticData,
712 {CastedNonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
714 FnNonVirtual = Builder.GetInsertBlock();
720 llvm::PHINode *CalleePtr = Builder.CreatePHI(FTy->getPointerTo(), 2);
721 CalleePtr->addIncoming(VirtualFn, FnVirtual);
722 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
730 llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
733 assert(MemPtr->getType() == CGM.PtrDiffTy);
738 Base = Builder.CreateElementBitCast(Base, CGF.
Int8Ty);
742 Builder.CreateInBoundsGEP(Base.
getPointer(), MemPtr,
"memptr.offset");
748 return Builder.CreateBitCast(Addr, PType);
778 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
779 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
783 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
786 if (isa<llvm::Constant>(src))
787 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
789 llvm::Constant *adj = getMemberPointerAdjustment(E);
790 if (!adj)
return src;
793 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
803 dst = Builder.CreateNSWSub(src, adj,
"adj");
805 dst = Builder.CreateNSWAdd(src, adj,
"adj");
808 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
809 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
810 return Builder.CreateSelect(isNull, src, dst);
814 if (UseARMMethodPtrABI) {
815 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
817 adj = llvm::ConstantInt::get(adj->getType(), offset);
820 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
823 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
825 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
827 return Builder.CreateInsertValue(src, dstAdj, 1);
831 ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
832 llvm::Constant *src) {
833 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
834 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
838 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
841 llvm::Constant *adj = getMemberPointerAdjustment(E);
842 if (!adj)
return src;
844 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
853 if (src->isAllOnesValue())
return src;
856 return llvm::ConstantExpr::getNSWSub(src, adj);
858 return llvm::ConstantExpr::getNSWAdd(src, adj);
862 if (UseARMMethodPtrABI) {
863 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
865 adj = llvm::ConstantInt::get(adj->getType(), offset);
868 llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
869 llvm::Constant *dstAdj;
871 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
873 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
875 return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
883 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
885 llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
886 llvm::Constant *Values[2] = { Zero, Zero };
887 return llvm::ConstantStruct::getAnon(Values);
896 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
900 ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
904 llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
906 assert(MD->
isInstance() &&
"Member function must not be static!");
911 llvm::Constant *MemPtr[2];
913 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
918 uint64_t VTableOffset = (Index * PointerWidth.
getQuantity());
920 if (UseARMMethodPtrABI) {
927 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
928 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
935 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
936 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
943 if (Types.isFuncTypeConvertible(FPT)) {
945 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
951 llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
953 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
954 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
955 (UseARMMethodPtrABI ? 2 : 1) *
959 return llvm::ConstantStruct::getAnon(MemPtr);
962 llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
967 return EmitNullMemberPointer(MPT);
969 CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
972 return BuildMemberPointer(MD, ThisAdjustment);
975 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
976 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
991 llvm::ICmpInst::Predicate Eq;
992 llvm::Instruction::BinaryOps
And, Or;
994 Eq = llvm::ICmpInst::ICMP_NE;
995 And = llvm::Instruction::Or;
998 Eq = llvm::ICmpInst::ICMP_EQ;
1000 Or = llvm::Instruction::Or;
1006 return Builder.CreateICmp(Eq, L, R);
1018 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1019 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1023 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1028 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
1029 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero,
"cmp.ptr.null");
1033 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1034 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1035 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1039 if (UseARMMethodPtrABI) {
1040 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1043 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1044 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1045 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
1047 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
1051 llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
1052 Result = Builder.CreateBinOp(And, PtrEq, Result,
1053 Inequality ?
"memptr.ne" :
"memptr.eq");
1065 assert(MemPtr->getType() == CGM.PtrDiffTy);
1067 llvm::Constant::getAllOnesValue(MemPtr->getType());
1068 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1072 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1074 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1075 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
1079 if (UseARMMethodPtrABI) {
1080 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1081 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1082 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1083 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1084 "memptr.isvirtual");
1085 Result = Builder.CreateOr(Result, IsVirtual);
1097 if (passClassIndirect(RD)) {
1098 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1119 if (UseGlobalDelete) {
1131 VTable, -2,
"complete-offset.ptr");
1138 CompletePtr = CGF.
Builder.CreateInBoundsGEP(CompletePtr, Offset);
1149 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
1151 if (UseGlobalDelete)
1155 void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1158 llvm::FunctionType *FTy =
1159 llvm::FunctionType::get(CGM.VoidTy,
false);
1161 llvm::Constant *Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1172 llvm::FunctionType *FTy =
1183 llvm::FunctionType *FTy =
1184 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1193 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1197 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1199 CharUnits ExnAlign = getAlignmentOfExnObject();
1203 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1208 llvm::Constant *Dtor =
nullptr;
1210 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
1214 Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy);
1217 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1219 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
1233 llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
1235 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1238 llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
1239 llvm::Attribute::ReadOnly };
1240 llvm::AttributeList Attrs = llvm::AttributeList::get(
1241 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1248 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1265 unsigned NumPublicPaths = 0;
1278 if (PathElement.Base->isVirtual())
1281 if (NumPublicPaths > 1)
1287 PathElement.Base->getType()->getAsCXXRecordDecl());
1292 if (NumPublicPaths == 0)
1296 if (NumPublicPaths > 1)
1306 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1311 bool ItaniumCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
1319 CGF.
Builder.CreateUnreachable();
1329 CGF.
GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo(), ClassDecl);
1332 Value = CGF.
Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
1336 bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1371 llvm::BasicBlock *BadCastBlock =
1375 CGF.
Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1378 EmitBadCastCall(CGF);
1400 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
1408 Value = CGF.
Builder.CreateInBoundsGEP(Value, OffsetToTop);
1416 CGF.
Builder.CreateUnreachable();
1427 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1432 "vbase.offset.ptr");
1434 CGM.PtrDiffTy->getPointerTo());
1445 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1469 ArgTys.insert(ArgTys.begin() + 1,
1471 return AddedStructorArgs::prefix(1);
1473 return AddedStructorArgs{};
1496 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1499 if (NeedsVTTParameter(CGF.
CurGD)) {
1507 Params.insert(Params.begin() + 1, VTTDecl);
1508 getStructorImplicitParamDecl(CGF) = VTTDecl;
1512 void ItaniumCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1519 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1522 if (getStructorImplicitParamDecl(CGF)) {
1535 if (HasThisReturn(CGF.
CurGD))
1541 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1543 return AddedStructorArgs{};
1548 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1550 return AddedStructorArgs::prefix(1);
1556 bool Delegating,
Address This) {
1559 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1562 if (getContext().getLangOpts().AppleKext &&
1576 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1577 if (VTable->hasInitializer())
1582 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
1583 llvm::Constant *RTTI =
1584 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1590 Components.finishAndSetAsInitializer(VTable);
1593 VTable->setLinkage(Linkage);
1595 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1596 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1599 CGM.setGVProperties(VTable, RD);
1607 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1608 cast<NamespaceDecl>(DC)->
getIdentifier()->isStr(
"__cxxabiv1") &&
1610 EmitFundamentalRTTIDescriptors(RD);
1612 if (!VTable->isDeclarationForLinker())
1613 CGM.EmitVTableTypeMetadata(VTable, VTLayout);
1616 bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1620 return NeedsVTTParameter(CGF.
CurGD);
1623 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1628 NeedsVTTParameter(CGF.
CurGD)) {
1629 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
1632 return getVTableAddressPoint(Base, VTableClass);
1638 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
1643 CGM.getItaniumVTableContext()
1644 .getVTableLayout(VTableClass)
1645 .getAddressPoint(Base);
1647 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1648 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
1652 return llvm::ConstantExpr::getGetElementPtr(VTable->getValueType(), VTable,
1657 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1661 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
1664 uint64_t VirtualPointerIndex =
1665 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
1669 if (VirtualPointerIndex)
1670 VTT = CGF.
Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
1676 llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
1678 return getVTableAddressPoint(Base, VTableClass);
1681 llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1683 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1685 llvm::GlobalVariable *&VTable = VTables[RD];
1690 CGM.addDeferredVTable(RD);
1693 llvm::raw_svector_ostream Out(Name);
1694 getMangleContext().mangleCXXVTable(RD, Out);
1697 CGM.getItaniumVTableContext().getVTableLayout(RD);
1698 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1703 unsigned PAlign = CGM.getTarget().getPointerAlign(0);
1705 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1707 getContext().toCharUnitsFromBits(PAlign).getQuantity());
1708 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1710 CGM.setGVProperties(VTable, RD);
1720 Ty = Ty->getPointerTo()->getPointerTo();
1721 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1724 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
1728 MethodDecl->getParent(), VTable,
1729 VTableIndex * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1734 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex,
"vfn");
1744 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1745 CGM.getCodeGenOpts().StrictVTablePointers)
1746 VFuncLoad->setMetadata(
1747 llvm::LLVMContext::MD_invariant_load,
1748 llvm::MDNode::get(CGM.getLLVMContext(),
1757 llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
1763 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1775 void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1781 bool ItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
1785 if (CGM.getLangOpts().AppleKext)
1790 if (isVTableHidden(RD))
1793 if (CGM.getCodeGenOpts().ForceEmitVTables)
1800 if (hasAnyUnusedVirtualInlineFunction(RD))
1808 for (
const auto &B : RD->
bases()) {
1809 auto *BRD = B.getType()->getAsCXXRecordDecl();
1810 assert(BRD &&
"no class for base specifier");
1811 if (B.isVirtual() || !BRD->isDynamicClass())
1813 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
1821 bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
1822 if (!canSpeculativelyEmitVTableAsBaseClass(RD))
1827 for (
const auto &B : RD->
vbases()) {
1828 auto *BRD = B.getType()->getAsCXXRecordDecl();
1829 assert(BRD &&
"no class for base specifier");
1830 if (!BRD->isDynamicClass())
1832 if (!canSpeculativelyEmitVTableAsBaseClass(BRD))
1840 int64_t NonVirtualAdjustment,
1841 int64_t VirtualAdjustment,
1842 bool IsReturnAdjustment) {
1843 if (!NonVirtualAdjustment && !VirtualAdjustment)
1849 if (NonVirtualAdjustment && !IsReturnAdjustment) {
1856 if (VirtualAdjustment) {
1864 CGF.
Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
1880 if (NonVirtualAdjustment && IsReturnAdjustment) {
1881 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(ResultPtr,
1882 NonVirtualAdjustment);
1891 const ThisAdjustment &TA) {
1899 const ReturnAdjustment &RA) {
1908 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
1913 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
1922 CGM.getContext().getTypeAlignInChars(elementType));
1930 assert(requiresArrayCookie(expr));
1940 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
1944 CharUnits CookieOffset = CookieSize - SizeSize;
1945 if (!CookieOffset.
isZero())
1954 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
1956 CGM.getCodeGenOpts().SanitizeAddressPoisonCustomArrayCookie)) {
1958 CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
1959 llvm::FunctionType *FTy =
1960 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
1962 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
1975 Address numElementsPtr = allocPtr;
1977 if (!numElementsOffset.
isZero())
1983 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
1990 llvm::FunctionType *FTy =
1991 llvm::FunctionType::get(CGF.
SizeTy, CGF.
SizeTy->getPointerTo(0),
false);
1993 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
2007 CGM.getContext().getTypeAlignInChars(elementType));
2015 assert(requiresArrayCookie(expr));
2023 getContext().getTypeSizeInChars(elementType).getQuantity());
2032 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2051 llvm::PointerType *GuardPtrTy) {
2053 llvm::FunctionType *FTy =
2057 FTy,
"__cxa_guard_acquire",
2059 llvm::AttributeList::FunctionIndex,
2060 llvm::Attribute::NoUnwind));
2064 llvm::PointerType *GuardPtrTy) {
2066 llvm::FunctionType *FTy =
2067 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2069 FTy,
"__cxa_guard_release",
2071 llvm::AttributeList::FunctionIndex,
2072 llvm::Attribute::NoUnwind));
2076 llvm::PointerType *GuardPtrTy) {
2078 llvm::FunctionType *FTy =
2079 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2081 FTy,
"__cxa_guard_abort",
2083 llvm::AttributeList::FunctionIndex,
2084 llvm::Attribute::NoUnwind));
2089 llvm::GlobalVariable *Guard;
2090 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2103 llvm::GlobalVariable *var,
2104 bool shouldPerformInit) {
2109 bool NonTemplateInline =
2116 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2122 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
2124 llvm::IntegerType *guardTy;
2126 if (useInt8GuardVariable) {
2132 if (UseARMGuardVarABI) {
2138 CGM.getDataLayout().getABITypeAlignment(guardTy));
2141 llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
2145 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2150 llvm::raw_svector_ostream out(guardName);
2151 getMangleContext().mangleStaticGuardVariable(&D, out);
2156 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2157 false, var->getLinkage(),
2158 llvm::ConstantInt::get(guardTy, 0),
2160 guard->setDSOLocal(var->isDSOLocal());
2161 guard->setVisibility(var->getVisibility());
2163 guard->setThreadLocalMode(var->getThreadLocalMode());
2164 guard->setAlignment(guardAlignment.
getQuantity());
2169 llvm::Comdat *C = var->getComdat();
2171 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2172 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2173 guard->setComdat(C);
2177 if (!NonTemplateInline)
2178 CGF.
CurFn->setComdat(C);
2179 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2180 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2183 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2206 llvm::LoadInst *LI =
2216 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2239 (UseARMGuardVarABI && !useInt8GuardVariable)
2240 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2242 llvm::Value *NeedsInit = Builder.CreateIsNull(V,
"guard.uninitialized");
2261 Builder.CreateCondBr(Builder.CreateIsNotNull(V,
"tobool"),
2262 InitBlock, EndBlock);
2281 Builder.
CreateStore(llvm::ConstantInt::get(guardTy, 1), guardAddr);
2289 llvm::Constant *dtor,
2290 llvm::Constant *addr,
2292 const char *Name =
"__cxa_atexit";
2295 Name = T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2302 llvm::FunctionType::get(CGF.
VoidTy, CGF.
Int8PtrTy,
false)->getPointerTo();
2306 llvm::FunctionType *atexitTy =
2307 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2311 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
2312 fn->setDoesNotThrow();
2315 llvm::Constant *handle =
2317 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2325 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2328 llvm::ConstantExpr::getBitCast(dtor, dtorTy),
2329 llvm::ConstantExpr::getBitCast(addr, CGF.
Int8PtrTy),
2335 void CodeGenModule::registerGlobalDtorsWithAtExit() {
2336 for (
const auto I : DtorsUsingAtExit) {
2337 int Priority = I.first;
2338 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2348 std::string GlobalInitFnName =
2349 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
2350 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
false);
2351 llvm::Function *GlobalInitFn = CreateGlobalInitOrDestructFunction(
2352 FTy, GlobalInitFnName, getTypes().arrangeNullaryFunction(),
2365 for (
auto *Dtor : Dtors) {
2368 if (getCodeGenOpts().CXAAtExit)
2375 AddGlobalCtor(GlobalInitFn, Priority,
nullptr);
2382 llvm::Constant *dtor,
2383 llvm::Constant *addr) {
2388 if (CGM.getCodeGenOpts().CXAAtExit)
2392 CGM.ErrorUnsupported(&D,
"non-trivial TLS destruction");
2396 if (CGM.getLangOpts().AppleKext) {
2398 return CGM.AddCXXDtorEntry(dtor, addr);
2406 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
2416 static llvm::GlobalValue::LinkageTypes
2418 llvm::GlobalValue::LinkageTypes VarLinkage =
2422 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
2427 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
2428 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
2430 return llvm::GlobalValue::WeakODRLinkage;
2434 ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
2439 llvm::raw_svector_ostream Out(WrapperName);
2440 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
2445 if (
llvm::Value *V = CGM.getModule().getNamedValue(WrapperName))
2446 return cast<llvm::Function>(V);
2452 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
2455 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
2456 llvm::Function *Wrapper =
2458 WrapperName.str(), &CGM.getModule());
2460 CGM.SetLLVMFunctionAttributes(
GlobalDecl(), FI, Wrapper);
2463 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, Wrapper);
2466 if (!Wrapper->hasLocalLinkage())
2468 llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
2469 llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
2474 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2475 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
2480 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2484 llvm::Function *InitFunc =
nullptr;
2489 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
2490 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
2494 CXXThreadLocalInits[I];
2496 OrderedInits.push_back(CXXThreadLocalInits[I]);
2499 if (!OrderedInits.empty()) {
2501 llvm::FunctionType *FTy =
2502 llvm::FunctionType::get(CGM.
VoidTy,
false);
2507 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
2510 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
2511 Guard->setThreadLocal(
true);
2520 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2521 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
2526 for (
const VarDecl *VD : CXXThreadLocals) {
2527 llvm::GlobalVariable *Var =
2529 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
2542 llvm::raw_svector_ostream Out(InitFnName);
2543 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
2549 llvm::GlobalValue *Init =
nullptr;
2550 bool InitIsInitFunc =
false;
2552 InitIsInitFunc =
true;
2553 llvm::Function *InitFuncToUse = InitFunc;
2564 llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2566 llvm::GlobalVariable::ExternalWeakLinkage,
2570 cast<llvm::Function>(Init));
2574 Init->setVisibility(Var->getVisibility());
2575 Init->setDSOLocal(Var->isDSOLocal());
2578 llvm::LLVMContext &Context = CGM.
getModule().getContext();
2581 if (InitIsInitFunc) {
2583 llvm::CallInst *CallVal = Builder.CreateCall(Init);
2585 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2586 llvm::Function *Fn =
2587 cast<llvm::Function>(cast<llvm::GlobalAlias>(Init)->getAliasee());
2588 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2593 llvm::Value *Have = Builder.CreateIsNotNull(Init);
2596 Builder.CreateCondBr(Have, InitBB, ExitBB);
2598 Builder.SetInsertPoint(InitBB);
2599 Builder.CreateCall(Init);
2600 Builder.CreateBr(ExitBB);
2602 Builder.SetInsertPoint(ExitBB);
2612 if (Val->getType() != Wrapper->getReturnType())
2614 Val, Wrapper->getReturnType(),
"");
2615 Builder.CreateRet(Val);
2623 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
2625 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
2626 CallVal->setCallingConv(Wrapper->getCallingConv());
2640 bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
2659 class ItaniumRTTIBuilder {
2661 llvm::LLVMContext &VMContext;
2662 const ItaniumCXXABI &
CXXABI;
2668 llvm::GlobalVariable *
2669 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
2673 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
2676 void BuildVTablePointer(
const Type *Ty);
2689 void BuildPointerTypeInfo(
QualType PointeeTy);
2700 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
2701 : CGM(ABI.CGM), VMContext(CGM.
getModule().getContext()), CXXABI(ABI) {}
2715 PTI_Incomplete = 0x8,
2719 PTI_ContainingClassIncomplete = 0x10,
2725 PTI_Noexcept = 0x40,
2731 VMI_NonDiamondRepeat = 0x1,
2734 VMI_DiamondShaped = 0x2
2748 llvm::Constant *BuildTypeInfo(
QualType Ty);
2751 llvm::Constant *BuildTypeInfo(
2753 llvm::GlobalVariable::LinkageTypes Linkage,
2754 llvm::GlobalValue::VisibilityTypes
Visibility,
2755 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
2759 llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
2762 llvm::raw_svector_ostream Out(Name);
2768 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
2773 Name, Init->getType(),
Linkage, Align.getQuantity());
2775 GV->setInitializer(Init);
2781 ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
2784 llvm::raw_svector_ostream Out(Name);
2788 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
2803 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
2824 case BuiltinType::Void:
2825 case BuiltinType::NullPtr:
2826 case BuiltinType::Bool:
2827 case BuiltinType::WChar_S:
2828 case BuiltinType::WChar_U:
2829 case BuiltinType::Char_U:
2830 case BuiltinType::Char_S:
2831 case BuiltinType::UChar:
2832 case BuiltinType::SChar:
2833 case BuiltinType::Short:
2834 case BuiltinType::UShort:
2835 case BuiltinType::Int:
2836 case BuiltinType::UInt:
2837 case BuiltinType::Long:
2838 case BuiltinType::ULong:
2839 case BuiltinType::LongLong:
2840 case BuiltinType::ULongLong:
2841 case BuiltinType::Half:
2842 case BuiltinType::Float:
2843 case BuiltinType::Double:
2844 case BuiltinType::LongDouble:
2845 case BuiltinType::Float16:
2846 case BuiltinType::Float128:
2847 case BuiltinType::Char8:
2848 case BuiltinType::Char16:
2849 case BuiltinType::Char32:
2850 case BuiltinType::Int128:
2851 case BuiltinType::UInt128:
2854 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 2855 case BuiltinType::Id: 2856 #include "clang/Basic/OpenCLImageTypes.def" 2857 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ 2858 case BuiltinType::Id: 2859 #include "clang/Basic/OpenCLExtensionTypes.def" 2860 case BuiltinType::OCLSampler:
2861 case BuiltinType::OCLEvent:
2862 case BuiltinType::OCLClkEvent:
2863 case BuiltinType::OCLQueue:
2864 case BuiltinType::OCLReserveID:
2865 case BuiltinType::ShortAccum:
2866 case BuiltinType::Accum:
2867 case BuiltinType::LongAccum:
2868 case BuiltinType::UShortAccum:
2869 case BuiltinType::UAccum:
2870 case BuiltinType::ULongAccum:
2871 case BuiltinType::ShortFract:
2872 case BuiltinType::Fract:
2873 case BuiltinType::LongFract:
2874 case BuiltinType::UShortFract:
2875 case BuiltinType::UFract:
2876 case BuiltinType::ULongFract:
2877 case BuiltinType::SatShortAccum:
2878 case BuiltinType::SatAccum:
2879 case BuiltinType::SatLongAccum:
2880 case BuiltinType::SatUShortAccum:
2881 case BuiltinType::SatUAccum:
2882 case BuiltinType::SatULongAccum:
2883 case BuiltinType::SatShortFract:
2884 case BuiltinType::SatFract:
2885 case BuiltinType::SatLongFract:
2886 case BuiltinType::SatUShortFract:
2887 case BuiltinType::SatUFract:
2888 case BuiltinType::SatULongFract:
2891 case BuiltinType::Dependent:
2892 #define BUILTIN_TYPE(Id, SingletonId) 2893 #define PLACEHOLDER_TYPE(Id, SingletonId) \ 2894 case BuiltinType::Id: 2895 #include "clang/AST/BuiltinTypes.def" 2896 llvm_unreachable(
"asking for RRTI for a placeholder type!");
2898 case BuiltinType::ObjCId:
2899 case BuiltinType::ObjCClass:
2900 case BuiltinType::ObjCSel:
2901 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
2904 llvm_unreachable(
"Invalid BuiltinType Kind!");
2927 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
2932 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2950 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2951 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2962 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
2965 if (CGM.
getTriple().isWindowsGNUEnvironment() && IsDLLImport)
2969 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
2997 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
3002 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
3006 dyn_cast<MemberPointerType>(Ty)) {
3008 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
3047 void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
3049 static const char *
const ClassTypeInfo =
3050 "_ZTVN10__cxxabiv117__class_type_infoE";
3052 static const char *
const SIClassTypeInfo =
3053 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3055 static const char *
const VMIClassTypeInfo =
3056 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3058 const char *VTableName =
nullptr;
3061 #define TYPE(Class, Base) 3062 #define ABSTRACT_TYPE(Class, Base) 3063 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 3064 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 3065 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 3066 #include "clang/AST/TypeNodes.def" 3067 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3069 case Type::LValueReference:
3070 case Type::RValueReference:
3071 llvm_unreachable(
"References shouldn't get here");
3074 case Type::DeducedTemplateSpecialization:
3075 llvm_unreachable(
"Undeduced type shouldn't get here");
3078 llvm_unreachable(
"Pipe types shouldn't get here");
3083 case Type::ExtVector:
3087 case Type::BlockPointer:
3089 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3092 case Type::ConstantArray:
3093 case Type::IncompleteArray:
3094 case Type::VariableArray:
3096 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3099 case Type::FunctionNoProto:
3100 case Type::FunctionProto:
3102 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3107 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3110 case Type::Record: {
3112 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3115 VTableName = ClassTypeInfo;
3117 VTableName = SIClassTypeInfo;
3119 VTableName = VMIClassTypeInfo;
3125 case Type::ObjCObject:
3127 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3130 if (isa<BuiltinType>(Ty)) {
3131 VTableName = ClassTypeInfo;
3135 assert(isa<ObjCInterfaceType>(Ty));
3138 case Type::ObjCInterface:
3139 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3140 VTableName = SIClassTypeInfo;
3142 VTableName = ClassTypeInfo;
3146 case Type::ObjCObjectPointer:
3149 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3152 case Type::MemberPointer:
3154 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3158 llvm::Constant *VTable =
3160 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3166 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3168 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8PtrTy, VTable, Two);
3169 VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.
Int8PtrTy);
3171 Fields.push_back(VTable);
3203 return llvm::GlobalValue::LinkOnceODRLinkage;
3205 if (
const RecordType *Record = dyn_cast<RecordType>(Ty)) {
3206 const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
3208 return llvm::GlobalValue::WeakODRLinkage;
3209 if (CGM.
getTriple().isWindowsItaniumEnvironment())
3210 if (RD->
hasAttr<DLLImportAttr>() &&
3218 .isWindowsGNUEnvironment())
3222 return llvm::GlobalValue::LinkOnceODRLinkage;
3225 llvm_unreachable(
"Invalid linkage!");
3228 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
3234 llvm::raw_svector_ostream Out(Name);
3237 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
3238 if (OldGV && !OldGV->isDeclaration()) {
3239 assert(!OldGV->hasAvailableExternallyLinkage() &&
3240 "available_externally typeinfos not yet implemented");
3242 return llvm::ConstantExpr::getBitCast(OldGV, CGM.
Int8PtrTy);
3248 return GetAddrOfExternalRTTIDescriptor(Ty);
3255 llvm::GlobalValue::VisibilityTypes llvmVisibility;
3256 if (llvm::GlobalValue::isLocalLinkage(Linkage))
3259 else if (
CXXABI.classifyRTTIUniqueness(Ty, Linkage) ==
3260 ItaniumCXXABI::RUK_NonUniqueHidden)
3265 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3266 llvm::GlobalValue::DefaultStorageClass;
3267 if (CGM.
getTriple().isWindowsItaniumEnvironment()) {
3269 if (RD && RD->
hasAttr<DLLExportAttr>())
3270 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
3273 return BuildTypeInfo(Ty, Linkage, llvmVisibility, DLLStorageClass);
3276 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
3278 llvm::GlobalVariable::LinkageTypes Linkage,
3279 llvm::GlobalValue::VisibilityTypes
Visibility,
3280 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
3282 BuildVTablePointer(cast<Type>(Ty));
3285 llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
3286 llvm::Constant *TypeNameField;
3290 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
3291 CXXABI.classifyRTTIUniqueness(Ty, Linkage);
3292 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
3295 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
3296 llvm::Constant *flag =
3297 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
3298 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
3300 llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.
Int8PtrTy);
3302 TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.
Int8PtrTy);
3304 Fields.push_back(TypeNameField);
3307 #define TYPE(Class, Base) 3308 #define ABSTRACT_TYPE(Class, Base) 3309 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 3310 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 3311 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 3312 #include "clang/AST/TypeNodes.def" 3313 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3318 case Type::ExtVector:
3320 case Type::BlockPointer:
3325 case Type::LValueReference:
3326 case Type::RValueReference:
3327 llvm_unreachable(
"References shouldn't get here");
3330 case Type::DeducedTemplateSpecialization:
3331 llvm_unreachable(
"Undeduced type shouldn't get here");
3334 llvm_unreachable(
"Pipe type shouldn't get here");
3336 case Type::ConstantArray:
3337 case Type::IncompleteArray:
3338 case Type::VariableArray:
3343 case Type::FunctionNoProto:
3344 case Type::FunctionProto:
3354 case Type::Record: {
3356 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3363 BuildSIClassTypeInfo(RD);
3365 BuildVMIClassTypeInfo(RD);
3370 case Type::ObjCObject:
3371 case Type::ObjCInterface:
3372 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
3375 case Type::ObjCObjectPointer:
3376 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
3380 BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
3383 case Type::MemberPointer:
3384 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
3392 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
3395 llvm::raw_svector_ostream Out(Name);
3398 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
3399 llvm::GlobalVariable *GV =
3400 new llvm::GlobalVariable(M, Init->getType(),
3405 GV->takeName(OldGV);
3406 llvm::Constant *NewPtr =
3407 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
3408 OldGV->replaceAllUsesWith(NewPtr);
3409 OldGV->eraseFromParent();
3413 GV->setComdat(M.getOrInsertComdat(GV->getName()));
3434 TypeName->setVisibility(Visibility);
3437 GV->setVisibility(Visibility);
3440 TypeName->setDLLStorageClass(DLLStorageClass);
3441 GV->setDLLStorageClass(DLLStorageClass);
3443 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3448 void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
3451 assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
3455 if (isa<BuiltinType>(T))
return;
3466 llvm::Constant *BaseTypeInfo =
3467 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
3468 Fields.push_back(BaseTypeInfo);
3473 void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
3477 llvm::Constant *BaseTypeInfo =
3479 Fields.push_back(BaseTypeInfo);
3486 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
3487 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
3504 if (!Bases.VirtualBases.insert(BaseDecl).second) {
3507 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
3509 if (Bases.NonVirtualBases.count(BaseDecl))
3510 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3514 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
3517 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3519 if (Bases.VirtualBases.count(BaseDecl))
3520 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3525 for (
const auto &I : BaseDecl->
bases())
3536 for (
const auto &I : RD->
bases())
3545 void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
3554 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3559 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
3594 for (
const auto &Base : RD->
bases()) {
3596 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(Base.getType()));
3599 cast<CXXRecordDecl>(Base.getType()->getAs<
RecordType>()->getDecl());
3601 int64_t OffsetFlags = 0;
3608 if (Base.isVirtual())
3616 OffsetFlags = uint64_t(Offset.
getQuantity()) << 8;
3620 if (Base.isVirtual())
3621 OffsetFlags |= BCTI_Virtual;
3622 if (Base.getAccessSpecifier() ==
AS_public)
3623 OffsetFlags |= BCTI_Public;
3625 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
3635 Flags |= ItaniumRTTIBuilder::PTI_Const;
3637 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
3639 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
3646 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
3649 if (Proto->isNothrow()) {
3650 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
3660 void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
3668 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3673 llvm::Constant *PointeeTypeInfo =
3674 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
3675 Fields.push_back(PointeeTypeInfo);
3691 Flags |= PTI_ContainingClassIncomplete;
3695 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3700 llvm::Constant *PointeeTypeInfo =
3701 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
3702 Fields.push_back(PointeeTypeInfo);
3709 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
3712 llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
3713 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
3716 void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
3719 getContext().VoidTy, getContext().NullPtrTy,
3720 getContext().BoolTy, getContext().WCharTy,
3721 getContext().CharTy, getContext().UnsignedCharTy,
3722 getContext().SignedCharTy, getContext().ShortTy,
3723 getContext().UnsignedShortTy, getContext().IntTy,
3724 getContext().UnsignedIntTy, getContext().LongTy,
3725 getContext().UnsignedLongTy, getContext().LongLongTy,
3726 getContext().UnsignedLongLongTy, getContext().Int128Ty,
3727 getContext().UnsignedInt128Ty, getContext().HalfTy,
3728 getContext().FloatTy, getContext().DoubleTy,
3729 getContext().LongDoubleTy, getContext().Float128Ty,
3730 getContext().Char8Ty, getContext().Char16Ty,
3731 getContext().Char32Ty
3733 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3735 ? llvm::GlobalValue::DLLExportStorageClass
3736 : llvm::GlobalValue::DefaultStorageClass;
3737 llvm::GlobalValue::VisibilityTypes Visibility =
3739 for (
const QualType &FundamentalType : FundamentalTypes) {
3741 QualType PointerTypeConst = getContext().getPointerType(
3742 FundamentalType.withConst());
3743 for (
QualType Type : {FundamentalType, PointerType, PointerTypeConst})
3744 ItaniumRTTIBuilder(*this).BuildTypeInfo(
3746 Visibility, DLLStorageClass);
3752 ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
3753 QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage)
const {
3754 if (shouldRTTIBeUnique())
3758 if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
3759 Linkage != llvm::GlobalValue::WeakODRLinkage)
3767 if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3768 return RUK_NonUniqueHidden;
3773 assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
3774 return RUK_NonUniqueVisible;
3784 return StructorCodegen::Emit;
3789 return StructorCodegen::Emit;
3792 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
3795 const auto *CD = cast<CXXConstructorDecl>(MD);
3800 if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
3801 return StructorCodegen::RAUW;
3804 if (!llvm::GlobalAlias::isValidLinkage(Linkage))
3805 return StructorCodegen::RAUW;
3807 if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
3811 return StructorCodegen::COMDAT;
3812 return StructorCodegen::Emit;
3815 return StructorCodegen::Alias;
3825 if (Entry && !Entry->isDeclaration())
3828 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
3834 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3838 assert(Entry->getType() == Aliasee->getType() &&
3839 "declaration exists with different type");
3840 Alias->takeName(Entry);
3841 Entry->replaceAllUsesWith(Alias);
3842 Entry->eraseFromParent();
3844 Alias->setName(MangledName);
3851 void ItaniumCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3869 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
3874 if (CGType == StructorCodegen::RAUW) {
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);
4215 llvm::Function *fn = dyn_cast<llvm::Function>(fnRef);
4216 if (fn && fn->empty()) {
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();
4259 ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
4269 std::pair<llvm::Value *, const CXXRecordDecl *>
4280 ItaniumCXXABI::emitBeginCatch(CGF, C);
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
void pushTerminate()
Push a terminate handler on the stack.
ReturnValueSlot - Contains the address where the return value of a function can be stored...
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.
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...
static llvm::Constant * getAllocateExceptionFn(CodeGenModule &CGM)
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).
struct clang::ThisAdjustment::VirtualAdjustment::@133 Itanium
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 call a handler function in a sanitizer runtime with the provided argum...
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::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.
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.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
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...
RValue EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method, const CGCallee &Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E, CallArgList *RtlArgs)
unsigned getAddressSpace() const
Return the address space that this address resides in.
The collection of all-type qualifiers we support.
struct clang::ReturnAdjustment::VirtualAdjustment::@131 Itanium
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::Constant * getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void (i8* exn) nounwind noreturn This code is used only in C++...
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.
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
StructorType getFromDtorType(CXXDtorType T)
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.
llvm::Function * codegenCXXStructor(const CXXMethodDecl *MD, StructorType Type)
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...
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
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
const Type * getClass() const
llvm::Constant * getTerminateFn()
Get the declaration of std::terminate for the platform.
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.
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
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, bool isConstexprSpecified=false)
This object can be modified without requiring retains or releases.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
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...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
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.
static llvm::Constant * getBadTypeidFn(CodeGenFunction &CGF)
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
static llvm::Constant * getGetExceptionPtrFn(CodeGenModule &CGM)
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.
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.
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.
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)"...
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
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.
static llvm::Constant * getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
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. ...
MangleContext & getMangleContext()
Gets the mangle context.
llvm::Instruction * CurrentFuncletPad
ItaniumVTableContext & getItaniumVTableContext()
Assigning into this object requires a lifetime extension.
static llvm::Constant * getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler...
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. ...
void EmitAnyExprToExn(const Expr *E, Address Addr)
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args)
Emits a call or invoke to the given noreturn runtime function.
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
Returns 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.
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, CharUnits EltSize, const llvm::Twine &Name="")
Given addr = T* ...
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)
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
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.
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.
static llvm::Constant * getItaniumDynamicCastFn(CodeGenFunction &CGF)
uint64_t getPointerAlign(unsigned AddrSpace) const
Copying closure variant of a ctor.
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.
__DEVICE__ int max(int __a, int __b)
static llvm::Constant * getEndCatchFn(CodeGenModule &CGM)
Struct with all information about dynamic [sub]class needed to set vptr.
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::Constant *dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
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.
static llvm::Constant * getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
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
static llvm::Constant * getBadCastFn(CodeGenFunction &CGF)
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...
static bool CanUseSingleInheritance(const CXXRecordDecl *RD)
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
static llvm::Constant * getBeginCatchFn(CodeGenModule &CGM)
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.
static llvm::Constant * getThrowFn(CodeGenModule &CGM)
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