31 #include "llvm/IR/CallSite.h"
32 #include "llvm/IR/DataLayout.h"
33 #include "llvm/IR/Instructions.h"
34 #include "llvm/IR/Intrinsics.h"
35 #include "llvm/IR/Value.h"
37 using namespace clang;
38 using namespace CodeGen;
43 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
46 bool UseARMMethodPtrABI;
47 bool UseARMGuardVarABI;
55 bool UseARMMethodPtrABI =
false,
56 bool UseARMGuardVarABI =
false) :
57 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
58 UseARMGuardVarABI(UseARMGuardVarABI) { }
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;
158 unsigned Align = CGM.getContext().getTargetInfo().getExnObjectAlignment();
159 return CGM.getContext().toCharUnitsFromBits(Align);
172 void EmitFundamentalRTTIDescriptors();
173 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
175 getAddrOfCXXCatchHandlerType(
QualType Ty,
176 QualType CatchHandlerType)
override {
180 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
186 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
192 llvm::BasicBlock *CastEnd)
override;
233 bool Delegating,
Address This)
override;
241 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
253 llvm::Value *getVTableAddressPointInStructorWithVTT(
261 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
274 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
276 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
278 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
GlobalDecl GD,
282 if (ForVTable && !Thunk->hasLocalLinkage())
283 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
290 const ReturnAdjustment &RA)
override;
294 assert(!Args.empty() &&
"expected the arglist to not be empty!");
295 return Args.size() - 1;
298 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
299 StringRef GetDeletedVirtualCallName()
override
300 {
return "__cxa_deleted_virtual"; }
313 llvm::GlobalVariable *DeclPtr,
314 bool PerformInit)
override;
316 llvm::Constant *dtor, llvm::Constant *addr)
override;
318 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
320 void EmitThreadLocalInitFuncs(
326 bool usesThreadWrapperFunction()
const override {
return true; }
330 bool NeedsVTTParameter(
GlobalDecl GD)
override;
337 virtual bool shouldRTTIBeUnique()
const {
return true; }
341 enum RTTIUniquenessKind {
359 classifyRTTIUniqueness(
QualType CanTy,
360 llvm::GlobalValue::LinkageTypes
Linkage)
const;
361 friend class ItaniumRTTIBuilder;
366 bool hasAnyUsedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
367 const auto &VtableLayout =
368 CGM.getItaniumVTableContext().getVTableLayout(RD);
370 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
371 if (!VtableComponent.isUsedFunctionPointerKind())
374 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
382 const auto &VtableLayout =
383 CGM.getItaniumVTableContext().getVTableLayout(RD);
385 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
386 if (VtableComponent.isRTTIKind()) {
387 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
390 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
391 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
401 class ARMCXXABI :
public ItaniumCXXABI {
404 ItaniumCXXABI(CGM,
true,
407 bool HasThisReturn(
GlobalDecl GD)
const override {
408 return (isa<CXXConstructorDecl>(GD.
getDecl()) || (
409 isa<CXXDestructorDecl>(GD.
getDecl()) &&
426 class iOS64CXXABI :
public ARMCXXABI {
431 bool shouldRTTIBeUnique()
const override {
return false; }
434 class WebAssemblyCXXABI final :
public ItaniumCXXABI {
437 : ItaniumCXXABI(CGM,
true,
441 bool HasThisReturn(
GlobalDecl GD)
const override {
442 return isa<CXXConstructorDecl>(GD.
getDecl()) ||
443 (isa<CXXDestructorDecl>(GD.
getDecl()) &&
446 bool canCallMismatchedFunctionType()
const override {
return false; }
457 return new ARMCXXABI(CGM);
460 return new iOS64CXXABI(CGM);
466 return new ItaniumCXXABI(CGM,
true,
470 return new ItaniumCXXABI(CGM,
true);
473 return new WebAssemblyCXXABI(CGM);
477 == llvm::Triple::le32) {
481 return new ItaniumCXXABI(CGM,
true,
484 return new ItaniumCXXABI(CGM);
487 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
489 llvm_unreachable(
"bad ABI kind");
495 return CGM.PtrDiffTy;
496 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy,
nullptr);
519 llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
530 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
531 CGM.getTypes().arrangeCXXMethodType(RD, FPT,
nullptr));
533 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
540 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
544 if (UseARMMethodPtrABI)
545 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
551 Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
552 This = Builder.
CreateBitCast(Ptr, This->getType(),
"this.adjusted");
553 ThisPtrForCall = This;
556 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
561 if (UseARMMethodPtrABI)
562 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
564 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
565 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
566 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
574 llvm::Type *VTableTy = Builder.getInt8PtrTy();
583 if (!UseARMMethodPtrABI)
584 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
585 VTable = Builder.CreateGEP(VTable, VTableOffset);
588 VTable = Builder.
CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
598 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(),
"memptr.nonvirtualfn");
602 llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
603 Callee->addIncoming(VirtualFn, FnVirtual);
604 Callee->addIncoming(NonVirtualFn, FnNonVirtual);
610 llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
613 assert(MemPtr->getType() == CGM.PtrDiffTy);
618 Base = Builder.CreateElementBitCast(Base, CGF.
Int8Ty);
622 Builder.CreateInBoundsGEP(Base.
getPointer(), MemPtr,
"memptr.offset");
628 return Builder.CreateBitCast(Addr, PType);
658 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
659 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
663 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
666 if (isa<llvm::Constant>(src))
667 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
669 llvm::Constant *adj = getMemberPointerAdjustment(E);
670 if (!adj)
return src;
673 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
683 dst = Builder.CreateNSWSub(src, adj,
"adj");
685 dst = Builder.CreateNSWAdd(src, adj,
"adj");
688 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
689 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
690 return Builder.CreateSelect(isNull, src, dst);
694 if (UseARMMethodPtrABI) {
695 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
697 adj = llvm::ConstantInt::get(adj->getType(), offset);
700 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
703 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
705 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
707 return Builder.CreateInsertValue(src, dstAdj, 1);
711 ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
712 llvm::Constant *src) {
713 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
714 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
718 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
721 llvm::Constant *adj = getMemberPointerAdjustment(E);
722 if (!adj)
return src;
724 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
733 if (src->isAllOnesValue())
return src;
736 return llvm::ConstantExpr::getNSWSub(src, adj);
738 return llvm::ConstantExpr::getNSWAdd(src, adj);
742 if (UseARMMethodPtrABI) {
743 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
745 adj = llvm::ConstantInt::get(adj->getType(), offset);
748 llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
749 llvm::Constant *dstAdj;
751 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
753 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
755 return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
763 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
765 llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
766 llvm::Constant *Values[2] = { Zero, Zero };
767 return llvm::ConstantStruct::getAnon(Values);
776 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
780 ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
784 llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
786 assert(MD->
isInstance() &&
"Member function must not be static!");
792 llvm::Constant *MemPtr[2];
793 if (MD->isVirtual()) {
794 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
799 uint64_t VTableOffset = (Index * PointerWidth.
getQuantity());
801 if (UseARMMethodPtrABI) {
808 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
809 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
816 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
817 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
832 llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
834 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
835 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
836 (UseARMMethodPtrABI ? 2 : 1) *
840 return llvm::ConstantStruct::getAnon(MemPtr);
843 llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
848 return EmitNullMemberPointer(MPT);
850 CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
853 return BuildMemberPointer(MD, ThisAdjustment);
856 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
857 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
872 llvm::ICmpInst::Predicate Eq;
873 llvm::Instruction::BinaryOps
And, Or;
875 Eq = llvm::ICmpInst::ICMP_NE;
876 And = llvm::Instruction::Or;
879 Eq = llvm::ICmpInst::ICMP_EQ;
881 Or = llvm::Instruction::Or;
887 return Builder.CreateICmp(Eq, L, R);
899 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
900 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
904 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
909 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
910 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero,
"cmp.ptr.null");
914 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
915 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
916 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
920 if (UseARMMethodPtrABI) {
921 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
924 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
925 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
926 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
928 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
933 Result = Builder.CreateBinOp(And, PtrEq, Result,
934 Inequality ?
"memptr.ne" :
"memptr.eq");
946 assert(MemPtr->getType() == CGM.PtrDiffTy);
948 llvm::Constant::getAllOnesValue(MemPtr->getType());
949 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
953 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
955 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
956 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
960 if (UseARMMethodPtrABI) {
961 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
962 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
963 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
964 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
966 Result = Builder.CreateOr(Result, IsVirtual);
981 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1002 if (UseGlobalDelete) {
1014 VTable, -2,
"complete-offset.ptr");
1021 CompletePtr = CGF.
Builder.CreateInBoundsGEP(CompletePtr, Offset);
1032 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
1034 if (UseGlobalDelete)
1038 void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1041 llvm::FunctionType *FTy =
1042 llvm::FunctionType::get(CGM.VoidTy,
false);
1044 llvm::Constant *Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1055 llvm::FunctionType *FTy =
1066 llvm::FunctionType *FTy =
1067 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1076 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1080 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1082 CharUnits ExnAlign = getAlignmentOfExnObject();
1086 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1091 llvm::Constant *Dtor =
nullptr;
1093 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
1097 Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy);
1100 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1102 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
1116 llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
1118 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1121 llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
1122 llvm::Attribute::ReadOnly };
1123 llvm::AttributeSet Attrs = llvm::AttributeSet::get(
1124 CGF.
getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs);
1131 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1148 unsigned NumPublicPaths = 0;
1161 if (PathElement.Base->isVirtual())
1164 if (NumPublicPaths > 1)
1170 PathElement.Base->getType()->getAsCXXRecordDecl());
1175 if (NumPublicPaths == 0)
1179 if (NumPublicPaths > 1)
1189 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1194 bool ItaniumCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
1202 CGF.
Builder.CreateUnreachable();
1212 CGF.
GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo(), ClassDecl);
1215 Value = CGF.
Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
1219 bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1254 llvm::BasicBlock *BadCastBlock =
1258 CGF.
Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1261 EmitBadCastCall(CGF);
1283 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
1291 Value = CGF.
Builder.CreateInBoundsGEP(Value, OffsetToTop);
1299 CGF.
Builder.CreateUnreachable();
1310 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1315 "vbase.offset.ptr");
1317 CGM.PtrDiffTy->getPointerTo());
1328 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1352 ArgTys.insert(ArgTys.begin() + 1,
1376 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1379 if (NeedsVTTParameter(CGF.
CurGD)) {
1387 Params.insert(Params.begin() + 1, VTTDecl);
1388 getStructorImplicitParamDecl(CGF) = VTTDecl;
1392 void ItaniumCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1397 if (getStructorImplicitParamDecl(CGF)) {
1410 if (HasThisReturn(CGF.
CurGD))
1414 unsigned ItaniumCXXABI::addImplicitConstructorArgs(
1416 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1423 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1424 Args.insert(Args.begin() + 1,
1432 bool Delegating,
Address This) {
1435 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1438 if (getContext().getLangOpts().AppleKext)
1450 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1451 if (VTable->hasInitializer())
1456 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
1457 llvm::Constant *RTTI =
1458 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1464 VTable->setInitializer(Init);
1467 VTable->setLinkage(Linkage);
1469 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1470 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1473 CGM.setGlobalVisibility(VTable, RD);
1478 unsigned PAlign = CGM.getTarget().getPointerAlign(0);
1479 VTable->setAlignment(getContext().toCharUnitsFromBits(PAlign).getQuantity());
1487 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1490 EmitFundamentalRTTIDescriptors();
1492 if (!VTable->isDeclarationForLinker())
1493 CGM.EmitVTableTypeMetadata(VTable, VTLayout);
1496 bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1500 return NeedsVTTParameter(CGF.
CurGD);
1503 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1508 NeedsVTTParameter(CGF.
CurGD)) {
1509 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
1512 return getVTableAddressPoint(Base, VTableClass);
1518 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
1521 uint64_t AddressPoint = CGM.getItaniumVTableContext()
1522 .getVTableLayout(VTableClass)
1523 .getAddressPoint(Base);
1525 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1526 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint)
1529 return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable->getValueType(),
1533 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1537 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
1540 uint64_t VirtualPointerIndex =
1541 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
1545 if (VirtualPointerIndex)
1546 VTT = CGF.
Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
1552 llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
1554 return getVTableAddressPoint(Base, VTableClass);
1557 llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1559 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1561 llvm::GlobalVariable *&VTable = VTables[RD];
1566 CGM.addDeferredVTable(RD);
1569 llvm::raw_svector_ostream Out(Name);
1570 getMangleContext().mangleCXXVTable(RD, Out);
1573 llvm::ArrayType *
ArrayType = llvm::ArrayType::get(
1576 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1578 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1580 if (RD->hasAttr<DLLImportAttr>())
1581 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1582 else if (RD->hasAttr<DLLExportAttr>())
1583 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1594 Ty = Ty->getPointerTo()->getPointerTo();
1595 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1598 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
1601 MethodDecl->getParent(), VTable,
1602 VTableIndex * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1607 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex,
"vfn");
1612 llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
1618 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1622 getVirtualFunctionPointer(CGF,
GlobalDecl(Dtor, DtorType), This, Ty,
1631 void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1637 bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
1640 if (CGM.getLangOpts().AppleKext)
1647 return !hasAnyUsedVirtualInlineFunction(RD) && !isVTableHidden(RD);
1651 int64_t NonVirtualAdjustment,
1652 int64_t VirtualAdjustment,
1653 bool IsReturnAdjustment) {
1654 if (!NonVirtualAdjustment && !VirtualAdjustment)
1660 if (NonVirtualAdjustment && !IsReturnAdjustment) {
1667 if (VirtualAdjustment) {
1675 CGF.
Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
1691 if (NonVirtualAdjustment && IsReturnAdjustment) {
1692 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(ResultPtr,
1693 NonVirtualAdjustment);
1702 const ThisAdjustment &TA) {
1710 const ReturnAdjustment &RA) {
1719 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
1724 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
1733 CGM.getContext().getTypeAlignInChars(elementType));
1741 assert(requiresArrayCookie(expr));
1751 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
1755 CharUnits CookieOffset = CookieSize - SizeSize;
1756 if (!CookieOffset.
isZero())
1765 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
1768 CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
1769 llvm::FunctionType *FTy =
1770 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
1772 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
1785 Address numElementsPtr = allocPtr;
1787 if (!numElementsOffset.
isZero())
1793 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
1800 llvm::FunctionType *FTy =
1801 llvm::FunctionType::get(CGF.
SizeTy, CGF.
SizeTy->getPointerTo(0),
false);
1803 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
1817 CGM.getContext().getTypeAlignInChars(elementType));
1825 assert(requiresArrayCookie(expr));
1833 getContext().getTypeSizeInChars(elementType).getQuantity());
1842 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
1861 llvm::PointerType *GuardPtrTy) {
1863 llvm::FunctionType *FTy =
1868 llvm::AttributeSet::FunctionIndex,
1869 llvm::Attribute::NoUnwind));
1873 llvm::PointerType *GuardPtrTy) {
1875 llvm::FunctionType *FTy =
1876 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
1879 llvm::AttributeSet::FunctionIndex,
1880 llvm::Attribute::NoUnwind));
1884 llvm::PointerType *GuardPtrTy) {
1886 llvm::FunctionType *FTy =
1887 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
1890 llvm::AttributeSet::FunctionIndex,
1891 llvm::Attribute::NoUnwind));
1896 llvm::GlobalVariable *Guard;
1897 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
1910 llvm::GlobalVariable *var,
1911 bool shouldPerformInit) {
1916 bool NonTemplateInline =
1923 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
1929 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
1931 llvm::IntegerType *guardTy;
1933 if (useInt8GuardVariable) {
1939 if (UseARMGuardVarABI) {
1945 CGM.getDataLayout().getABITypeAlignment(guardTy));
1948 llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
1952 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
1957 llvm::raw_svector_ostream out(guardName);
1958 getMangleContext().mangleStaticGuardVariable(&D, out);
1963 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
1964 false, var->getLinkage(),
1965 llvm::ConstantInt::get(guardTy, 0),
1967 guard->setVisibility(var->getVisibility());
1969 guard->setThreadLocalMode(var->getThreadLocalMode());
1970 guard->setAlignment(guardAlignment.
getQuantity());
1975 llvm::Comdat *
C = var->getComdat();
1977 CGM.getTarget().getTriple().isOSBinFormatELF()) {
1978 guard->setComdat(C);
1982 if (!NonTemplateInline)
1983 CGF.
CurFn->setComdat(C);
1984 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
1985 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
1988 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2011 llvm::LoadInst *LI =
2021 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2044 (UseARMGuardVarABI && !useInt8GuardVariable)
2045 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2047 llvm::Value *isInitialized = Builder.CreateIsNull(V,
"guard.uninitialized");
2053 Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
2065 Builder.CreateCondBr(Builder.CreateIsNotNull(V,
"tobool"),
2066 InitBlock, EndBlock);
2085 Builder.
CreateStore(llvm::ConstantInt::get(guardTy, 1), guardAddr);
2093 llvm::Constant *dtor,
2094 llvm::Constant *addr,
2096 const char *Name =
"__cxa_atexit";
2099 Name = T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2106 llvm::FunctionType::get(CGF.
VoidTy, CGF.
Int8PtrTy,
false)->getPointerTo();
2110 llvm::FunctionType *atexitTy =
2111 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2115 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
2116 fn->setDoesNotThrow();
2119 llvm::Constant *handle =
2123 llvm::ConstantExpr::getBitCast(dtor, dtorTy),
2124 llvm::ConstantExpr::getBitCast(addr, CGF.
Int8PtrTy),
2133 llvm::Constant *dtor,
2134 llvm::Constant *addr) {
2136 if (CGM.getCodeGenOpts().CXAAtExit)
2140 CGM.ErrorUnsupported(&D,
"non-trivial TLS destruction");
2144 if (CGM.getLangOpts().AppleKext) {
2146 return CGM.AddCXXDtorEntry(dtor, addr);
2154 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
2164 static llvm::GlobalValue::LinkageTypes
2166 llvm::GlobalValue::LinkageTypes VarLinkage =
2170 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
2175 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
2176 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
2178 return llvm::GlobalValue::WeakODRLinkage;
2182 ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
2187 llvm::raw_svector_ostream Out(WrapperName);
2188 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
2193 if (
llvm::Value *V = CGM.getModule().getNamedValue(WrapperName))
2194 return cast<llvm::Function>(V);
2200 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
2203 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
2204 llvm::Function *Wrapper =
2206 WrapperName.str(), &CGM.getModule());
2208 CGM.SetLLVMFunctionAttributes(
nullptr, FI, Wrapper);
2211 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, Wrapper);
2215 !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) &&
2216 !llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage())))
2220 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2221 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
2226 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2230 llvm::Function *InitFunc =
nullptr;
2231 if (!CXXThreadLocalInits.empty()) {
2233 llvm::FunctionType *FTy =
2234 llvm::FunctionType::get(CGM.
VoidTy,
false);
2239 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
2242 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
2243 Guard->setThreadLocal(
true);
2253 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2254 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
2257 for (
const VarDecl *VD : CXXThreadLocals) {
2258 llvm::GlobalVariable *Var =
2270 llvm::raw_svector_ostream Out(InitFnName);
2271 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
2277 llvm::GlobalValue *Init =
nullptr;
2278 bool InitIsInitFunc =
false;
2280 InitIsInitFunc =
true;
2289 llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2291 FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(),
2298 Init->setVisibility(Var->getVisibility());
2300 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
2301 llvm::LLVMContext &Context = CGM.
getModule().getContext();
2304 if (InitIsInitFunc) {
2306 llvm::CallInst *CallVal = Builder.CreateCall(Init);
2308 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2312 llvm::Value *Have = Builder.CreateIsNotNull(Init);
2315 Builder.CreateCondBr(Have, InitBB, ExitBB);
2317 Builder.SetInsertPoint(InitBB);
2318 Builder.CreateCall(Init);
2319 Builder.CreateBr(ExitBB);
2321 Builder.SetInsertPoint(ExitBB);
2331 if (Val->getType() != Wrapper->getReturnType())
2333 Val, Wrapper->getReturnType(),
"");
2334 Builder.CreateRet(Val);
2342 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
2344 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
2346 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2360 bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
2379 class ItaniumRTTIBuilder {
2381 llvm::LLVMContext &VMContext;
2382 const ItaniumCXXABI &
CXXABI;
2388 llvm::GlobalVariable *
2389 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
2393 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
2396 void BuildVTablePointer(
const Type *Ty);
2409 void BuildPointerTypeInfo(
QualType PointeeTy);
2420 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
2421 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
2435 PTI_Incomplete = 0x8,
2439 PTI_ContainingClassIncomplete = 0x10
2445 VMI_NonDiamondRepeat = 0x1,
2448 VMI_DiamondShaped = 0x2
2463 llvm::Constant *BuildTypeInfo(
QualType Ty,
bool Force =
false);
2467 llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
2468 QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) {
2470 llvm::raw_svector_ostream Out(Name);
2476 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
2479 llvm::GlobalVariable *GV =
2482 GV->setInitializer(Init);
2488 ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
2491 llvm::raw_svector_ostream Out(Name);
2495 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
2503 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2504 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2505 if (RD->hasAttr<DLLImportAttr>())
2506 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
2510 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
2531 case BuiltinType::Void:
2532 case BuiltinType::NullPtr:
2533 case BuiltinType::Bool:
2534 case BuiltinType::WChar_S:
2535 case BuiltinType::WChar_U:
2536 case BuiltinType::Char_U:
2537 case BuiltinType::Char_S:
2538 case BuiltinType::UChar:
2539 case BuiltinType::SChar:
2540 case BuiltinType::Short:
2541 case BuiltinType::UShort:
2542 case BuiltinType::Int:
2543 case BuiltinType::UInt:
2544 case BuiltinType::Long:
2545 case BuiltinType::ULong:
2546 case BuiltinType::LongLong:
2547 case BuiltinType::ULongLong:
2548 case BuiltinType::Half:
2549 case BuiltinType::Float:
2550 case BuiltinType::Double:
2551 case BuiltinType::LongDouble:
2552 case BuiltinType::Float128:
2553 case BuiltinType::Char16:
2554 case BuiltinType::Char32:
2555 case BuiltinType::Int128:
2556 case BuiltinType::UInt128:
2559 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2560 case BuiltinType::Id:
2561 #include "clang/Basic/OpenCLImageTypes.def"
2562 case BuiltinType::OCLSampler:
2563 case BuiltinType::OCLEvent:
2564 case BuiltinType::OCLClkEvent:
2565 case BuiltinType::OCLQueue:
2566 case BuiltinType::OCLNDRange:
2567 case BuiltinType::OCLReserveID:
2570 case BuiltinType::Dependent:
2571 #define BUILTIN_TYPE(Id, SingletonId)
2572 #define PLACEHOLDER_TYPE(Id, SingletonId) \
2573 case BuiltinType::Id:
2574 #include "clang/AST/BuiltinTypes.def"
2575 llvm_unreachable(
"asking for RRTI for a placeholder type!");
2577 case BuiltinType::ObjCId:
2578 case BuiltinType::ObjCClass:
2579 case BuiltinType::ObjCSel:
2580 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
2583 llvm_unreachable(
"Invalid BuiltinType Kind!");
2606 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
2611 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2629 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2630 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2641 bool IsDLLImport = RD->hasAttr<DLLImportAttr>();
2643 return IsDLLImport ?
false :
true;
2669 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2674 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2678 dyn_cast<MemberPointerType>(Ty)) {
2680 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
2719 void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
2721 static const char *
const ClassTypeInfo =
2722 "_ZTVN10__cxxabiv117__class_type_infoE";
2724 static const char *
const SIClassTypeInfo =
2725 "_ZTVN10__cxxabiv120__si_class_type_infoE";
2727 static const char *
const VMIClassTypeInfo =
2728 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
2730 const char *VTableName =
nullptr;
2733 #define TYPE(Class, Base)
2734 #define ABSTRACT_TYPE(Class, Base)
2735 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
2736 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
2737 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
2738 #include "clang/AST/TypeNodes.def"
2739 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
2741 case Type::LValueReference:
2742 case Type::RValueReference:
2743 llvm_unreachable(
"References shouldn't get here");
2746 llvm_unreachable(
"Undeduced auto type shouldn't get here");
2749 llvm_unreachable(
"Pipe types shouldn't get here");
2754 case Type::ExtVector:
2758 case Type::BlockPointer:
2760 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
2763 case Type::ConstantArray:
2764 case Type::IncompleteArray:
2765 case Type::VariableArray:
2767 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
2770 case Type::FunctionNoProto:
2771 case Type::FunctionProto:
2773 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
2778 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
2781 case Type::Record: {
2783 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
2786 VTableName = ClassTypeInfo;
2788 VTableName = SIClassTypeInfo;
2790 VTableName = VMIClassTypeInfo;
2796 case Type::ObjCObject:
2798 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
2801 if (isa<BuiltinType>(Ty)) {
2802 VTableName = ClassTypeInfo;
2806 assert(isa<ObjCInterfaceType>(Ty));
2809 case Type::ObjCInterface:
2810 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
2811 VTableName = SIClassTypeInfo;
2813 VTableName = ClassTypeInfo;
2817 case Type::ObjCObjectPointer:
2820 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
2823 case Type::MemberPointer:
2825 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
2829 llvm::Constant *VTable =
2836 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
2838 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8PtrTy, VTable, Two);
2839 VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.
Int8PtrTy);
2841 Fields.push_back(VTable);
2871 return llvm::GlobalValue::LinkOnceODRLinkage;
2874 if (
const RecordType *Record = dyn_cast<RecordType>(Ty)) {
2875 const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
2876 if (RD->hasAttr<WeakAttr>())
2877 return llvm::GlobalValue::WeakODRLinkage;
2882 if (RD->hasAttr<DLLImportAttr>() &&
2883 llvm::GlobalValue::isAvailableExternallyLinkage(LT))
2884 LT = llvm::GlobalValue::LinkOnceODRLinkage;
2889 return llvm::GlobalValue::LinkOnceODRLinkage;
2892 llvm_unreachable(
"Invalid linkage!");
2895 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty,
bool Force) {
2901 llvm::raw_svector_ostream Out(Name);
2904 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
2905 if (OldGV && !OldGV->isDeclaration()) {
2906 assert(!OldGV->hasAvailableExternallyLinkage() &&
2907 "available_externally typeinfos not yet implemented");
2909 return llvm::ConstantExpr::getBitCast(OldGV, CGM.
Int8PtrTy);
2915 return GetAddrOfExternalRTTIDescriptor(Ty);
2918 llvm::GlobalVariable::LinkageTypes
Linkage;
2925 BuildVTablePointer(cast<Type>(Ty));
2928 llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
2929 llvm::Constant *TypeNameField;
2933 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
2934 CXXABI.classifyRTTIUniqueness(Ty, Linkage);
2935 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
2938 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
2939 llvm::Constant *flag =
2940 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
2941 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
2943 llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.
Int8PtrTy);
2945 TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.
Int8PtrTy);
2947 Fields.push_back(TypeNameField);
2950 #define TYPE(Class, Base)
2951 #define ABSTRACT_TYPE(Class, Base)
2952 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
2953 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
2954 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
2955 #include "clang/AST/TypeNodes.def"
2956 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
2961 case Type::ExtVector:
2963 case Type::BlockPointer:
2968 case Type::LValueReference:
2969 case Type::RValueReference:
2970 llvm_unreachable(
"References shouldn't get here");
2973 llvm_unreachable(
"Undeduced auto type shouldn't get here");
2976 llvm_unreachable(
"Pipe type shouldn't get here");
2978 case Type::ConstantArray:
2979 case Type::IncompleteArray:
2980 case Type::VariableArray:
2985 case Type::FunctionNoProto:
2986 case Type::FunctionProto:
2996 case Type::Record: {
2998 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3005 BuildSIClassTypeInfo(RD);
3007 BuildVMIClassTypeInfo(RD);
3012 case Type::ObjCObject:
3013 case Type::ObjCInterface:
3014 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
3017 case Type::ObjCObjectPointer:
3018 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
3022 BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
3025 case Type::MemberPointer:
3026 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
3034 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
3037 llvm::GlobalVariable *GV =
3038 new llvm::GlobalVariable(M, Init->getType(),
3043 GV->takeName(OldGV);
3044 llvm::Constant *NewPtr =
3045 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
3046 OldGV->replaceAllUsesWith(NewPtr);
3047 OldGV->eraseFromParent();
3051 GV->setComdat(M.getOrInsertComdat(GV->getName()));
3070 llvm::GlobalValue::VisibilityTypes llvmVisibility;
3071 if (llvm::GlobalValue::isLocalLinkage(Linkage))
3074 else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden)
3078 TypeName->setVisibility(llvmVisibility);
3079 GV->setVisibility(llvmVisibility);
3081 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3090 Flags |= ItaniumRTTIBuilder::PTI_Const;
3092 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
3094 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
3101 void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
3104 assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
3108 if (isa<BuiltinType>(T))
return;
3119 llvm::Constant *BaseTypeInfo =
3120 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
3121 Fields.push_back(BaseTypeInfo);
3126 void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
3130 llvm::Constant *BaseTypeInfo =
3132 Fields.push_back(BaseTypeInfo);
3139 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
3140 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
3157 if (!Bases.VirtualBases.insert(BaseDecl).second) {
3160 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
3162 if (Bases.NonVirtualBases.count(BaseDecl))
3163 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3167 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
3170 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3172 if (Bases.VirtualBases.count(BaseDecl))
3173 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3178 for (
const auto &
I : BaseDecl->
bases())
3189 for (
const auto &
I : RD->
bases())
3198 void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
3207 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3212 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
3237 for (
const auto &Base : RD->
bases()) {
3239 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(Base.getType()));
3242 cast<CXXRecordDecl>(Base.getType()->getAs<
RecordType>()->getDecl());
3244 int64_t OffsetFlags = 0;
3251 if (Base.isVirtual())
3259 OffsetFlags = uint64_t(Offset.
getQuantity()) << 8;
3263 if (Base.isVirtual())
3264 OffsetFlags |= BCTI_Virtual;
3265 if (Base.getAccessSpecifier() ==
AS_public)
3266 OffsetFlags |= BCTI_Public;
3268 Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
3274 void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
3288 Flags |= PTI_Incomplete;
3292 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3297 llvm::Constant *PointeeTypeInfo =
3298 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
3299 Fields.push_back(PointeeTypeInfo);
3323 Flags |= PTI_Incomplete;
3326 Flags |= PTI_ContainingClassIncomplete;
3330 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3335 llvm::Constant *PointeeTypeInfo =
3336 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
3337 Fields.push_back(PointeeTypeInfo);
3344 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
3347 llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
3348 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
3351 void ItaniumCXXABI::EmitFundamentalRTTIDescriptor(
QualType Type) {
3354 ItaniumRTTIBuilder(*this).BuildTypeInfo(Type,
true);
3355 ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType,
true);
3356 ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst,
true);
3359 void ItaniumCXXABI::EmitFundamentalRTTIDescriptors() {
3362 getContext().VoidTy, getContext().NullPtrTy,
3363 getContext().BoolTy, getContext().WCharTy,
3364 getContext().CharTy, getContext().UnsignedCharTy,
3365 getContext().SignedCharTy, getContext().ShortTy,
3366 getContext().UnsignedShortTy, getContext().IntTy,
3367 getContext().UnsignedIntTy, getContext().LongTy,
3368 getContext().UnsignedLongTy, getContext().LongLongTy,
3369 getContext().UnsignedLongLongTy, getContext().Int128Ty,
3370 getContext().UnsignedInt128Ty, getContext().HalfTy,
3371 getContext().FloatTy, getContext().DoubleTy,
3372 getContext().LongDoubleTy, getContext().Float128Ty,
3373 getContext().Char16Ty, getContext().Char32Ty
3375 for (
const QualType &FundamentalType : FundamentalTypes)
3376 EmitFundamentalRTTIDescriptor(FundamentalType);
3381 ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
3382 QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage)
const {
3383 if (shouldRTTIBeUnique())
3387 if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
3388 Linkage != llvm::GlobalValue::WeakODRLinkage)
3396 if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3397 return RUK_NonUniqueHidden;
3402 assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
3403 return RUK_NonUniqueVisible;
3413 return StructorCodegen::Emit;
3418 return StructorCodegen::Emit;
3421 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
3424 const auto *CD = cast<CXXConstructorDecl>(MD);
3429 if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
3430 return StructorCodegen::RAUW;
3433 if (!llvm::GlobalAlias::isValidLinkage(Linkage))
3434 return StructorCodegen::RAUW;
3436 if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
3439 return StructorCodegen::COMDAT;
3440 return StructorCodegen::Emit;
3443 return StructorCodegen::Alias;
3453 if (Entry && !Entry->isDeclaration())
3456 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
3463 assert(Entry->getType() == Aliasee->getType() &&
3464 "declaration exists with different type");
3465 Alias->takeName(Entry);
3466 Entry->replaceAllUsesWith(Alias);
3467 Entry->eraseFromParent();
3469 Alias->setName(MangledName);
3476 void ItaniumCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3494 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
3499 if (CGType == StructorCodegen::RAUW) {
3517 if (CGType == StructorCodegen::COMDAT) {
3519 llvm::raw_svector_ostream Out(Buffer);
3521 getMangleContext().mangleCXXDtorComdat(DD, Out);
3523 getMangleContext().mangleCXXCtorComdat(CD, Out);
3524 llvm::Comdat *C = CGM.
getModule().getOrInsertComdat(Out.str());
3533 llvm::FunctionType *FTy = llvm::FunctionType::get(
3541 llvm::FunctionType *FTy =
3542 llvm::FunctionType::get(CGM.
VoidTy,
false);
3549 llvm::FunctionType *FTy = llvm::FunctionType::get(
3569 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
3589 bool EndMightThrow) {
3590 llvm::CallInst *call =
3613 if (isa<ReferenceType>(CatchType)) {
3614 QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
3623 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
3632 unsigned HeaderSize =
3634 AdjustedExn = CGF.
Builder.CreateConstGEP1_32(Exn, HeaderSize);
3653 cast<llvm::PointerType>(LLVMCatchTy)->getElementType();
3679 if (CatchType->hasPointerRepresentation()) {
3698 llvm_unreachable(
"bad ownership qualifier!");
3703 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
3719 llvm_unreachable(
"evaluation kind filtered out!");
3721 llvm_unreachable(
"bad evaluation kind");
3724 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
3725 auto catchRD = CatchType->getAsCXXRecordDecl();
3728 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
3736 caughtExnAlignment);
3743 llvm::CallInst *rawAdjustedExn =
3748 caughtExnAlignment);
3820 llvm::FunctionType *fnTy =
3822 llvm::Constant *fnRef =
3825 llvm::Function *fn = dyn_cast<llvm::Function>(fnRef);
3826 if (fn && fn->empty()) {
3827 fn->setDoesNotThrow();
3828 fn->setDoesNotReturn();
3833 fn->addFnAttr(llvm::Attribute::NoInline);
3837 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
3840 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
3843 llvm::BasicBlock *entry =
3851 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
3852 catchCall->setDoesNotThrow();
3856 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
3857 termCall->setDoesNotThrow();
3858 termCall->setDoesNotReturn();
3862 builder.CreateUnreachable();
3869 ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
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...
CastKind getCastKind() const
void EmitVTTDefinition(llvm::GlobalVariable *VTT, llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD)
EmitVTTDefinition - Emit the definition of the given vtable.
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
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, Address Guard=Address::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
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.
PointerType - C99 6.7.5.1 - Pointer Declarators.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
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...
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
static llvm::Constant * getAllocateExceptionFn(CodeGenModule &CGM)
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
bool isReplaceableGlobalAllocationFunction() const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
CanQualType getReturnType() const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
QualType getType() const
Retrieves the type of the base class.
CXXCtorType getCtorType() const
llvm::Module & getModule() const
llvm::LLVMContext & getLLVMContext()
The COMDAT used for ctors.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const TargetInfo & getTarget() const
bool isGlobalDelete() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateTempAlloca - This creates a alloca and inserts it into the entry block.
No linkage, which means that the entity is unique and can only be referred to from within its scope...
C Language Family Type Representation.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isRecordType() const
void setAliasAttributes(const Decl *D, llvm::GlobalValue *GV)
Set attributes which must be preserved by an alias.
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
llvm::CallingConv::ID getRuntimeCC() const
vtable_component_iterator vtable_component_begin() const
bool hasDefinition() const
QualType getPointeeType() const
The base class of the type hierarchy.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
std::unique_ptr< llvm::MemoryBuffer > Buffer
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const Expr * getInit() const
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i...
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.
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.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Objects with "hidden" visibility are not seen by the dynamic linker.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
TLSKind getTLSKind() const
ObjCLifetime getObjCLifetime() const
SourceLocation getLocStart() const LLVM_READONLY
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.
Visibility getVisibility() const
Determines the visibility of this entity.
A C++ throw-expression (C++ [except.throw]).
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
The collection of all-type qualifiers we support.
GlobalDecl getCanonicalDecl() const
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 isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
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
bool hasNonTrivialCopyConstructor() const
Determine whether this class has a non-trivial copy constructor (C++ [class.copy]p6, C++11 [class.copy]p12)
bool isReferenceType() const
The generic Mips ABI is a modified version of the Itanium ABI.
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
uint64_t getNumVTableComponents() const
llvm::IntegerType * SizeTy
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
StructorType getFromDtorType(CXXDtorType T)
CXXMethodDecl * getCanonicalDecl() override
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
bool isTranslationUnit() const
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
llvm::Function * codegenCXXStructor(const CXXMethodDecl *MD, StructorType Type)
const Decl * getDecl() const
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...
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
const TargetInfo & getTargetInfo() const
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
const LangOptions & getLangOpts() const
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...
QualType getBaseType() const
Gets the base type of this object type.
The Microsoft ABI is the ABI used by Microsoft Visual Studio (and compatible compilers).
const ValueDecl * getMemberPointerDecl() const
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
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].
RecordDecl * getDecl() 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.
llvm::Constant * getTerminateFn()
Get the declaration of std::terminate for the platform.
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, bool IsForDefinition=false)
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
TypeClass getTypeClass() const
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.
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
Represents an ObjC class declaration.
detail::InMemoryDirectory::const_iterator I
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
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
This object can be modified without requiring retains or releases.
bool isDefined(const FunctionDecl *&Definition) const
isDefined - Returns true if the function is defined at all, including a deleted definition.
CharUnits getSizeSize() const
bool isAbstract() const
Determine whether this class has a pure virtual function.
struct clang::ReturnAdjustment::VirtualAdjustment::@110 Itanium
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource AlignSource=AlignmentSource::Type)
FunctionDecl * getOperatorDelete() const
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.
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="")
const TargetCodeGenInfo & getTargetCodeGenInfo()
const TargetInfo & getTarget() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
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...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
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)
hasAggregateLLVMType - Return true if the specified AST type will map into an aggregate LLVM type or ...
void SetLLVMFunctionAttributes(const Decl *D, const CGFunctionInfo &Info, llvm::Function *F)
Set the LLVM function attributes (sext, zext, etc).
CXXDtorType
C++ destructor types.
llvm::Value * getPointer() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
CXXDtorType getDtorType() const
Qualifiers getQualifiers() const
Retrieve all qualifiers.
static llvm::Constant * getBadTypeidFn(CodeGenFunction &CGF)
CGCXXABI & getCXXABI() const
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource AlignSource=AlignmentSource::Type, llvm::MDNode *TBAAInfo=nullptr, bool isInit=false, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
RValue EmitCXXMemberOrOperatorCall(const CXXMethodDecl *MD, llvm::Value *Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E)
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
Represents a C++ destructor within a class.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
ASTContext & getContext() const
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
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.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
llvm::LLVMContext & getLLVMContext()
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
static llvm::Constant * getGetExceptionPtrFn(CodeGenModule &CGM)
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant)
Returns LLVM linkage for a declarator.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD)
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
Implements C++ ABI-specific semantic analysis functions.
CharUnits getSizeAlign() const
unsigned getNumBases() const
Retrieves the number of base classes of this class.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
The result type of a method or function.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
forAddr - Make a slot for an aggregate value.
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
The COMDAT used for dtors.
GlobalDecl - represents a global declaration.
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage)
Will return a global variable of the given type.
WatchOS is a modernisation of the iOS ABI, which roughly means it's the iOS64 ABI ported to 32-bits...
The l-value was considered opaque, so the alignment was determined from a type.
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="")
uint64_t getNumVTableThunks() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs=llvm::AttributeSet())
Create a new runtime function with the specified type and name.
Assigning into this object requires the old value to be released and the new value to be retained...
virtual void mangleCXXRTTIName(QualType T, raw_ostream &)=0
ASTContext & getContext() const
Encodes a location in the source.
CharUnits getPointerAlign() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, bool IsForDefinition=false)
Return the llvm::Constant for the address of the given global variable.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Visibility getVisibility() const
Determine the visibility of this type.
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource AlignSource=AlignmentSource::Type, llvm::MDNode *TBAAInfo=nullptr, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Represents a call to a member function that may be written either with member call syntax (e...
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.
bool isLocalVarDecl() const
isLocalVarDecl - Returns true for local variable declarations other than parameters.
llvm::GlobalVariable * GetAddrOfVTT(const CXXRecordDecl *RD)
GetAddrOfVTT - Get the address of the VTT for the given record decl.
QualType withConst() const
Represents a static or instance method of a struct/union/class.
static llvm::Constant * getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
const CodeGenOptions & getCodeGenOpts() const
static unsigned ComputeQualifierFlags(Qualifiers Quals)
ComputeQualifierFlags - Compute the pointer type info flags from the given qualifier.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
const LangOptions & getLangOpts() const
The generic Itanium ABI is the standard ABI of most open-source and Unix-like platforms.
const T * castAs() const
Member-template castAs<specific type>.
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset. ...
MangleContext & getMangleContext()
Gets the mangle context.
const IdentifierInfo * getIdentifier() const
unsigned getAddressSpace() const
Return the address space that this address resides in.
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...
bool isDynamicClass() const
CXXCtorType
C++ constructor types.
The WebAssembly ABI is a modified version of the Itanium ABI.
QualType getPointeeType() const
void addReplacement(StringRef Name, llvm::Constant *C)
FunctionArgList - Type for representing both the decl and type of parameters to a function...
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
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.
CharUnits getAlignment() const
Return the alignment of this pointer.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
const Expr * getSubExpr() const
Address getObjectAddress(CodeGenFunction &CGF) const
Returns the address of the object within this declaration.
External linkage within a unique namespace.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
struct clang::ThisAdjustment::VirtualAdjustment::@112 Itanium
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
bool isZero() const
isZero - Test whether the quantity equals zero.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
void EmitAnyExprToExn(const Expr *E, Address Addr)
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
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.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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* ...
detail::InMemoryDirectory::const_iterator E
A pointer to member type per C++ 8.3.3 - Pointers to members.
void EmitAggregateCopy(Address DestPtr, Address SrcPtr, QualType EltTy, bool isVolatile=false, bool isAssignment=false)
EmitAggregateCopy - Emit an aggregate copy.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
union clang::ThisAdjustment::VirtualAdjustment Virtual
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type. ...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
vtable_thunk_iterator vtable_thunk_begin() const
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)
llvm::PointerType * getType() const
Return the type of the pointer value.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
FunctionDecl * getOperatorNew() const
const T * getAs() const
Member-template getAs<specific type>'.
QualType getCanonicalType() const
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
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.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
llvm::PointerType * Int8PtrTy
SourceLocation getLocStart() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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...
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
Linkage getLinkage() const
Determine the linkage of this type.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
const Type * getClass() const
Reading or writing from this object requires a barrier call.
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Represents a C++ struct/union/class.
CGCXXABI * CreateItaniumCXXABI(CodeGenModule &CGM)
Creates an Itanium-family ABI.
BoundNodesTreeBuilder *const Builder
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
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.
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)
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
bool isInline() const
Whether this variable is (C++1z) inline.
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...
llvm::Constant * CreateVTableInitializer(const CXXRecordDecl *RD, const VTableComponent *Components, unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks, unsigned NumVTableThunks, llvm::Constant *RTTI)
CreateVTableInitializer - Create a vtable initializer for the given record decl.
This class is used for builtin types like 'int'.
static llvm::Constant * getItaniumDynamicCastFn(CodeGenFunction &CGF)
Copying closure variant of a ctor.
ObjCInterfaceDecl * getSuperClass() const
static llvm::Constant * getEndCatchFn(CodeGenModule &CGM)
Struct with all informations 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.
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units. ...
VarDecl * getExceptionDecl() const
static RValue get(llvm::Value *V)
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...
CodeGenVTables & getVTables()
static void emitConstructorDestructorAlias(CodeGenModule &CGM, GlobalDecl AliasDecl, GlobalDecl TargetDecl)
LValue - This represents an lvalue references.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Information for lazily generating a cleanup.
static llvm::Constant * getBadCastFn(CodeGenFunction &CGF)
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
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.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
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.
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals...
bool supportsCOMDAT() const
CanQualType UnsignedIntTy
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
static llvm::Constant * getThrowFn(CodeGenModule &CGM)
llvm::Value * BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, const CXXRecordDecl *RD)
BuildVirtualCall - This routine makes indirect vtable call for call to virtual destructors.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.