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;
166 auto align = CGM.getContext().getTargetDefaultAlignForAttributeAligned();
167 return CGM.getContext().toCharUnitsFromBits(align);
180 void EmitFundamentalRTTIDescriptors();
181 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
183 getAddrOfCXXCatchHandlerType(
QualType Ty,
184 QualType CatchHandlerType)
override {
188 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
194 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
200 llvm::BasicBlock *CastEnd)
override;
241 bool Delegating,
Address This)
override;
249 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
261 llvm::Value *getVTableAddressPointInStructorWithVTT(
269 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
282 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
284 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
286 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
GlobalDecl GD,
290 if (ForVTable && !Thunk->hasLocalLinkage())
291 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
298 const ReturnAdjustment &RA)
override;
302 assert(!Args.empty() &&
"expected the arglist to not be empty!");
303 return Args.size() - 1;
306 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
307 StringRef GetDeletedVirtualCallName()
override
308 {
return "__cxa_deleted_virtual"; }
321 llvm::GlobalVariable *DeclPtr,
322 bool PerformInit)
override;
324 llvm::Constant *dtor, llvm::Constant *addr)
override;
326 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
328 void EmitThreadLocalInitFuncs(
334 bool usesThreadWrapperFunction()
const override {
return true; }
338 bool NeedsVTTParameter(
GlobalDecl GD)
override;
345 virtual bool shouldRTTIBeUnique()
const {
return true; }
349 enum RTTIUniquenessKind {
367 classifyRTTIUniqueness(
QualType CanTy,
368 llvm::GlobalValue::LinkageTypes
Linkage)
const;
369 friend class ItaniumRTTIBuilder;
374 bool hasAnyUsedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
375 const auto &VtableLayout =
376 CGM.getItaniumVTableContext().getVTableLayout(RD);
378 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
379 if (!VtableComponent.isUsedFunctionPointerKind())
382 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
390 const auto &VtableLayout =
391 CGM.getItaniumVTableContext().getVTableLayout(RD);
393 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
394 if (VtableComponent.isRTTIKind()) {
395 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
398 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
399 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
409 class ARMCXXABI :
public ItaniumCXXABI {
412 ItaniumCXXABI(CGM,
true,
415 bool HasThisReturn(
GlobalDecl GD)
const override {
416 return (isa<CXXConstructorDecl>(GD.
getDecl()) || (
417 isa<CXXDestructorDecl>(GD.
getDecl()) &&
434 class iOS64CXXABI :
public ARMCXXABI {
439 bool shouldRTTIBeUnique()
const override {
return false; }
442 class WebAssemblyCXXABI final :
public ItaniumCXXABI {
445 : ItaniumCXXABI(CGM,
true,
449 bool HasThisReturn(
GlobalDecl GD)
const override {
450 return isa<CXXConstructorDecl>(GD.
getDecl()) ||
451 (isa<CXXDestructorDecl>(GD.
getDecl()) &&
464 return new ARMCXXABI(CGM);
467 return new iOS64CXXABI(CGM);
473 return new ItaniumCXXABI(CGM,
true,
477 return new ItaniumCXXABI(CGM,
true);
480 return new WebAssemblyCXXABI(CGM);
484 == llvm::Triple::le32) {
488 return new ItaniumCXXABI(CGM,
true,
491 return new ItaniumCXXABI(CGM);
494 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
496 llvm_unreachable(
"bad ABI kind");
502 return CGM.PtrDiffTy;
503 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy,
nullptr);
526 llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
537 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
538 CGM.getTypes().arrangeCXXMethodType(RD, FPT,
nullptr));
540 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
547 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
551 if (UseARMMethodPtrABI)
552 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
558 Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
559 This = Builder.
CreateBitCast(Ptr, This->getType(),
"this.adjusted");
560 ThisPtrForCall = This;
563 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
568 if (UseARMMethodPtrABI)
569 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
571 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
572 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
573 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
581 llvm::Type *VTableTy = Builder.getInt8PtrTy();
590 if (!UseARMMethodPtrABI)
591 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
592 VTable = Builder.CreateGEP(VTable, VTableOffset);
595 VTable = Builder.
CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
605 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(),
"memptr.nonvirtualfn");
609 llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
610 Callee->addIncoming(VirtualFn, FnVirtual);
611 Callee->addIncoming(NonVirtualFn, FnNonVirtual);
617 llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
620 assert(MemPtr->getType() == CGM.PtrDiffTy);
625 Base = Builder.CreateElementBitCast(Base, CGF.
Int8Ty);
629 Builder.CreateInBoundsGEP(Base.
getPointer(), MemPtr,
"memptr.offset");
635 return Builder.CreateBitCast(Addr, PType);
673 if (isa<llvm::Constant>(src))
674 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
676 llvm::Constant *adj = getMemberPointerAdjustment(E);
677 if (!adj)
return src;
690 dst = Builder.CreateNSWSub(src, adj,
"adj");
692 dst = Builder.CreateNSWAdd(src, adj,
"adj");
695 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
696 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
697 return Builder.CreateSelect(isNull, src, dst);
701 if (UseARMMethodPtrABI) {
702 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
704 adj = llvm::ConstantInt::get(adj->getType(), offset);
707 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
710 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
712 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
714 return Builder.CreateInsertValue(src, dstAdj, 1);
718 ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
719 llvm::Constant *src) {
728 llvm::Constant *adj = getMemberPointerAdjustment(E);
729 if (!adj)
return src;
740 if (src->isAllOnesValue())
return src;
743 return llvm::ConstantExpr::getNSWSub(src, adj);
745 return llvm::ConstantExpr::getNSWAdd(src, adj);
749 if (UseARMMethodPtrABI) {
750 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
752 adj = llvm::ConstantInt::get(adj->getType(), offset);
755 llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
756 llvm::Constant *dstAdj;
758 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
760 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
762 return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
770 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
772 llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
773 llvm::Constant *Values[2] = { Zero, Zero };
774 return llvm::ConstantStruct::getAnon(Values);
783 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
787 ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
791 llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
793 assert(MD->
isInstance() &&
"Member function must not be static!");
799 llvm::Constant *MemPtr[2];
800 if (MD->isVirtual()) {
801 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
806 uint64_t VTableOffset = (Index * PointerWidth.
getQuantity());
808 if (UseARMMethodPtrABI) {
815 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
816 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
823 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
824 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
839 llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
841 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
842 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
843 (UseARMMethodPtrABI ? 2 : 1) *
847 return llvm::ConstantStruct::getAnon(MemPtr);
850 llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
855 return EmitNullMemberPointer(MPT);
857 CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
860 return BuildMemberPointer(MD, ThisAdjustment);
863 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
864 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
879 llvm::ICmpInst::Predicate Eq;
880 llvm::Instruction::BinaryOps
And, Or;
882 Eq = llvm::ICmpInst::ICMP_NE;
883 And = llvm::Instruction::Or;
886 Eq = llvm::ICmpInst::ICMP_EQ;
888 Or = llvm::Instruction::Or;
894 return Builder.CreateICmp(Eq, L, R);
906 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
907 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
911 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
916 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
917 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero,
"cmp.ptr.null");
921 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
922 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
923 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
927 if (UseARMMethodPtrABI) {
928 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
931 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
932 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
933 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
935 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
940 Result = Builder.CreateBinOp(And, PtrEq, Result,
941 Inequality ?
"memptr.ne" :
"memptr.eq");
953 assert(MemPtr->getType() == CGM.PtrDiffTy);
955 llvm::Constant::getAllOnesValue(MemPtr->getType());
956 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
960 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
962 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
963 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
967 if (UseARMMethodPtrABI) {
968 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
969 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
970 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
971 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
973 Result = Builder.CreateOr(Result, IsVirtual);
979 bool ItaniumCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
988 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1009 if (UseGlobalDelete) {
1021 VTable, -2,
"complete-offset.ptr");
1028 CompletePtr = CGF.
Builder.CreateInBoundsGEP(CompletePtr, Offset);
1039 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
1041 if (UseGlobalDelete)
1045 void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1048 llvm::FunctionType *FTy =
1049 llvm::FunctionType::get(CGM.VoidTy,
false);
1051 llvm::Constant *Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1062 llvm::FunctionType *FTy =
1073 llvm::FunctionType *FTy =
1074 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1083 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1087 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1089 CharUnits ExnAlign = getAlignmentOfExnObject();
1093 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1098 llvm::Constant *Dtor =
nullptr;
1100 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
1104 Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy);
1107 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1109 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
1123 llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
1125 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1128 llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
1129 llvm::Attribute::ReadOnly };
1130 llvm::AttributeSet Attrs = llvm::AttributeSet::get(
1131 CGF.
getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs);
1138 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1155 unsigned NumPublicPaths = 0;
1168 if (PathElement.Base->isVirtual())
1171 if (NumPublicPaths > 1)
1177 PathElement.Base->getType()->getAsCXXRecordDecl());
1182 if (NumPublicPaths == 0)
1186 if (NumPublicPaths > 1)
1196 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1201 bool ItaniumCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
1209 CGF.
Builder.CreateUnreachable();
1219 CGF.
GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo(), ClassDecl);
1222 Value = CGF.
Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
1226 bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1261 llvm::BasicBlock *BadCastBlock =
1265 CGF.
Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1268 EmitBadCastCall(CGF);
1290 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
1298 Value = CGF.
Builder.CreateInBoundsGEP(Value, OffsetToTop);
1306 CGF.
Builder.CreateUnreachable();
1317 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1322 "vbase.offset.ptr");
1324 CGM.PtrDiffTy->getPointerTo());
1335 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1359 ArgTys.insert(ArgTys.begin() + 1,
1383 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1386 if (NeedsVTTParameter(CGF.
CurGD)) {
1394 Params.insert(Params.begin() + 1, VTTDecl);
1395 getStructorImplicitParamDecl(CGF) = VTTDecl;
1399 void ItaniumCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1404 if (getStructorImplicitParamDecl(CGF)) {
1417 if (HasThisReturn(CGF.
CurGD))
1421 unsigned ItaniumCXXABI::addImplicitConstructorArgs(
1423 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1430 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1431 Args.insert(Args.begin() + 1,
1439 bool Delegating,
Address This) {
1442 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1445 if (getContext().getLangOpts().AppleKext)
1457 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1458 if (VTable->hasInitializer())
1463 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
1464 llvm::Constant *RTTI =
1465 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1471 VTable->setInitializer(Init);
1474 VTable->setLinkage(Linkage);
1476 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1477 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1480 CGM.setGlobalVisibility(VTable, RD);
1485 unsigned PAlign = CGM.getTarget().getPointerAlign(0);
1486 VTable->setAlignment(getContext().toCharUnitsFromBits(PAlign).getQuantity());
1494 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1497 EmitFundamentalRTTIDescriptors();
1499 CGM.EmitVTableBitSetEntries(VTable, VTLayout);
1502 bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1506 return NeedsVTTParameter(CGF.
CurGD);
1509 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1514 NeedsVTTParameter(CGF.
CurGD)) {
1515 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
1518 return getVTableAddressPoint(Base, VTableClass);
1524 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
1527 uint64_t AddressPoint = CGM.getItaniumVTableContext()
1528 .getVTableLayout(VTableClass)
1529 .getAddressPoint(Base);
1531 llvm::ConstantInt::get(CGM.Int64Ty, 0),
1532 llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint)
1535 return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable->getValueType(),
1539 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1543 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
1546 uint64_t VirtualPointerIndex =
1547 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
1551 if (VirtualPointerIndex)
1552 VTT = CGF.
Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
1558 llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
1560 return getVTableAddressPoint(Base, VTableClass);
1563 llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1565 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1567 llvm::GlobalVariable *&VTable = VTables[RD];
1572 CGM.addDeferredVTable(RD);
1575 llvm::raw_svector_ostream Out(Name);
1576 getMangleContext().mangleCXXVTable(RD, Out);
1579 llvm::ArrayType *
ArrayType = llvm::ArrayType::get(
1582 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1584 VTable->setUnnamedAddr(
true);
1586 if (RD->
hasAttr<DLLImportAttr>())
1587 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1588 else if (RD->
hasAttr<DLLExportAttr>())
1589 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1600 Ty = Ty->getPointerTo()->getPointerTo();
1601 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1604 if (CGF.
SanOpts.
has(SanitizerKind::CFIVCall))
1608 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
1610 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex,
"vfn");
1614 llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
1620 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1624 getVirtualFunctionPointer(CGF,
GlobalDecl(Dtor, DtorType), This, Ty,
1633 void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1639 bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
1642 if (CGM.getLangOpts().AppleKext)
1649 return !hasAnyUsedVirtualInlineFunction(RD) && !isVTableHidden(RD);
1653 int64_t NonVirtualAdjustment,
1654 int64_t VirtualAdjustment,
1655 bool IsReturnAdjustment) {
1656 if (!NonVirtualAdjustment && !VirtualAdjustment)
1662 if (NonVirtualAdjustment && !IsReturnAdjustment) {
1669 if (VirtualAdjustment) {
1677 CGF.
Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
1693 if (NonVirtualAdjustment && IsReturnAdjustment) {
1694 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(ResultPtr,
1695 NonVirtualAdjustment);
1704 const ThisAdjustment &TA) {
1712 const ReturnAdjustment &RA) {
1721 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
1726 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
1735 CGM.getContext().getTypeAlignInChars(elementType));
1743 assert(requiresArrayCookie(expr));
1753 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
1757 CharUnits CookieOffset = CookieSize - SizeSize;
1758 if (!CookieOffset.
isZero())
1767 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
1770 CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
1771 llvm::FunctionType *FTy =
1772 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
1774 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
1787 Address numElementsPtr = allocPtr;
1789 if (!numElementsOffset.
isZero())
1795 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
1802 llvm::FunctionType *FTy =
1803 llvm::FunctionType::get(CGF.
SizeTy, CGF.
SizeTy->getPointerTo(0),
false);
1805 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
1819 CGM.getContext().getTypeAlignInChars(elementType));
1827 assert(requiresArrayCookie(expr));
1835 getContext().getTypeSizeInChars(elementType).getQuantity());
1844 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
1863 llvm::PointerType *GuardPtrTy) {
1865 llvm::FunctionType *FTy =
1870 llvm::AttributeSet::FunctionIndex,
1871 llvm::Attribute::NoUnwind));
1875 llvm::PointerType *GuardPtrTy) {
1877 llvm::FunctionType *FTy =
1878 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
1881 llvm::AttributeSet::FunctionIndex,
1882 llvm::Attribute::NoUnwind));
1886 llvm::PointerType *GuardPtrTy) {
1888 llvm::FunctionType *FTy =
1889 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
1892 llvm::AttributeSet::FunctionIndex,
1893 llvm::Attribute::NoUnwind));
1898 llvm::GlobalVariable *Guard;
1899 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
1912 llvm::GlobalVariable *var,
1913 bool shouldPerformInit) {
1918 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
1923 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
1925 llvm::IntegerType *guardTy;
1927 if (useInt8GuardVariable) {
1933 if (UseARMGuardVarABI) {
1939 CGM.getDataLayout().getABITypeAlignment(guardTy));
1942 llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
1946 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
1951 llvm::raw_svector_ostream out(guardName);
1952 getMangleContext().mangleStaticGuardVariable(&D, out);
1957 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
1958 false, var->getLinkage(),
1959 llvm::ConstantInt::get(guardTy, 0),
1961 guard->setVisibility(var->getVisibility());
1963 guard->setThreadLocalMode(var->getThreadLocalMode());
1964 guard->setAlignment(guardAlignment.
getQuantity());
1969 llvm::Comdat *
C = var->getComdat();
1971 CGM.getTarget().getTriple().isOSBinFormatELF()) {
1972 guard->setComdat(C);
1973 CGF.
CurFn->setComdat(C);
1974 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
1975 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
1978 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2001 llvm::LoadInst *LI =
2011 LI->setAtomic(llvm::Acquire);
2034 (UseARMGuardVarABI && !useInt8GuardVariable)
2035 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2037 llvm::Value *isInitialized = Builder.CreateIsNull(V,
"guard.uninitialized");
2043 Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
2055 Builder.CreateCondBr(Builder.CreateIsNotNull(V,
"tobool"),
2056 InitBlock, EndBlock);
2075 Builder.
CreateStore(llvm::ConstantInt::get(guardTy, 1), guardAddr);
2083 llvm::Constant *dtor,
2084 llvm::Constant *addr,
2086 const char *Name =
"__cxa_atexit";
2089 Name = T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2096 llvm::FunctionType::get(CGF.
VoidTy, CGF.
Int8PtrTy,
false)->getPointerTo();
2100 llvm::FunctionType *atexitTy =
2101 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2105 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
2106 fn->setDoesNotThrow();
2109 llvm::Constant *handle =
2113 llvm::ConstantExpr::getBitCast(dtor, dtorTy),
2114 llvm::ConstantExpr::getBitCast(addr, CGF.
Int8PtrTy),
2123 llvm::Constant *dtor,
2124 llvm::Constant *addr) {
2126 if (CGM.getCodeGenOpts().CXAAtExit)
2130 CGM.ErrorUnsupported(&D,
"non-trivial TLS destruction");
2134 if (CGM.getLangOpts().AppleKext) {
2136 return CGM.AddCXXDtorEntry(dtor, addr);
2144 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
2154 static llvm::GlobalValue::LinkageTypes
2156 llvm::GlobalValue::LinkageTypes VarLinkage =
2160 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
2165 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
2166 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
2168 return llvm::GlobalValue::WeakODRLinkage;
2172 ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
2177 llvm::raw_svector_ostream Out(WrapperName);
2178 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
2181 if (
llvm::Value *V = CGM.getModule().getNamedValue(WrapperName))
2182 return cast<llvm::Function>(V);
2186 RetTy = RetTy->getPointerElementType();
2188 llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy,
false);
2189 llvm::Function *Wrapper =
2191 WrapperName.str(), &CGM.getModule());
2194 !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) &&
2195 !llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage())))
2199 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2200 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
2205 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2209 llvm::Function *InitFunc =
nullptr;
2210 if (!CXXThreadLocalInits.empty()) {
2212 llvm::FunctionType *FTy =
2213 llvm::FunctionType::get(CGM.
VoidTy,
false);
2218 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
2221 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
2222 Guard->setThreadLocal(
true);
2231 for (
const VarDecl *VD : CXXThreadLocals) {
2232 llvm::GlobalVariable *Var =
2244 llvm::raw_svector_ostream Out(InitFnName);
2245 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
2251 llvm::GlobalValue *Init =
nullptr;
2252 bool InitIsInitFunc =
false;
2254 InitIsInitFunc =
true;
2263 llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2265 FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(),
2270 Init->setVisibility(Var->getVisibility());
2272 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
2273 llvm::LLVMContext &Context = CGM.
getModule().getContext();
2276 if (InitIsInitFunc) {
2278 Builder.CreateCall(Init);
2281 llvm::Value *Have = Builder.CreateIsNotNull(Init);
2284 Builder.CreateCondBr(Have, InitBB, ExitBB);
2286 Builder.SetInsertPoint(InitBB);
2287 Builder.CreateCall(Init);
2288 Builder.CreateBr(ExitBB);
2290 Builder.SetInsertPoint(ExitBB);
2300 if (Val->getType() != Wrapper->getReturnType())
2302 Val, Wrapper->getReturnType(),
"");
2303 Builder.CreateRet(Val);
2311 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
2313 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
2315 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2329 bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
2348 class ItaniumRTTIBuilder {
2350 llvm::LLVMContext &VMContext;
2351 const ItaniumCXXABI &
CXXABI;
2357 llvm::GlobalVariable *
2358 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
2362 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
2365 void BuildVTablePointer(
const Type *Ty);
2378 void BuildPointerTypeInfo(
QualType PointeeTy);
2389 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
2390 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
2404 PTI_Incomplete = 0x8,
2408 PTI_ContainingClassIncomplete = 0x10
2414 VMI_NonDiamondRepeat = 0x1,
2417 VMI_DiamondShaped = 0x2
2432 llvm::Constant *BuildTypeInfo(
QualType Ty,
bool Force =
false);
2436 llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
2437 QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) {
2439 llvm::raw_svector_ostream Out(Name);
2445 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
2448 llvm::GlobalVariable *GV =
2451 GV->setInitializer(Init);
2457 ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
2460 llvm::raw_svector_ostream Out(Name);
2464 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
2472 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2473 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2474 if (RD->
hasAttr<DLLImportAttr>())
2475 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
2479 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
2495 case BuiltinType::Void:
2496 case BuiltinType::NullPtr:
2497 case BuiltinType::Bool:
2498 case BuiltinType::WChar_S:
2499 case BuiltinType::WChar_U:
2500 case BuiltinType::Char_U:
2501 case BuiltinType::Char_S:
2502 case BuiltinType::UChar:
2503 case BuiltinType::SChar:
2504 case BuiltinType::Short:
2505 case BuiltinType::UShort:
2506 case BuiltinType::Int:
2507 case BuiltinType::UInt:
2508 case BuiltinType::Long:
2509 case BuiltinType::ULong:
2510 case BuiltinType::LongLong:
2511 case BuiltinType::ULongLong:
2512 case BuiltinType::Half:
2513 case BuiltinType::Float:
2514 case BuiltinType::Double:
2515 case BuiltinType::LongDouble:
2516 case BuiltinType::Char16:
2517 case BuiltinType::Char32:
2518 case BuiltinType::Int128:
2519 case BuiltinType::UInt128:
2520 case BuiltinType::OCLImage1d:
2521 case BuiltinType::OCLImage1dArray:
2522 case BuiltinType::OCLImage1dBuffer:
2523 case BuiltinType::OCLImage2d:
2524 case BuiltinType::OCLImage2dArray:
2525 case BuiltinType::OCLImage2dDepth:
2526 case BuiltinType::OCLImage2dArrayDepth:
2527 case BuiltinType::OCLImage2dMSAA:
2528 case BuiltinType::OCLImage2dArrayMSAA:
2529 case BuiltinType::OCLImage2dMSAADepth:
2530 case BuiltinType::OCLImage2dArrayMSAADepth:
2531 case BuiltinType::OCLImage3d:
2532 case BuiltinType::OCLSampler:
2533 case BuiltinType::OCLEvent:
2534 case BuiltinType::OCLClkEvent:
2535 case BuiltinType::OCLQueue:
2536 case BuiltinType::OCLNDRange:
2537 case BuiltinType::OCLReserveID:
2540 case BuiltinType::Dependent:
2541 #define BUILTIN_TYPE(Id, SingletonId)
2542 #define PLACEHOLDER_TYPE(Id, SingletonId) \
2543 case BuiltinType::Id:
2544 #include "clang/AST/BuiltinTypes.def"
2545 llvm_unreachable(
"asking for RRTI for a placeholder type!");
2547 case BuiltinType::ObjCId:
2548 case BuiltinType::ObjCClass:
2549 case BuiltinType::ObjCSel:
2550 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
2553 llvm_unreachable(
"Invalid BuiltinType Kind!");
2576 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
2581 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2599 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2600 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2611 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
2613 return IsDLLImport ?
false :
true;
2639 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2644 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2648 dyn_cast<MemberPointerType>(Ty)) {
2650 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
2689 void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
2691 static const char *
const ClassTypeInfo =
2692 "_ZTVN10__cxxabiv117__class_type_infoE";
2694 static const char *
const SIClassTypeInfo =
2695 "_ZTVN10__cxxabiv120__si_class_type_infoE";
2697 static const char *
const VMIClassTypeInfo =
2698 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
2700 const char *VTableName =
nullptr;
2703 #define TYPE(Class, Base)
2704 #define ABSTRACT_TYPE(Class, Base)
2705 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
2706 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
2707 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
2708 #include "clang/AST/TypeNodes.def"
2709 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
2711 case Type::LValueReference:
2712 case Type::RValueReference:
2713 llvm_unreachable(
"References shouldn't get here");
2716 llvm_unreachable(
"Undeduced auto type shouldn't get here");
2719 llvm_unreachable(
"Pipe types shouldn't get here");
2724 case Type::ExtVector:
2728 case Type::BlockPointer:
2730 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
2733 case Type::ConstantArray:
2734 case Type::IncompleteArray:
2735 case Type::VariableArray:
2737 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
2740 case Type::FunctionNoProto:
2741 case Type::FunctionProto:
2743 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
2748 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
2751 case Type::Record: {
2753 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
2756 VTableName = ClassTypeInfo;
2758 VTableName = SIClassTypeInfo;
2760 VTableName = VMIClassTypeInfo;
2766 case Type::ObjCObject:
2768 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
2771 if (isa<BuiltinType>(Ty)) {
2772 VTableName = ClassTypeInfo;
2776 assert(isa<ObjCInterfaceType>(Ty));
2779 case Type::ObjCInterface:
2780 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
2781 VTableName = SIClassTypeInfo;
2783 VTableName = ClassTypeInfo;
2787 case Type::ObjCObjectPointer:
2790 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
2793 case Type::MemberPointer:
2795 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
2799 llvm::Constant *VTable =
2806 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
2808 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8PtrTy, VTable, Two);
2809 VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.
Int8PtrTy);
2811 Fields.push_back(VTable);
2841 return llvm::GlobalValue::LinkOnceODRLinkage;
2844 if (
const RecordType *Record = dyn_cast<RecordType>(Ty)) {
2845 const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
2847 return llvm::GlobalValue::WeakODRLinkage;
2852 if (RD->
hasAttr<DLLImportAttr>() &&
2853 llvm::GlobalValue::isAvailableExternallyLinkage(LT))
2854 LT = llvm::GlobalValue::LinkOnceODRLinkage;
2859 return llvm::GlobalValue::LinkOnceODRLinkage;
2862 llvm_unreachable(
"Invalid linkage!");
2865 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty,
bool Force) {
2871 llvm::raw_svector_ostream Out(Name);
2874 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
2875 if (OldGV && !OldGV->isDeclaration()) {
2876 assert(!OldGV->hasAvailableExternallyLinkage() &&
2877 "available_externally typeinfos not yet implemented");
2879 return llvm::ConstantExpr::getBitCast(OldGV, CGM.
Int8PtrTy);
2885 return GetAddrOfExternalRTTIDescriptor(Ty);
2888 llvm::GlobalVariable::LinkageTypes
Linkage;
2895 BuildVTablePointer(cast<Type>(Ty));
2898 llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
2899 llvm::Constant *TypeNameField;
2903 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
2904 CXXABI.classifyRTTIUniqueness(Ty, Linkage);
2905 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
2908 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
2909 llvm::Constant *flag =
2910 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
2911 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
2913 llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.
Int8PtrTy);
2915 TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.
Int8PtrTy);
2917 Fields.push_back(TypeNameField);
2920 #define TYPE(Class, Base)
2921 #define ABSTRACT_TYPE(Class, Base)
2922 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
2923 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
2924 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
2925 #include "clang/AST/TypeNodes.def"
2926 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
2931 case Type::ExtVector:
2933 case Type::BlockPointer:
2938 case Type::LValueReference:
2939 case Type::RValueReference:
2940 llvm_unreachable(
"References shouldn't get here");
2943 llvm_unreachable(
"Undeduced auto type shouldn't get here");
2946 llvm_unreachable(
"Pipe type shouldn't get here");
2948 case Type::ConstantArray:
2949 case Type::IncompleteArray:
2950 case Type::VariableArray:
2955 case Type::FunctionNoProto:
2956 case Type::FunctionProto:
2966 case Type::Record: {
2968 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
2975 BuildSIClassTypeInfo(RD);
2977 BuildVMIClassTypeInfo(RD);
2982 case Type::ObjCObject:
2983 case Type::ObjCInterface:
2984 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
2987 case Type::ObjCObjectPointer:
2988 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
2992 BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
2995 case Type::MemberPointer:
2996 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
3004 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
3007 llvm::GlobalVariable *GV =
3008 new llvm::GlobalVariable(M, Init->getType(),
3013 GV->takeName(OldGV);
3014 llvm::Constant *NewPtr =
3015 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
3016 OldGV->replaceAllUsesWith(NewPtr);
3017 OldGV->eraseFromParent();
3021 GV->setComdat(M.getOrInsertComdat(GV->getName()));
3040 llvm::GlobalValue::VisibilityTypes llvmVisibility;
3041 if (llvm::GlobalValue::isLocalLinkage(Linkage))
3044 else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden)
3048 TypeName->setVisibility(llvmVisibility);
3049 GV->setVisibility(llvmVisibility);
3051 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3060 Flags |= ItaniumRTTIBuilder::PTI_Const;
3062 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
3064 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
3071 void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
3074 assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
3078 if (isa<BuiltinType>(T))
return;
3089 llvm::Constant *BaseTypeInfo =
3090 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
3091 Fields.push_back(BaseTypeInfo);
3096 void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
3100 llvm::Constant *BaseTypeInfo =
3102 Fields.push_back(BaseTypeInfo);
3109 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
3110 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
3127 if (!Bases.VirtualBases.insert(BaseDecl).second) {
3130 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
3132 if (Bases.NonVirtualBases.count(BaseDecl))
3133 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3137 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
3140 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3142 if (Bases.VirtualBases.count(BaseDecl))
3143 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3148 for (
const auto &
I : BaseDecl->
bases())
3159 for (
const auto &
I : RD->
bases())
3168 void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
3177 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3182 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
3207 for (
const auto &Base : RD->
bases()) {
3209 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(Base.getType()));
3212 cast<CXXRecordDecl>(Base.getType()->getAs<
RecordType>()->getDecl());
3214 int64_t OffsetFlags = 0;
3221 if (Base.isVirtual())
3229 OffsetFlags = uint64_t(Offset.
getQuantity()) << 8;
3233 if (Base.isVirtual())
3234 OffsetFlags |= BCTI_Virtual;
3235 if (Base.getAccessSpecifier() ==
AS_public)
3236 OffsetFlags |= BCTI_Public;
3238 Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
3244 void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
3258 Flags |= PTI_Incomplete;
3262 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3267 llvm::Constant *PointeeTypeInfo =
3268 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
3269 Fields.push_back(PointeeTypeInfo);
3293 Flags |= PTI_Incomplete;
3296 Flags |= PTI_ContainingClassIncomplete;
3300 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3305 llvm::Constant *PointeeTypeInfo =
3306 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
3307 Fields.push_back(PointeeTypeInfo);
3314 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
3317 llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
3318 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
3321 void ItaniumCXXABI::EmitFundamentalRTTIDescriptor(
QualType Type) {
3324 ItaniumRTTIBuilder(*this).BuildTypeInfo(Type,
true);
3325 ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType,
true);
3326 ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst,
true);
3329 void ItaniumCXXABI::EmitFundamentalRTTIDescriptors() {
3331 getContext().VoidTy, getContext().NullPtrTy,
3332 getContext().BoolTy, getContext().WCharTy,
3333 getContext().CharTy, getContext().UnsignedCharTy,
3334 getContext().SignedCharTy, getContext().ShortTy,
3335 getContext().UnsignedShortTy, getContext().IntTy,
3336 getContext().UnsignedIntTy, getContext().LongTy,
3337 getContext().UnsignedLongTy, getContext().LongLongTy,
3338 getContext().UnsignedLongLongTy, getContext().HalfTy,
3339 getContext().FloatTy, getContext().DoubleTy,
3340 getContext().LongDoubleTy, getContext().Char16Ty,
3341 getContext().Char32Ty,
3343 for (
const QualType &FundamentalType : FundamentalTypes)
3344 EmitFundamentalRTTIDescriptor(FundamentalType);
3349 ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
3350 QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage)
const {
3351 if (shouldRTTIBeUnique())
3355 if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
3356 Linkage != llvm::GlobalValue::WeakODRLinkage)
3364 if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3365 return RUK_NonUniqueHidden;
3370 assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
3371 return RUK_NonUniqueVisible;
3381 return StructorCodegen::Emit;
3386 return StructorCodegen::Emit;
3389 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
3392 const auto *CD = cast<CXXConstructorDecl>(MD);
3397 if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
3398 return StructorCodegen::RAUW;
3401 if (!llvm::GlobalAlias::isValidLinkage(Linkage))
3402 return StructorCodegen::RAUW;
3404 if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
3407 return StructorCodegen::COMDAT;
3408 return StructorCodegen::Emit;
3411 return StructorCodegen::Alias;
3421 if (Entry && !Entry->isDeclaration())
3424 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
3431 assert(Entry->getType() == Aliasee->getType() &&
3432 "declaration exists with different type");
3433 Alias->takeName(Entry);
3434 Entry->replaceAllUsesWith(Alias);
3435 Entry->eraseFromParent();
3437 Alias->setName(MangledName);
3444 void ItaniumCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3462 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
3467 if (CGType == StructorCodegen::RAUW) {
3485 if (CGType == StructorCodegen::COMDAT) {
3487 llvm::raw_svector_ostream Out(Buffer);
3489 getMangleContext().mangleCXXDtorComdat(DD, Out);
3491 getMangleContext().mangleCXXCtorComdat(CD, Out);
3492 llvm::Comdat *C = CGM.
getModule().getOrInsertComdat(Out.str());
3501 llvm::FunctionType *FTy = llvm::FunctionType::get(
3509 llvm::FunctionType *FTy =
3510 llvm::FunctionType::get(CGM.
VoidTy,
false);
3517 llvm::FunctionType *FTy = llvm::FunctionType::get(
3537 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
3557 bool EndMightThrow) {
3558 llvm::CallInst *call =
3581 if (isa<ReferenceType>(CatchType)) {
3582 QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
3591 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
3600 unsigned HeaderSize =
3602 AdjustedExn = CGF.
Builder.CreateConstGEP1_32(Exn, HeaderSize);
3647 if (CatchType->hasPointerRepresentation()) {
3666 llvm_unreachable(
"bad ownership qualifier!");
3671 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
3687 llvm_unreachable(
"evaluation kind filtered out!");
3689 llvm_unreachable(
"bad evaluation kind");
3692 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
3693 auto catchRD = CatchType->getAsCXXRecordDecl();
3696 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
3704 caughtExnAlignment);
3711 llvm::CallInst *rawAdjustedExn =
3716 caughtExnAlignment);
3788 llvm::FunctionType *fnTy =
3790 llvm::Constant *fnRef =
3793 llvm::Function *fn = dyn_cast<llvm::Function>(fnRef);
3794 if (fn && fn->empty()) {
3795 fn->setDoesNotThrow();
3796 fn->setDoesNotReturn();
3801 fn->addFnAttr(llvm::Attribute::NoInline);
3805 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
3808 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
3811 llvm::BasicBlock *entry =
3819 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
3820 catchCall->setDoesNotThrow();
3824 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
3825 termCall->setDoesNotThrow();
3826 termCall->setDoesNotReturn();
3830 builder.CreateUnreachable();
3837 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.
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).
void EmitVTablePtrCheckForCall(const CXXMethodDecl *MD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
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.
CK_BaseToDerivedMemberPointer - Member pointer in base class to member pointer in derived class...
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...
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr)
Return the llvm::Constant for the address of the given global variable.
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.
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
Retrieves the "canonical" declaration of the given declaration.
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.
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...
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units. ...
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)
Arrange the argument and result information for a declaration or definition of the given C++ non-stat...
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.
struct clang::ThisAdjustment::VirtualAdjustment::@113 Itanium
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.
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 ...
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()
getNullaryFunctionInfo - Get the function info for a void() function with standard CC...
Represents a C++ destructor within a class.
DeclContext * getDeclContext()
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)
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)
Creates clause with a list of variables VL and a linear step Step.
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.
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.
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...
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)
CK_ReinterpretMemberPointer - Reinterpret a member pointer as a different kind of member pointer...
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.
struct clang::ReturnAdjustment::VirtualAdjustment::@111 Itanium
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
static const Type * getElementType(const Expr *BaseExpr)
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...
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. ...
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>'.
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
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
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...
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.
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.
VarDecl * getExceptionDecl() const
static RValue get(llvm::Value *V)
CK_DerivedToBaseMemberPointer - Member pointer in derived class to member pointer in base class...
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)
SourceLocation getLocation() const
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)
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.