29 #include "llvm/ADT/StringExtras.h"
30 #include "llvm/ADT/StringSet.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;
136 if (getContext().getLangOpts().EHAsynch)
142 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
146 llvm::Type *StdTypeInfoPtrTy)
override;
148 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
154 llvm::BasicBlock *CastEnd)
override;
161 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override {
214 AddedStructorArgCounts
224 void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
228 llvm::GlobalValue::LinkageTypes
235 getThisArgumentTypeForMethod(
const CXXMethodDecl *MD)
override {
236 if (MD->
isVirtual() && !isa<CXXDestructorDecl>(MD)) {
238 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
254 bool VirtualCall)
override;
265 bool Delegating)
override;
271 bool Delegating)
override;
279 llvm::GlobalVariable *VTable);
289 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
290 return !VTableClass->
hasAttr<MSNoVTableAttr>();
297 llvm::Value *getVTableAddressPointInStructor(
305 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
315 DeleteOrMemberCallExpr E)
override;
320 "Only deleting destructor thunks are available in this ABI");
325 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
327 llvm::GlobalVariable *
329 llvm::GlobalVariable::LinkageTypes
Linkage);
331 llvm::GlobalVariable *
335 llvm::raw_svector_ostream Out(OutName);
336 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
337 StringRef MangledName = OutName.str();
339 if (
auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
345 llvm::UndefValue::get(CGM.IntTy));
346 Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
347 bool AnyDifferent =
false;
348 for (
const auto &I : SrcRD->
vbases()) {
349 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
355 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
356 AnyDifferent |= SrcVBIndex != DstVBIndex;
362 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy, Map.size());
363 llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy, Map);
364 llvm::GlobalValue::LinkageTypes
Linkage =
366 ? llvm::GlobalValue::LinkOnceODRLinkage
368 auto *VDispMap =
new llvm::GlobalVariable(
369 CGM.getModule(), VDispMapTy,
true,
Linkage,
375 llvm::GlobalVariable *GV)
const;
377 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
380 getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.
getDecl()));
385 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
387 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
390 bool exportThunk()
override {
return false; }
398 void EmitThreadLocalInitFuncs(
403 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
404 return getContext().getLangOpts().isCompatibleWithMSVC(
406 (!isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD));
412 llvm::GlobalVariable *DeclPtr,
413 bool PerformInit)
override;
415 llvm::FunctionCallee Dtor,
416 llvm::Constant *Addr)
override;
447 llvm::Value *NumElements,
454 friend struct MSRTTIBuilder;
456 bool isImageRelative()
const {
457 return CGM.getTarget().getPointerWidth(0) == 64;
461 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
463 TDTypeName += llvm::utostr(TypeInfoString.size());
464 llvm::StructType *&TypeDescriptorType =
465 TypeDescriptorTypeMap[TypeInfoString.size()];
466 if (TypeDescriptorType)
467 return TypeDescriptorType;
468 llvm::Type *FieldTypes[] = {
471 llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
474 return TypeDescriptorType;
477 llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
478 if (!isImageRelative())
483 llvm::StructType *getBaseClassDescriptorType() {
484 if (BaseClassDescriptorType)
485 return BaseClassDescriptorType;
486 llvm::Type *FieldTypes[] = {
487 getImageRelativeType(CGM.Int8PtrTy),
493 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
496 CGM.getLLVMContext(), FieldTypes,
"rtti.BaseClassDescriptor");
497 return BaseClassDescriptorType;
500 llvm::StructType *getClassHierarchyDescriptorType() {
501 if (ClassHierarchyDescriptorType)
502 return ClassHierarchyDescriptorType;
505 CGM.getLLVMContext(),
"rtti.ClassHierarchyDescriptor");
506 llvm::Type *FieldTypes[] = {
510 getImageRelativeType(
511 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
513 ClassHierarchyDescriptorType->setBody(FieldTypes);
514 return ClassHierarchyDescriptorType;
517 llvm::StructType *getCompleteObjectLocatorType() {
518 if (CompleteObjectLocatorType)
519 return CompleteObjectLocatorType;
521 CGM.getLLVMContext(),
"rtti.CompleteObjectLocator");
522 llvm::Type *FieldTypes[] = {
526 getImageRelativeType(CGM.Int8PtrTy),
527 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
528 getImageRelativeType(CompleteObjectLocatorType),
531 if (!isImageRelative())
532 FieldTypesRef = FieldTypesRef.drop_back();
533 CompleteObjectLocatorType->setBody(FieldTypesRef);
534 return CompleteObjectLocatorType;
537 llvm::GlobalVariable *getImageBase() {
538 StringRef Name =
"__ImageBase";
539 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
542 auto *GV =
new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
550 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
551 if (!isImageRelative())
554 if (PtrVal->isNullValue())
555 return llvm::Constant::getNullValue(CGM.IntTy);
557 llvm::Constant *ImageBaseAsInt =
558 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
559 llvm::Constant *PtrValAsInt =
560 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
561 llvm::Constant *Diff =
562 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
564 return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
572 llvm::Constant *getZeroInt() {
573 return llvm::ConstantInt::get(CGM.IntTy, 0);
576 llvm::Constant *getAllOnesInt() {
577 return llvm::Constant::getAllOnesValue(CGM.IntTy);
591 llvm::Value *VBPtrOffset,
592 llvm::Value *VBTableOffset,
593 llvm::Value **VBPtr =
nullptr);
598 int32_t VBTableOffset,
599 llvm::Value **VBPtr =
nullptr) {
600 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
601 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
602 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
603 return GetVBaseOffsetFromVBPtr(CGF,
Base, VBPOffset, VBTOffset, VBPtr);
606 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
614 llvm::Value *VirtualBaseAdjustmentOffset,
615 llvm::Value *VBPtrOffset );
619 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
620 bool IsMemberFunction,
623 unsigned VBTableIndex);
632 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
635 llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
638 llvm::Constant *EmitMemberDataPointer(
const CXXRecordDecl *RD,
648 return RD->
hasAttr<MSInheritanceAttr>();
655 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
656 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
662 bool Inequality)
override;
673 llvm::Value *EmitNonNullMemberPointerConversion(
681 llvm::Value *Src)
override;
683 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
684 llvm::Constant *Src)
override;
686 llvm::Constant *EmitMemberPointerConversion(
699 llvm::StructType *getCatchableTypeType() {
700 if (CatchableTypeType)
701 return CatchableTypeType;
702 llvm::Type *FieldTypes[] = {
704 getImageRelativeType(CGM.Int8PtrTy),
709 getImageRelativeType(CGM.Int8PtrTy)
712 CGM.getLLVMContext(), FieldTypes,
"eh.CatchableType");
713 return CatchableTypeType;
716 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
717 llvm::StructType *&CatchableTypeArrayType =
718 CatchableTypeArrayTypeMap[NumEntries];
719 if (CatchableTypeArrayType)
720 return CatchableTypeArrayType;
723 CTATypeName += llvm::utostr(NumEntries);
725 getImageRelativeType(getCatchableTypeType()->getPointerTo());
726 llvm::Type *FieldTypes[] = {
728 llvm::ArrayType::get(CTType, NumEntries)
730 CatchableTypeArrayType =
732 return CatchableTypeArrayType;
735 llvm::StructType *getThrowInfoType() {
737 return ThrowInfoType;
738 llvm::Type *FieldTypes[] = {
740 getImageRelativeType(CGM.Int8PtrTy),
741 getImageRelativeType(CGM.Int8PtrTy),
742 getImageRelativeType(CGM.Int8PtrTy)
746 return ThrowInfoType;
752 llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
753 llvm::FunctionType *FTy =
754 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
755 llvm::FunctionCallee Throw =
756 CGM.CreateRuntimeFunction(FTy,
"_CxxThrowException");
758 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
759 if (
auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
760 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
768 llvm::Constant *getCatchableType(
QualType T,
769 uint32_t NVOffset = 0,
770 int32_t VBPtrOffset = -1,
771 uint32_t VBIndex = 0);
773 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
775 llvm::GlobalVariable *getThrowInfo(
QualType T)
override;
777 std::pair<llvm::Value *, const CXXRecordDecl *>
782 isPermittedToBeHomogeneousAggregate(
const CXXRecordDecl *RD)
const override;
785 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
786 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
787 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
789 VFTablesMapTy VFTablesMap;
790 VTablesMapTy VTablesMap;
797 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
802 GuardInfo() : Guard(nullptr), BitIndex(0) {}
803 llvm::GlobalVariable *Guard;
809 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
810 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
811 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
813 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
814 llvm::StructType *BaseClassDescriptorType;
815 llvm::StructType *ClassHierarchyDescriptorType;
816 llvm::StructType *CompleteObjectLocatorType;
818 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
820 llvm::StructType *CatchableTypeType;
821 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
822 llvm::StructType *ThrowInfoType;
835 switch (CGM.getTarget().getTriple().getArch()) {
840 case llvm::Triple::thumb:
846 case llvm::Triple::x86: {
857 return RAA_DirectInMemory;
860 case llvm::Triple::x86_64:
861 case llvm::Triple::aarch64:
865 llvm_unreachable(
"invalid enum");
877 llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
882 void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
883 llvm::Value *Args[] = {
884 llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
885 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
897 VarDecl *CatchParam = S->getExceptionDecl();
898 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
899 llvm::CatchPadInst *CPI =
900 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
911 CPI->setArgOperand(2,
var.getObjectAddress(CGF).getPointer());
919 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
930 return std::make_tuple(
Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
939 PolymorphicBase = BaseDecl;
943 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
946 GetVirtualBaseClassOffset(CGF,
Value, SrcDecl, PolymorphicBase);
947 llvm::Value *Ptr = CGF.
Builder.CreateInBoundsGEP(
955 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
959 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
963 llvm::Value *Argument) {
964 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
965 llvm::FunctionType *FTy =
966 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
967 llvm::Value *Args[] = {Argument};
973 llvm::CallBase *
Call =
975 Call->setDoesNotReturn();
976 CGF.
Builder.CreateUnreachable();
982 llvm::Type *StdTypeInfoPtrTy) {
983 std::tie(ThisPtr, std::ignore, std::ignore) =
984 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
986 return CGF.
Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
989 bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
993 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
996 llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
1001 llvm::Value *SrcRTTI =
1003 llvm::Value *DestRTTI =
1008 performBaseAdjustment(CGF,
This, SrcRecordTy);
1009 llvm::Value *ThisPtr =
This.getPointer();
1021 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1023 llvm::Value *Args[] = {
1024 ThisPtr,
Offset, SrcRTTI, DestRTTI,
1027 return CGF.
Builder.CreateBitCast(ThisPtr, DestLTy);
1034 std::tie(
Value, std::ignore, std::ignore) =
1035 performBaseAdjustment(CGF,
Value, SrcRecordTy);
1039 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1041 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1043 llvm::Value *Args[] = {
Value.getPointer()};
1051 llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1055 int64_t VBPtrChars =
1057 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
1061 CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
1062 llvm::Value *VBTableOffset =
1063 llvm::ConstantInt::get(CGM.IntTy, VBTableChars.
getQuantity());
1065 llvm::Value *VBPtrToNewBase =
1066 GetVBaseOffsetFromVBPtr(CGF,
This, VBPtrOffset, VBTableOffset);
1068 CGF.
Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
1069 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1072 bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1073 return isa<CXXConstructorDecl>(GD.
getDecl());
1077 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1081 bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1102 if (Ctor->isUserProvided())
1119 bool isTrivialForABI = RD->
isPOD();
1120 bool isAArch64 = CGM.getTarget().getTriple().isAArch64();
1127 if (isIndirectReturn) {
1148 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1149 assert(IsMostDerivedClass &&
1150 "ctor for a class with virtual bases must have an implicit parameter");
1151 llvm::Value *IsCompleteObject =
1152 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1154 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1155 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1156 CGF.
Builder.CreateCondBr(IsCompleteObject,
1157 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1162 EmitVBPtrStores(CGF, RD);
1166 return SkipVbaseCtorsBB;
1170 MicrosoftCXXABI::EmitDtorCompleteObjectHandler(
CodeGenFunction &CGF) {
1171 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1172 assert(IsMostDerivedClass &&
1173 "ctor for a class with virtual bases must have an implicit parameter");
1174 llvm::Value *IsCompleteObject =
1175 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1177 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1178 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1179 CGF.
Builder.CreateCondBr(IsCompleteObject,
1180 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1185 return SkipVbaseDtorsBB;
1188 void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1208 unsigned AS = getThisAddress(CGF).getAddressSpace();
1209 llvm::Value *Int8This =
nullptr;
1212 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1213 auto I = VBaseMap.find(VBase);
1214 assert(I != VBaseMap.end());
1215 if (!I->second.hasVtorDisp())
1218 llvm::Value *VBaseOffset =
1219 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1220 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1223 llvm::Value *VtorDispValue = Builder.CreateSub(
1224 VBaseOffset, llvm::ConstantInt::get(CGM.PtrDiffTy, ConstantVBaseOffset),
1226 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1229 Int8This = Builder.CreateBitCast(getThisValue(CGF),
1230 CGF.
Int8Ty->getPointerTo(AS));
1231 llvm::Value *VtorDispPtr =
1232 Builder.CreateInBoundsGEP(CGF.
Int8Ty, Int8This, VBaseOffset);
1234 VtorDispPtr = Builder.CreateConstGEP1_32(CGF.
Int8Ty, VtorDispPtr, -4);
1235 VtorDispPtr = Builder.CreateBitCast(
1236 VtorDispPtr, CGF.
Int32Ty->getPointerTo(AS),
"vtordisp.ptr");
1238 Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1249 return ExpectedCallingConv == ActualCallingConv;
1264 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1265 CGM.setGVProperties(Fn, D);
1277 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1278 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1279 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1280 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1285 if (VBT->getVBaseWithVPtr())
1288 llvm::Value *GVPtr =
1291 "vbptr." + VBT->ObjectWithVPtr->getName());
1297 MicrosoftCXXABI::buildStructorSignature(
GlobalDecl GD,
1299 AddedStructorArgCounts Added;
1301 if (isa<CXXDestructorDecl>(GD.
getDecl()) &&
1304 ArgTys.push_back(getContext().IntTy);
1307 auto *CD = dyn_cast<CXXConstructorDecl>(GD.
getDecl());
1316 if (
Class->getNumVBases()) {
1318 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1321 ArgTys.push_back(getContext().IntTy);
1329 void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1335 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1338 CGM.setDLLImportDLLExport(GV, ND);
1342 llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1353 return CGM.getLLVMLinkageForDeclarator(Dtor,
Linkage,
1359 if (Dtor->
hasAttr<DLLExportAttr>())
1360 return llvm::GlobalValue::WeakODRLinkage;
1361 if (Dtor->
hasAttr<DLLImportAttr>())
1362 return llvm::GlobalValue::AvailableExternallyLinkage;
1363 return llvm::GlobalValue::LinkOnceODRLinkage;
1368 return llvm::GlobalValue::LinkOnceODRLinkage;
1370 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1372 llvm_unreachable(
"invalid dtor type");
1389 MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1404 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1411 if (isa<CXXDestructorDecl>(MD))
1416 getContext().getASTRecordLayout(MD->
getParent());
1423 Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1429 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1452 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1468 llvm::Value *VBaseOffset =
1469 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1470 llvm::Value *VBasePtr = CGF.
Builder.CreateInBoundsGEP(
1471 Result.getElementType(), Result.getPointer(), VBaseOffset);
1476 if (!StaticOffset.
isZero()) {
1497 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1507 Params.insert(Params.begin() + 1, IsMostDerived);
1509 Params.push_back(IsMostDerived);
1510 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1516 Params.push_back(ShouldDelete);
1517 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1521 void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1538 llvm::Value *
This = loadIncomingCXXThis(CGF);
1541 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1542 if (!Adjustment.
isZero()) {
1543 unsigned AS = cast<llvm::PointerType>(
This->getType())->getAddressSpace();
1544 llvm::Type *charPtrTy = CGF.
Int8Ty->getPointerTo(AS),
1545 *thisTy =
This->getType();
1553 setCXXABIThisValue(CGF,
This);
1563 if (HasThisReturn(CGF.
CurGD))
1565 else if (hasMostDerivedReturn(CGF.
CurGD))
1570 assert(getStructorImplicitParamDecl(CGF) &&
1571 "no implicit parameter for a constructor with virtual bases?");
1572 getStructorImplicitParamValue(CGF)
1579 assert(getStructorImplicitParamDecl(CGF) &&
1580 "no implicit parameter for a deleting destructor?");
1581 getStructorImplicitParamValue(CGF)
1584 "should_call_delete");
1590 bool ForVirtualBase,
bool Delegating) {
1595 return AddedStructorArgs{};
1599 llvm::Value *MostDerivedArg;
1601 MostDerivedArg = getStructorImplicitParamValue(CGF);
1606 return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1608 return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1613 bool ForVirtualBase,
bool Delegating) {
1633 "The deleting destructor should only be called via a virtual call");
1638 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1639 if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1640 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1649 if (BaseDtorEndBB) {
1651 CGF.
Builder.CreateBr(BaseDtorEndBB);
1656 void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1658 llvm::GlobalVariable *VTable) {
1659 if (!CGM.getCodeGenOpts().LTOUnit)
1664 if (CGM.getCodeGenOpts().WholeProgramVTables) {
1666 llvm::GlobalObject::VCallVisibility TypeVis =
1667 CGM.GetVCallVisibilityLevel(RD, Visited);
1668 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1669 VTable->setVCallVisibilityMetadata(TypeVis);
1676 getContext().getLangOpts().RTTIData
1677 ? getContext().toCharUnitsFromBits(
1678 getContext().getTargetInfo().getPointerWidth(0))
1682 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1687 CGM.AddVTableTypeMetadata(VTable, AddressPoint,
1697 getContext().getASTRecordLayout(DerivedRD);
1703 Offset = VBI->second.VBaseOffset;
1706 CGM.AddVTableTypeMetadata(VTable, AddressPoint, DerivedRD);
1711 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1714 void MicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables &CGVT,
1719 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1720 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1721 if (VTable->hasInitializer())
1727 llvm::Constant *RTTI =
nullptr;
1730 RTTI = getMSCompleteObjectLocator(RD, *Info);
1733 auto components = builder.beginStruct();
1735 VTable->hasLocalLinkage());
1736 components.finishAndSetAsInitializer(VTable);
1738 emitVTableTypeMetadata(*Info, RD, VTable);
1742 bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1747 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1750 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(
Base, VTableClass);
1751 if (!VTableAddressPoint) {
1752 assert(
Base.getBase()->getNumVBases() &&
1753 !getContext().getASTRecordLayout(
Base.getBase()).hasOwnVFPtr());
1755 return VTableAddressPoint;
1761 llvm::raw_svector_ostream Out(Name);
1768 (void)getAddrOfVTable(VTableClass,
Base.getBaseOffset());
1769 VFTableIdTy
ID(VTableClass,
Base.getBaseOffset());
1770 return VFTablesMap[
ID];
1773 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1775 llvm::Constant *VFTable = getVTableAddressPoint(
Base, VTableClass);
1776 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1780 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1786 VFTableIdTy
ID(RD, VPtrOffset);
1787 VTablesMapTy::iterator I;
1789 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(
ID,
nullptr));
1793 llvm::GlobalVariable *&VTable = I->second;
1798 if (DeferredVFTables.insert(RD).second) {
1801 CGM.addDeferredVTable(RD);
1806 llvm::StringSet<> ObservedMangledNames;
1807 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1810 if (!ObservedMangledNames.insert(Name.str()).second)
1811 llvm_unreachable(
"Already saw this mangling before?");
1816 const std::unique_ptr<VPtrInfo> *VFPtrI =
1817 llvm::find_if(VFPtrs, [&](
const std::unique_ptr<VPtrInfo> &VPI) {
1818 return VPI->FullOffsetInMDC == VPtrOffset;
1820 if (VFPtrI == VFPtrs.end()) {
1821 VFTablesMap[
ID] =
nullptr;
1824 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1836 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1837 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1838 : CGM.getVTableLinkage(RD);
1839 bool VFTableComesFromAnotherTU =
1840 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1841 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1842 bool VTableAliasIsRequred =
1843 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1845 if (llvm::GlobalValue *VFTable =
1846 CGM.getModule().getNamedGlobal(VFTableName)) {
1847 VFTablesMap[
ID] = VFTable;
1848 VTable = VTableAliasIsRequred
1849 ? cast<llvm::GlobalVariable>(
1850 cast<llvm::GlobalAlias>(VFTable)->getAliaseeObject())
1851 :
cast<
llvm::GlobalVariable>(VFTable);
1857 llvm::GlobalValue::LinkageTypes VTableLinkage =
1858 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1860 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1862 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1866 llvm::GlobalValue *VFTable;
1867 VTable =
new llvm::GlobalVariable(CGM.getModule(), VTableType,
1868 true, VTableLinkage,
1869 nullptr, VTableName);
1870 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1872 llvm::Comdat *
C =
nullptr;
1873 if (!VFTableComesFromAnotherTU &&
1874 (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1875 (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1876 VTableAliasIsRequred)))
1877 C = CGM.getModule().getOrInsertComdat(VFTableName.str());
1882 if (VTableAliasIsRequred) {
1883 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.Int32Ty, 0),
1884 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1885 llvm::ConstantInt::get(CGM.Int32Ty, 1)};
1888 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1889 VTable->getValueType(), VTable, GEPIndices);
1890 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1893 C->setSelectionKind(llvm::Comdat::Largest);
1897 VFTableName.str(), VTableGEP,
1899 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1908 VTable->setComdat(C);
1910 if (RD->
hasAttr<DLLExportAttr>())
1911 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1913 VFTablesMap[
ID] = VFTable;
1924 Ty = Ty->getPointerTo();
1926 adjustThisArgumentForVirtualFunctionCall(CGF, GD,
This,
true);
1928 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1929 llvm::Value *VTable = CGF.
GetVTablePtr(VPtr, Ty->getPointerTo(),
1930 MethodDecl->getParent());
1937 auto getObjectWithVPtr = [&] {
1940 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1941 return Info->FullOffsetInMDC == ML.VFPtrOffset;
1950 getObjectWithVPtr(), VTable, Ty,
1951 ML.
Index * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1953 if (CGM.getCodeGenOpts().PrepareForLTO)
1956 llvm::Value *VFuncPtr =
1957 Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.
Index,
"vfn");
1958 VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.
getPointerAlign());
1965 llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1970 assert((CE !=
nullptr) ^ (D !=
nullptr));
1971 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
1978 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
1983 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1989 ThisTy = CE->getObjectType();
1991 ThisTy = D->getDestroyedType();
1994 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD,
This,
true);
1996 ImplicitParam, Context.
IntTy, CE);
2000 const VBTableGlobals &
2001 MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
2004 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
2006 std::tie(Entry, Added) =
2007 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
2008 VBTableGlobals &VBGlobals = Entry->second;
2013 VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2017 llvm::GlobalVariable::LinkageTypes
Linkage = CGM.getVTableLinkage(RD);
2018 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2019 E = VBGlobals.VBTables->end();
2021 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,
Linkage));
2028 MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2030 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
2031 "can't form pointers to ctors or virtual dtors");
2035 llvm::raw_svector_ostream Out(ThunkName);
2036 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2039 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
2040 return cast<llvm::Function>(GV);
2044 CGM.getTypes().arrangeUnprototypedMustTailThunk(MD);
2045 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
2046 llvm::Function *ThunkFn =
2048 ThunkName.str(), &CGM.getModule());
2049 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2052 ? llvm::GlobalValue::LinkOnceODRLinkage
2055 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
2057 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn,
false);
2058 CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
2064 ThunkFn->addFnAttr(
"thunk");
2077 buildThisParam(CGF, FunctionArgs);
2082 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2086 llvm::Type *ThunkPtrTy = ThunkTy->getPointerTo();
2088 getThisAddress(CGF), ThunkPtrTy->getPointerTo(), MD->
getParent());
2090 llvm::Value *VFuncPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2091 ThunkPtrTy, VTable, ML.
Index,
"vfn");
2100 void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2101 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2102 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2103 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2104 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2105 if (GV->isDeclaration())
2106 emitVBTableDefinition(*VBT, RD, GV);
2110 llvm::GlobalVariable *
2112 llvm::GlobalVariable::LinkageTypes
Linkage) {
2114 llvm::raw_svector_ostream Out(OutName);
2115 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2116 StringRef Name = OutName.str();
2118 llvm::ArrayType *VBTableType =
2121 assert(!CGM.getModule().getNamedGlobal(Name) &&
2122 "vbtable with this name already exists: mangling bug?");
2124 CGM.getContext().getTypeAlignInChars(CGM.getContext().IntTy);
2125 llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable(
2127 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2129 if (RD->
hasAttr<DLLImportAttr>())
2130 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2131 else if (RD->
hasAttr<DLLExportAttr>())
2132 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2134 if (!GV->hasExternalLinkage())
2135 emitVBTableDefinition(VBT, RD, GV);
2140 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2142 llvm::GlobalVariable *GV)
const {
2146 "should only emit vbtables for classes with vbtables");
2150 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2157 Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.
getQuantity());
2160 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2161 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2163 assert(!
Offset.isNegative());
2168 CompleteVBPtrOffset +=
2170 Offset -= CompleteVBPtrOffset;
2172 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2173 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2174 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy,
Offset.getQuantity());
2177 assert(Offsets.size() ==
2178 cast<llvm::ArrayType>(GV->getValueType())->getNumElements());
2179 llvm::ArrayType *VBTableType =
2180 llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2181 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2182 GV->setInitializer(Init);
2184 if (RD->
hasAttr<DLLImportAttr>())
2185 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2188 llvm::Value *MicrosoftCXXABI::performThisAdjustment(
CodeGenFunction &CGF,
2192 return This.getPointer();
2198 V =
This.getPointer();
2208 CGF.
Builder.CreateNeg(VtorDisp));
2221 llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2225 V = CGF.
Builder.CreateInBoundsGEP(CGF.
Int8Ty, VBPtr, VBaseOffset);
2244 return Ret.getPointer();
2246 auto OrigTy =
Ret.getType();
2249 llvm::Value *
V =
Ret.getPointer();
2254 llvm::Value *VBaseOffset =
2257 V = CGF.
Builder.CreateInBoundsGEP(CGF.
Int8Ty, VBPtr, VBaseOffset);
2264 return CGF.
Builder.CreateBitCast(
V, OrigTy);
2274 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *
expr) {
2277 return expr->getAllocatedType().isDestructedType();
2288 llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(
CodeGenFunction &CGF,
2298 llvm::Value *numElements,
2301 assert(requiresArrayCookie(
expr));
2304 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2320 llvm::FunctionCallee Dtor,
2321 llvm::Constant *Addr) {
2326 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2327 CGF.
IntTy, DtorStub->getType(),
false);
2330 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2331 if (llvm::Function *TLRegDtorFn =
2332 dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2333 TLRegDtorFn->setDoesNotThrow();
2339 llvm::FunctionCallee Dtor,
2340 llvm::Constant *Addr) {
2351 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2355 if (CXXThreadLocalInits.empty())
2360 ?
"/include:___dyn_tls_init@12"
2361 :
"/include:__dyn_tls_init");
2366 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2367 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2368 CGM.
getModule(), InitFunc->getType(),
true,
2370 Twine(InitFunc->getName(),
"$initializer$"));
2371 InitFuncPtr->setSection(
".CRT$XDU");
2378 std::vector<llvm::Function *> NonComdatInits;
2379 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2380 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2382 llvm::Function *F = CXXThreadLocalInits[I];
2385 if (llvm::Comdat *C = GV->getComdat())
2386 AddToXDU(F)->setComdat(C);
2388 NonComdatInits.push_back(F);
2391 if (!NonComdatInits.empty()) {
2392 llvm::FunctionType *FTy =
2393 llvm::FunctionType::get(CGM.
VoidTy,
false);
2409 llvm::Constant *TlsGuardConstant =
2411 llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant);
2413 TlsGuard->setThreadLocal(
true);
2421 llvm::FunctionType *FTy =
2422 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()), {},
2425 FTy,
"__dyn_tls_on_demand_init",
2427 llvm::AttributeList::FunctionIndex,
2428 llvm::Attribute::NoUnwind),
2433 llvm::BasicBlock *DynInitBB,
2434 llvm::BasicBlock *ContinueBB) {
2435 llvm::LoadInst *TlsGuardValue =
2437 llvm::Value *CmpResult =
2439 CGF.
Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2443 llvm::GlobalValue *TlsGuard,
2444 llvm::BasicBlock *ContinueBB) {
2446 llvm::Function *InitializerFunction =
2448 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(InitializerFunction);
2449 CallVal->setCallingConv(InitializerFunction->getCallingConv());
2451 CGF.
Builder.CreateBr(ContinueBB);
2455 llvm::BasicBlock *DynInitBB =
2457 llvm::BasicBlock *ContinueBB =
2463 CGF.
Builder.SetInsertPoint(DynInitBB);
2465 CGF.
Builder.SetInsertPoint(ContinueBB);
2483 unsigned AS = cast<llvm::PointerType>(
V->getType())->getAddressSpace();
2484 V = CGF.
Builder.CreateBitCast(
V, RealVarTy->getPointerTo(AS));
2487 Address Addr(
V, RealVarTy, Alignment);
2497 StringRef VarName(
"_Init_thread_epoch");
2499 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2501 auto *GV =
new llvm::GlobalVariable(
2505 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2511 llvm::FunctionType *FTy =
2512 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2513 CGM.
IntTy->getPointerTo(),
false);
2515 FTy,
"_Init_thread_header",
2517 llvm::AttributeList::FunctionIndex,
2518 llvm::Attribute::NoUnwind),
2523 llvm::FunctionType *FTy =
2524 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2525 CGM.
IntTy->getPointerTo(),
false);
2527 FTy,
"_Init_thread_footer",
2529 llvm::AttributeList::FunctionIndex,
2530 llvm::Attribute::NoUnwind),
2535 llvm::FunctionType *FTy =
2536 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2537 CGM.
IntTy->getPointerTo(),
false);
2539 FTy,
"_Init_thread_abort",
2541 llvm::AttributeList::FunctionIndex,
2542 llvm::Attribute::NoUnwind),
2550 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2551 : Guard(Guard), GuardNum(GuardNum) {}
2557 llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2558 llvm::ConstantInt *Mask =
2559 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2560 Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2566 CallInitThreadAbort(
Address Guard) : Guard(Guard.getPointer()) {}
2576 llvm::GlobalVariable *GV,
2580 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2582 llvm::Function *F = CGF.
CurFn;
2583 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2584 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2590 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2594 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2597 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2598 llvm::ConstantInt *
Zero = llvm::ConstantInt::get(GuardTy, 0);
2602 GuardInfo *GI =
nullptr;
2603 if (ThreadlocalStatic)
2605 else if (!ThreadsafeStatic)
2608 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2613 GuardNum = getContext().getStaticLocalNumber(&D);
2614 assert(GuardNum > 0);
2616 }
else if (HasPerVariableGuard) {
2620 GuardNum = GI->BitIndex++;
2623 if (!HasPerVariableGuard && GuardNum >= 32) {
2625 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2634 llvm::raw_svector_ostream Out(GuardName);
2635 if (HasPerVariableGuard)
2636 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2639 getMangleContext().mangleStaticGuardVariable(&D, Out);
2645 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2646 GV->getLinkage(),
Zero, GuardName.str());
2647 GuardVar->setVisibility(GV->getVisibility());
2648 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2649 GuardVar->setAlignment(GuardAlign.
getAsAlign());
2650 if (GuardVar->isWeakForLinker())
2651 GuardVar->setComdat(
2652 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2655 if (GI && !HasPerVariableGuard)
2656 GI->Guard = GuardVar;
2661 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2662 "static local from the same function had different linkage");
2664 if (!HasPerVariableGuard) {
2672 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2673 llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2674 llvm::Value *NeedsInit =
2675 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit),
Zero);
2684 Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2688 Builder.CreateBr(EndBlock);
2706 llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2707 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2708 llvm::LoadInst *InitThreadEpoch =
2710 llvm::Value *IsUninitialized =
2711 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2721 GuardAddr.getPointer());
2722 llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2723 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2724 llvm::Value *ShouldDoInit =
2725 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2727 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2735 GuardAddr.getPointer());
2736 Builder.CreateBr(EndBlock);
2765 fields.push_back(CGM.
IntTy);
2769 fields.push_back(CGM.
IntTy);
2771 fields.push_back(CGM.
IntTy);
2773 fields.push_back(CGM.
IntTy);
2775 if (fields.size() == 1)
2780 void MicrosoftCXXABI::
2783 assert(fields.empty());
2788 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2791 fields.push_back(getZeroInt());
2793 fields.push_back(getAllOnesInt());
2798 fields.push_back(getZeroInt());
2800 fields.push_back(getZeroInt());
2802 fields.push_back(getAllOnesInt());
2808 GetNullMemberPointerFields(MPT, fields);
2809 if (fields.size() == 1)
2811 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2812 assert(Res->getType() == ConvertMemberPointerType(MPT));
2817 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2818 bool IsMemberFunction,
2821 unsigned VBTableIndex) {
2830 fields.push_back(FirstField);
2833 fields.push_back(llvm::ConstantInt::get(
2839 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2845 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2847 return llvm::ConstantStruct::getAnon(fields);
2856 llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl *RD,
2860 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2861 llvm::Constant *FirstField =
2863 return EmitFullMemberPointer(FirstField,
false, RD,
2867 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2872 return EmitNullMemberPointer(DstTy);
2878 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2879 C = EmitMemberFunctionPointer(MD);
2886 const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2888 FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
2891 C = EmitMemberDataPointer(RD, FieldOffset);
2894 if (!MemberPointerPath.empty()) {
2895 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2907 if (DerivedMember) {
2915 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2916 Base->getCanonicalDecl())
2917 DerivedToBasePath.push_back(&BS);
2920 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2922 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2923 : CK_BaseToDerivedMemberPointer;
2924 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2925 DerivedToBasePath.end(), C);
2931 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2932 assert(MD->
isInstance() &&
"Member function must not be static!");
2938 unsigned VBTableIndex = 0;
2939 llvm::Constant *FirstField;
2944 if (Types.isFuncTypeConvertible(FPT)) {
2946 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
2956 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2960 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2963 if (VBTableIndex == 0 &&
2966 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2969 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2970 return EmitFullMemberPointer(FirstField,
true, RD,
2971 NonVirtualBaseAdjustment, VBTableIndex);
2986 llvm::ICmpInst::Predicate
Eq;
2987 llvm::Instruction::BinaryOps
And, Or;
2989 Eq = llvm::ICmpInst::ICMP_NE;
2990 And = llvm::Instruction::Or;
2993 Eq = llvm::ICmpInst::ICMP_EQ;
2995 Or = llvm::Instruction::Or;
3004 return Builder.CreateICmp(Eq, L, R);
3007 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
3008 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
3009 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
3012 llvm::Value *Res =
nullptr;
3013 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
3014 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3015 llvm::Value *LF = Builder.CreateExtractValue(L, I);
3016 llvm::Value *RF = Builder.CreateExtractValue(R, I);
3017 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
3019 Res = Builder.CreateBinOp(
And, Res, Cmp);
3027 llvm::Value *
Zero = llvm::Constant::getNullValue(L0->getType());
3028 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0,
Zero,
"memptr.cmp.iszero");
3029 Res = Builder.CreateBinOp(Or, Res, IsZero);
3034 return Builder.CreateBinOp(
And, Res, Cmp0,
"memptr.cmp");
3039 llvm::Value *MemPtr,
3045 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
3047 GetNullMemberPointerFields(MPT, fields);
3048 assert(!fields.empty());
3049 llvm::Value *FirstField = MemPtr;
3050 if (MemPtr->getType()->isStructTy())
3051 FirstField = Builder.CreateExtractValue(MemPtr, 0);
3052 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
3060 for (
int I = 1, E = fields.size(); I < E; ++I) {
3061 llvm::Value *
Field = Builder.CreateExtractValue(MemPtr, I);
3062 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
3063 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
3069 llvm::Constant *Val) {
3072 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3073 Val->getAggregateElement(0
U) : Val;
3074 return FirstField->isNullValue();
3079 if (isZeroInitializable(MPT) && Val->isNullValue())
3085 GetNullMemberPointerFields(MPT, Fields);
3086 if (Fields.size() == 1) {
3087 assert(Val->getType()->isIntegerTy());
3088 return Val == Fields[0];
3092 for (I = 0, E = Fields.size(); I != E; ++I) {
3093 if (Val->getAggregateElement(I) != Fields[I])
3102 llvm::Value *VBPtrOffset,
3103 llvm::Value *VBTableOffset,
3104 llvm::Value **VBPtrOut) {
3108 llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3109 This.getElementType(),
This.getPointer(), VBPtrOffset,
"vbptr");
3110 if (VBPtrOut) *VBPtrOut = VBPtr;
3111 VBPtr = Builder.CreateBitCast(VBPtr,
3112 CGM.
Int32Ty->getPointerTo(0)->getPointerTo(
This.getAddressSpace()));
3115 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3116 VBPtrAlign =
This.getAlignment().alignmentAtOffset(
3122 llvm::Value *VBTable = Builder.CreateAlignedLoad(
3123 CGM.
Int32Ty->getPointerTo(0), VBPtr, VBPtrAlign,
"vbtable");
3126 llvm::Value *VBTableIndex = Builder.CreateAShr(
3127 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3131 llvm::Value *VBaseOffs =
3132 Builder.CreateInBoundsGEP(CGM.
Int32Ty, VBTable, VBTableIndex);
3133 VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.
Int32Ty->getPointerTo(0));
3134 return Builder.CreateAlignedLoad(CGM.
Int32Ty, VBaseOffs,
3140 llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3142 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3145 llvm::BasicBlock *OriginalBB =
nullptr;
3146 llvm::BasicBlock *SkipAdjustBB =
nullptr;
3147 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3154 OriginalBB = Builder.GetInsertBlock();
3157 llvm::Value *IsVirtual =
3158 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3160 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3172 "member pointer representation requires a "
3173 "complete class type for %0 to perform this expression");
3176 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3179 llvm::Value *VBPtr =
nullptr;
3180 llvm::Value *VBaseOffs =
3181 GetVBaseOffsetFromVBPtr(CGF,
Base, VBPtrOffset, VBTableOffset, &VBPtr);
3182 llvm::Value *AdjustedBase =
3183 Builder.CreateInBoundsGEP(CGM.
Int8Ty, VBPtr, VBaseOffs);
3186 if (VBaseAdjustBB) {
3187 Builder.CreateBr(SkipAdjustBB);
3189 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3190 Phi->addIncoming(
Base.getPointer(), OriginalBB);
3191 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3194 return AdjustedBase;
3197 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3201 unsigned AS =
Base.getAddressSpace();
3210 llvm::Value *FieldOffset = MemPtr;
3211 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3212 llvm::Value *VBPtrOffset =
nullptr;
3213 if (MemPtr->getType()->isStructTy()) {
3216 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3218 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3220 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3224 if (VirtualBaseAdjustmentOffset) {
3225 Addr = AdjustVirtualBase(CGF, E, RD,
Base, VirtualBaseAdjustmentOffset,
3228 Addr =
Base.getPointer();
3232 Addr = Builder.CreateBitCast(Addr, CGF.
Int8Ty->getPointerTo(AS));
3235 Addr = Builder.CreateInBoundsGEP(CGF.
Int8Ty, Addr, FieldOffset,
3240 return Builder.CreateBitCast(Addr, PType);
3247 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3248 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3252 if (isa<llvm::Constant>(Src))
3253 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3263 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3264 if (IsReinterpret && IsFunc)
3269 if (IsReinterpret &&
3276 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3277 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3281 if (IsReinterpret) {
3284 assert(Src->getType() == DstNull->getType());
3285 return Builder.CreateSelect(IsNotNull, Src, DstNull);
3288 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3291 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3294 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3298 Builder.CreateBr(ContinueBB);
3302 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3303 Phi->addIncoming(DstNull, OriginalBB);
3304 Phi->addIncoming(Dst, ConvertBB);
3308 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3318 bool IsConstant = isa<llvm::Constant>(Src);
3321 llvm::Value *FirstField = Src;
3322 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3323 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3324 llvm::Value *VBPtrOffset = getZeroInt();
3328 FirstField = Builder.CreateExtractValue(Src, I++);
3330 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3332 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3334 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3337 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3343 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3350 llvm::Value *SrcVBIndexEqZero =
3351 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3353 if (int64_t SrcOffsetToFirstVBase =
3354 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3355 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3357 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3359 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3370 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3375 llvm::Value *NVDisp;
3376 if (IsDerivedToBase)
3377 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3379 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3381 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3385 llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3388 if (llvm::GlobalVariable *VDispMap =
3389 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3390 llvm::Value *VBIndex = Builder.CreateExactUDiv(
3391 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3393 llvm::Constant *Mapping = VDispMap->getInitializer();
3394 VirtualBaseAdjustmentOffset =
3395 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3397 llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3398 VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3399 CGM.
IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3405 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3412 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3414 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3416 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3423 if (int64_t DstOffsetToFirstVBase =
3424 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3425 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3427 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3429 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3438 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3440 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3442 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3444 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3446 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3452 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3453 llvm::Constant *Src) {
3460 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3464 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3468 assert(CK == CK_DerivedToBaseMemberPointer ||
3469 CK == CK_BaseToDerivedMemberPointer ||
3470 CK == CK_ReinterpretMemberPointer);
3473 if (MemberPointerConstantIsNull(SrcTy, Src))
3474 return EmitNullMemberPointer(DstTy);
3479 if (CK == CK_ReinterpretMemberPointer)
3483 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3484 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3489 CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3491 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3505 llvm::Value *FunctionPointer = MemPtr;
3506 llvm::Value *NonVirtualBaseAdjustment =
nullptr;
3507 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3508 llvm::Value *VBPtrOffset =
nullptr;
3509 if (MemPtr->getType()->isStructTy()) {
3512 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3514 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3516 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3518 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3521 if (VirtualBaseAdjustmentOffset) {
3522 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD,
This,
3523 VirtualBaseAdjustmentOffset, VBPtrOffset);
3525 ThisPtrForCall =
This.getPointer();
3528 if (NonVirtualBaseAdjustment) {
3530 llvm::Value *Ptr = Builder.CreateBitCast(ThisPtrForCall, CGF.
Int8PtrTy);
3531 Ptr = Builder.CreateInBoundsGEP(CGF.
Int8Ty, Ptr, NonVirtualBaseAdjustment);
3532 ThisPtrForCall = Builder.CreateBitCast(Ptr, ThisPtrForCall->getType(),
3537 Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo());
3543 return new MicrosoftCXXABI(CGM);
3577 StringRef MangledName(
"??_7type_info@@6B@");
3578 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3583 nullptr, MangledName);
3594 struct MSRTTIClass {
3596 IsPrivateOnPath = 1 | 8,
3600 HasHierarchyDescriptor = 64
3606 MSRTTIClass *getFirstChild() {
return this + 1; }
3607 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3608 return Child + 1 + Child->NumBases;
3612 uint32_t Flags, NumBases, OffsetInVBase;
3618 Flags = HasHierarchyDescriptor;
3620 VirtualRoot =
nullptr;
3624 Flags |= IsPrivate | IsPrivateOnPath;
3630 if (
Parent->Flags & IsPrivateOnPath)
3631 Flags |= IsPrivateOnPath;
3632 VirtualRoot =
Parent->VirtualRoot;
3633 OffsetInVBase =
Parent->OffsetInVBase + RD->getASTContext()
3634 .getASTRecordLayout(
Parent->RD).getBaseClassOffset(RD).getQuantity();
3638 MSRTTIClass *Child = getFirstChild();
3640 NumBases += Child->initialize(
this, &
Base) + 1;
3641 Child = getNextChild(Child);
3646 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3657 return llvm::GlobalValue::LinkOnceODRLinkage;
3659 llvm_unreachable(
"Invalid linkage!");
3665 struct MSRTTIBuilder {
3667 HasBranchingHierarchy = 1,
3668 HasVirtualBranchingHierarchy = 2,
3669 HasAmbiguousBases = 4
3672 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3673 : CGM(ABI.CGM), Context(CGM.getContext()),
3674 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3675 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3678 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3679 llvm::GlobalVariable *
3681 llvm::GlobalVariable *getClassHierarchyDescriptor();
3682 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3686 llvm::LLVMContext &VMContext;
3689 llvm::GlobalVariable::LinkageTypes
Linkage;
3690 MicrosoftCXXABI &ABI;
3699 Classes.push_back(MSRTTIClass(RD));
3710 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3711 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3712 !VirtualBases.insert(Class->RD).second) {
3713 Class = MSRTTIClass::getNextChild(Class);
3716 if (!UniqueBases.insert(Class->RD).second)
3717 AmbiguousBases.insert(Class->RD);
3720 if (AmbiguousBases.empty())
3722 for (MSRTTIClass &Class : Classes)
3723 if (AmbiguousBases.count(Class.RD))
3724 Class.Flags |= MSRTTIClass::IsAmbiguous;
3727 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3730 llvm::raw_svector_ostream Out(MangledName);
3731 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3735 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3741 Classes.front().initialize(
nullptr,
nullptr);
3744 for (
auto Class : Classes) {
3745 if (
Class.RD->getNumBases() > 1)
3746 Flags |= HasBranchingHierarchy;
3749 if (
Class.Flags & MSRTTIClass::IsAmbiguous)
3750 Flags |= HasAmbiguousBases;
3752 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3753 Flags |= HasVirtualBranchingHierarchy;
3756 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
IntTy, 0),
3757 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3760 auto Type = ABI.getClassHierarchyDescriptorType();
3764 if (CHD->isWeakForLinker())
3765 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3767 auto *Bases = getBaseClassArray(Classes);
3770 llvm::Constant *Fields[] = {
3771 llvm::ConstantInt::get(CGM.
IntTy, 0),
3772 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3773 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3774 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3775 Bases->getValueType(), Bases,
3778 CHD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3782 llvm::GlobalVariable *
3786 llvm::raw_svector_ostream Out(MangledName);
3787 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3795 llvm::Type *PtrType = ABI.getImageRelativeType(
3796 ABI.getBaseClassDescriptorType()->getPointerTo());
3797 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3799 new llvm::GlobalVariable(
Module, ArrType,
3801 nullptr, MangledName);
3802 if (BCA->isWeakForLinker())
3803 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3807 for (MSRTTIClass &Class : Classes)
3808 BaseClassArrayData.push_back(
3809 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3810 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3811 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3815 llvm::GlobalVariable *
3816 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3819 uint32_t OffsetInVBTable = 0;
3820 int32_t VBPtrOffset = -1;
3821 if (
Class.VirtualRoot) {
3829 llvm::raw_svector_ostream Out(MangledName);
3830 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3831 Class.RD,
Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3836 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3840 auto Type = ABI.getBaseClassDescriptorType();
3843 nullptr, MangledName);
3844 if (BCD->isWeakForLinker())
3845 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3848 llvm::Constant *Fields[] = {
3849 ABI.getImageRelativeConstant(
3851 llvm::ConstantInt::get(CGM.
IntTy,
Class.NumBases),
3852 llvm::ConstantInt::get(CGM.
IntTy,
Class.OffsetInVBase),
3853 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3854 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3855 llvm::ConstantInt::get(CGM.
IntTy,
Class.Flags),
3856 ABI.getImageRelativeConstant(
3857 MSRTTIBuilder(ABI,
Class.RD).getClassHierarchyDescriptor()),
3859 BCD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3863 llvm::GlobalVariable *
3864 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3867 llvm::raw_svector_ostream Out(MangledName);
3868 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3872 if (
auto COL =
Module.getNamedGlobal(MangledName))
3877 int VFPtrOffset = 0;
3883 ->second.hasVtorDisp())
3887 llvm::StructType *
Type = ABI.getCompleteObjectLocatorType();
3889 nullptr, MangledName);
3892 llvm::Constant *Fields[] = {
3893 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3894 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3895 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3896 ABI.getImageRelativeConstant(
3898 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3899 ABI.getImageRelativeConstant(COL),
3902 if (!ABI.isImageRelative())
3903 FieldsRef = FieldsRef.drop_back();
3904 COL->setInitializer(llvm::ConstantStruct::get(
Type, FieldsRef));
3905 if (COL->isWeakForLinker())
3906 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3911 bool &IsConst,
bool &IsVolatile,
3912 bool &IsUnaligned) {
3922 IsUnaligned =
false;
3924 if (!PointeeType.
isNull()) {
3945 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3950 bool IsConst, IsVolatile, IsUnaligned;
3974 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3977 llvm::raw_svector_ostream Out(MangledName);
3978 getMangleContext().mangleCXXRTTI(
Type, Out);
3982 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3983 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3991 llvm::raw_svector_ostream Out(TypeInfoString);
3992 getMangleContext().mangleCXXRTTIName(
Type, Out);
3996 llvm::Constant *Fields[] = {
3998 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3999 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
4000 llvm::StructType *TypeDescriptorType =
4001 getTypeDescriptorType(TypeInfoString);
4002 auto *Var =
new llvm::GlobalVariable(
4003 CGM.
getModule(), TypeDescriptorType,
false,
4004 getLinkageForRTTI(
Type),
4005 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
4007 if (Var->isWeakForLinker())
4008 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
4009 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
4013 llvm::GlobalVariable *
4014 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
4016 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
4019 void MicrosoftCXXABI::emitCXXStructor(
GlobalDecl GD) {
4020 if (
auto *ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
4022 llvm::Function *Fn =
4028 auto *dtor = cast<CXXDestructorDecl>(GD.
getDecl());
4034 dtor->getParent()->getNumVBases() == 0)
4045 if (Fn->isWeakForLinker())
4046 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
4056 llvm::raw_svector_ostream Out(ThunkName);
4057 getMangleContext().mangleName(
GlobalDecl(CD, CT), Out);
4060 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
4061 return cast<llvm::Function>(GV);
4067 QualType RecordTy = getContext().getRecordType(RD);
4068 llvm::Function *ThunkFn = llvm::Function::Create(
4069 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
4072 if (ThunkFn->isWeakForLinker())
4073 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
4084 buildThisParam(CGF, FunctionArgs);
4090 &getContext().Idents.get(
"src"),
4091 getContext().getLValueReferenceType(RecordTy,
4095 FunctionArgs.push_back(&SrcParam);
4102 &getContext().Idents.get(
"is_most_derived"),
4106 FunctionArgs.push_back(&IsMostDerived);
4114 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4115 llvm::Value *
This = getThisValue(CGF);
4117 llvm::Value *SrcVal =
4134 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
4135 ArgVec.push_back(PD->getDefaultArg());
4141 CGF.
EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
4144 AddedStructorArgCounts ExtraArgs =
4149 llvm::Constant *CalleePtr =
4154 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4157 Cleanups.ForceCleanup();
4166 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
4168 int32_t VBPtrOffset,
4180 uint32_t
Size = getContext().getTypeSizeInChars(T).getQuantity();
4183 llvm::raw_svector_ostream Out(MangledName);
4184 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
4185 VBPtrOffset, VBIndex, Out);
4187 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4188 return getImageRelativeConstant(GV);
4192 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
4196 llvm::Constant *CopyCtor;
4203 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
4205 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4207 CopyCtor = getImageRelativeConstant(CopyCtor);
4209 bool IsScalar = !RD;
4210 bool HasVirtualBases =
false;
4211 bool IsStdBadAlloc =
false;
4226 if (HasVirtualBases)
4231 llvm::Constant *Fields[] = {
4232 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4234 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4235 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4236 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4237 llvm::ConstantInt::get(CGM.
IntTy, Size),
4240 llvm::StructType *CTType = getCatchableTypeType();
4241 auto *GV =
new llvm::GlobalVariable(
4242 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
4243 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4244 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4245 GV->setSection(
".xdata");
4246 if (GV->isWeakForLinker())
4247 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4248 return getImageRelativeConstant(GV);
4251 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4255 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4280 if (MostDerivedClass) {
4287 Classes.front().initialize(
nullptr,
nullptr);
4289 for (
const MSRTTIClass &Class : Classes) {
4292 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4295 uint32_t OffsetInVBTable = 0;
4296 int32_t VBPtrOffset = -1;
4297 if (
Class.VirtualRoot) {
4308 CatchableTypes.insert(getCatchableType(RTTITy,
Class.OffsetInVBase,
4309 VBPtrOffset, OffsetInVBTable));
4317 CatchableTypes.insert(getCatchableType(T));
4330 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4341 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4343 uint32_t NumEntries = CatchableTypes.size();
4344 llvm::Type *CTType =
4345 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4346 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4347 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4348 llvm::Constant *Fields[] = {
4349 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4350 llvm::ConstantArray::get(
4351 AT, llvm::makeArrayRef(CatchableTypes.begin(),
4352 CatchableTypes.end()))
4356 llvm::raw_svector_ostream Out(MangledName);
4357 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4359 CTA =
new llvm::GlobalVariable(
4360 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4361 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4362 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4363 CTA->setSection(
".xdata");
4364 if (CTA->isWeakForLinker())
4365 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4369 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4370 bool IsConst, IsVolatile, IsUnaligned;
4375 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4380 uint32_t NumEntries =
4381 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0
U))
4382 ->getLimitedValue();
4386 llvm::raw_svector_ostream Out(MangledName);
4387 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4393 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4409 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4412 if (!DtorD->isTrivial())
4413 CleanupFn = llvm::ConstantExpr::getBitCast(
4417 llvm::Constant *ForwardCompat =
4418 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4419 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4420 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4421 llvm::StructType *TIType = getThrowInfoType();
4422 llvm::Constant *Fields[] = {
4423 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4424 getImageRelativeConstant(CleanupFn),
4426 PointerToCatchableTypes
4428 auto *GV =
new llvm::GlobalVariable(
4429 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4430 llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4431 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4432 GV->setSection(
".xdata");
4433 if (GV->isWeakForLinker())
4434 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4440 assert(SubExpr &&
"SubExpr cannot be null");
4450 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4453 llvm::Value *Args[] = {
4460 std::pair<llvm::Value *, const CXXRecordDecl *>
4463 std::tie(
This, std::ignore, RD) =
4468 bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(