32 #include "llvm/IR/CallSite.h" 33 #include "llvm/IR/DataLayout.h" 34 #include "llvm/IR/GlobalValue.h" 35 #include "llvm/IR/Instructions.h" 36 #include "llvm/IR/Intrinsics.h" 37 #include "llvm/IR/Value.h" 38 #include "llvm/Support/ScopedPrinter.h" 40 using namespace clang;
41 using namespace CodeGen;
46 llvm::DenseMap<const CXXRecordDecl *, llvm::GlobalVariable *> VTables;
49 bool UseARMMethodPtrABI;
50 bool UseARMGuardVarABI;
51 bool Use32BitVTableOffsetABI;
59 bool UseARMMethodPtrABI =
false,
60 bool UseARMGuardVarABI =
false) :
61 CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
62 UseARMGuardVarABI(UseARMGuardVarABI),
63 Use32BitVTableOffsetABI(
false) { }
68 return !canCopyArgument(RD);
73 if (passClassIndirect(RD))
78 bool isThisCompleteObject(
GlobalDecl GD)
const override {
81 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
91 llvm_unreachable(
"emitting dtor comdat as function?");
93 llvm_unreachable(
"bad dtor kind");
95 if (isa<CXXConstructorDecl>(GD.
getDecl())) {
105 llvm_unreachable(
"closure ctors in Itanium ABI?");
108 llvm_unreachable(
"emitting ctor comdat as function?");
110 llvm_unreachable(
"bad dtor kind");
138 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
139 llvm::Constant *Src)
override;
143 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
146 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
153 bool Inequality)
override;
172 auto align = CGM.getContext().getTargetDefaultAlignForAttributeAligned();
173 return CGM.getContext().toCharUnitsFromBits(align);
185 void EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD);
186 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
188 getAddrOfCXXCatchHandlerType(
QualType Ty,
189 QualType CatchHandlerType)
override {
193 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
199 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
205 llvm::BasicBlock *CastEnd)
override;
246 bool Delegating,
Address This)
override;
254 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
266 llvm::Value *getVTableAddressPointInStructorWithVTT(
274 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
287 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
289 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
291 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
GlobalDecl GD,
295 if (ForVTable && !Thunk->hasLocalLinkage())
296 Thunk->setLinkage(llvm::GlobalValue::AvailableExternallyLinkage);
297 CGM.setGVProperties(Thunk, GD);
300 bool exportThunk()
override {
return true; }
306 const ReturnAdjustment &RA)
override;
310 assert(!Args.empty() &&
"expected the arglist to not be empty!");
311 return Args.size() - 1;
314 StringRef GetPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
315 StringRef GetDeletedVirtualCallName()
override 316 {
return "__cxa_deleted_virtual"; }
329 llvm::GlobalVariable *DeclPtr,
330 bool PerformInit)
override;
332 llvm::Constant *dtor, llvm::Constant *addr)
override;
334 llvm::Function *getOrCreateThreadLocalWrapper(
const VarDecl *VD,
336 void EmitThreadLocalInitFuncs(
342 bool usesThreadWrapperFunction()
const override {
return true; }
346 bool NeedsVTTParameter(
GlobalDecl GD)
override;
353 virtual bool shouldRTTIBeUnique()
const {
return true; }
357 enum RTTIUniquenessKind {
375 classifyRTTIUniqueness(
QualType CanTy,
376 llvm::GlobalValue::LinkageTypes
Linkage)
const;
377 friend class ItaniumRTTIBuilder;
381 std::pair<llvm::Value *, const CXXRecordDecl *>
386 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *RD)
const {
387 const auto &VtableLayout =
388 CGM.getItaniumVTableContext().getVTableLayout(RD);
390 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
392 if (!VtableComponent.isUsedFunctionPointerKind())
395 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
399 StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
400 auto *Entry = CGM.GetGlobalValue(Name);
406 if (!Entry || Entry->isDeclaration())
413 const auto &VtableLayout =
414 CGM.getItaniumVTableContext().getVTableLayout(RD);
416 for (
const auto &VtableComponent : VtableLayout.vtable_components()) {
417 if (VtableComponent.isRTTIKind()) {
418 const CXXRecordDecl *RTTIDecl = VtableComponent.getRTTIDecl();
421 }
else if (VtableComponent.isUsedFunctionPointerKind()) {
422 const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
432 class ARMCXXABI :
public ItaniumCXXABI {
435 ItaniumCXXABI(CGM,
true,
438 bool HasThisReturn(
GlobalDecl GD)
const override {
439 return (isa<CXXConstructorDecl>(GD.
getDecl()) || (
440 isa<CXXDestructorDecl>(GD.
getDecl()) &&
457 class iOS64CXXABI :
public ARMCXXABI {
460 Use32BitVTableOffsetABI =
true;
464 bool shouldRTTIBeUnique()
const override {
return false; }
467 class WebAssemblyCXXABI final :
public ItaniumCXXABI {
470 : ItaniumCXXABI(CGM,
true,
475 bool HasThisReturn(
GlobalDecl GD)
const override {
476 return isa<CXXConstructorDecl>(GD.
getDecl()) ||
477 (isa<CXXDestructorDecl>(GD.
getDecl()) &&
480 bool canCallMismatchedFunctionType()
const override {
return false; }
491 return new ARMCXXABI(CGM);
494 return new iOS64CXXABI(CGM);
500 return new ItaniumCXXABI(CGM,
true,
504 return new ItaniumCXXABI(CGM,
true);
507 return new WebAssemblyCXXABI(CGM);
511 == llvm::Triple::le32) {
515 return new ItaniumCXXABI(CGM,
true,
518 return new ItaniumCXXABI(CGM);
521 llvm_unreachable(
"Microsoft ABI is not Itanium-based");
523 llvm_unreachable(
"bad ABI kind");
529 return CGM.PtrDiffTy;
530 return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
553 CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
564 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
565 CGM.getTypes().arrangeCXXMethodType(RD, FPT,
nullptr));
567 llvm::Constant *ptrdiff_1 = llvm::ConstantInt::get(CGM.PtrDiffTy, 1);
574 llvm::Value *RawAdj = Builder.CreateExtractValue(MemFnPtr, 1,
"memptr.adj");
578 if (UseARMMethodPtrABI)
579 Adj = Builder.CreateAShr(Adj, ptrdiff_1,
"memptr.adj.shifted");
585 Ptr = Builder.CreateInBoundsGEP(Ptr, Adj);
586 This = Builder.
CreateBitCast(Ptr, This->getType(),
"this.adjusted");
587 ThisPtrForCall = This;
590 llvm::Value *FnAsInt = Builder.CreateExtractValue(MemFnPtr, 0,
"memptr.ptr");
595 if (UseARMMethodPtrABI)
596 IsVirtual = Builder.CreateAnd(RawAdj, ptrdiff_1);
598 IsVirtual = Builder.CreateAnd(FnAsInt, ptrdiff_1);
599 IsVirtual = Builder.CreateIsNotNull(IsVirtual,
"memptr.isvirtual");
600 Builder.CreateCondBr(IsVirtual, FnVirtual, FnNonVirtual);
608 llvm::Type *VTableTy = Builder.getInt8PtrTy();
619 if (!UseARMMethodPtrABI)
620 VTableOffset = Builder.CreateSub(VTableOffset, ptrdiff_1);
621 if (Use32BitVTableOffsetABI) {
622 VTableOffset = Builder.CreateTrunc(VTableOffset, CGF.
Int32Ty);
623 VTableOffset = Builder.CreateZExt(VTableOffset, CGM.PtrDiffTy);
626 llvm::Value *VFPAddr = Builder.CreateGEP(VTable, VTableOffset);
630 llvm::Constant *CheckSourceLocation;
631 llvm::Constant *CheckTypeDesc;
632 bool ShouldEmitCFICheck = CGF.
SanOpts.
has(SanitizerKind::CFIMFCall) &&
633 CGM.HasHiddenLTOVisibility(RD);
634 if (ShouldEmitCFICheck) {
639 llvm::Constant *StaticData[] = {
646 CGM.CreateMetadataIdentifierForVirtualMemPtrType(
QualType(MPT, 0));
650 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VFPAddr, TypeId});
652 if (CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIMFCall)) {
655 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
656 CGM.getLLVMContext(),
657 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
659 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
660 CGF.
EmitCheck(std::make_pair(TypeTest, SanitizerKind::CFIMFCall),
661 SanitizerHandler::CFICheckFail, StaticData,
662 {VTable, ValidVtable});
665 FnVirtual = Builder.GetInsertBlock();
669 VFPAddr = Builder.
CreateBitCast(VFPAddr, FTy->getPointerTo()->getPointerTo());
678 Builder.CreateIntToPtr(FnAsInt, FTy->getPointerTo(),
"memptr.nonvirtualfn");
681 if (ShouldEmitCFICheck) {
686 llvm::Constant *StaticData[] = {
696 llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
697 getContext().getMemberPointerType(
704 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
705 {CastedNonVirtualFn, TypeId});
706 Bit = Builder.CreateOr(Bit, TypeTest);
709 CGF.
EmitCheck(std::make_pair(Bit, SanitizerKind::CFIMFCall),
710 SanitizerHandler::CFICheckFail, StaticData,
711 {CastedNonVirtualFn, llvm::UndefValue::get(CGF.
IntPtrTy)});
713 FnNonVirtual = Builder.GetInsertBlock();
719 llvm::PHINode *CalleePtr = Builder.CreatePHI(FTy->getPointerTo(), 2);
720 CalleePtr->addIncoming(VirtualFn, FnVirtual);
721 CalleePtr->addIncoming(NonVirtualFn, FnNonVirtual);
729 llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
732 assert(MemPtr->getType() == CGM.PtrDiffTy);
737 Base = Builder.CreateElementBitCast(Base, CGF.
Int8Ty);
741 Builder.CreateInBoundsGEP(Base.
getPointer(), MemPtr,
"memptr.offset");
747 return Builder.CreateBitCast(Addr, PType);
777 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
778 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
782 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
785 if (isa<llvm::Constant>(src))
786 return EmitMemberPointerConversion(E, cast<llvm::Constant>(src));
788 llvm::Constant *adj = getMemberPointerAdjustment(E);
789 if (!adj)
return src;
792 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
802 dst = Builder.CreateNSWSub(src, adj,
"adj");
804 dst = Builder.CreateNSWAdd(src, adj,
"adj");
807 llvm::Value *null = llvm::Constant::getAllOnesValue(src->getType());
808 llvm::Value *isNull = Builder.CreateICmpEQ(src, null,
"memptr.isnull");
809 return Builder.CreateSelect(isNull, src, dst);
813 if (UseARMMethodPtrABI) {
814 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
816 adj = llvm::ConstantInt::get(adj->getType(), offset);
819 llvm::Value *srcAdj = Builder.CreateExtractValue(src, 1,
"src.adj");
822 dstAdj = Builder.CreateNSWSub(srcAdj, adj,
"adj");
824 dstAdj = Builder.CreateNSWAdd(srcAdj, adj,
"adj");
826 return Builder.CreateInsertValue(src, dstAdj, 1);
830 ItaniumCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
831 llvm::Constant *src) {
832 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
833 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
837 if (E->
getCastKind() == CK_ReinterpretMemberPointer)
return src;
840 llvm::Constant *adj = getMemberPointerAdjustment(E);
841 if (!adj)
return src;
843 bool isDerivedToBase = (E->
getCastKind() == CK_DerivedToBaseMemberPointer);
852 if (src->isAllOnesValue())
return src;
855 return llvm::ConstantExpr::getNSWSub(src, adj);
857 return llvm::ConstantExpr::getNSWAdd(src, adj);
861 if (UseARMMethodPtrABI) {
862 uint64_t offset = cast<llvm::ConstantInt>(adj)->getZExtValue();
864 adj = llvm::ConstantInt::get(adj->getType(), offset);
867 llvm::Constant *srcAdj = llvm::ConstantExpr::getExtractValue(src, 1);
868 llvm::Constant *dstAdj;
870 dstAdj = llvm::ConstantExpr::getNSWSub(srcAdj, adj);
872 dstAdj = llvm::ConstantExpr::getNSWAdd(srcAdj, adj);
874 return llvm::ConstantExpr::getInsertValue(src, dstAdj, 1);
882 return llvm::ConstantInt::get(CGM.PtrDiffTy, -1ULL,
true);
884 llvm::Constant *Zero = llvm::ConstantInt::get(CGM.PtrDiffTy, 0);
885 llvm::Constant *Values[2] = { Zero, Zero };
886 return llvm::ConstantStruct::getAnon(Values);
895 return llvm::ConstantInt::get(CGM.PtrDiffTy, offset.
getQuantity());
899 ItaniumCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
903 llvm::Constant *ItaniumCXXABI::BuildMemberPointer(
const CXXMethodDecl *MD,
905 assert(MD->
isInstance() &&
"Member function must not be static!");
910 llvm::Constant *MemPtr[2];
912 uint64_t Index = CGM.getItaniumVTableContext().getMethodVTableIndex(MD);
917 uint64_t VTableOffset = (Index * PointerWidth.
getQuantity());
919 if (UseARMMethodPtrABI) {
926 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset);
927 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
934 MemPtr[0] = llvm::ConstantInt::get(CGM.PtrDiffTy, VTableOffset + 1);
935 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
942 if (Types.isFuncTypeConvertible(FPT)) {
944 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
950 llvm::Constant *addr = CGM.GetAddrOfFunction(MD, Ty);
952 MemPtr[0] = llvm::ConstantExpr::getPtrToInt(addr, CGM.PtrDiffTy);
953 MemPtr[1] = llvm::ConstantInt::get(CGM.PtrDiffTy,
954 (UseARMMethodPtrABI ? 2 : 1) *
958 return llvm::ConstantStruct::getAnon(MemPtr);
961 llvm::Constant *ItaniumCXXABI::EmitMemberPointer(
const APValue &MP,
966 return EmitNullMemberPointer(MPT);
968 CharUnits ThisAdjustment = getMemberPointerPathAdjustment(MP);
971 return BuildMemberPointer(MD, ThisAdjustment);
974 getContext().toCharUnitsFromBits(getContext().
getFieldOffset(MPD));
975 return EmitMemberDataPointer(MPT, ThisAdjustment + FieldOffset);
990 llvm::ICmpInst::Predicate Eq;
991 llvm::Instruction::BinaryOps
And, Or;
993 Eq = llvm::ICmpInst::ICMP_NE;
994 And = llvm::Instruction::Or;
997 Eq = llvm::ICmpInst::ICMP_EQ;
999 Or = llvm::Instruction::Or;
1005 return Builder.CreateICmp(Eq, L, R);
1017 llvm::Value *LPtr = Builder.CreateExtractValue(L, 0,
"lhs.memptr.ptr");
1018 llvm::Value *RPtr = Builder.CreateExtractValue(R, 0,
"rhs.memptr.ptr");
1022 llvm::Value *PtrEq = Builder.CreateICmp(Eq, LPtr, RPtr,
"cmp.ptr");
1027 llvm::Value *Zero = llvm::Constant::getNullValue(LPtr->getType());
1028 llvm::Value *EqZero = Builder.CreateICmp(Eq, LPtr, Zero,
"cmp.ptr.null");
1032 llvm::Value *LAdj = Builder.CreateExtractValue(L, 1,
"lhs.memptr.adj");
1033 llvm::Value *RAdj = Builder.CreateExtractValue(R, 1,
"rhs.memptr.adj");
1034 llvm::Value *AdjEq = Builder.CreateICmp(Eq, LAdj, RAdj,
"cmp.adj");
1038 if (UseARMMethodPtrABI) {
1039 llvm::Value *One = llvm::ConstantInt::get(LPtr->getType(), 1);
1042 llvm::Value *OrAdj = Builder.CreateOr(LAdj, RAdj,
"or.adj");
1043 llvm::Value *OrAdjAnd1 = Builder.CreateAnd(OrAdj, One);
1044 llvm::Value *OrAdjAnd1EqZero = Builder.CreateICmp(Eq, OrAdjAnd1, Zero,
1046 EqZero = Builder.CreateBinOp(And, EqZero, OrAdjAnd1EqZero);
1050 llvm::Value *Result = Builder.CreateBinOp(Or, EqZero, AdjEq);
1051 Result = Builder.CreateBinOp(And, PtrEq, Result,
1052 Inequality ?
"memptr.ne" :
"memptr.eq");
1064 assert(MemPtr->getType() == CGM.PtrDiffTy);
1066 llvm::Constant::getAllOnesValue(MemPtr->getType());
1067 return Builder.CreateICmpNE(MemPtr, NegativeOne,
"memptr.tobool");
1071 llvm::Value *Ptr = Builder.CreateExtractValue(MemPtr, 0,
"memptr.ptr");
1073 llvm::Constant *Zero = llvm::ConstantInt::get(Ptr->getType(), 0);
1074 llvm::Value *Result = Builder.CreateICmpNE(Ptr, Zero,
"memptr.tobool");
1078 if (UseARMMethodPtrABI) {
1079 llvm::Constant *One = llvm::ConstantInt::get(Ptr->getType(), 1);
1080 llvm::Value *Adj = Builder.CreateExtractValue(MemPtr, 1,
"memptr.adj");
1081 llvm::Value *VirtualBit = Builder.CreateAnd(Adj, One,
"memptr.virtualbit");
1082 llvm::Value *IsVirtual = Builder.CreateICmpNE(VirtualBit, Zero,
1083 "memptr.isvirtual");
1084 Result = Builder.CreateOr(Result, IsVirtual);
1096 if (passClassIndirect(RD)) {
1097 auto Align = CGM.getContext().getTypeAlignInChars(FI.
getReturnType());
1118 if (UseGlobalDelete) {
1130 VTable, -2,
"complete-offset.ptr");
1137 CompletePtr = CGF.
Builder.CreateInBoundsGEP(CompletePtr, Offset);
1148 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
1150 if (UseGlobalDelete)
1154 void ItaniumCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
1157 llvm::FunctionType *FTy =
1158 llvm::FunctionType::get(CGM.VoidTy,
false);
1160 llvm::Constant *Fn = CGM.CreateRuntimeFunction(FTy,
"__cxa_rethrow");
1171 llvm::FunctionType *FTy =
1182 llvm::FunctionType *FTy =
1183 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
1192 uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
1196 AllocExceptionFn, llvm::ConstantInt::get(SizeTy, TypeSize),
"exception");
1198 CharUnits ExnAlign = getAlignmentOfExnObject();
1202 llvm::Constant *
TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType,
1207 llvm::Constant *Dtor =
nullptr;
1209 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
1213 Dtor = llvm::ConstantExpr::getBitCast(Dtor, CGM.Int8PtrTy);
1216 if (!Dtor) Dtor = llvm::Constant::getNullValue(CGM.Int8PtrTy);
1218 llvm::Value *args[] = { ExceptionPtr, TypeInfo, Dtor };
1232 llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
1234 llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args,
false);
1237 llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
1238 llvm::Attribute::ReadOnly };
1239 llvm::AttributeList Attrs = llvm::AttributeList::get(
1240 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);
1247 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1264 unsigned NumPublicPaths = 0;
1277 if (PathElement.Base->isVirtual())
1280 if (NumPublicPaths > 1)
1286 PathElement.Base->getType()->getAsCXXRecordDecl());
1291 if (NumPublicPaths == 0)
1295 if (NumPublicPaths > 1)
1305 llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.
VoidTy,
false);
1310 bool ItaniumCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
1318 CGF.
Builder.CreateUnreachable();
1328 CGF.
GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo(), ClassDecl);
1331 Value = CGF.
Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
1335 bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1370 llvm::BasicBlock *BadCastBlock =
1374 CGF.
Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
1377 EmitBadCastCall(CGF);
1399 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
1407 Value = CGF.
Builder.CreateInBoundsGEP(Value, OffsetToTop);
1415 CGF.
Builder.CreateUnreachable();
1426 CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
1431 "vbase.offset.ptr");
1433 CGM.PtrDiffTy->getPointerTo());
1444 assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
1468 ArgTys.insert(ArgTys.begin() + 1,
1470 return AddedStructorArgs::prefix(1);
1472 return AddedStructorArgs{};
1495 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1498 if (NeedsVTTParameter(CGF.
CurGD)) {
1506 Params.insert(Params.begin() + 1, VTTDecl);
1507 getStructorImplicitParamDecl(CGF) = VTTDecl;
1511 void ItaniumCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1518 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1521 if (getStructorImplicitParamDecl(CGF)) {
1534 if (HasThisReturn(CGF.
CurGD))
1540 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1542 return AddedStructorArgs{};
1547 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1549 return AddedStructorArgs::prefix(1);
1555 bool Delegating,
Address This) {
1558 QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
1561 if (getContext().getLangOpts().AppleKext &&
1576 llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
CharUnits());
1577 if (VTable->hasInitializer())
1582 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
1583 llvm::Constant *RTTI =
1584 CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
1590 Components.finishAndSetAsInitializer(VTable);
1593 VTable->setLinkage(Linkage);
1595 if (CGM.supportsCOMDAT() && VTable->isWeakForLinker())
1596 VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
1599 CGM.setGVProperties(VTable, RD);
1604 unsigned PAlign = CGM.getTarget().getPointerAlign(0);
1605 VTable->setAlignment(getContext().toCharUnitsFromBits(PAlign).getQuantity());
1613 isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
1614 cast<NamespaceDecl>(DC)->
getIdentifier()->isStr(
"__cxxabiv1") &&
1616 EmitFundamentalRTTIDescriptors(RD);
1618 if (!VTable->isDeclarationForLinker())
1619 CGM.EmitVTableTypeMetadata(VTable, VTLayout);
1622 bool ItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1626 return NeedsVTTParameter(CGF.
CurGD);
1629 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
1634 NeedsVTTParameter(CGF.
CurGD)) {
1635 return getVTableAddressPointInStructorWithVTT(CGF, VTableClass, Base,
1638 return getVTableAddressPoint(Base, VTableClass);
1644 llvm::GlobalValue *VTable = getAddrOfVTable(VTableClass,
CharUnits());
1649 CGM.getItaniumVTableContext()
1650 .getVTableLayout(VTableClass)
1651 .getAddressPoint(Base);
1653 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1654 llvm::ConstantInt::get(CGM.Int32Ty, AddressPoint.
VTableIndex),
1658 return llvm::ConstantExpr::getGetElementPtr(VTable->getValueType(), VTable,
1663 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1667 NeedsVTTParameter(CGF.
CurGD) &&
"This class doesn't have VTT");
1670 uint64_t VirtualPointerIndex =
1671 CGM.getVTables().getSecondaryVirtualPointerIndex(VTableClass, Base);
1675 if (VirtualPointerIndex)
1676 VTT = CGF.
Builder.CreateConstInBoundsGEP1_64(VTT, VirtualPointerIndex);
1682 llvm::Constant *ItaniumCXXABI::getVTableAddressPointForConstExpr(
1684 return getVTableAddressPoint(Base, VTableClass);
1687 llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1689 assert(VPtrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1691 llvm::GlobalVariable *&VTable = VTables[RD];
1696 CGM.addDeferredVTable(RD);
1699 llvm::raw_svector_ostream Out(Name);
1700 getMangleContext().mangleCXXVTable(RD, Out);
1703 CGM.getItaniumVTableContext().getVTableLayout(RD);
1704 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1706 VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
1708 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1710 CGM.setGVProperties(VTable, RD);
1720 Ty = Ty->getPointerTo()->getPointerTo();
1721 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1724 uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
1728 MethodDecl->getParent(), VTable,
1729 VTableIndex * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1734 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex,
"vfn");
1744 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1745 CGM.getCodeGenOpts().StrictVTablePointers)
1746 VFuncLoad->setMetadata(
1747 llvm::LLVMContext::MD_invariant_load,
1748 llvm::MDNode::get(CGM.getLLVMContext(),
1753 CGCallee Callee(MethodDecl->getCanonicalDecl(), VFunc);
1757 llvm::Value *ItaniumCXXABI::EmitVirtualDestructorCall(
1763 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1775 void ItaniumCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1781 bool ItaniumCXXABI::canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const {
1784 if (CGM.getLangOpts().AppleKext)
1789 if (isVTableHidden(RD))
1792 if (CGM.getCodeGenOpts().ForceEmitVTables)
1799 return !hasAnyUnusedVirtualInlineFunction(RD);
1803 int64_t NonVirtualAdjustment,
1804 int64_t VirtualAdjustment,
1805 bool IsReturnAdjustment) {
1806 if (!NonVirtualAdjustment && !VirtualAdjustment)
1812 if (NonVirtualAdjustment && !IsReturnAdjustment) {
1819 if (VirtualAdjustment) {
1827 CGF.
Builder.CreateConstInBoundsGEP1_64(VTablePtr, VirtualAdjustment);
1843 if (NonVirtualAdjustment && IsReturnAdjustment) {
1844 ResultPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(ResultPtr,
1845 NonVirtualAdjustment);
1854 const ThisAdjustment &TA) {
1862 const ReturnAdjustment &RA) {
1871 return ItaniumCXXABI::EmitReturnFromThunk(CGF, RV, ResultType);
1876 return ItaniumCXXABI::EmitReturnFromThunk(CGF, Undef, ResultType);
1885 CGM.getContext().getTypeAlignInChars(elementType));
1893 assert(requiresArrayCookie(expr));
1903 assert(CookieSize == getArrayCookieSizeImpl(ElementType));
1907 CharUnits CookieOffset = CookieSize - SizeSize;
1908 if (!CookieOffset.
isZero())
1917 if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) && AS == 0 &&
1919 CGM.getCodeGenOpts().SanitizeAddressPoisonClassMemberArrayNewCookie)) {
1921 CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
1922 llvm::FunctionType *FTy =
1923 llvm::FunctionType::get(CGM.VoidTy, NumElementsPtr.
getType(),
false);
1925 CGM.CreateRuntimeFunction(FTy,
"__asan_poison_cxx_array_cookie");
1938 Address numElementsPtr = allocPtr;
1940 if (!numElementsOffset.
isZero())
1946 if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address) || AS != 0)
1953 llvm::FunctionType *FTy =
1954 llvm::FunctionType::get(CGF.
SizeTy, CGF.
SizeTy->getPointerTo(0),
false);
1956 CGM.CreateRuntimeFunction(FTy,
"__asan_load_cxx_array_cookie");
1970 CGM.getContext().getTypeAlignInChars(elementType));
1978 assert(requiresArrayCookie(expr));
1986 getContext().getTypeSizeInChars(elementType).getQuantity());
1995 CharUnits cookieSize = ARMCXXABI::getArrayCookieSizeImpl(elementType);
2014 llvm::PointerType *GuardPtrTy) {
2016 llvm::FunctionType *FTy =
2020 FTy,
"__cxa_guard_acquire",
2022 llvm::AttributeList::FunctionIndex,
2023 llvm::Attribute::NoUnwind));
2027 llvm::PointerType *GuardPtrTy) {
2029 llvm::FunctionType *FTy =
2030 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2032 FTy,
"__cxa_guard_release",
2034 llvm::AttributeList::FunctionIndex,
2035 llvm::Attribute::NoUnwind));
2039 llvm::PointerType *GuardPtrTy) {
2041 llvm::FunctionType *FTy =
2042 llvm::FunctionType::get(CGM.
VoidTy, GuardPtrTy,
false);
2044 FTy,
"__cxa_guard_abort",
2046 llvm::AttributeList::FunctionIndex,
2047 llvm::Attribute::NoUnwind));
2052 llvm::GlobalVariable *Guard;
2053 CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2066 llvm::GlobalVariable *var,
2067 bool shouldPerformInit) {
2072 bool NonTemplateInline =
2079 bool threadsafe = getContext().getLangOpts().ThreadsafeStatics &&
2085 bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
2087 llvm::IntegerType *guardTy;
2089 if (useInt8GuardVariable) {
2095 if (UseARMGuardVarABI) {
2101 CGM.getDataLayout().getABITypeAlignment(guardTy));
2104 llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
2108 llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
2113 llvm::raw_svector_ostream out(guardName);
2114 getMangleContext().mangleStaticGuardVariable(&D, out);
2119 guard =
new llvm::GlobalVariable(CGM.getModule(), guardTy,
2120 false, var->getLinkage(),
2121 llvm::ConstantInt::get(guardTy, 0),
2123 guard->setDSOLocal(var->isDSOLocal());
2124 guard->setVisibility(var->getVisibility());
2126 guard->setThreadLocalMode(var->getThreadLocalMode());
2127 guard->setAlignment(guardAlignment.
getQuantity());
2132 llvm::Comdat *C = var->getComdat();
2134 (CGM.getTarget().getTriple().isOSBinFormatELF() ||
2135 CGM.getTarget().getTriple().isOSBinFormatWasm())) {
2136 guard->setComdat(C);
2140 if (!NonTemplateInline)
2141 CGF.
CurFn->setComdat(C);
2142 }
else if (CGM.supportsCOMDAT() && guard->isWeakForLinker()) {
2143 guard->setComdat(CGM.getModule().getOrInsertComdat(guard->getName()));
2146 CGM.setStaticLocalDeclGuardAddress(&D, guard);
2169 llvm::LoadInst *LI =
2179 LI->setAtomic(llvm::AtomicOrdering::Acquire);
2202 (UseARMGuardVarABI && !useInt8GuardVariable)
2203 ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
2205 llvm::Value *NeedsInit = Builder.CreateIsNull(V,
"guard.uninitialized");
2224 Builder.CreateCondBr(Builder.CreateIsNotNull(V,
"tobool"),
2225 InitBlock, EndBlock);
2244 Builder.
CreateStore(llvm::ConstantInt::get(guardTy, 1), guardAddr);
2252 llvm::Constant *dtor,
2253 llvm::Constant *addr,
2255 const char *Name =
"__cxa_atexit";
2258 Name = T.isOSDarwin() ?
"_tlv_atexit" :
"__cxa_thread_atexit";
2265 llvm::FunctionType::get(CGF.
VoidTy, CGF.
Int8PtrTy,
false)->getPointerTo();
2269 llvm::FunctionType *atexitTy =
2270 llvm::FunctionType::get(CGF.
IntTy, paramTys,
false);
2274 if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit))
2275 fn->setDoesNotThrow();
2278 llvm::Constant *handle =
2280 auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
2288 addr = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
2291 llvm::ConstantExpr::getBitCast(dtor, dtorTy),
2292 llvm::ConstantExpr::getBitCast(addr, CGF.
Int8PtrTy),
2298 void CodeGenModule::registerGlobalDtorsWithAtExit() {
2299 for (
const auto I : DtorsUsingAtExit) {
2300 int Priority = I.first;
2301 const llvm::TinyPtrVector<llvm::Function *> &Dtors = I.second;
2311 std::string GlobalInitFnName =
2312 std::string(
"__GLOBAL_init_") + llvm::to_string(Priority);
2313 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
false);
2314 llvm::Function *GlobalInitFn = CreateGlobalInitOrDestructFunction(
2315 FTy, GlobalInitFnName, getTypes().arrangeNullaryFunction(),
2326 for (
auto *Dtor : Dtors) {
2329 if (getCodeGenOpts().CXAAtExit)
2336 AddGlobalCtor(GlobalInitFn, Priority,
nullptr);
2343 llvm::Constant *dtor,
2344 llvm::Constant *addr) {
2346 if (CGM.getCodeGenOpts().CXAAtExit)
2350 CGM.ErrorUnsupported(&D,
"non-trivial TLS destruction");
2354 if (CGM.getLangOpts().AppleKext) {
2356 return CGM.AddCXXDtorEntry(dtor, addr);
2364 assert(!VD->
isStaticLocal() &&
"static local VarDecls don't need wrappers!");
2374 static llvm::GlobalValue::LinkageTypes
2376 llvm::GlobalValue::LinkageTypes VarLinkage =
2380 if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
2385 if (!llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) &&
2386 !llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
2388 return llvm::GlobalValue::WeakODRLinkage;
2392 ItaniumCXXABI::getOrCreateThreadLocalWrapper(
const VarDecl *VD,
2397 llvm::raw_svector_ostream Out(WrapperName);
2398 getMangleContext().mangleItaniumThreadLocalWrapper(VD, Out);
2403 if (
llvm::Value *V = CGM.getModule().getNamedValue(WrapperName))
2404 return cast<llvm::Function>(V);
2410 const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
2413 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FI);
2414 llvm::Function *Wrapper =
2416 WrapperName.str(), &CGM.getModule());
2418 CGM.SetLLVMFunctionAttributes(
nullptr, FI, Wrapper);
2421 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, Wrapper);
2425 !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) &&
2426 !llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage())))
2430 Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2431 Wrapper->addFnAttr(llvm::Attribute::NoUnwind);
2436 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2440 llvm::Function *InitFunc =
nullptr;
2445 llvm::SmallDenseMap<const VarDecl *, llvm::Function *> UnorderedInits;
2446 for (
unsigned I = 0; I != CXXThreadLocalInits.size(); ++I) {
2450 CXXThreadLocalInits[I];
2452 OrderedInits.push_back(CXXThreadLocalInits[I]);
2455 if (!OrderedInits.empty()) {
2457 llvm::FunctionType *FTy =
2458 llvm::FunctionType::get(CGM.
VoidTy,
false);
2463 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
2466 llvm::ConstantInt::get(CGM.
Int8Ty, 0),
"__tls_guard");
2467 Guard->setThreadLocal(
true);
2476 InitFunc->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2477 InitFunc->addFnAttr(llvm::Attribute::NoUnwind);
2482 for (
const VarDecl *VD : CXXThreadLocals) {
2483 llvm::GlobalVariable *Var =
2485 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Var);
2498 llvm::raw_svector_ostream Out(InitFnName);
2499 getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
2505 llvm::GlobalValue *Init =
nullptr;
2506 bool InitIsInitFunc =
false;
2508 InitIsInitFunc =
true;
2509 llvm::Function *InitFuncToUse = InitFunc;
2520 llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.
VoidTy,
false);
2522 llvm::GlobalVariable::ExternalWeakLinkage,
2529 Init->setVisibility(Var->getVisibility());
2530 Init->setDSOLocal(Var->isDSOLocal());
2533 llvm::LLVMContext &Context = CGM.
getModule().getContext();
2536 if (InitIsInitFunc) {
2538 llvm::CallInst *CallVal = Builder.CreateCall(Init);
2540 CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2541 llvm::Function *Fn =
2542 cast<llvm::Function>(cast<llvm::GlobalAlias>(Init)->getAliasee());
2543 Fn->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
2548 llvm::Value *Have = Builder.CreateIsNotNull(Init);
2551 Builder.CreateCondBr(Have, InitBB, ExitBB);
2553 Builder.SetInsertPoint(InitBB);
2554 Builder.CreateCall(Init);
2555 Builder.CreateBr(ExitBB);
2557 Builder.SetInsertPoint(ExitBB);
2567 if (Val->getType() != Wrapper->getReturnType())
2569 Val, Wrapper->getReturnType(),
"");
2570 Builder.CreateRet(Val);
2578 llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val);
2580 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(Wrapper);
2581 CallVal->setCallingConv(Wrapper->getCallingConv());
2595 bool ItaniumCXXABI::NeedsVTTParameter(
GlobalDecl GD) {
2614 class ItaniumRTTIBuilder {
2616 llvm::LLVMContext &VMContext;
2617 const ItaniumCXXABI &
CXXABI;
2623 llvm::GlobalVariable *
2624 GetAddrOfTypeName(
QualType Ty, llvm::GlobalVariable::LinkageTypes
Linkage);
2628 llvm::Constant *GetAddrOfExternalRTTIDescriptor(
QualType Ty);
2631 void BuildVTablePointer(
const Type *Ty);
2644 void BuildPointerTypeInfo(
QualType PointeeTy);
2655 ItaniumRTTIBuilder(
const ItaniumCXXABI &ABI)
2656 : CGM(ABI.CGM), VMContext(CGM.
getModule().getContext()), CXXABI(ABI) {}
2670 PTI_Incomplete = 0x8,
2674 PTI_ContainingClassIncomplete = 0x10,
2680 PTI_Noexcept = 0x40,
2686 VMI_NonDiamondRepeat = 0x1,
2689 VMI_DiamondShaped = 0x2
2703 llvm::Constant *BuildTypeInfo(
QualType Ty);
2706 llvm::Constant *BuildTypeInfo(
2708 llvm::GlobalVariable::LinkageTypes Linkage,
2709 llvm::GlobalValue::VisibilityTypes
Visibility,
2710 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass);
2714 llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
2717 llvm::raw_svector_ostream Out(Name);
2723 llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
2726 llvm::GlobalVariable *GV =
2729 GV->setInitializer(Init);
2735 ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(
QualType Ty) {
2738 llvm::raw_svector_ostream Out(Name);
2742 llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name);
2757 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
2778 case BuiltinType::Void:
2779 case BuiltinType::NullPtr:
2780 case BuiltinType::Bool:
2781 case BuiltinType::WChar_S:
2782 case BuiltinType::WChar_U:
2783 case BuiltinType::Char_U:
2784 case BuiltinType::Char_S:
2785 case BuiltinType::UChar:
2786 case BuiltinType::SChar:
2787 case BuiltinType::Short:
2788 case BuiltinType::UShort:
2789 case BuiltinType::Int:
2790 case BuiltinType::UInt:
2791 case BuiltinType::Long:
2792 case BuiltinType::ULong:
2793 case BuiltinType::LongLong:
2794 case BuiltinType::ULongLong:
2795 case BuiltinType::Half:
2796 case BuiltinType::Float:
2797 case BuiltinType::Double:
2798 case BuiltinType::LongDouble:
2799 case BuiltinType::Float16:
2800 case BuiltinType::Float128:
2801 case BuiltinType::Char8:
2802 case BuiltinType::Char16:
2803 case BuiltinType::Char32:
2804 case BuiltinType::Int128:
2805 case BuiltinType::UInt128:
2808 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 2809 case BuiltinType::Id: 2810 #include "clang/Basic/OpenCLImageTypes.def" 2811 case BuiltinType::OCLSampler:
2812 case BuiltinType::OCLEvent:
2813 case BuiltinType::OCLClkEvent:
2814 case BuiltinType::OCLQueue:
2815 case BuiltinType::OCLReserveID:
2816 case BuiltinType::ShortAccum:
2817 case BuiltinType::Accum:
2818 case BuiltinType::LongAccum:
2819 case BuiltinType::UShortAccum:
2820 case BuiltinType::UAccum:
2821 case BuiltinType::ULongAccum:
2822 case BuiltinType::ShortFract:
2823 case BuiltinType::Fract:
2824 case BuiltinType::LongFract:
2825 case BuiltinType::UShortFract:
2826 case BuiltinType::UFract:
2827 case BuiltinType::ULongFract:
2828 case BuiltinType::SatShortAccum:
2829 case BuiltinType::SatAccum:
2830 case BuiltinType::SatLongAccum:
2831 case BuiltinType::SatUShortAccum:
2832 case BuiltinType::SatUAccum:
2833 case BuiltinType::SatULongAccum:
2834 case BuiltinType::SatShortFract:
2835 case BuiltinType::SatFract:
2836 case BuiltinType::SatLongFract:
2837 case BuiltinType::SatUShortFract:
2838 case BuiltinType::SatUFract:
2839 case BuiltinType::SatULongFract:
2842 case BuiltinType::Dependent:
2843 #define BUILTIN_TYPE(Id, SingletonId) 2844 #define PLACEHOLDER_TYPE(Id, SingletonId) \ 2845 case BuiltinType::Id: 2846 #include "clang/AST/BuiltinTypes.def" 2847 llvm_unreachable(
"asking for RRTI for a placeholder type!");
2849 case BuiltinType::ObjCId:
2850 case BuiltinType::ObjCClass:
2851 case BuiltinType::ObjCSel:
2852 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
2855 llvm_unreachable(
"Invalid BuiltinType Kind!");
2878 if (
const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
2883 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2901 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2902 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
2913 bool IsDLLImport = RD->
hasAttr<DLLImportAttr>();
2916 if (CGM.
getTriple().isWindowsGNUEnvironment() && IsDLLImport)
2920 return IsDLLImport && !CGM.
getTriple().isWindowsItaniumEnvironment()
2948 if (
const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
2953 if (
const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
2957 dyn_cast<MemberPointerType>(Ty)) {
2959 const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
2998 void ItaniumRTTIBuilder::BuildVTablePointer(
const Type *Ty) {
3000 static const char *
const ClassTypeInfo =
3001 "_ZTVN10__cxxabiv117__class_type_infoE";
3003 static const char *
const SIClassTypeInfo =
3004 "_ZTVN10__cxxabiv120__si_class_type_infoE";
3006 static const char *
const VMIClassTypeInfo =
3007 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
3009 const char *VTableName =
nullptr;
3012 #define TYPE(Class, Base) 3013 #define ABSTRACT_TYPE(Class, Base) 3014 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 3015 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 3016 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 3017 #include "clang/AST/TypeNodes.def" 3018 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3020 case Type::LValueReference:
3021 case Type::RValueReference:
3022 llvm_unreachable(
"References shouldn't get here");
3025 case Type::DeducedTemplateSpecialization:
3026 llvm_unreachable(
"Undeduced type shouldn't get here");
3029 llvm_unreachable(
"Pipe types shouldn't get here");
3034 case Type::ExtVector:
3038 case Type::BlockPointer:
3040 VTableName =
"_ZTVN10__cxxabiv123__fundamental_type_infoE";
3043 case Type::ConstantArray:
3044 case Type::IncompleteArray:
3045 case Type::VariableArray:
3047 VTableName =
"_ZTVN10__cxxabiv117__array_type_infoE";
3050 case Type::FunctionNoProto:
3051 case Type::FunctionProto:
3053 VTableName =
"_ZTVN10__cxxabiv120__function_type_infoE";
3058 VTableName =
"_ZTVN10__cxxabiv116__enum_type_infoE";
3061 case Type::Record: {
3063 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3066 VTableName = ClassTypeInfo;
3068 VTableName = SIClassTypeInfo;
3070 VTableName = VMIClassTypeInfo;
3076 case Type::ObjCObject:
3078 Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
3081 if (isa<BuiltinType>(Ty)) {
3082 VTableName = ClassTypeInfo;
3086 assert(isa<ObjCInterfaceType>(Ty));
3089 case Type::ObjCInterface:
3090 if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
3091 VTableName = SIClassTypeInfo;
3093 VTableName = ClassTypeInfo;
3097 case Type::ObjCObjectPointer:
3100 VTableName =
"_ZTVN10__cxxabiv119__pointer_type_infoE";
3103 case Type::MemberPointer:
3105 VTableName =
"_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
3109 llvm::Constant *VTable =
3111 CGM.
setDSOLocal(cast<llvm::GlobalValue>(VTable->stripPointerCasts()));
3117 llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
3119 llvm::ConstantExpr::getInBoundsGetElementPtr(CGM.
Int8PtrTy, VTable, Two);
3120 VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.
Int8PtrTy);
3122 Fields.push_back(VTable);
3154 return llvm::GlobalValue::LinkOnceODRLinkage;
3156 if (
const RecordType *Record = dyn_cast<RecordType>(Ty)) {
3157 const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
3159 return llvm::GlobalValue::WeakODRLinkage;
3160 if (CGM.
getTriple().isWindowsItaniumEnvironment())
3161 if (RD->
hasAttr<DLLImportAttr>() &&
3169 .isWindowsGNUEnvironment())
3173 return llvm::GlobalValue::LinkOnceODRLinkage;
3176 llvm_unreachable(
"Invalid linkage!");
3179 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
QualType Ty) {
3185 llvm::raw_svector_ostream Out(Name);
3188 llvm::GlobalVariable *OldGV = CGM.
getModule().getNamedGlobal(Name);
3189 if (OldGV && !OldGV->isDeclaration()) {
3190 assert(!OldGV->hasAvailableExternallyLinkage() &&
3191 "available_externally typeinfos not yet implemented");
3193 return llvm::ConstantExpr::getBitCast(OldGV, CGM.
Int8PtrTy);
3199 return GetAddrOfExternalRTTIDescriptor(Ty);
3206 llvm::GlobalValue::VisibilityTypes llvmVisibility;
3207 if (llvm::GlobalValue::isLocalLinkage(Linkage))
3210 else if (
CXXABI.classifyRTTIUniqueness(Ty, Linkage) ==
3211 ItaniumCXXABI::RUK_NonUniqueHidden)
3216 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3217 llvm::GlobalValue::DefaultStorageClass;
3218 if (CGM.
getTriple().isWindowsItaniumEnvironment()) {
3220 if (RD && RD->
hasAttr<DLLExportAttr>())
3221 DLLStorageClass = llvm::GlobalValue::DLLExportStorageClass;
3224 return BuildTypeInfo(Ty, Linkage, llvmVisibility, DLLStorageClass);
3227 llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
3229 llvm::GlobalVariable::LinkageTypes Linkage,
3230 llvm::GlobalValue::VisibilityTypes
Visibility,
3231 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
3233 BuildVTablePointer(cast<Type>(Ty));
3236 llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
3237 llvm::Constant *TypeNameField;
3241 ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
3242 CXXABI.classifyRTTIUniqueness(Ty, Linkage);
3243 if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
3246 TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.
Int64Ty);
3247 llvm::Constant *flag =
3248 llvm::ConstantInt::get(CGM.
Int64Ty, ((uint64_t)1) << 63);
3249 TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
3251 llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.
Int8PtrTy);
3253 TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.
Int8PtrTy);
3255 Fields.push_back(TypeNameField);
3258 #define TYPE(Class, Base) 3259 #define ABSTRACT_TYPE(Class, Base) 3260 #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class: 3261 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class: 3262 #define DEPENDENT_TYPE(Class, Base) case Type::Class: 3263 #include "clang/AST/TypeNodes.def" 3264 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
3269 case Type::ExtVector:
3271 case Type::BlockPointer:
3276 case Type::LValueReference:
3277 case Type::RValueReference:
3278 llvm_unreachable(
"References shouldn't get here");
3281 case Type::DeducedTemplateSpecialization:
3282 llvm_unreachable(
"Undeduced type shouldn't get here");
3285 llvm_unreachable(
"Pipe type shouldn't get here");
3287 case Type::ConstantArray:
3288 case Type::IncompleteArray:
3289 case Type::VariableArray:
3294 case Type::FunctionNoProto:
3295 case Type::FunctionProto:
3305 case Type::Record: {
3307 cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
3314 BuildSIClassTypeInfo(RD);
3316 BuildVMIClassTypeInfo(RD);
3321 case Type::ObjCObject:
3322 case Type::ObjCInterface:
3323 BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
3326 case Type::ObjCObjectPointer:
3327 BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
3331 BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
3334 case Type::MemberPointer:
3335 BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
3343 llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
3346 llvm::raw_svector_ostream Out(Name);
3349 llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
3350 llvm::GlobalVariable *GV =
3351 new llvm::GlobalVariable(M, Init->getType(),
3356 GV->takeName(OldGV);
3357 llvm::Constant *NewPtr =
3358 llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
3359 OldGV->replaceAllUsesWith(NewPtr);
3360 OldGV->eraseFromParent();
3364 GV->setComdat(M.getOrInsertComdat(GV->getName()));
3381 TypeName->setVisibility(Visibility);
3384 GV->setVisibility(Visibility);
3387 TypeName->setDLLStorageClass(DLLStorageClass);
3388 GV->setDLLStorageClass(DLLStorageClass);
3390 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3395 void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(
const ObjCObjectType *OT) {
3398 assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
3402 if (isa<BuiltinType>(T))
return;
3413 llvm::Constant *BaseTypeInfo =
3414 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(SuperTy);
3415 Fields.push_back(BaseTypeInfo);
3420 void ItaniumRTTIBuilder::BuildSIClassTypeInfo(
const CXXRecordDecl *RD) {
3424 llvm::Constant *BaseTypeInfo =
3426 Fields.push_back(BaseTypeInfo);
3433 llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
3434 llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
3451 if (!Bases.VirtualBases.insert(BaseDecl).second) {
3454 Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
3456 if (Bases.NonVirtualBases.count(BaseDecl))
3457 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3461 if (!Bases.NonVirtualBases.insert(BaseDecl).second) {
3464 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3466 if (Bases.VirtualBases.count(BaseDecl))
3467 Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
3472 for (
const auto &I : BaseDecl->
bases())
3483 for (
const auto &I : RD->
bases())
3492 void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(
const CXXRecordDecl *RD) {
3501 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3506 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->
getNumBases()));
3541 for (
const auto &Base : RD->
bases()) {
3543 Fields.push_back(ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(Base.getType()));
3546 cast<CXXRecordDecl>(Base.getType()->getAs<
RecordType>()->getDecl());
3548 int64_t OffsetFlags = 0;
3555 if (Base.isVirtual())
3563 OffsetFlags = uint64_t(Offset.
getQuantity()) << 8;
3567 if (Base.isVirtual())
3568 OffsetFlags |= BCTI_Virtual;
3569 if (Base.getAccessSpecifier() ==
AS_public)
3570 OffsetFlags |= BCTI_Public;
3572 Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
3582 Flags |= ItaniumRTTIBuilder::PTI_Const;
3584 Flags |= ItaniumRTTIBuilder::PTI_Volatile;
3586 Flags |= ItaniumRTTIBuilder::PTI_Restrict;
3593 Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
3596 if (Proto->isNothrow()) {
3597 Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
3607 void ItaniumRTTIBuilder::BuildPointerTypeInfo(
QualType PointeeTy) {
3615 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3620 llvm::Constant *PointeeTypeInfo =
3621 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
3622 Fields.push_back(PointeeTypeInfo);
3638 Flags |= PTI_ContainingClassIncomplete;
3642 Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
3647 llvm::Constant *PointeeTypeInfo =
3648 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(PointeeTy);
3649 Fields.push_back(PointeeTypeInfo);
3656 ItaniumRTTIBuilder(
CXXABI).BuildTypeInfo(
QualType(ClassType, 0)));
3659 llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(
QualType Ty) {
3660 return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
3663 void ItaniumCXXABI::EmitFundamentalRTTIDescriptors(
const CXXRecordDecl *RD) {
3666 getContext().VoidTy, getContext().NullPtrTy,
3667 getContext().BoolTy, getContext().WCharTy,
3668 getContext().CharTy, getContext().UnsignedCharTy,
3669 getContext().SignedCharTy, getContext().ShortTy,
3670 getContext().UnsignedShortTy, getContext().IntTy,
3671 getContext().UnsignedIntTy, getContext().LongTy,
3672 getContext().UnsignedLongTy, getContext().LongLongTy,
3673 getContext().UnsignedLongLongTy, getContext().Int128Ty,
3674 getContext().UnsignedInt128Ty, getContext().HalfTy,
3675 getContext().FloatTy, getContext().DoubleTy,
3676 getContext().LongDoubleTy, getContext().Float128Ty,
3677 getContext().Char8Ty, getContext().Char16Ty,
3678 getContext().Char32Ty
3680 llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass =
3682 ? llvm::GlobalValue::DLLExportStorageClass
3683 : llvm::GlobalValue::DefaultStorageClass;
3684 llvm::GlobalValue::VisibilityTypes Visibility =
3686 for (
const QualType &FundamentalType : FundamentalTypes) {
3688 QualType PointerTypeConst = getContext().getPointerType(
3689 FundamentalType.withConst());
3690 for (
QualType Type : {FundamentalType, PointerType, PointerTypeConst})
3691 ItaniumRTTIBuilder(*this).BuildTypeInfo(
3693 Visibility, DLLStorageClass);
3699 ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
3700 QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage)
const {
3701 if (shouldRTTIBeUnique())
3705 if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
3706 Linkage != llvm::GlobalValue::WeakODRLinkage)
3714 if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
3715 return RUK_NonUniqueHidden;
3720 assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
3721 return RUK_NonUniqueVisible;
3731 return StructorCodegen::Emit;
3736 return StructorCodegen::Emit;
3739 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
3742 const auto *CD = cast<CXXConstructorDecl>(MD);
3747 if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
3748 return StructorCodegen::RAUW;
3751 if (!llvm::GlobalAlias::isValidLinkage(Linkage))
3752 return StructorCodegen::RAUW;
3754 if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
3758 return StructorCodegen::COMDAT;
3759 return StructorCodegen::Emit;
3762 return StructorCodegen::Alias;
3772 if (Entry && !Entry->isDeclaration())
3775 auto *Aliasee = cast<llvm::GlobalValue>(CGM.
GetAddrOfGlobal(TargetDecl));
3781 Alias->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3785 assert(Entry->getType() == Aliasee->getType() &&
3786 "declaration exists with different type");
3787 Alias->takeName(Entry);
3788 Entry->replaceAllUsesWith(Alias);
3789 Entry->eraseFromParent();
3791 Alias->setName(MangledName);
3798 void ItaniumCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3816 if (CGType == StructorCodegen::Alias || CGType == StructorCodegen::COMDAT) {
3821 if (CGType == StructorCodegen::RAUW) {
3851 if (CGType == StructorCodegen::COMDAT) {
3853 llvm::raw_svector_ostream Out(Buffer);
3855 getMangleContext().mangleCXXDtorComdat(DD, Out);
3857 getMangleContext().mangleCXXCtorComdat(CD, Out);
3858 llvm::Comdat *C = CGM.
getModule().getOrInsertComdat(Out.str());
3867 llvm::FunctionType *FTy = llvm::FunctionType::get(
3875 llvm::FunctionType *FTy =
3876 llvm::FunctionType::get(CGM.
VoidTy,
false);
3883 llvm::FunctionType *FTy = llvm::FunctionType::get(
3903 CallEndCatch(
bool MightThrow) : MightThrow(MightThrow) {}
3923 bool EndMightThrow) {
3924 llvm::CallInst *call =
3947 if (isa<ReferenceType>(CatchType)) {
3948 QualType CaughtType = cast<ReferenceType>(CatchType)->getPointeeType();
3957 if (
const PointerType *PT = dyn_cast<PointerType>(CaughtType)) {
3966 unsigned HeaderSize =
3968 AdjustedExn = CGF.
Builder.CreateConstGEP1_32(Exn, HeaderSize);
3987 cast<llvm::PointerType>(LLVMCatchTy)->getElementType();
4013 if (CatchType->hasPointerRepresentation()) {
4032 llvm_unreachable(
"bad ownership qualifier!");
4037 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
4053 llvm_unreachable(
"evaluation kind filtered out!");
4055 llvm_unreachable(
"bad evaluation kind");
4058 assert(isa<RecordType>(CatchType) &&
"unexpected catch type!");
4059 auto catchRD = CatchType->getAsCXXRecordDecl();
4062 llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0);
4070 caughtExnAlignment);
4079 llvm::CallInst *rawAdjustedExn =
4084 caughtExnAlignment);
4157 llvm::FunctionType *fnTy =
4160 fnTy,
"__clang_call_terminate", llvm::AttributeList(),
true);
4162 llvm::Function *fn = dyn_cast<llvm::Function>(fnRef);
4163 if (fn && fn->empty()) {
4164 fn->setDoesNotThrow();
4165 fn->setDoesNotReturn();
4170 fn->addFnAttr(llvm::Attribute::NoInline);
4174 fn->setLinkage(llvm::Function::LinkOnceODRLinkage);
4177 fn->setComdat(CGM.
getModule().getOrInsertComdat(fn->getName()));
4180 llvm::BasicBlock *entry =
4188 llvm::CallInst *catchCall = builder.CreateCall(
getBeginCatchFn(CGM), exn);
4189 catchCall->setDoesNotThrow();
4193 llvm::CallInst *termCall = builder.CreateCall(CGM.
getTerminateFn());
4194 termCall->setDoesNotThrow();
4195 termCall->setDoesNotReturn();
4199 builder.CreateUnreachable();
4206 ItaniumCXXABI::emitTerminateForUnexpectedException(
CodeGenFunction &CGF,
4216 std::pair<llvm::Value *, const CXXRecordDecl *>
4227 ItaniumCXXABI::emitBeginCatch(CGF, C);
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
void pushTerminate()
Push a terminate handler on the stack.
ReturnValueSlot - Contains the address where the return value of a function can be stored...
The generic AArch64 ABI is also a modified version of the Itanium ABI, but it has fewer divergences t...
void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, llvm::BasicBlock *InitBlock, llvm::BasicBlock *NoInitBlock, GuardKind Kind, const VarDecl *D)
Emit a branch to select whether or not to perform guarded initialization.
void EmitVTTDefinition(llvm::GlobalVariable *VTT, llvm::GlobalVariable::LinkageTypes Linkage, const CXXRecordDecl *RD)
EmitVTTDefinition - Emit the definition of the given vtable.
static const Decl * getCanonicalDecl(const Decl *D)
Represents a function declaration or definition.
static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty)
Return the linkage that the type info and type info name constants should have for the given type...
llvm::IntegerType * IntTy
int
static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
Get the appropriate linkage for the wrapper function.
External linkage, which indicates that the entity can be referred to from other translation units...
static void InitCatchParam(CodeGenFunction &CGF, const VarDecl &CatchParam, Address ParamAddr, SourceLocation Loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
no exception specification
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
A (possibly-)qualified type.
The iOS 64-bit ABI is follows ARM's published 64-bit ABI more closely, but we don't guarantee to foll...
static llvm::Constant * getAllocateExceptionFn(CodeGenModule &CGM)
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
const CodeGenOptions & getCodeGenOpts() const
unsigned getNumBases() const
Retrieves the number of base classes of this class.
Internal linkage according to the Modules TS, but can be referred to from other translation units ind...
const Expr * getSubExpr() const
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target...
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler...
llvm::LLVMContext & getLLVMContext()
The COMDAT used for ctors.
CXXDtorType getDtorType() const
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
The standard implementation of ConstantInitBuilder used in Clang.
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function *> CXXThreadLocals, Address Guard=Address::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
No linkage, which means that the entity is unique and can only be referred to from within its scope...
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
C Language Family Type Representation.
bool isRecordType() const
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D)
Determine what kind of template specialization the given declaration is.
FunctionDecl * getOperatorNew() const
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask >> Checked, SanitizerHandler Check, ArrayRef< llvm::Constant *> StaticArgs, ArrayRef< llvm::Value *> DynamicArgs)
Create a basic block that will call a handler function in a sanitizer runtime with the provided argum...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
The base class of the type hierarchy.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
bool isZero() const
isZero - Test whether the quantity equals zero.
const TargetInfo & getTargetInfo() const
Linkage getLinkage() const
Determine the linkage of this type.
bool isDefined(const FunctionDecl *&Definition) const
Returns true if the function has a definition that does not need to be instantiated.
llvm::Value * EmitARCRetainNonBlock(llvm::Value *value)
Retain the given object, with normal retain semantics.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V)
Default closure variant of a ctor.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
static const OpaqueValueExpr * findInCopyConstruct(const Expr *expr)
Given an expression which invokes a copy constructor — i.e.
Represents a variable declaration or definition.
Address getObjectAddress(CodeGenFunction &CGF) const
Returns the address of the object within this declaration.
Objects with "hidden" visibility are not seen by the dynamic linker.
unsigned AddressPointIndex
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const T * getAs() const
Member-template getAs<specific type>'.
SourceLocation getLocStart() const LLVM_READONLY
bool supportsCOMDAT() const
A this pointer adjustment.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * getPointer() const
A C++ throw-expression (C++ [except.throw]).
bool hasDefinition() const
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
RValue EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method, const CGCallee &Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E, CallArgList *RtlArgs)
unsigned getAddressSpace() const
Return the address space that this address resides in.
The collection of all-type qualifiers we support.
const ValueDecl * getMemberPointerDecl() const
Qualifiers getQualifiers() const
Retrieve all qualifiers.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
const TargetInfo & getTarget() const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
static llvm::Constant * getClangCallTerminateFn(CodeGenModule &CGM)
Get or define the following function: void (i8* exn) nounwind noreturn This code is used only in C++...
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Represents a class type in Objective C.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const CXXRecordDecl * NearestVBase
llvm::IntegerType * Int64Ty
CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD, CXXDtorType Type, const CXXRecordDecl *RD)
BuildVirtualCall - This routine makes indirect vtable call for call to virtual destructors.
The generic Mips ABI is a modified version of the Itanium ABI.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
Parameter for C++ virtual table pointers.
llvm::IntegerType * SizeTy
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
CharUnits getSizeAlign() const
StructorType getFromDtorType(CXXDtorType T)
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isReferenceType() const
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
llvm::Function * codegenCXXStructor(const CXXMethodDecl *MD, StructorType Type)
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
Objects with "default" visibility are seen by the dynamic linker and act like normal objects...
CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, const CXXRecordDecl *Class, CharUnits ExpectedTargetAlign)
Given a class pointer with an actual known alignment, and the expected alignment of an object at a dy...
bool isReplaceableGlobalAllocationFunction(bool *IsAligned=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type...
FunctionDecl * getOperatorDelete() const
static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, SeenBases &Bases)
ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in abi::__vmi_class_type_info.
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
void setDSOLocal(llvm::GlobalValue *GV) const
The Microsoft ABI is the ABI used by Microsoft Visual Studio (and compatible compilers).
struct clang::ReturnAdjustment::VirtualAdjustment::@117 Itanium
Visibility
Describes the different kinds of visibility that a declaration may have.
CharUnits getAlignment() const
Return the alignment of this pointer.
Visibility getVisibility() const
Determine the visibility of this type.
static CharUnits computeOffsetHint(ASTContext &Context, const CXXRecordDecl *Src, const CXXRecordDecl *Dst)
Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7].
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
CXXCtorType getCtorType() const
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
const Type * getClass() const
llvm::Constant * getTerminateFn()
Get the declaration of std::terminate for the platform.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
static StructorCodegen getCodegenToUse(CodeGenModule &CGM, const CXXMethodDecl *MD)
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
base_class_iterator bases_begin()
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getPointerAlign() const
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Represents an ObjC class declaration.
bool isAbstract() const
Determine whether this class has a pure virtual function.
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
The iOS ABI is a partial implementation of the ARM ABI.
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool isInlineSpecified=false, bool hasWrittenPrototype=true, bool isConstexprSpecified=false)
This object can be modified without requiring retains or releases.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
CanQualType getReturnType() const
QualType getBaseType() const
Gets the base type of this object type.
static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty)
TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type info for that type is de...
static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM, QualType Ty)
ShouldUseExternalRTTIDescriptor - Returns whether the type information for the given type exists some...
static CharUnits One()
One - Construct a CharUnits quantity of one.
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ASTContext & getContext() const
Represents a prototype with parameter type info, e.g.
The generic ARM ABI is a modified version of the Itanium ABI proposed by ARM for use on ARM-based pla...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
bool isDynamicClass() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
Module linkage, which indicates that the entity can be referred to from other translation units withi...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isVTableExternal(const CXXRecordDecl *RD)
At this point in the translation unit, does it appear that can we rely on the vtable being defined el...
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::CallingConv::ID getRuntimeCC() const
Exposes information about the current target.
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void SetLLVMFunctionAttributes(const Decl *D, const CGFunctionInfo &Info, llvm::Function *F)
Set the LLVM function attributes (sext, zext, etc).
CXXDtorType
C++ destructor types.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Expr - This represents one expression.
static llvm::Constant * getBadTypeidFn(CodeGenFunction &CGF)
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
const T * castAs() const
Member-template castAs<specific type>.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Represents a C++ destructor within a class.
VarDecl * getExceptionDecl() const
llvm::PointerType * getType() const
Return the type of the pointer value.
ObjCLifetime getObjCLifetime() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
DeclContext * getDeclContext()
static bool IsIncompleteClassType(const RecordType *RecordTy)
IsIncompleteClassType - Returns whether the given record type is incomplete.
ObjCInterfaceDecl * getSuperClass() const
TLSKind getTLSKind() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
llvm::Value * getExceptionFromSlot()
Returns the contents of the function's exception object and selector slots.
CharUnits getSizeSize() const
static bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
llvm::LLVMContext & getLLVMContext()
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
llvm::IntegerType * Int32Ty
static llvm::Constant * getGetExceptionPtrFn(CodeGenModule &CGM)
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant)
Returns LLVM linkage for a declarator.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD)
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl...
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI)
Get a function type and produce the equivalent function type with the specified exception specificati...
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units. ...
Implements C++ ABI-specific semantic analysis functions.
const TargetInfo & getTarget() const
void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV)
Set attributes which are common to any form of a global definition (alias, Objective-C method...
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
const LangOptions & getLangOpts() const
ASTContext & getContext() const
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
The COMDAT used for dtors.
static StringRef getIdentifier(const Token &Tok)
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
GlobalDecl - represents a global declaration.
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...
bool isConstQualified() const
Determine whether this type is const-qualified.
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
static llvm::Value * performTypeAdjustment(CodeGenFunction &CGF, Address InitialPtr, int64_t NonVirtualAdjustment, int64_t VirtualAdjustment, bool IsReturnAdjustment)
There is no lifetime qualification on this type.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Assigning into this object requires the old value to be released and the new value to be retained...
QualType getCanonicalType() const
virtual void mangleCXXRTTIName(QualType T, raw_ostream &)=0
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
CastKind getCastKind() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
Represents a call to a member function that may be written either with member call syntax (e...
SourceLocation getLocStart() const LLVM_READONLY
const Decl * getDecl() const
llvm::GlobalVariable * GetAddrOfVTT(const CXXRecordDecl *RD)
GetAddrOfVTT - Get the address of the VTT for the given record decl.
Represents a static or instance method of a struct/union/class.
static llvm::Constant * getGuardAbortFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
SanitizerSet SanOpts
Sanitizers enabled for this function.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti)
Add vtable components for the given vtable layout to the given global initializer.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
The generic Itanium ABI is the standard ABI of most open-source and Unix-like platforms.
All available information about a concrete callee.
TypeClass getTypeClass() const
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset. ...
MangleContext & getMangleContext()
Gets the mangle context.
llvm::Instruction * CurrentFuncletPad
ItaniumVTableContext & getItaniumVTableContext()
Assigning into this object requires a lifetime extension.
static llvm::Constant * getGuardReleaseFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
CXXCtorType
C++ constructor types.
The WebAssembly ABI is a modified version of the Itanium ABI.
void addReplacement(StringRef Name, llvm::Constant *C)
llvm::Constant * GetAddrOfGlobal(GlobalDecl GD, ForDefinition_t IsForDefinition=NotForDefinition)
FunctionArgList - Type for representing both the decl and type of parameters to a function...
Represents an element in a path from a derived class to a base class.
TLS with a dynamic initializer.
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
Dataflow Directional Tag Classes.
External linkage within a unique namespace.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
void EmitAnyExprToExn(const Expr *E, Address Addr)
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args)
Emits a call or invoke to the given noreturn runtime function.
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
const Expr * getInit() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
static llvm::Value * CallBeginCatch(CodeGenFunction &CGF, llvm::Value *Exn, bool EndMightThrow)
Emits a call to __cxa_begin_catch and enters a cleanup to call __cxa_end_catch.
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, CharUnits EltSize, const llvm::Twine &Name="")
Given addr = T* ...
struct clang::ThisAdjustment::VirtualAdjustment::@119 Itanium
A pointer to member type per C++ 8.3.3 - Pointers to members.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
union clang::ThisAdjustment::VirtualAdjustment Virtual
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type. ...
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class...
void EmitAutoVarCleanups(const AutoVarEmission &emission)
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
static bool isThreadWrapperReplaceable(const VarDecl *VD, CodeGen::CodeGenModule &CGM)
Implements C++ ABI-specific code generation functions.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
llvm::PointerType * Int8PtrTy
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
StringRef getMangledName(GlobalDecl GD)
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitARCInitWeak(Address addr, llvm::Value *value)
i8* @objc_initWeak(i8** addr, i8* value) Returns value.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
ABIArgInfo & getReturnInfo()
Represents a base class of a C++ class.
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases...
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Reading or writing from this object requires a barrier call.
TranslationUnitDecl * getTranslationUnitDecl() const
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
true
A convenience builder class for complex constant initializers, especially for anonymous global struct...
Represents a C++ struct/union/class.
CGCXXABI * CreateItaniumCXXABI(CodeGenModule &CGM)
Creates an Itanium-family ABI.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block, taking care to avoid creation of branches from dummy blocks.
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
static bool ContainsIncompleteClassType(QualType Ty)
ContainsIncompleteClassType - Returns whether the given type contains an incomplete class type...
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false)
CXXCatchStmt - This represents a C++ catch block.
llvm::Type * ConvertType(QualType T)
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EmitTrapCheck(llvm::Value *Checked)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it...
void popTerminate()
Pops a terminate handler off the stack.
No linkage according to the standard, but is visible from other translation units because of types de...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
This class is used for builtin types like 'int'.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
bool isGlobalDelete() const
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
static llvm::Constant * getItaniumDynamicCastFn(CodeGenFunction &CGF)
Copying closure variant of a ctor.
CGCXXABI & getCXXABI() const
__DEVICE__ int max(int __a, int __b)
static llvm::Constant * getEndCatchFn(CodeGenModule &CGM)
Struct with all information about dynamic [sub]class needed to set vptr.
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF, llvm::Constant *dtor, llvm::Constant *addr, bool TLS)
Register a global destructor using __cxa_atexit.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
static RValue get(llvm::Value *V)
Visibility getVisibility() const
Determines the visibility of this entity.
static llvm::Constant * getGuardAcquireFn(CodeGenModule &CGM, llvm::PointerType *GuardPtrTy)
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
CodeGenVTables & getVTables()
static void emitConstructorDestructorAlias(CodeGenModule &CGM, GlobalDecl AliasDecl, GlobalDecl TargetDecl)
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
bool isTranslationUnit() const
static llvm::Constant * getBadCastFn(CodeGenFunction &CGF)
bool isInline() const
Whether this variable is (C++1z) inline.
Notes how many arguments were added to the beginning (Prefix) and ending (Suffix) of an arg list...
static bool IsStandardLibraryRTTIDescriptor(QualType Ty)
IsStandardLibraryRTTIDescriptor - Returns whether the type information for the given type exists in t...
static bool CanUseSingleInheritance(const CXXRecordDecl *RD)
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
static llvm::Constant * getBeginCatchFn(CodeGenModule &CGM)
CallArgList - Type for representing both the value and type of arguments in a call.
const LangOptions & getLangOpts() const
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
SourceLocation getLocation() const
QualType getPointeeType() const
CanQualType UnsignedIntTy
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
static llvm::Constant * getThrowFn(CodeGenModule &CGM)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
QualType getType() const
Retrieves the type of the base class.
const llvm::Triple & getTriple() const