28 #include "llvm/ADT/StringExtras.h" 29 #include "llvm/ADT/StringSet.h" 30 #include "llvm/IR/CallSite.h" 31 #include "llvm/IR/Intrinsics.h" 33 using namespace clang;
34 using namespace CodeGen;
39 struct VBTableGlobals {
44 class MicrosoftCXXABI :
public CGCXXABI {
47 :
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
48 ClassHierarchyDescriptorType(nullptr),
49 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
50 ThrowInfoType(nullptr) {}
52 bool HasThisReturn(
GlobalDecl GD)
const override;
53 bool hasMostDerivedReturn(
GlobalDecl GD)
const override;
59 bool isSRetParameterAfterThis()
const override {
return true; }
61 bool isThisCompleteObject(
GlobalDecl GD)
const override {
64 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
73 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
75 llvm_unreachable(
"bad dtor kind");
84 assert(Args.size() >= 2 &&
85 "expected the arglist to have at least two args!");
94 std::vector<CharUnits> getVBPtrOffsets(
const CXXRecordDecl *RD)
override {
95 std::vector<CharUnits> VBPtrOffsets;
99 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
100 for (
const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
105 if (VBT->getVBaseWithVPtr())
107 VBPtrOffsets.push_back(Offs);
109 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
113 StringRef GetPureVirtualCallName()
override {
return "_purecall"; }
114 StringRef GetDeletedVirtualCallName()
override {
return "_purecall"; }
125 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
128 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
130 getAddrOfCXXCatchHandlerType(
QualType Ty,
QualType CatchHandlerType)
override;
137 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
143 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
149 llvm::BasicBlock *CastEnd)
override;
156 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override {
222 getThisArgumentTypeForMethod(
const CXXMethodDecl *MD)
override {
224 if (MD->
isVirtual() && !isa<CXXDestructorDecl>(MD)) {
226 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
242 bool VirtualCall)
override;
256 bool Delegating,
Address This)
override;
259 llvm::GlobalVariable *VTable);
269 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
270 return !VTableClass->
hasAttr<MSNoVTableAttr>();
285 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
301 "Only deleting destructor thunks are available in this ABI");
306 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
308 llvm::GlobalVariable *
310 llvm::GlobalVariable::LinkageTypes
Linkage);
312 llvm::GlobalVariable *
316 llvm::raw_svector_ostream Out(OutName);
317 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
318 StringRef MangledName = OutName.str();
320 if (
auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
326 llvm::UndefValue::get(CGM.IntTy));
327 Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
328 bool AnyDifferent =
false;
329 for (
const auto &I : SrcRD->
vbases()) {
330 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
336 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
337 AnyDifferent |= SrcVBIndex != DstVBIndex;
343 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy, Map.size());
344 llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy, Map);
345 llvm::GlobalValue::LinkageTypes
Linkage =
347 ? llvm::GlobalValue::LinkOnceODRLinkage
349 auto *VDispMap =
new llvm::GlobalVariable(
350 CGM.getModule(), VDispMapTy,
true,
Linkage,
356 llvm::GlobalVariable *GV)
const;
358 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
361 Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
364 getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.
getDecl()));
368 else if (ReturnAdjustment)
369 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
371 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
378 const ReturnAdjustment &RA)
override;
380 void EmitThreadLocalInitFuncs(
385 bool usesThreadWrapperFunction()
const override {
return false; }
390 llvm::GlobalVariable *DeclPtr,
391 bool PerformInit)
override;
393 llvm::Constant *Dtor, llvm::Constant *Addr)
override;
431 friend struct MSRTTIBuilder;
433 bool isImageRelative()
const {
434 return CGM.getTarget().getPointerWidth(0) == 64;
438 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
440 TDTypeName += llvm::utostr(TypeInfoString.size());
441 llvm::StructType *&TypeDescriptorType =
442 TypeDescriptorTypeMap[TypeInfoString.size()];
443 if (TypeDescriptorType)
444 return TypeDescriptorType;
448 llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
451 return TypeDescriptorType;
455 if (!isImageRelative())
460 llvm::StructType *getBaseClassDescriptorType() {
461 if (BaseClassDescriptorType)
462 return BaseClassDescriptorType;
464 getImageRelativeType(CGM.Int8PtrTy),
470 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
473 CGM.getLLVMContext(), FieldTypes,
"rtti.BaseClassDescriptor");
474 return BaseClassDescriptorType;
477 llvm::StructType *getClassHierarchyDescriptorType() {
478 if (ClassHierarchyDescriptorType)
479 return ClassHierarchyDescriptorType;
482 CGM.getLLVMContext(),
"rtti.ClassHierarchyDescriptor");
487 getImageRelativeType(
488 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
490 ClassHierarchyDescriptorType->setBody(FieldTypes);
491 return ClassHierarchyDescriptorType;
494 llvm::StructType *getCompleteObjectLocatorType() {
495 if (CompleteObjectLocatorType)
496 return CompleteObjectLocatorType;
498 CGM.getLLVMContext(),
"rtti.CompleteObjectLocator");
503 getImageRelativeType(CGM.Int8PtrTy),
504 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
505 getImageRelativeType(CompleteObjectLocatorType),
508 if (!isImageRelative())
509 FieldTypesRef = FieldTypesRef.drop_back();
510 CompleteObjectLocatorType->setBody(FieldTypesRef);
511 return CompleteObjectLocatorType;
514 llvm::GlobalVariable *getImageBase() {
515 StringRef Name =
"__ImageBase";
516 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
519 return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
525 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
526 if (!isImageRelative())
529 if (PtrVal->isNullValue())
530 return llvm::Constant::getNullValue(CGM.IntTy);
532 llvm::Constant *ImageBaseAsInt =
533 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
534 llvm::Constant *PtrValAsInt =
535 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
536 llvm::Constant *Diff =
537 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
539 return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
547 llvm::Constant *getZeroInt() {
548 return llvm::ConstantInt::get(CGM.IntTy, 0);
551 llvm::Constant *getAllOnesInt() {
552 return llvm::Constant::getAllOnesValue(CGM.IntTy);
573 int32_t VBTableOffset,
575 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
576 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
577 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
578 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
581 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
594 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
595 bool IsMemberFunction,
598 unsigned VBTableIndex);
607 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
610 llvm::Function *EmitVirtualMemPtrThunk(
621 return RD->
hasAttr<MSInheritanceAttr>();
628 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
629 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
635 bool Inequality)
override;
656 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
657 llvm::Constant *Src)
override;
659 llvm::Constant *EmitMemberPointerConversion(
672 llvm::StructType *getCatchableTypeType() {
673 if (CatchableTypeType)
674 return CatchableTypeType;
677 getImageRelativeType(CGM.Int8PtrTy),
682 getImageRelativeType(CGM.Int8PtrTy)
685 CGM.getLLVMContext(), FieldTypes,
"eh.CatchableType");
686 return CatchableTypeType;
689 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
690 llvm::StructType *&CatchableTypeArrayType =
691 CatchableTypeArrayTypeMap[NumEntries];
692 if (CatchableTypeArrayType)
693 return CatchableTypeArrayType;
696 CTATypeName += llvm::utostr(NumEntries);
698 getImageRelativeType(getCatchableTypeType()->getPointerTo());
701 llvm::ArrayType::get(CTType, NumEntries)
703 CatchableTypeArrayType =
705 return CatchableTypeArrayType;
708 llvm::StructType *getThrowInfoType() {
710 return ThrowInfoType;
713 getImageRelativeType(CGM.Int8PtrTy),
714 getImageRelativeType(CGM.Int8PtrTy),
715 getImageRelativeType(CGM.Int8PtrTy)
719 return ThrowInfoType;
725 llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
726 llvm::FunctionType *FTy =
727 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
728 auto *Fn = cast<llvm::Function>(
729 CGM.CreateRuntimeFunction(FTy,
"_CxxThrowException"));
731 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86)
732 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
739 llvm::Constant *getCatchableType(
QualType T,
740 uint32_t NVOffset = 0,
741 int32_t VBPtrOffset = -1,
742 uint32_t VBIndex = 0);
744 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
746 llvm::GlobalVariable *getThrowInfo(
QualType T)
override;
748 std::pair<llvm::Value *, const CXXRecordDecl *>
753 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
754 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
755 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
757 VFTablesMapTy VFTablesMap;
758 VTablesMapTy VTablesMap;
761 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
765 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
770 GuardInfo() : Guard(nullptr), BitIndex(0) {}
771 llvm::GlobalVariable *Guard;
777 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
778 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
779 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
781 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
782 llvm::StructType *BaseClassDescriptorType;
783 llvm::StructType *ClassHierarchyDescriptorType;
784 llvm::StructType *CompleteObjectLocatorType;
786 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
788 llvm::StructType *CatchableTypeType;
789 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
790 llvm::StructType *ThrowInfoType;
797 switch (CGM.getTarget().getTriple().getArch()) {
802 case llvm::Triple::thumb:
806 return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
808 case llvm::Triple::x86:
815 if (!canCopyArgument(RD))
816 return RAA_DirectInMemory;
822 case llvm::Triple::x86_64:
864 llvm_unreachable(
"invalid enum");
877 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
882 void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
884 llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
885 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
895 llvm::CatchPadInst *CPI;
897 CatchRetScope(llvm::CatchPadInst *CPI) : CPI(CPI) {}
901 CGF.
Builder.CreateCatchRet(CPI, BB);
912 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
913 llvm::CatchPadInst *CPI =
914 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
933 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
944 return std::make_tuple(Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
953 PolymorphicBase = BaseDecl;
957 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
960 GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase);
964 return std::make_tuple(
Address(Ptr, VBaseAlign), Offset, PolymorphicBase);
967 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
971 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
977 llvm::FunctionType *FTy =
978 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
985 llvm::CallSite Call =
987 Call.setDoesNotReturn();
988 CGF.
Builder.CreateUnreachable();
995 std::tie(ThisPtr, std::ignore, std::ignore) =
996 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
1001 bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1005 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1008 llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
1019 std::tie(This, Offset, std::ignore) =
1020 performBaseAdjustment(CGF, This, SrcRecordTy);
1033 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1036 ThisPtr,
Offset, SrcRTTI, DestRTTI,
1046 std::tie(Value, std::ignore, std::ignore) =
1047 performBaseAdjustment(CGF, Value, SrcRecordTy);
1053 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1063 llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1067 int64_t VBPtrChars =
1069 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
1073 CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
1075 llvm::ConstantInt::get(CGM.IntTy, VBTableChars.
getQuantity());
1078 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1080 CGF.
Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
1081 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1084 bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1085 return isa<CXXConstructorDecl>(GD.
getDecl());
1089 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1093 bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1109 }
else if (!RD->
isPOD()) {
1122 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1123 assert(IsMostDerivedClass &&
1124 "ctor for a class with virtual bases must have an implicit parameter");
1126 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1128 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1129 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1130 CGF.
Builder.CreateCondBr(IsCompleteObject,
1131 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1136 EmitVBPtrStores(CGF, RD);
1140 return SkipVbaseCtorsBB;
1144 MicrosoftCXXABI::EmitDtorCompleteObjectHandler(
CodeGenFunction &CGF) {
1145 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1146 assert(IsMostDerivedClass &&
1147 "ctor for a class with virtual bases must have an implicit parameter");
1149 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1151 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1152 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1153 CGF.
Builder.CreateCondBr(IsCompleteObject,
1154 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1159 return SkipVbaseDtorsBB;
1162 void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1182 unsigned AS = getThisAddress(CGF).getAddressSpace();
1185 for (VBOffsets::const_iterator I = VBaseMap.begin(), E = VBaseMap.end();
1187 if (!I->second.hasVtorDisp())
1191 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, I->first);
1192 uint64_t ConstantVBaseOffset =
1197 VBaseOffset, llvm::ConstantInt::get(CGM.PtrDiffTy, ConstantVBaseOffset),
1199 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1203 CGF.
Int8Ty->getPointerTo(AS));
1204 llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset);
1206 VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4);
1208 VtorDispPtr, CGF.
Int32Ty->getPointerTo(AS),
"vtordisp.ptr");
1221 return ExpectedCallingConv == ActualCallingConv;
1235 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1236 Fn->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1242 Address This = getThisAddress(CGF);
1247 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1248 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1249 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1250 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1255 if (VBT->getVBaseWithVPtr())
1259 CGF.
Builder.CreateConstInBoundsGEP2_32(GV->getValueType(), GV, 0, 0);
1261 "vbptr." + VBT->ObjectWithVPtr->getName());
1269 AddedStructorArgs Added;
1273 ArgTys.push_back(getContext().IntTy);
1287 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1290 ArgTys.push_back(getContext().IntTy);
1305 MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1322 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1329 if (isa<CXXDestructorDecl>(MD))
1334 getContext().getASTRecordLayout(MD->
getParent());
1341 Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1347 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1371 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1388 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1393 Result =
Address(VBasePtr, VBaseAlign);
1395 if (!StaticOffset.
isZero()) {
1416 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1425 if (FPT->isVariadic())
1426 Params.insert(Params.begin() + 1, IsMostDerived);
1428 Params.push_back(IsMostDerived);
1429 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1435 Params.push_back(ShouldDelete);
1436 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1440 void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1460 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1461 if (!Adjustment.
isZero()) {
1462 unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1464 *thisTy = This->getType();
1467 This = CGF.
Builder.CreateConstInBoundsGEP1_32(CGF.
Int8Ty, This,
1472 setCXXABIThisValue(CGF, This);
1482 if (HasThisReturn(CGF.
CurGD))
1484 else if (hasMostDerivedReturn(CGF.
CurGD))
1489 assert(getStructorImplicitParamDecl(CGF) &&
1490 "no implicit parameter for a constructor with virtual bases?");
1491 getStructorImplicitParamValue(CGF)
1498 assert(getStructorImplicitParamDecl(CGF) &&
1499 "no implicit parameter for a deleting destructor?");
1500 getStructorImplicitParamValue(CGF)
1503 "should_call_delete");
1509 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1514 return AddedStructorArgs{};
1520 MostDerivedArg = getStructorImplicitParamValue(CGF);
1522 MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type ==
Ctor_Complete);
1526 Args.insert(Args.begin() + 1,
1527 CallArg(RV, getContext().IntTy,
false));
1528 return AddedStructorArgs::prefix(1);
1530 Args.
add(RV, getContext().IntTy);
1531 return AddedStructorArgs::suffix(1);
1537 bool Delegating,
Address This) {
1544 "The deleting destructor should only be called via a virtual call");
1545 This = adjustThisArgumentForVirtualFunctionCall(CGF,
GlobalDecl(DD, Type),
1549 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1550 if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1551 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1558 if (BaseDtorEndBB) {
1560 CGF.
Builder.CreateBr(BaseDtorEndBB);
1565 void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1567 llvm::GlobalVariable *VTable) {
1568 if (!CGM.getCodeGenOpts().LTOUnit)
1575 getContext().getLangOpts().RTTIData
1576 ? getContext().toCharUnitsFromBits(
1577 getContext().getTargetInfo().getPointerWidth(0))
1581 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1586 CGM.AddVTableTypeMetadata(VTable, AddressPoint,
1596 getContext().getASTRecordLayout(DerivedRD);
1602 Offset = VBI->second.VBaseOffset;
1605 CGM.AddVTableTypeMetadata(VTable, AddressPoint, DerivedRD);
1610 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1613 void MicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables &CGVT,
1618 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1619 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1620 if (VTable->hasInitializer())
1626 llvm::Constant *RTTI =
nullptr;
1629 RTTI = getMSCompleteObjectLocator(RD, *Info);
1634 Components.finishAndSetAsInitializer(VTable);
1636 emitVTableTypeMetadata(*Info, RD, VTable);
1640 bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1645 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1648 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1649 if (!VTableAddressPoint) {
1651 !getContext().getASTRecordLayout(Base.
getBase()).hasOwnVFPtr());
1653 return VTableAddressPoint;
1659 llvm::raw_svector_ostream Out(Name);
1668 return VFTablesMap[
ID];
1671 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1673 llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass);
1674 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1678 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1684 VFTableIdTy
ID(RD, VPtrOffset);
1685 VTablesMapTy::iterator I;
1687 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID,
nullptr));
1691 llvm::GlobalVariable *&VTable = I->second;
1696 if (DeferredVFTables.insert(RD).second) {
1699 CGM.addDeferredVTable(RD);
1704 llvm::StringSet<> ObservedMangledNames;
1705 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1708 if (!ObservedMangledNames.insert(Name.str()).second)
1709 llvm_unreachable(
"Already saw this mangling before?");
1714 const std::unique_ptr<VPtrInfo> *VFPtrI = std::find_if(
1715 VFPtrs.begin(), VFPtrs.end(), [&](
const std::unique_ptr<VPtrInfo>& VPI) {
1716 return VPI->FullOffsetInMDC == VPtrOffset;
1718 if (VFPtrI == VFPtrs.end()) {
1719 VFTablesMap[
ID] =
nullptr;
1722 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1734 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1735 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1736 : CGM.getVTableLinkage(RD);
1737 bool VFTableComesFromAnotherTU =
1738 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1739 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1740 bool VTableAliasIsRequred =
1741 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1743 if (llvm::GlobalValue *VFTable =
1744 CGM.getModule().getNamedGlobal(VFTableName)) {
1745 VFTablesMap[
ID] = VFTable;
1746 VTable = VTableAliasIsRequred
1747 ? cast<llvm::GlobalVariable>(
1748 cast<llvm::GlobalAlias>(VFTable)->getBaseObject())
1749 : cast<llvm::GlobalVariable>(VFTable);
1755 llvm::GlobalValue::LinkageTypes VTableLinkage =
1756 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1758 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1760 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1764 llvm::GlobalValue *VFTable;
1765 VTable =
new llvm::GlobalVariable(CGM.getModule(), VTableType,
1766 true, VTableLinkage,
1767 nullptr, VTableName);
1768 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1770 llvm::Comdat *C =
nullptr;
1771 if (!VFTableComesFromAnotherTU &&
1772 (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1773 (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1774 VTableAliasIsRequred)))
1775 C = CGM.getModule().getOrInsertComdat(VFTableName.str());
1780 if (VTableAliasIsRequred) {
1781 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.Int32Ty, 0),
1782 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1783 llvm::ConstantInt::get(CGM.Int32Ty, 1)};
1786 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1787 VTable->getValueType(), VTable, GEPIndices);
1788 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1791 C->setSelectionKind(llvm::Comdat::Largest);
1795 VFTableName.str(), VTableGEP,
1797 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1806 VTable->setComdat(C);
1808 if (RD->
hasAttr<DLLExportAttr>())
1809 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1811 VFTablesMap[
ID] = VFTable;
1823 Ty = Ty->getPointerTo()->getPointerTo();
1825 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1827 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1836 auto getObjectWithVPtr = [&] {
1839 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1849 getObjectWithVPtr(), VTable,
1850 ML.
Index * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1852 if (CGM.getCodeGenOpts().PrepareForLTO)
1856 Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1860 CGCallee Callee(MethodDecl, VFunc);
1864 llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1873 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1876 CGCallee Callee = getVirtualFunctionPointer(
1880 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1884 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1891 const VBTableGlobals &
1892 MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
1895 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
1897 std::tie(Entry, Added) =
1898 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
1899 VBTableGlobals &VBGlobals = Entry->second;
1908 llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
1909 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
1910 E = VBGlobals.VBTables->end();
1912 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
1918 llvm::Function *MicrosoftCXXABI::EmitVirtualMemPtrThunk(
1921 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
1922 "can't form pointers to ctors or virtual dtors");
1926 llvm::raw_svector_ostream Out(ThunkName);
1927 getMangleContext().mangleVirtualMemPtrThunk(MD, Out);
1930 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
1931 return cast<llvm::Function>(GV);
1934 const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSMemberPointerThunk(MD);
1935 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
1936 llvm::Function *ThunkFn =
1938 ThunkName.str(), &CGM.getModule());
1939 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
1942 ? llvm::GlobalValue::LinkOnceODRLinkage
1945 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
1947 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
1948 CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
1954 ThunkFn->addFnAttr(
"thunk");
1967 buildThisParam(CGF, FunctionArgs);
1972 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1977 getThisAddress(CGF), ThunkTy->getPointerTo()->getPointerTo(), MD->
getParent());
1980 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1989 void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1990 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1991 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1992 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
1993 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1994 if (GV->isDeclaration())
1995 emitVBTableDefinition(*VBT, RD, GV);
1999 llvm::GlobalVariable *
2001 llvm::GlobalVariable::LinkageTypes Linkage) {
2003 llvm::raw_svector_ostream Out(OutName);
2004 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2005 StringRef Name = OutName.str();
2007 llvm::ArrayType *VBTableType =
2010 assert(!CGM.getModule().getNamedGlobal(Name) &&
2011 "vbtable with this name already exists: mangling bug?");
2012 llvm::GlobalVariable *GV =
2013 CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, Linkage);
2014 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2016 if (RD->
hasAttr<DLLImportAttr>())
2017 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2018 else if (RD->
hasAttr<DLLExportAttr>())
2019 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2021 if (!GV->hasExternalLinkage())
2022 emitVBTableDefinition(VBT, RD, GV);
2027 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2029 llvm::GlobalVariable *GV)
const {
2033 "should only emit vbtables for classes with vbtables");
2037 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2043 CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2044 Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
2047 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2048 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2055 CompleteVBPtrOffset +=
2057 Offset -= CompleteVBPtrOffset;
2059 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2060 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2061 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.
getQuantity());
2064 assert(Offsets.size() ==
2065 cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
2066 ->getElementType())->getNumElements());
2067 llvm::ArrayType *VBTableType =
2068 llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2069 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2070 GV->setInitializer(Init);
2072 if (RD->
hasAttr<DLLImportAttr>())
2073 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2096 CGF.
Builder.CreateNeg(VtorDisp));
2113 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2130 const ReturnAdjustment &RA) {
2145 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2162 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *expr) {
2189 assert(requiresArrayCookie(expr));
2192 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2208 llvm::Constant *Dtor,
2209 llvm::Constant *Addr) {
2214 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2215 CGF.
IntTy, DtorStub->getType(),
false);
2218 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2219 if (llvm::Function *TLRegDtorFn = dyn_cast<llvm::Function>(TLRegDtor))
2220 TLRegDtorFn->setDoesNotThrow();
2226 llvm::Constant *Dtor,
2227 llvm::Constant *Addr) {
2235 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2239 if (CXXThreadLocalInits.empty())
2244 ?
"/include:___dyn_tls_init@12" 2245 :
"/include:__dyn_tls_init");
2250 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2251 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2252 CGM.
getModule(), InitFunc->getType(),
true,
2254 Twine(InitFunc->getName(),
"$initializer$"));
2255 InitFuncPtr->setSection(
".CRT$XDU");
2262 std::vector<llvm::Function *> NonComdatInits;
2263 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2264 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2266 llvm::Function *F = CXXThreadLocalInits[I];
2269 if (llvm::Comdat *C = GV->getComdat())
2270 AddToXDU(F)->setComdat(C);
2272 NonComdatInits.push_back(F);
2275 if (!NonComdatInits.empty()) {
2276 llvm::FunctionType *FTy =
2277 llvm::FunctionType::get(CGM.
VoidTy,
false);
2295 StringRef VarName(
"_Init_thread_epoch");
2297 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2299 auto *GV =
new llvm::GlobalVariable(
2303 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2309 llvm::FunctionType *FTy =
2310 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2311 CGM.
IntTy->getPointerTo(),
false);
2313 FTy,
"_Init_thread_header",
2315 llvm::AttributeList::FunctionIndex,
2316 llvm::Attribute::NoUnwind),
2321 llvm::FunctionType *FTy =
2322 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2323 CGM.
IntTy->getPointerTo(),
false);
2325 FTy,
"_Init_thread_footer",
2327 llvm::AttributeList::FunctionIndex,
2328 llvm::Attribute::NoUnwind),
2333 llvm::FunctionType *FTy =
2334 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2335 CGM.
IntTy->getPointerTo(),
false);
2337 FTy,
"_Init_thread_abort",
2339 llvm::AttributeList::FunctionIndex,
2340 llvm::Attribute::NoUnwind),
2348 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2349 : Guard(Guard), GuardNum(GuardNum) {}
2355 llvm::LoadInst *LI = Builder.
CreateLoad(Guard);
2356 llvm::ConstantInt *Mask =
2357 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2358 Builder.
CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2374 llvm::GlobalVariable *GV,
2378 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2380 llvm::Function *F = CGF.
CurFn;
2381 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2382 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2388 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2392 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2395 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2396 llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
2400 GuardInfo *GI =
nullptr;
2401 if (ThreadlocalStatic)
2403 else if (!ThreadsafeStatic)
2406 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2411 GuardNum = getContext().getStaticLocalNumber(&D);
2412 assert(GuardNum > 0);
2414 }
else if (HasPerVariableGuard) {
2418 GuardNum = GI->BitIndex++;
2421 if (!HasPerVariableGuard && GuardNum >= 32) {
2423 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2432 llvm::raw_svector_ostream Out(GuardName);
2433 if (HasPerVariableGuard)
2434 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2437 getMangleContext().mangleStaticGuardVariable(&D, Out);
2443 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2444 GV->getLinkage(), Zero, GuardName.str());
2445 GuardVar->setVisibility(GV->getVisibility());
2446 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2448 if (GuardVar->isWeakForLinker())
2449 GuardVar->setComdat(
2450 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2452 GuardVar->setThreadLocal(
true);
2453 if (GI && !HasPerVariableGuard)
2454 GI->Guard = GuardVar;
2459 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2460 "static local from the same function had different linkage");
2462 if (!HasPerVariableGuard) {
2470 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2471 llvm::LoadInst *LI = Builder.
CreateLoad(GuardAddr);
2473 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
2482 Builder.
CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2486 Builder.CreateBr(EndBlock);
2504 llvm::LoadInst *FirstGuardLoad = Builder.
CreateLoad(GuardAddr);
2505 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2506 llvm::LoadInst *InitThreadEpoch =
2509 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2520 llvm::LoadInst *SecondGuardLoad = Builder.
CreateLoad(GuardAddr);
2521 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2523 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2525 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2534 Builder.CreateBr(EndBlock);
2551 return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) &&
2563 fields.push_back(CGM.
IntTy);
2567 fields.push_back(CGM.
IntTy);
2568 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2569 fields.push_back(CGM.
IntTy);
2570 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2571 fields.push_back(CGM.
IntTy);
2573 if (fields.size() == 1)
2578 void MicrosoftCXXABI::
2581 assert(fields.empty());
2586 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2588 if (RD->nullFieldOffsetIsZero())
2589 fields.push_back(getZeroInt());
2591 fields.push_back(getAllOnesInt());
2596 fields.push_back(getZeroInt());
2597 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2598 fields.push_back(getZeroInt());
2599 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2600 fields.push_back(getAllOnesInt());
2606 GetNullMemberPointerFields(MPT, fields);
2607 if (fields.size() == 1)
2609 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2610 assert(Res->getType() == ConvertMemberPointerType(MPT));
2615 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2616 bool IsMemberFunction,
2619 unsigned VBTableIndex) {
2624 if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance))
2628 fields.push_back(FirstField);
2630 if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance))
2631 fields.push_back(llvm::ConstantInt::get(
2634 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) {
2637 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2642 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2643 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2645 return llvm::ConstantStruct::getAnon(fields);
2653 MSInheritanceAttr::Keyword_virtual_inheritance)
2654 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2655 llvm::Constant *FirstField =
2657 return EmitFullMemberPointer(FirstField,
false, RD,
2661 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2666 return EmitNullMemberPointer(DstTy);
2672 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2673 C = EmitMemberFunctionPointer(MD);
2676 C = EmitMemberDataPointer(DstTy, FieldOffset);
2679 if (!MemberPointerPath.empty()) {
2680 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2684 ->castAs<MemberPointerType>();
2692 if (DerivedMember) {
2700 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2702 DerivedToBasePath.push_back(&BS);
2705 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2707 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2708 : CK_BaseToDerivedMemberPointer;
2709 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2710 DerivedToBasePath.end(), C);
2716 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2717 assert(MD->
isInstance() &&
"Member function must not be static!");
2724 unsigned VBTableIndex = 0;
2725 llvm::Constant *FirstField;
2727 if (!MD->isVirtual()) {
2742 VTableContext.getMethodVFTableLocation(MD);
2743 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2747 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2750 if (VBTableIndex == 0 &&
2752 MSInheritanceAttr::Keyword_virtual_inheritance)
2753 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2756 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2757 return EmitFullMemberPointer(FirstField,
true, RD,
2758 NonVirtualBaseAdjustment, VBTableIndex);
2773 llvm::ICmpInst::Predicate Eq;
2774 llvm::Instruction::BinaryOps
And, Or;
2776 Eq = llvm::ICmpInst::ICMP_NE;
2777 And = llvm::Instruction::Or;
2780 Eq = llvm::ICmpInst::ICMP_EQ;
2782 Or = llvm::Instruction::Or;
2791 return Builder.CreateICmp(Eq, L, R);
2794 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
2795 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
2796 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
2800 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
2801 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
2802 llvm::Value *LF = Builder.CreateExtractValue(L, I);
2803 llvm::Value *RF = Builder.CreateExtractValue(R, I);
2804 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
2806 Res = Builder.CreateBinOp(And, Res, Cmp);
2814 llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
2815 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero,
"memptr.cmp.iszero");
2816 Res = Builder.CreateBinOp(Or, Res, IsZero);
2821 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
2832 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2834 GetNullMemberPointerFields(MPT, fields);
2835 assert(!fields.empty());
2837 if (MemPtr->getType()->isStructTy())
2838 FirstField = Builder.CreateExtractValue(MemPtr, 0);
2839 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
2847 for (
int I = 1, E = fields.size(); I < E; ++I) {
2848 llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
2849 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
2850 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
2856 llvm::Constant *Val) {
2859 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
2860 Val->getAggregateElement(0U) : Val;
2861 return FirstField->isNullValue();
2866 if (isZeroInitializable(MPT) && Val->isNullValue())
2872 GetNullMemberPointerFields(MPT, Fields);
2873 if (Fields.size() == 1) {
2874 assert(Val->getType()->isIntegerTy());
2875 return Val == Fields[0];
2879 for (I = 0, E = Fields.size(); I != E; ++I) {
2880 if (Val->getAggregateElement(I) != Fields[I])
2896 Builder.CreateInBoundsGEP(This.
getPointer(), VBPtrOffset,
"vbptr");
2897 if (VBPtrOut) *VBPtrOut = VBPtr;
2902 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
2913 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
2917 llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex);
2930 llvm::BasicBlock *OriginalBB =
nullptr;
2931 llvm::BasicBlock *SkipAdjustBB =
nullptr;
2932 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
2939 OriginalBB = Builder.GetInsertBlock();
2943 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
2945 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
2957 "member pointer representation requires a " 2958 "complete class type for %0 to perform this expression");
2961 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2966 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
2967 llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
2970 if (VBaseAdjustBB) {
2971 Builder.CreateBr(SkipAdjustBB);
2973 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
2974 Phi->addIncoming(Base.
getPointer(), OriginalBB);
2975 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
2978 return AdjustedBase;
2981 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
2995 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
2997 if (MemPtr->getType()->isStructTy()) {
3000 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3001 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3002 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3003 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3004 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3008 if (VirtualBaseAdjustmentOffset) {
3009 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
3019 Addr = Builder.CreateInBoundsGEP(Addr, FieldOffset,
"memptr.offset");
3030 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3031 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3035 if (isa<llvm::Constant>(Src))
3036 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3046 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3047 if (IsReinterpret && IsFunc)
3052 if (IsReinterpret &&
3059 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3060 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3064 if (IsReinterpret) {
3067 assert(Src->getType() == DstNull->getType());
3068 return Builder.CreateSelect(IsNotNull, Src, DstNull);
3071 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3074 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3077 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3081 Builder.CreateBr(ContinueBB);
3085 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3086 Phi->addIncoming(DstNull, OriginalBB);
3087 Phi->addIncoming(Dst, ConvertBB);
3091 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3101 bool IsConstant = isa<llvm::Constant>(Src);
3105 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3106 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3108 if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
3111 FirstField = Builder.CreateExtractValue(Src, I++);
3112 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
3113 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3114 if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
3115 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3116 if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
3117 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3120 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3126 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3134 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3135 if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3136 if (int64_t SrcOffsetToFirstVBase =
3137 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3138 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3140 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3142 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3153 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3159 if (IsDerivedToBase)
3160 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3162 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3164 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3169 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) &&
3170 MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) {
3171 if (llvm::GlobalVariable *VDispMap =
3172 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3174 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3176 llvm::Constant *Mapping = VDispMap->getInitializer();
3177 VirtualBaseAdjustmentOffset =
3178 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3181 VirtualBaseAdjustmentOffset =
3187 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3193 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) {
3194 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3196 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3198 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3204 if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3205 if (int64_t DstOffsetToFirstVBase =
3206 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3207 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3209 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3211 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3217 if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) {
3220 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3222 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3223 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
3224 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3225 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
3226 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3227 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
3228 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3234 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3235 llvm::Constant *Src) {
3242 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3246 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3250 assert(CK == CK_DerivedToBaseMemberPointer ||
3251 CK == CK_BaseToDerivedMemberPointer ||
3252 CK == CK_ReinterpretMemberPointer);
3255 if (MemberPointerConstantIsNull(SrcTy, Src))
3256 return EmitNullMemberPointer(DstTy);
3261 if (CK == CK_ReinterpretMemberPointer)
3265 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3266 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3271 CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3283 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
3289 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3291 if (MemPtr->getType()->isStructTy()) {
3294 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3295 if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance))
3296 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3297 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3298 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3299 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3300 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3303 if (VirtualBaseAdjustmentOffset) {
3304 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3305 VirtualBaseAdjustmentOffset, VBPtrOffset);
3310 if (NonVirtualBaseAdjustment) {
3313 Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
3314 ThisPtrForCall = Builder.
CreateBitCast(Ptr, ThisPtrForCall->getType(),
3319 Builder.
CreateBitCast(FunctionPointer, FTy->getPointerTo());
3320 CGCallee Callee(FPT, FunctionPointer);
3325 return new MicrosoftCXXABI(CGM);
3359 StringRef MangledName(
"\01??_7type_info@@6B@");
3360 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3365 nullptr, MangledName);
3376 struct MSRTTIClass {
3378 IsPrivateOnPath = 1 | 8,
3382 HasHierarchyDescriptor = 64
3385 uint32_t initialize(
const MSRTTIClass *
Parent,
3388 MSRTTIClass *getFirstChild() {
return this + 1; }
3389 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3390 return Child + 1 + Child->NumBases;
3394 uint32_t Flags, NumBases, OffsetInVBase;
3398 uint32_t MSRTTIClass::initialize(
const MSRTTIClass *
Parent,
3400 Flags = HasHierarchyDescriptor;
3402 VirtualRoot =
nullptr;
3406 Flags |= IsPrivate | IsPrivateOnPath;
3412 if (Parent->Flags & IsPrivateOnPath)
3413 Flags |= IsPrivateOnPath;
3414 VirtualRoot = Parent->VirtualRoot;
3420 MSRTTIClass *Child = getFirstChild();
3422 NumBases += Child->initialize(
this, &Base) + 1;
3423 Child = getNextChild(Child);
3428 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3439 return llvm::GlobalValue::LinkOnceODRLinkage;
3441 llvm_unreachable(
"Invalid linkage!");
3447 struct MSRTTIBuilder {
3449 HasBranchingHierarchy = 1,
3450 HasVirtualBranchingHierarchy = 2,
3451 HasAmbiguousBases = 4
3454 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3460 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3461 llvm::GlobalVariable *
3463 llvm::GlobalVariable *getClassHierarchyDescriptor();
3464 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3468 llvm::LLVMContext &VMContext;
3471 llvm::GlobalVariable::LinkageTypes
Linkage;
3472 MicrosoftCXXABI &ABI;
3481 Classes.push_back(MSRTTIClass(RD));
3489 llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3490 llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3491 llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3492 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3493 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3494 !VirtualBases.insert(Class->RD).second) {
3495 Class = MSRTTIClass::getNextChild(Class);
3498 if (!UniqueBases.insert(Class->RD).second)
3499 AmbiguousBases.insert(Class->RD);
3502 if (AmbiguousBases.empty())
3504 for (MSRTTIClass &Class : Classes)
3505 if (AmbiguousBases.count(Class.RD))
3506 Class.Flags |= MSRTTIClass::IsAmbiguous;
3509 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3512 llvm::raw_svector_ostream Out(MangledName);
3513 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3517 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3523 Classes.front().initialize(
nullptr,
nullptr);
3526 for (
auto Class : Classes) {
3527 if (Class.RD->getNumBases() > 1)
3528 Flags |= HasBranchingHierarchy;
3531 if (Class.Flags & MSRTTIClass::IsAmbiguous)
3532 Flags |= HasAmbiguousBases;
3534 if ((Flags & HasBranchingHierarchy) && RD->
getNumVBases() != 0)
3535 Flags |= HasVirtualBranchingHierarchy;
3539 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3542 auto Type = ABI.getClassHierarchyDescriptorType();
3543 auto CHD =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3546 if (CHD->isWeakForLinker())
3547 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3549 auto *Bases = getBaseClassArray(Classes);
3552 llvm::Constant *Fields[] = {
3553 llvm::ConstantInt::get(CGM.
IntTy, 0),
3554 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3555 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3556 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3557 Bases->getValueType(), Bases,
3560 CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3564 llvm::GlobalVariable *
3568 llvm::raw_svector_ostream Out(MangledName);
3569 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3577 llvm::Type *PtrType = ABI.getImageRelativeType(
3578 ABI.getBaseClassDescriptorType()->getPointerTo());
3579 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3581 new llvm::GlobalVariable(
Module, ArrType,
3583 nullptr, MangledName);
3584 if (BCA->isWeakForLinker())
3585 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3589 for (MSRTTIClass &Class : Classes)
3590 BaseClassArrayData.push_back(
3591 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3592 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3593 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3597 llvm::GlobalVariable *
3598 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3601 uint32_t OffsetInVBTable = 0;
3602 int32_t VBPtrOffset = -1;
3603 if (Class.VirtualRoot) {
3605 OffsetInVBTable = VTableContext.
getVBTableIndex(RD, Class.VirtualRoot) * 4;
3611 llvm::raw_svector_ostream Out(MangledName);
3612 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3613 Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3618 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3622 auto Type = ABI.getBaseClassDescriptorType();
3624 new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3625 nullptr, MangledName);
3626 if (BCD->isWeakForLinker())
3627 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3630 llvm::Constant *Fields[] = {
3631 ABI.getImageRelativeConstant(
3633 llvm::ConstantInt::get(CGM.
IntTy, Class.NumBases),
3634 llvm::ConstantInt::get(CGM.
IntTy, Class.OffsetInVBase),
3635 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3636 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3637 llvm::ConstantInt::get(CGM.
IntTy, Class.Flags),
3638 ABI.getImageRelativeConstant(
3639 MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3641 BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3645 llvm::GlobalVariable *
3646 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3649 llvm::raw_svector_ostream Out(MangledName);
3650 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3654 if (
auto COL =
Module.getNamedGlobal(MangledName))
3659 int VFPtrOffset = 0;
3665 ->second.hasVtorDisp())
3669 llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3670 auto COL =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3671 nullptr, MangledName);
3674 llvm::Constant *Fields[] = {
3675 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3676 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3677 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3678 ABI.getImageRelativeConstant(
3680 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3681 ABI.getImageRelativeConstant(COL),
3684 if (!ABI.isImageRelative())
3685 FieldsRef = FieldsRef.drop_back();
3686 COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
3687 if (COL->isWeakForLinker())
3688 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3693 bool &IsConst,
bool &IsVolatile,
3694 bool &IsUnaligned) {
3704 IsUnaligned =
false;
3706 if (!PointeeType.
isNull()) {
3727 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3732 bool IsConst, IsVolatile, IsUnaligned;
3748 return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(),
3756 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3759 llvm::raw_svector_ostream Out(MangledName);
3760 getMangleContext().mangleCXXRTTI(Type, Out);
3764 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3765 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3773 llvm::raw_svector_ostream Out(TypeInfoString);
3774 getMangleContext().mangleCXXRTTIName(Type, Out);
3778 llvm::Constant *Fields[] = {
3780 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3781 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
3782 llvm::StructType *TypeDescriptorType =
3783 getTypeDescriptorType(TypeInfoString);
3784 auto *Var =
new llvm::GlobalVariable(
3785 CGM.
getModule(), TypeDescriptorType,
false,
3786 getLinkageForRTTI(Type),
3787 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
3789 if (Var->isWeakForLinker())
3790 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
3791 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
3795 llvm::GlobalVariable *
3796 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
3798 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
3817 if (ProducedAlias) {
3833 if (Fn->isWeakForLinker())
3834 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
3837 void MicrosoftCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3839 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
3853 llvm::raw_svector_ostream Out(ThunkName);
3854 getMangleContext().mangleCXXCtor(CD, CT, Out);
3857 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
3858 return cast<llvm::Function>(GV);
3864 QualType RecordTy = getContext().getRecordType(RD);
3866 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
3867 ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
3869 if (ThunkFn->isWeakForLinker())
3870 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
3881 buildThisParam(CGF, FunctionArgs);
3887 &getContext().Idents.get(
"src"),
3888 getContext().getLValueReferenceType(RecordTy,
3892 FunctionArgs.push_back(&SrcParam);
3899 &getContext().Idents.get(
"is_most_derived"),
3903 FunctionArgs.push_back(&IsMostDerived);
3911 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
3931 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
3932 ArgVec.push_back(PD->getDefaultArg());
3938 CGF.
EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
3941 AddedStructorArgs ExtraArgs =
3946 llvm::Constant *CalleePtr =
3950 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
3962 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
3964 int32_t VBPtrOffset,
3976 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
3979 llvm::raw_svector_ostream Out(MangledName);
3980 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
3981 VBPtrOffset, VBIndex, Out);
3983 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3984 return getImageRelativeConstant(GV);
3988 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
3992 llvm::Constant *CopyCtor;
3999 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
4001 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4003 CopyCtor = getImageRelativeConstant(CopyCtor);
4005 bool IsScalar = !RD;
4006 bool HasVirtualBases =
false;
4007 bool IsStdBadAlloc =
false;
4012 HasVirtualBases = RD->getNumVBases() > 0;
4014 IsStdBadAlloc = II->isStr(
"bad_alloc") && RD->isInStdNamespace();
4022 if (HasVirtualBases)
4027 llvm::Constant *Fields[] = {
4028 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4030 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4031 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4032 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4033 llvm::ConstantInt::get(CGM.
IntTy, Size),
4036 llvm::StructType *CTType = getCatchableTypeType();
4037 auto *GV =
new llvm::GlobalVariable(
4038 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
4039 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4040 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4041 GV->setSection(
".xdata");
4042 if (GV->isWeakForLinker())
4043 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4044 return getImageRelativeConstant(GV);
4047 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4051 llvm::GlobalVariable *&CTA = CatchableTypeArrays[
T];
4076 if (MostDerivedClass) {
4083 Classes.front().initialize(
nullptr,
nullptr);
4085 for (
const MSRTTIClass &Class : Classes) {
4088 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4091 uint32_t OffsetInVBTable = 0;
4092 int32_t VBPtrOffset = -1;
4093 if (Class.VirtualRoot) {
4104 CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
4105 VBPtrOffset, OffsetInVBTable));
4113 CatchableTypes.insert(getCatchableType(T));
4126 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4137 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4139 uint32_t NumEntries = CatchableTypes.size();
4141 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4142 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4143 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4144 llvm::Constant *Fields[] = {
4145 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4146 llvm::ConstantArray::get(
4147 AT, llvm::makeArrayRef(CatchableTypes.begin(),
4148 CatchableTypes.end()))
4152 llvm::raw_svector_ostream Out(MangledName);
4153 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4155 CTA =
new llvm::GlobalVariable(
4156 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4157 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4158 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4159 CTA->setSection(
".xdata");
4160 if (CTA->isWeakForLinker())
4161 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4165 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4166 bool IsConst, IsVolatile, IsUnaligned;
4171 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4176 uint32_t NumEntries =
4177 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
4178 ->getLimitedValue();
4182 llvm::raw_svector_ostream Out(MangledName);
4183 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4189 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4205 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4208 if (!DtorD->isTrivial())
4209 CleanupFn = llvm::ConstantExpr::getBitCast(
4213 llvm::Constant *ForwardCompat =
4214 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4215 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4216 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4217 llvm::StructType *TIType = getThrowInfoType();
4218 llvm::Constant *Fields[] = {
4219 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4220 getImageRelativeConstant(CleanupFn),
4222 PointerToCatchableTypes
4224 auto *GV =
new llvm::GlobalVariable(
4225 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4226 llvm::ConstantStruct::get(TIType, Fields), StringRef(MangledName));
4227 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4228 GV->setSection(
".xdata");
4229 if (GV->isWeakForLinker())
4230 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4245 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4255 std::pair<llvm::Value *, const CXXRecordDecl *>
4258 std::tie(This, std::ignore, RD) =
ReturnValueSlot - Contains the address where the return value of a function can be stored...
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.
static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile, bool &IsUnaligned)
llvm::IntegerType * IntTy
int
struct clang::ThisAdjustment::VirtualAdjustment::@119 Microsoft
CharUnits getIntAlign() const
void setSRetAfterThis(bool AfterThis)
External linkage, which indicates that the entity can be referred to from other translation units...
Other implicit parameter.
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
A (possibly-)qualified type.
static llvm::Constant * getInitThreadFooterFn(CodeGenModule &CGM)
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
uint32_t VBPtrOffset
The offset (in bytes) of the vbptr, relative to the beginning of the derived class.
Internal linkage according to the Modules TS, but can be referred to from other translation units ind...
const Expr * getSubExpr() const
llvm::LLVMContext & getLLVMContext()
static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)
Find ambiguity among base classes.
CXXDtorType getDtorType() const
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.
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.
const Type * getTypeForDecl() const
const CGFunctionInfo & arrangeCXXMethodType(const CXXRecordDecl *RD, const FunctionProtoType *FTP, const CXXMethodDecl *MD)
Arrange the argument and result information for a call to an unknown C++ non-static member function o...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
bool isPOD() const
Whether this class is a POD-type (C++ [class]p4)
GlobalDecl getCanonicalDecl() const
The base class of the type hierarchy.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isZero() const
isZero - Test whether the quantity equals zero.
const NestedNameSpecifier * Specifier
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i...
Linkage getLinkage() const
Determine the linkage of this type.
BasePath MangledPath
The bases from the inheritance path that got used to mangle the vbtable name.
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.
Default closure variant of a ctor.
MSInheritanceAttr::Spelling getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
const CXXBaseSpecifier *const * path_const_iterator
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::Instruction **callOrInvoke, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Address getObjectAddress(CodeGenFunction &CGF) const
Returns the address of the object within this declaration.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const T * getAs() const
Member-template getAs<specific type>'.
static llvm::Constant * getInitThreadHeaderFn(CodeGenModule &CGM)
A this pointer adjustment.
DiagnosticsEngine & getDiags() const
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
llvm::Value * getPointer() const
A C++ throw-expression (C++ [except.throw]).
static llvm::Constant * getInitThreadAbortFn(CodeGenModule &CGM)
bool hasDefinition() const
ParmVarDecl - Represents a parameter to a function.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
unsigned getAddressSpace() const
Return the address space that this address resides in.
const ValueDecl * getMemberPointerDecl() const
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
One of these records is kept for each identifier that is lexed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const CXXRecordDecl * NearestVBase
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl *> BasePath, raw_ostream &Out)=0
Mangle vftable symbols.
llvm::Constant * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the constructor/destructor of the given type.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::IntegerType * SizeTy
StructorType getFromDtorType(CXXDtorType T)
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
bool isReferenceType() const
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
llvm::Function * codegenCXXStructor(const CXXMethodDecl *MD, StructorType Type)
Describes a module or submodule.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
ArrayRef< ParmVarDecl * > parameters() const
ArrayRef< VTableComponent > vtable_components() const
QualType getThisType(ASTContext &C) const
Returns the type of the this pointer.
FunctionDecl * getOperatorDelete() const
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
const CXXRecordDecl * IntroducingObject
This is the class that introduced the vptr by declaring new virtual methods or virtual bases...
path_iterator path_begin()
CharUnits getAlignment() const
Return the alignment of this pointer.
llvm::PointerType * VoidPtrTy
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
Concrete class used by the front-end to report problems and issues.
static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM)
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
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.
QualType getExceptionObjectType(QualType T) const
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
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...
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getPointerAlign() const
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
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.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to...
CanQualType getReturnType() const
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...
Represents a prototype with parameter type info, e.g.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
CastKind
CastKind - The kind of operation required for a conversion.
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.
static void emitCXXConstructor(CodeGenModule &CGM, const CXXConstructorDecl *ctor, StructorType ctorType)
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
CXXDtorType
C++ destructor types.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
const FunctionProtoType * T
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
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
static llvm::CallSite emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
bool isNullPtrType() const
llvm::PointerType * getType() const
Return the type of the pointer value.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
DeclContext * getDeclContext()
TLSKind getTLSKind() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
MicrosoftVTableContext & getMicrosoftVTableContext()
void add(RValue rvalue, QualType type, bool needscopy=false)
llvm::LLVMContext & getLLVMContext()
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
llvm::IntegerType * Int32Ty
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
const TargetInfo & getTarget() const
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class...
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
ASTContext & getContext() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
The COMDAT used for dtors.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
GlobalDecl - represents a global declaration.
bool isConstQualified() const
Determine whether this type is const-qualified.
The l-value was considered opaque, so the alignment was determined from a type.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target)
Try to emit a definition as a global alias for another definition.
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
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.
Represents a call to a member function that may be written either with member call syntax (e...
ASTContext & getASTContext() const LLVM_READONLY
const Decl * getDecl() const
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
Represents a single component in a vtable.
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Represents a static or instance method of a struct/union/class.
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
bool isInstanceMethod() const
QualType getAllocatedType() const
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.
const CXXRecordDecl * ObjectWithVPtr
This is the most derived class that has this vptr at offset zero.
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.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
All available information about a concrete callee.
MangleContext & getMangleContext()
Gets the mangle context.
llvm::Instruction * CurrentFuncletPad
CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)
Creates a Microsoft-family ABI.
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo &VFPtr, SmallString< 256 > &Name)
bool isMemberPointerToDerivedMember() const
bool defaultedCopyConstructorIsDeleted() const
true if a defaulted copy constructor for this class would be deleted.
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.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod) const
Retrieves the default calling convention for the current target.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is virtually derived from the class Base.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
Dataflow Directional Tag Classes.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This)
External linkage within a unique namespace.
static bool isDeletingDtor(GlobalDecl GD)
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
const VPtrInfoVector & enumerateVBTables(const CXXRecordDecl *RD)
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args)
Emits a call or invoke to the given noreturn runtime function.
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
llvm::Constant * getPointer() 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="")
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
A pointer to member type per C++ 8.3.3 - Pointers to members.
CharUnits NonVirtualOffset
IntroducingObject is at this offset from its containing complete object or virtual base...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
void EmitThunks(GlobalDecl GD)
EmitThunks - Emit the associated thunks for the given global decl.
union clang::ThisAdjustment::VirtualAdjustment Virtual
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void AppendLinkerOptions(StringRef Opts)
Appends Opts to the "llvm.linker.options" metadata value.
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
const CXXRecordDecl * getVBaseWithVPtr() const
The vptr is stored inside the non-virtual component of this virtual base.
Implements C++ ABI-specific code generation functions.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
llvm::PointerType * Int8PtrTy
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
SourceLocation getLocStart() const LLVM_READONLY
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
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.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
ABIArgInfo & getReturnInfo()
Represents a base class of a C++ class.
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
bool isObjectType() const
Determine whether this type is an object type.
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
CharUnits getIntSize() const
bool needsImplicitCopyConstructor() const
Determine whether this class needs an implicit copy constructor to be lazily declared.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
bool hasUnaligned() const
Represents a C++ struct/union/class.
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
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.
static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor, StructorType dtorType)
A specialization of Address that requires the address to be an LLVM Constant.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
No linkage according to the standard, but is visible from other translation units because of types de...
struct clang::ReturnAdjustment::VirtualAdjustment::@117 Microsoft
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
bool isGlobalDelete() const
Copying closure variant of a ctor.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CharUnits FullOffsetInMDC
Static offset from the top of the most derived class to this vfptr, including any virtual base offset...
uint64_t Index
Method's index in the vftable.
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
Struct with all informations about dynamic [sub]class needed to set vptr.
static RValue get(llvm::Value *V)
GVALinkage
A more specific kind of linkage than enum Linkage.
bool isDeleted() const
Whether this function has been deleted.
Holds information about the inheritance path to a virtual base or function table pointer.
bool isPointerType() const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
CodeGenVTables & getVTables()
uint32_t VBIndex
Index of the virtual base in the vbtable.
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
BasePath PathToIntroducingObject
This holds the base classes path from the complete type to the first base with the given vfptr offset...
const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
Notes how many arguments were added to the beginning (Prefix) and ending (Suffix) of an arg list...
RecordArgABI
Specify how one should pass an argument of a record type.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
CallArgList - Type for representing both the value and type of arguments in a call.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...
Address CreateMemTemp(QualType T, const Twine &Name="tmp", bool CastToDefaultAddrSpace=true)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)
Recursively serializes a class hierarchy in pre-order depth first order.
base_class_range vbases()
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
const MethodVFTableLocation & getMethodVFTableLocation(GlobalDecl GD)
SourceLocation getLocation() const
QualType getPointeeType() const
bool isExternallyVisible() const
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.
void EmitMustTailThunk(const CXXMethodDecl *MD, llvm::Value *AdjustedThisPtr, llvm::Value *Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
static llvm::Constant * getThrowFn(CodeGenModule &CGM)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.