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) { }
92 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
93 llvm::Constant *Src)
override;
97 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
100 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
107 bool Inequality)
override;
127 void EmitFundamentalRTTIDescriptors();
128 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
130 getAddrOfCXXCatchHandlerType(
QualType Ty,
131 QualType CatchHandlerType)
override {
132 return getAddrOfRTTIDescriptor(Ty);
135 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
139 llvm::Type *StdTypeInfoPtrTy)
override;
141 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
147 llvm::BasicBlock *CastEnd)
override;
196 bool &NeedsVirtualOffset)
override;
202 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
216 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
218 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
GlobalDecl GD,
222 if (ForVTable && !Thunk->hasLocalLinkage())
223 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
230 const ReturnAdjustment &RA)
override;
234 assert(!Args.empty() &&
"expected the arglist to not be empty!");
235 return Args.size() - 1;
238 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
239 StringRef GetDeletedVirtualCallName()
override
240 {
return "__cxa_deleted_virtual"; }
253 llvm::GlobalVariable *DeclPtr,
254 bool PerformInit)
override;
256 llvm::Constant *dtor, llvm::Constant *addr)
override;
258 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
260 void EmitThreadLocalInitFuncs(
262 ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *>>
267 bool usesThreadWrapperFunction()
const override {
return true; }
271 bool NeedsVTTParameter(
GlobalDecl GD)
override;
278 virtual bool shouldRTTIBeUnique()
const {
return true; }
282 enum RTTIUniquenessKind {
300 classifyRTTIUniqueness(
QualType CanTy,
301 llvm::GlobalValue::LinkageTypes
Linkage)
const;
302 friend class ItaniumRTTIBuilder;
307 class ARMCXXABI :
public ItaniumCXXABI {
310 ItaniumCXXABI(CGM,
true,
313 bool HasThisReturn(
GlobalDecl GD)
const override {
314 return (isa<CXXConstructorDecl>(GD.
getDecl()) || (
315 isa<CXXDestructorDecl>(GD.
getDecl()) &&
332 class iOS64CXXABI :
public ARMCXXABI {
337 bool shouldRTTIBeUnique()
const override {
return false; }
347 return new ARMCXXABI(CGM);
350 return new iOS64CXXABI(CGM);
356 return new ItaniumCXXABI(CGM,
true,
360 return new ItaniumCXXABI(CGM,
true);
364 == llvm::Triple::le32) {
368 return new ItaniumCXXABI(CGM,
true,
371 return new ItaniumCXXABI(CGM);
374 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
376 llvm_unreachable(
"bad ABI kind");
382 return CGM.PtrDiffTy;
383 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy,
nullptr);
406 llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
416 llvm::FunctionType *FTy =
417 CGM.getTypes().GetFunctionType(
418 CGM.getTypes().arrangeCXXMethodType(RD, FPT));
420 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
427 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
431 if (UseARMMethodPtrABI)
432 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
436 llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
437 Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
438 This = Builder.CreateBitCast(Ptr, This->getType(),
"this.adjusted");
441 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
446 if (UseARMMethodPtrABI)
447 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
449 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
450 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
451 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
459 llvm::Type *VTableTy = Builder.getInt8PtrTy();
464 if (!UseARMMethodPtrABI)
465 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
466 VTable = Builder.CreateGEP(VTable, VTableOffset);
469 VTable = Builder.CreateBitCast(VTable, FTy->getPointerTo()->getPointerTo());
470 llvm::Value *VirtualFn = Builder.CreateLoad(VTable,
"memptr.virtualfn");
477 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(),
"memptr.nonvirtualfn");
481 llvm::PHINode *Callee = Builder.CreatePHI(FTy->getPointerTo(), 2);
482 Callee->addIncoming(VirtualFn, FnVirtual);
483 Callee->addIncoming(NonVirtualFn, FnNonVirtual);
489 llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
492 assert(MemPtr->getType() == CGM.PtrDiffTy);
496 unsigned AS = Base->getType()->getPointerAddressSpace();
499 Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
502 llvm::Value *Addr = Builder.CreateInBoundsGEP(Base, MemPtr,
"memptr.offset");
508 return Builder.CreateBitCast(Addr, PType);
546 if (isa<llvm::Constant>(src))
547 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
549 llvm::Constant *adj = getMemberPointerAdjustment(E);
550 if (!adj)
return src;
563 dst = Builder.CreateNSWSub(src, adj,
"adj");
565 dst = Builder.CreateNSWAdd(src, adj,
"adj");
568 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
569 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
570 return Builder.CreateSelect(isNull, src, dst);
574 if (UseARMMethodPtrABI) {
575 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
577 adj = llvm::ConstantInt::get(adj->getType(), offset);
580 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
583 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
585 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
587 return Builder.CreateInsertValue(src, dstAdj, 1);
591 ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
592 llvm::Constant *src) {
601 llvm::Constant *adj = getMemberPointerAdjustment(E);
602 if (!adj)
return src;
613 if (src->isAllOnesValue())
return src;
616 return llvm::ConstantExpr::getNSWSub(src, adj);
618 return llvm::ConstantExpr::getNSWAdd(src, adj);
622 if (UseARMMethodPtrABI) {
623 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
625 adj = llvm::ConstantInt::get(adj->getType(), offset);
628 llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
629 llvm::Constant *dstAdj;
631 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
633 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
635 return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
643 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
645 llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
646 llvm::Constant *Values[2] = { Zero, Zero };
647 return llvm::ConstantStruct::getAnon(Values);
656 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
660 ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
664 llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
666 assert(MD->
isInstance() &&
"Member function must not be static!");
672 llvm::Constant *MemPtr[2];
673 if (MD->isVirtual()) {
674 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
679 uint64_t VTableOffset = (Index * PointerWidth.
getQuantity());
681 if (UseARMMethodPtrABI) {
688 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
689 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
696 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
697 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
712 llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
714 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
715 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
716 (UseARMMethodPtrABI ? 2 : 1) *
720 return llvm::ConstantStruct::getAnon(MemPtr);
723 llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
728 return EmitNullMemberPointer(MPT);
730 CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
733 return BuildMemberPointer(MD, ThisAdjustment);
736 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
737 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
752 llvm::ICmpInst::Predicate Eq;
753 llvm::Instruction::BinaryOps
And, Or;
755 Eq = llvm::ICmpInst::ICMP_NE;
756 And = llvm::Instruction::Or;
759 Eq = llvm::ICmpInst::ICMP_EQ;
761 Or = llvm::Instruction::Or;
767 return Builder.CreateICmp(Eq, L, R);
779 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
780 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
784 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
789 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
790 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero,
"cmp.ptr.null");
794 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
795 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
796 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
800 if (UseARMMethodPtrABI) {
801 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
804 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
805 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
806 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
808 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
813 Result = Builder.CreateBinOp(And, PtrEq, Result,
814 Inequality ?
"memptr.ne" :
"memptr.eq");
826 assert(MemPtr->getType() == CGM.PtrDiffTy);
828 llvm::Constant::getAllOnesValue(MemPtr->getType());
829 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
833 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
835 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
836 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
840 if (UseARMMethodPtrABI) {
841 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
842 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
843 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
844 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
846 Result = Builder.CreateOr(Result, IsVirtual);
852 bool ItaniumCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
881 if (UseGlobalDelete) {
890 VTable, -2,
"complete-offset.ptr");
896 CompletePtr = CGF.
Builder.CreateInBoundsGEP(CompletePtr, Offset);
907 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
913 void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
916 llvm::FunctionType *FTy =
917 llvm::FunctionType::get(CGM.VoidTy,
false);
919 llvm::Constant *Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
930 llvm::FunctionType *FTy =
941 llvm::FunctionType *FTy =
942 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
950 llvm::Type *SizeTy = CGF.
ConvertType(getContext().getSizeType());
951 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
955 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
960 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
965 llvm::Constant *Dtor =
nullptr;
967 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
971 Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy);
974 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
976 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
987 llvm::Type *PtrDiffTy =
990 llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
992 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
995 llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
996 llvm::Attribute::ReadOnly };
997 llvm::AttributeSet Attrs = llvm::AttributeSet::get(
998 CGF.
getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs);
1005 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1022 unsigned NumPublicPaths = 0;
1033 for (CXXBasePath::iterator J = I->begin(), JE = I->end(); J != JE; ++J) {
1036 if (J->Base->isVirtual())
1039 if (NumPublicPaths > 1)
1049 if (NumPublicPaths == 0)
1053 if (NumPublicPaths > 1)
1063 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1068 bool ItaniumCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
1076 CGF.
Builder.CreateUnreachable();
1082 llvm::Type *StdTypeInfoPtrTy) {
1084 CGF.
GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo());
1087 Value = CGF.
Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
1088 return CGF.
Builder.CreateLoad(Value);
1091 bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1099 llvm::Type *PtrDiffLTy =
1120 Value = CGF.
Builder.CreateBitCast(Value, DestLTy);
1125 llvm::BasicBlock *BadCastBlock =
1129 CGF.
Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1132 EmitBadCastCall(CGF);
1142 llvm::Type *PtrDiffLTy =
1151 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
1152 OffsetToTop = CGF.
Builder.CreateLoad(OffsetToTop,
"offset.to.top");
1156 Value = CGF.
Builder.CreateInBoundsGEP(Value, OffsetToTop);
1158 return CGF.
Builder.CreateBitCast(Value, DestLTy);
1164 CGF.
Builder.CreateUnreachable();
1175 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1180 "vbase.offset.ptr");
1181 VBaseOffsetPtr = CGF.
Builder.CreateBitCast(VBaseOffsetPtr,
1182 CGM.PtrDiffTy->getPointerTo());
1185 CGF.
Builder.CreateLoad(VBaseOffsetPtr,
"vbase.offset");
1192 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1216 ArgTys.insert(ArgTys.begin() + 1,
1240 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1243 if (NeedsVTTParameter(CGF.
CurGD)) {
1251 Params.insert(Params.begin() + 1, VTTDecl);
1252 getStructorImplicitParamDecl(CGF) = VTTDecl;
1256 void ItaniumCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1261 if (getStructorImplicitParamDecl(CGF)) {
1262 getStructorImplicitParamValue(CGF) = CGF.
Builder.CreateLoad(
1274 if (HasThisReturn(CGF.
CurGD))
1278 unsigned ItaniumCXXABI::addImplicitConstructorArgs(
1280 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1287 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1288 Args.insert(Args.begin() + 1,
1299 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1302 if (getContext().getLangOpts().AppleKext)
1314 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1315 if (VTable->hasInitializer())
1320 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
1321 llvm::Constant *RTTI =
1322 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1328 VTable->setInitializer(Init);
1331 VTable->setLinkage(Linkage);
1333 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1334 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1337 CGM.setGlobalVisibility(VTable, RD);
1342 unsigned PAlign = CGM.getTarget().getPointerAlign(0);
1343 VTable->setAlignment(getContext().toCharUnitsFromBits(PAlign).getQuantity());
1351 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1352 cast<NamespaceDecl>(DC)->getIdentifier()->isStr(
"__cxxabiv1") &&
1354 EmitFundamentalRTTIDescriptors();
1356 CGM.EmitVTableBitSetEntries(VTable, VTLayout);
1359 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1361 const CXXRecordDecl *NearestVBase,
bool &NeedsVirtualOffset) {
1362 bool NeedsVTTParam = CGM.getCXXABI().NeedsVTTParameter(CGF.
CurGD);
1363 NeedsVirtualOffset = (NeedsVTTParam && NearestVBase);
1368 uint64_t VirtualPointerIndex =
1369 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
1373 if (VirtualPointerIndex)
1374 VTT = CGF.
Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
1377 VTableAddressPoint = CGF.
Builder.CreateLoad(VTT);
1379 llvm::Constant *VTable =
1380 CGM.getCXXABI().getAddrOfVTable(VTableClass,
CharUnits());
1381 uint64_t AddressPoint = CGM.getItaniumVTableContext()
1382 .getVTableLayout(VTableClass)
1383 .getAddressPoint(Base);
1384 VTableAddressPoint =
1385 CGF.
Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);
1388 return VTableAddressPoint;
1391 llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
1393 auto *VTable = getAddrOfVTable(VTableClass,
CharUnits());
1396 uint64_t AddressPoint = CGM.getItaniumVTableContext()
1397 .getVTableLayout(VTableClass)
1398 .getAddressPoint(Base);
1400 llvm::ConstantInt::get(CGM.Int64Ty, 0),
1401 llvm::ConstantInt::get(CGM.Int64Ty, AddressPoint)
1404 return llvm::ConstantExpr::getInBoundsGetElementPtr(VTable->getValueType(),
1408 llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1410 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1412 llvm::GlobalVariable *&VTable = VTables[RD];
1417 CGM.addDeferredVTable(RD);
1420 llvm::raw_svector_ostream Out(OutName);
1421 getMangleContext().mangleCXXVTable(RD, Out);
1423 StringRef Name = OutName.str();
1426 llvm::ArrayType *
ArrayType = llvm::ArrayType::get(
1429 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1431 VTable->setUnnamedAddr(
true);
1433 if (RD->
hasAttr<DLLImportAttr>())
1434 VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1435 else if (RD->
hasAttr<DLLExportAttr>())
1436 VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1447 Ty = Ty->getPointerTo()->getPointerTo();
1450 if (CGF.
SanOpts.
has(SanitizerKind::CFIVCall))
1454 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
1456 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex,
"vfn");
1457 return CGF.
Builder.CreateLoad(VFuncPtr);
1460 llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
1466 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1470 getVirtualFunctionPointer(CGF,
GlobalDecl(Dtor, DtorType), This, Ty,
1478 void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1486 int64_t NonVirtualAdjustment,
1487 int64_t VirtualAdjustment,
1488 bool IsReturnAdjustment) {
1489 if (!NonVirtualAdjustment && !VirtualAdjustment)
1495 if (NonVirtualAdjustment && !IsReturnAdjustment) {
1497 V = CGF.
Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment);
1500 if (VirtualAdjustment) {
1501 llvm::Type *PtrDiffTy =
1506 CGF.
Builder.CreateBitCast(V, Int8PtrTy->getPointerTo());
1511 CGF.
Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
1513 OffsetPtr = CGF.
Builder.CreateBitCast(OffsetPtr, PtrDiffTy->getPointerTo());
1519 V = CGF.
Builder.CreateInBoundsGEP(V, Offset);
1522 if (NonVirtualAdjustment && IsReturnAdjustment) {
1524 V = CGF.
Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment);
1528 return CGF.
Builder.CreateBitCast(V, Ptr->getType());
1533 const ThisAdjustment &TA) {
1541 const ReturnAdjustment &RA) {
1550 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
1556 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
1565 CGM.getContext().getTypeAlignInChars(elementType));
1573 assert(requiresArrayCookie(expr));
1575 unsigned AS = NewPtr->getType()->getPointerAddressSpace();
1584 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
1588 CharUnits CookieOffset = CookieSize - SizeSize;
1589 if (!CookieOffset.
isZero())
1590 CookiePtr = CGF.
Builder.CreateConstInBoundsGEP1_64(CookiePtr,
1594 llvm::Type *NumElementsTy = CGF.
ConvertType(SizeTy)->getPointerTo(AS);
1596 CGF.
Builder.CreateBitCast(CookiePtr, NumElementsTy);
1597 llvm::Instruction *SI = CGF.
Builder.CreateStore(NumElements, NumElementsPtr);
1598 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
1601 CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
1602 llvm::FunctionType *FTy =
1603 llvm::FunctionType::get(CGM.VoidTy, NumElementsTy,
false);
1605 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
1606 CGF.
Builder.CreateCall(F, NumElementsPtr);
1611 return CGF.
Builder.CreateConstInBoundsGEP1_64(NewPtr,
1622 if (!numElementsOffset.
isZero())
1624 CGF.
Builder.CreateConstInBoundsGEP1_64(numElementsPtr,
1627 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
1629 CGF.
Builder.CreateBitCast(numElementsPtr, CGF.
SizeTy->getPointerTo(AS));
1630 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
1631 return CGF.
Builder.CreateLoad(numElementsPtr);
1637 llvm::FunctionType *FTy =
1638 llvm::FunctionType::get(CGF.
SizeTy, CGF.
SizeTy->getPointerTo(0),
false);
1640 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
1641 return CGF.
Builder.CreateCall(F, numElementsPtr);
1654 CGM.getContext().getTypeAlignInChars(elementType));
1662 assert(requiresArrayCookie(expr));
1665 unsigned AS = newPtr->getType()->getPointerAddressSpace();
1671 cookie = CGF.
Builder.CreateBitCast(cookie, CGF.
SizeTy->getPointerTo(AS));
1673 getContext().getTypeSizeInChars(elementType).getQuantity());
1674 CGF.
Builder.CreateStore(elementSize, cookie);
1677 cookie = CGF.
Builder.CreateConstInBoundsGEP1_32(CGF.
SizeTy, cookie, 1);
1678 CGF.
Builder.CreateStore(numElements, cookie);
1682 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
1683 return CGF.
Builder.CreateConstInBoundsGEP1_64(newPtr,
1695 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
1697 CGF.
Builder.CreateBitCast(numElementsPtr, CGF.
SizeTy->getPointerTo(AS));
1698 return CGF.
Builder.CreateLoad(numElementsPtr);
1704 llvm::PointerType *GuardPtrTy) {
1706 llvm::FunctionType *FTy =
1711 llvm::AttributeSet::FunctionIndex,
1712 llvm::Attribute::NoUnwind));
1716 llvm::PointerType *GuardPtrTy) {
1718 llvm::FunctionType *FTy =
1719 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
1722 llvm::AttributeSet::FunctionIndex,
1723 llvm::Attribute::NoUnwind));
1727 llvm::PointerType *GuardPtrTy) {
1729 llvm::FunctionType *FTy =
1730 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
1733 llvm::AttributeSet::FunctionIndex,
1734 llvm::Attribute::NoUnwind));
1739 llvm::GlobalVariable *Guard;
1740 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
1753 llvm::GlobalVariable *var,
1754 bool shouldPerformInit) {
1759 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
1764 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
1766 llvm::IntegerType *guardTy;
1767 if (useInt8GuardVariable) {
1774 llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
1778 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
1783 llvm::raw_svector_ostream out(guardName);
1784 getMangleContext().mangleStaticGuardVariable(&D, out);
1790 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
1791 false, var->getLinkage(),
1792 llvm::ConstantInt::get(guardTy, 0),
1794 guard->setVisibility(var->getVisibility());
1796 guard->setThreadLocalMode(var->getThreadLocalMode());
1800 llvm::Comdat *
C = var->getComdat();
1802 guard->setComdat(C);
1803 CGF.
CurFn->setComdat(C);
1804 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
1805 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
1808 CGM.setStaticLocalDeclGuardAddress(&D, guard);
1829 llvm::LoadInst *LI =
1830 Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy));
1831 LI->setAlignment(1);
1840 LI->setAtomic(llvm::Acquire);
1863 (UseARMGuardVarABI && !useInt8GuardVariable)
1864 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
1866 llvm::Value *isInitialized = Builder.CreateIsNull(V,
"guard.uninitialized");
1872 Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
1884 Builder.CreateCondBr(Builder.CreateIsNotNull(V,
"tobool"),
1885 InitBlock, EndBlock);
1903 Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard);
1911 llvm::Constant *dtor,
1912 llvm::Constant *addr,
1914 const char *Name =
"__cxa_atexit";
1917 Name = T.isMacOSX() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
1923 llvm::Type *dtorTy =
1924 llvm::FunctionType::get(CGF.
VoidTy, CGF.
Int8PtrTy,
false)->getPointerTo();
1928 llvm::FunctionType *atexitTy =
1929 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
1933 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
1934 fn->setDoesNotThrow();
1937 llvm::Constant *handle =
1941 llvm::ConstantExpr::getBitCast(dtor, dtorTy),
1942 llvm::ConstantExpr::getBitCast(addr, CGF.
Int8PtrTy),
1951 llvm::Constant *dtor,
1952 llvm::Constant *addr) {
1954 if (CGM.getCodeGenOpts().CXAAtExit)
1958 CGM.ErrorUnsupported(&D,
"non-trivial TLS destruction");
1962 if (CGM.getLangOpts().AppleKext) {
1964 return CGM.AddCXXDtorEntry(dtor, addr);
1972 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
1982 static llvm::GlobalValue::LinkageTypes
1984 llvm::GlobalValue::LinkageTypes VarLinkage =
1988 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
1993 if (llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) ||
1994 llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
1995 return llvm::GlobalVariable::WeakAnyLinkage;
1998 return llvm::GlobalValue::WeakODRLinkage;
2002 ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
2007 llvm::raw_svector_ostream Out(WrapperName);
2008 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
2012 if (
llvm::Value *V = CGM.getModule().getNamedValue(WrapperName))
2013 return cast<llvm::Function>(V);
2015 llvm::Type *RetTy = Val->getType();
2017 RetTy = RetTy->getPointerElementType();
2019 llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy,
false);
2020 llvm::Function *Wrapper =
2022 WrapperName.str(), &CGM.getModule());
2029 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2031 ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *>>
2034 llvm::Function *InitFunc =
nullptr;
2035 if (!CXXThreadLocalInits.empty()) {
2037 llvm::FunctionType *FTy =
2038 llvm::FunctionType::get(CGM.
VoidTy,
false);
2042 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
2045 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
2046 Guard->setThreadLocal(
true);
2050 for (
unsigned I = 0, N = CXXThreadLocals.size(); I != N; ++I) {
2051 const VarDecl *VD = CXXThreadLocals[I].first;
2052 llvm::GlobalVariable *Var = CXXThreadLocals[I].second;
2063 llvm::raw_svector_ostream Out(InitFnName);
2064 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
2071 llvm::GlobalValue *Init =
nullptr;
2072 bool InitIsInitFunc =
false;
2074 InitIsInitFunc =
true;
2083 llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2085 FnTy, llvm::GlobalVariable::ExternalWeakLinkage, InitFnName.str(),
2090 Init->setVisibility(Var->getVisibility());
2092 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
2093 llvm::LLVMContext &Context = CGM.
getModule().getContext();
2096 if (InitIsInitFunc) {
2098 Builder.CreateCall(Init);
2101 llvm::Value *Have = Builder.CreateIsNotNull(Init);
2104 Builder.CreateCondBr(Have, InitBB, ExitBB);
2106 Builder.SetInsertPoint(InitBB);
2107 Builder.CreateCall(Init);
2108 Builder.CreateBr(ExitBB);
2110 Builder.SetInsertPoint(ExitBB);
2117 llvm::LoadInst *LI = Builder.CreateLoad(Val);
2121 if (Val->getType() != Wrapper->getReturnType())
2122 Val = Builder.CreatePointerBitCastOrAddrSpaceCast(
2123 Val, Wrapper->getReturnType(),
"");
2124 Builder.CreateRet(Val);
2134 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
2136 Val = CGF.
Builder.CreateCall(Wrapper);
2149 bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
2168 class ItaniumRTTIBuilder {
2170 llvm::LLVMContext &VMContext;
2171 const ItaniumCXXABI &
CXXABI;
2177 llvm::GlobalVariable *
2178 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
2182 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
2185 void BuildVTablePointer(
const Type *Ty);
2198 void BuildPointerTypeInfo(
QualType PointeeTy);
2209 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
2210 : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()),
CXXABI(ABI) {}
2224 PTI_Incomplete = 0x8,
2228 PTI_ContainingClassIncomplete = 0x10
2234 VMI_NonDiamondRepeat = 0x1,
2237 VMI_DiamondShaped = 0x2
2252 llvm::Constant *BuildTypeInfo(
QualType Ty,
bool Force =
false);
2256 llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
2257 QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) {
2259 llvm::raw_svector_ostream Out(OutName);
2262 StringRef Name = OutName.str();
2267 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
2270 llvm::GlobalVariable *GV =
2273 GV->setInitializer(Init);
2279 ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
2282 llvm::raw_svector_ostream Out(OutName);
2285 StringRef Name = OutName.str();
2288 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
2296 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2297 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2298 if (RD->
hasAttr<DLLImportAttr>())
2299 GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
2303 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
2319 case BuiltinType::Void:
2320 case BuiltinType::NullPtr:
2321 case BuiltinType::Bool:
2322 case BuiltinType::WChar_S:
2323 case BuiltinType::WChar_U:
2324 case BuiltinType::Char_U:
2325 case BuiltinType::Char_S:
2326 case BuiltinType::UChar:
2327 case BuiltinType::SChar:
2328 case BuiltinType::Short:
2329 case BuiltinType::UShort:
2330 case BuiltinType::Int:
2331 case BuiltinType::UInt:
2332 case BuiltinType::Long:
2333 case BuiltinType::ULong:
2334 case BuiltinType::LongLong:
2335 case BuiltinType::ULongLong:
2336 case BuiltinType::Half:
2337 case BuiltinType::Float:
2338 case BuiltinType::Double:
2339 case BuiltinType::LongDouble:
2340 case BuiltinType::Char16:
2341 case BuiltinType::Char32:
2342 case BuiltinType::Int128:
2343 case BuiltinType::UInt128:
2344 case BuiltinType::OCLImage1d:
2345 case BuiltinType::OCLImage1dArray:
2346 case BuiltinType::OCLImage1dBuffer:
2347 case BuiltinType::OCLImage2d:
2348 case BuiltinType::OCLImage2dArray:
2349 case BuiltinType::OCLImage3d:
2350 case BuiltinType::OCLSampler:
2351 case BuiltinType::OCLEvent:
2354 case BuiltinType::Dependent:
2355 #define BUILTIN_TYPE(Id, SingletonId)
2356 #define PLACEHOLDER_TYPE(Id, SingletonId) \
2357 case BuiltinType::Id:
2358 #include "clang/AST/BuiltinTypes.def"
2359 llvm_unreachable(
"asking for RRTI for a placeholder type!");
2361 case BuiltinType::ObjCId:
2362 case BuiltinType::ObjCClass:
2363 case BuiltinType::ObjCSel:
2364 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
2367 llvm_unreachable(
"Invalid BuiltinType Kind!");
2390 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
2395 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2413 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2414 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2425 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
2427 return IsDLLImport ?
false :
true;
2453 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2458 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2462 dyn_cast<MemberPointerType>(Ty)) {
2464 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
2503 void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
2505 static const char *
const ClassTypeInfo =
2506 "_ZTVN10__cxxabiv117__class_type_infoE";
2508 static const char *
const SIClassTypeInfo =
2509 "_ZTVN10__cxxabiv120__si_class_type_infoE";
2511 static const char *
const VMIClassTypeInfo =
2512 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
2514 const char *VTableName =
nullptr;
2517 #define TYPE(Class, Base)
2518 #define ABSTRACT_TYPE(Class, Base)
2519 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
2520 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
2521 #define DEPENDENT_TYPE(Class, Base) case Type::Class:
2522 #include "clang/AST/TypeNodes.def"
2523 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
2525 case Type::LValueReference:
2526 case Type::RValueReference:
2527 llvm_unreachable(
"References shouldn't get here");
2530 llvm_unreachable(
"Undeduced auto type shouldn't get here");
2535 case Type::ExtVector:
2539 case Type::BlockPointer:
2541 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
2544 case Type::ConstantArray:
2545 case Type::IncompleteArray:
2546 case Type::VariableArray:
2548 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
2551 case Type::FunctionNoProto:
2552 case Type::FunctionProto:
2554 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
2559 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
2562 case Type::Record: {
2564 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
2567 VTableName = ClassTypeInfo;
2569 VTableName = SIClassTypeInfo;
2571 VTableName = VMIClassTypeInfo;
2577 case Type::ObjCObject:
2579 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
2582 if (isa<BuiltinType>(Ty)) {
2583 VTableName = ClassTypeInfo;
2587 assert(isa<ObjCInterfaceType>(Ty));
2590 case Type::ObjCInterface:
2591 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
2592 VTableName = SIClassTypeInfo;
2594 VTableName = ClassTypeInfo;
2598 case Type::ObjCObjectPointer:
2601 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
2604 case Type::MemberPointer:
2606 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
2610 llvm::Constant *VTable =
2613 llvm::Type *PtrDiffTy =
2617 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
2619 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8PtrTy, VTable, Two);
2620 VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.
Int8PtrTy);
2622 Fields.push_back(VTable);
2652 return llvm::GlobalValue::LinkOnceODRLinkage;
2655 if (
const RecordType *Record = dyn_cast<RecordType>(Ty)) {
2656 const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
2658 return llvm::GlobalValue::WeakODRLinkage;
2663 if (RD->
hasAttr<DLLImportAttr>() &&
2664 llvm::GlobalValue::isAvailableExternallyLinkage(LT))
2665 LT = llvm::GlobalValue::LinkOnceODRLinkage;
2670 return llvm::GlobalValue::LinkOnceODRLinkage;
2673 llvm_unreachable(
"Invalid linkage!");
2676 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty,
bool Force) {
2682 llvm::raw_svector_ostream Out(OutName);
2685 StringRef Name = OutName.str();
2687 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
2688 if (OldGV && !OldGV->isDeclaration()) {
2689 assert(!OldGV->hasAvailableExternallyLinkage() &&
2690 "available_externally typeinfos not yet implemented");
2692 return llvm::ConstantExpr::getBitCast(OldGV, CGM.
Int8PtrTy);
2698 return GetAddrOfExternalRTTIDescriptor(Ty);
2701 llvm::GlobalVariable::LinkageTypes
Linkage;
2708 BuildVTablePointer(cast<Type>(Ty));
2711 llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
2712 llvm::Constant *TypeNameField;
2716 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
2717 CXXABI.classifyRTTIUniqueness(Ty, Linkage);
2718 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
2721 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
2722 llvm::Constant *flag =
2723 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
2724 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
2726 llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.
Int8PtrTy);
2728 TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.
Int8PtrTy);
2730 Fields.push_back(TypeNameField);
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");
2744 case Type::ExtVector:
2746 case Type::BlockPointer:
2751 case Type::LValueReference:
2752 case Type::RValueReference:
2753 llvm_unreachable(
"References shouldn't get here");
2756 llvm_unreachable(
"Undeduced auto type shouldn't get here");
2758 case Type::ConstantArray:
2759 case Type::IncompleteArray:
2760 case Type::VariableArray:
2765 case Type::FunctionNoProto:
2766 case Type::FunctionProto:
2776 case Type::Record: {
2778 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
2785 BuildSIClassTypeInfo(RD);
2787 BuildVMIClassTypeInfo(RD);
2792 case Type::ObjCObject:
2793 case Type::ObjCInterface:
2794 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
2797 case Type::ObjCObjectPointer:
2798 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
2802 BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
2805 case Type::MemberPointer:
2806 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
2814 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
2817 llvm::GlobalVariable *GV =
2818 new llvm::GlobalVariable(M, Init->getType(),
2822 GV->setComdat(M.getOrInsertComdat(GV->getName()));
2826 GV->takeName(OldGV);
2827 llvm::Constant *NewPtr =
2828 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
2829 OldGV->replaceAllUsesWith(NewPtr);
2830 OldGV->eraseFromParent();
2850 llvm::GlobalValue::VisibilityTypes llvmVisibility;
2851 if (llvm::GlobalValue::isLocalLinkage(Linkage))
2854 else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden)
2858 TypeName->setVisibility(llvmVisibility);
2859 GV->setVisibility(llvmVisibility);
2861 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
2870 Flags |= ItaniumRTTIBuilder::PTI_Const;
2872 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
2874 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
2881 void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
2884 assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
2888 if (isa<BuiltinType>(T))
return;
2899 llvm::Constant *BaseTypeInfo =
2900 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
2901 Fields.push_back(BaseTypeInfo);
2906 void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
2910 llvm::Constant *BaseTypeInfo =
2912 Fields.push_back(BaseTypeInfo);
2919 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
2920 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
2937 if (!Bases.VirtualBases.insert(BaseDecl).second) {
2940 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
2942 if (Bases.NonVirtualBases.count(BaseDecl))
2943 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
2947 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
2950 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
2952 if (Bases.VirtualBases.count(BaseDecl))
2953 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
2958 for (
const auto &I : BaseDecl->
bases())
2969 for (
const auto &I : RD->
bases())
2978 void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
2979 llvm::Type *UnsignedIntLTy =
2987 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
2992 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
2997 llvm::Type *LongLTy =
3017 for (
const auto &Base : RD->
bases()) {
3019 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(Base.getType()));
3022 cast<CXXRecordDecl>(Base.getType()->getAs<
RecordType>()->getDecl());
3024 int64_t OffsetFlags = 0;
3031 if (Base.isVirtual())
3039 OffsetFlags = uint64_t(Offset.
getQuantity()) << 8;
3043 if (Base.isVirtual())
3044 OffsetFlags |= BCTI_Virtual;
3045 if (Base.getAccessSpecifier() ==
AS_public)
3046 OffsetFlags |= BCTI_Public;
3048 Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
3054 void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
3068 Flags |= PTI_Incomplete;
3070 llvm::Type *UnsignedIntLTy =
3072 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3077 llvm::Constant *PointeeTypeInfo =
3078 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
3079 Fields.push_back(PointeeTypeInfo);
3103 Flags |= PTI_Incomplete;
3106 Flags |= PTI_ContainingClassIncomplete;
3108 llvm::Type *UnsignedIntLTy =
3110 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3115 llvm::Constant *PointeeTypeInfo =
3116 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
3117 Fields.push_back(PointeeTypeInfo);
3124 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
3127 llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
3128 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
3131 void ItaniumCXXABI::EmitFundamentalRTTIDescriptor(
QualType Type) {
3134 ItaniumRTTIBuilder(*this).BuildTypeInfo(Type,
true);
3135 ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType,
true);
3136 ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst,
true);
3139 void ItaniumCXXABI::EmitFundamentalRTTIDescriptors() {
3141 getContext().VoidTy, getContext().NullPtrTy,
3142 getContext().BoolTy, getContext().WCharTy,
3143 getContext().CharTy, getContext().UnsignedCharTy,
3144 getContext().SignedCharTy, getContext().ShortTy,
3145 getContext().UnsignedShortTy, getContext().IntTy,
3146 getContext().UnsignedIntTy, getContext().LongTy,
3147 getContext().UnsignedLongTy, getContext().LongLongTy,
3148 getContext().UnsignedLongLongTy, getContext().HalfTy,
3149 getContext().FloatTy, getContext().DoubleTy,
3150 getContext().LongDoubleTy, getContext().Char16Ty,
3151 getContext().Char32Ty,
3153 for (
const QualType &FundamentalType : FundamentalTypes)
3154 EmitFundamentalRTTIDescriptor(FundamentalType);
3159 ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
3160 QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage)
const {
3161 if (shouldRTTIBeUnique())
3165 if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
3166 Linkage != llvm::GlobalValue::WeakODRLinkage)
3174 if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3175 return RUK_NonUniqueHidden;
3180 assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
3181 return RUK_NonUniqueVisible;
3191 return StructorCodegen::Emit;
3196 return StructorCodegen::Emit;
3199 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
3202 const auto *CD = cast<CXXConstructorDecl>(MD);
3207 if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
3208 return StructorCodegen::RAUW;
3211 if (!llvm::GlobalAlias::isValidLinkage(Linkage))
3212 return StructorCodegen::RAUW;
3214 if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
3217 return StructorCodegen::COMDAT;
3218 return StructorCodegen::Emit;
3221 return StructorCodegen::Alias;
3231 if (Entry && !Entry->isDeclaration())
3234 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
3235 llvm::PointerType *AliasType = Aliasee->getType();
3243 assert(Entry->getType() == AliasType &&
3244 "declaration exists with different type");
3245 Alias->takeName(Entry);
3246 Entry->replaceAllUsesWith(Alias);
3247 Entry->eraseFromParent();
3249 Alias->setName(MangledName);
3256 void ItaniumCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3274 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
3279 if (CGType == StructorCodegen::RAUW) {
3281 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(BaseDecl));
3297 if (CGType == StructorCodegen::COMDAT) {
3299 llvm::raw_svector_ostream Out(Buffer);
3301 getMangleContext().mangleCXXDtorComdat(DD, Out);
3303 getMangleContext().mangleCXXCtorComdat(CD, Out);
3304 llvm::Comdat *C = CGM.
getModule().getOrInsertComdat(Out.str());
3313 llvm::FunctionType *FTy = llvm::FunctionType::get(
3321 llvm::FunctionType *FTy =
3322 llvm::FunctionType::get(CGM.
VoidTy,
false);
3329 llvm::FunctionType *FTy = llvm::FunctionType::get(
3349 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
3369 bool EndMightThrow) {
3370 llvm::CallInst *call =
3393 if (isa<ReferenceType>(CatchType)) {
3394 QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
3403 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
3412 unsigned HeaderSize =
3414 AdjustedExn = CGF.
Builder.CreateConstGEP1_32(Exn, HeaderSize);
3438 CGF.
Builder.CreateStore(Casted, ExnPtrTmp);
3441 AdjustedExn = ExnPtrTmp;
3446 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.byref");
3447 CGF.
Builder.CreateStore(ExnCast, ParamAddr);
3458 if (CatchType->hasPointerRepresentation()) {
3460 CGF.
Builder.CreateBitCast(AdjustedExn, LLVMCatchTy,
"exn.casted");
3470 CGF.
Builder.CreateStore(CastExn, ParamAddr);
3477 llvm_unreachable(
"bad ownership qualifier!");
3482 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
3499 llvm_unreachable(
"evaluation kind filtered out!");
3501 llvm_unreachable(
"bad evaluation kind");
3504 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
3506 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
3520 llvm::CallInst *rawAdjustedExn =
3597 llvm::FunctionType *fnTy =
3599 llvm::Constant *fnRef =
3602 llvm::Function *fn = dyn_cast<llvm::Function>(fnRef);
3603 if (fn && fn->empty()) {
3604 fn->setDoesNotThrow();
3605 fn->setDoesNotReturn();
3610 fn->addFnAttr(llvm::Attribute::NoInline);
3614 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
3617 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
3620 llvm::BasicBlock *entry =
3628 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
3629 catchCall->setDoesNotThrow();
3633 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
3634 termCall->setDoesNotThrow();
3635 termCall->setDoesNotReturn();
3639 builder.CreateUnreachable();
3646 ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
void pushTerminate()
Push a terminate handler on the stack.
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.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
External linkage, which indicates that the entity can be referred to from other translation units...
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)
static llvm::Constant * getAllocateExceptionFn(CodeGenModule &CGM)
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
void EmitAnyExprToExn(const Expr *E, llvm::Value *Addr)
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()
IdentifierInfo * getIdentifier() const
const TargetInfo & getTarget() const
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
bool isGlobalDelete() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
No linkage, which means that the entity is unique and can only be referred to from within its scope...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isRecordType() const
void setAliasAttributes(const Decl *D, llvm::GlobalValue *GV)
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
llvm::CallingConv::ID getRuntimeCC() const
static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
vtable_component_iterator vtable_component_begin() const
bool hasDefinition() const
QualType getPointeeType() const
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
const Expr * getInit() const
bool isFuncTypeConvertible(const FunctionType *FT)
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V)
static const OpaqueValueExpr * findInCopyConstruct(const Expr *expr)
TLSKind getTLSKind() const
ObjCLifetime getObjCLifetime() const
SourceLocation getLocStart() const LLVM_READONLY
A this pointer adjustment.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr)
llvm::Value * ReturnValue
llvm::Type * ConvertTypeForMem(QualType T)
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...
GlobalDecl getCanonicalDecl() const
static llvm::Constant * getClangCallTerminateFn(CodeGenModule &CGM)
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
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 ...
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
bool isCompleteDefinition() const
uint64_t getNumVTableComponents() const
llvm::IntegerType * SizeTy
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
StructorType getFromDtorType(CXXDtorType T)
void EmitARCInitWeak(llvm::Value *value, llvm::Value *addr)
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
struct clang::ReturnAdjustment::VirtualAdjustment::@113 Itanium
bool isTranslationUnit() const
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.
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment=CharUnits())
llvm::Value * GetVTablePtr(llvm::Value *This, llvm::Type *Ty)
const TargetInfo & getTargetInfo() const
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
const LangOptions & getLangOpts() const
QualType getBaseType() const
const ValueDecl * getMemberPointerDecl() const
const CXXRecordDecl * getParent() const
virtual unsigned getSizeOfUnwindException() const
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)
Register a global destructor using the C atexit runtime function.
llvm::Constant * getTerminateFn()
Get the declaration of std::terminate for the platform.
llvm::Value * getObjectAddress(CodeGenFunction &CGF) const
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
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.
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)
bool isStaticLocal() const
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
Represents an ObjC class declaration.
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
bool isMemberFunctionPointer() 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.
FunctionDecl * getOperatorDelete() const
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, llvm::GlobalVariable *Guard=nullptr)
static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty)
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
const TargetCodeGenInfo & getTargetCodeGenInfo()
const TargetInfo & getTarget() const
union clang::ReturnAdjustment::VirtualAdjustment Virtual
bool isVTableExternal(const CXXRecordDecl *RD)
QualType getPointeeType() const
struct clang::ThisAdjustment::VirtualAdjustment::@115 Itanium
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
static TypeEvaluationKind getEvaluationKind(QualType T)
CXXDtorType
C++ destructor types.
CXXDtorType getDtorType() const
Qualifiers getQualifiers() const
Retrieve all qualifiers.
static llvm::Constant * getBadTypeidFn(CodeGenFunction &CGF)
CGCXXABI & getCXXABI() const
RValue EmitCXXMemberOrOperatorCall(const CXXMethodDecl *MD, llvm::Value *Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E)
llvm::Value * GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
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()
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.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
The result type of a method or function.
llvm::IRBuilder< PreserveNames, llvm::ConstantFolder, CGBuilderInserterTy > CGBuilderTy
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage)
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
There is no lifetime qualification on this type.
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.
virtual void mangleCXXRTTIName(QualType T, raw_ostream &)=0
ASTContext & getContext() const
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
const Type * getTypePtr() const
Visibility getVisibility() const
Determine the visibility of this type.
void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr, QualType EltTy, bool isVolatile=false, CharUnits Alignment=CharUnits::Zero(), bool isAssignment=false)
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
bool isLocalVarDecl() const
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)
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.
const CodeGenOptions & getCodeGenOpts() const
static unsigned ComputeQualifierFlags(Qualifiers Quals)
bool isMemberDataPointer() const
const LangOptions & getLangOpts() const
static llvm::Value * performTypeAdjustment(CodeGenFunction &CGF, llvm::Value *Ptr, int64_t NonVirtualAdjustment, int64_t VirtualAdjustment, bool IsReturnAdjustment)
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset. ...
MangleContext & getMangleContext()
Gets the mangle context.
ItaniumVTableContext & getItaniumVTableContext()
Assigning into this object requires a lifetime extension.
static llvm::Constant * getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
bool isDynamicClass() const
CXXCtorType
C++ constructor types.
QualType getPointeeType() const
void addReplacement(StringRef Name, llvm::Constant *C)
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
TLS with a dynamic initializer.
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
const Expr * getSubExpr() const
static const Type * getElementType(const Expr *BaseExpr)
External linkage within a unique namespace.
Represents a delete expression for memory deallocation and destructor calls, e.g. "delete[] pArray"...
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
bool isZero() const
isZero - Test whether the quantity equals zero.
unsigned char PointerAlignInBytes
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::IntegerType * IntPtrTy
static llvm::Value * CallBeginCatch(CodeGenFunction &CGF, llvm::Value *Exn, bool EndMightThrow)
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.
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)
void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo=nullptr, bool isInit=false, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0)
union clang::ThisAdjustment::VirtualAdjustment Virtual
void EmitAggExpr(const Expr *E, AggValueSlot AS)
vtable_thunk_iterator vtable_thunk_begin() const
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>. Pointer - pointer requires t...
FunctionDecl * getOperatorNew() const
static void InitCatchParam(CodeGenFunction &CGF, const VarDecl &CatchParam, llvm::Value *ParamAddr, SourceLocation Loc)
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.
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)
ABIArgInfo & getReturnInfo()
Represents a base class of a C++ class.
llvm::Value * LoadCXXVTT()
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)
static bool ContainsIncompleteClassType(QualType Ty)
llvm::Type * ConvertType(QualType T)
void popTerminate()
Pops a terminate handler off the stack.
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD)
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)
static llvm::Constant * getItaniumDynamicCastFn(CodeGenFunction &CGF)
ObjCInterfaceDecl * getSuperClass() const
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, SourceLocation Loc=SourceLocation(), bool TLS=false)
static llvm::Constant * getEndCatchFn(CodeGenModule &CGM)
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::Constant *dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
unsigned char SizeSizeInBytes
VarDecl * getExceptionDecl() const
static RValue get(llvm::Value *V)
llvm::Value * EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, SourceLocation Loc, llvm::MDNode *TBAAInfo=nullptr, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0)
static llvm::Constant * getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
static AggValueSlot forAddr(llvm::Value *addr, CharUnits align, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
CodeGenVTables & getVTables()
static void emitConstructorDestructorAlias(CodeGenModule &CGM, GlobalDecl AliasDecl, GlobalDecl TargetDecl)
CodeGenTypes & getTypes() const
SourceLocation getLocation() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
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)
static bool CanUseSingleInheritance(const CXXRecordDecl *RD)
static llvm::Constant * getBeginCatchFn(CodeGenModule &CGM)
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
std::list< CXXBasePath >::iterator paths_iterator
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)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.