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;
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 {
219 void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
223 llvm::GlobalValue::LinkageTypes
230 getThisArgumentTypeForMethod(
const CXXMethodDecl *MD)
override {
231 if (MD->
isVirtual() && !isa<CXXDestructorDecl>(MD)) {
233 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
249 bool VirtualCall)
override;
267 llvm::GlobalVariable *VTable);
277 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
278 return !VTableClass->
hasAttr<MSNoVTableAttr>();
293 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
303 DeleteOrMemberCallExpr E)
override;
308 "Only deleting destructor thunks are available in this ABI");
313 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
315 llvm::GlobalVariable *
317 llvm::GlobalVariable::LinkageTypes
Linkage);
319 llvm::GlobalVariable *
323 llvm::raw_svector_ostream Out(OutName);
324 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
325 StringRef MangledName = OutName.str();
327 if (
auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
333 llvm::UndefValue::get(CGM.IntTy));
334 Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
335 bool AnyDifferent =
false;
336 for (
const auto &I : SrcRD->
vbases()) {
337 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
343 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
344 AnyDifferent |= SrcVBIndex != DstVBIndex;
350 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy, Map.size());
351 llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy, Map);
352 llvm::GlobalValue::LinkageTypes
Linkage =
354 ? llvm::GlobalValue::LinkOnceODRLinkage
356 auto *VDispMap =
new llvm::GlobalVariable(
357 CGM.getModule(), VDispMapTy,
true,
Linkage,
363 llvm::GlobalVariable *GV)
const;
365 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
368 getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.
getDecl()));
372 else if (ReturnAdjustment)
373 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
375 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
378 bool exportThunk()
override {
return false; }
384 const ReturnAdjustment &RA)
override;
386 void EmitThreadLocalInitFuncs(
391 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
398 llvm::GlobalVariable *DeclPtr,
399 bool PerformInit)
override;
401 llvm::FunctionCallee Dtor,
402 llvm::Constant *Addr)
override;
440 friend struct MSRTTIBuilder;
442 bool isImageRelative()
const {
443 return CGM.getTarget().getPointerWidth(0) == 64;
447 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
449 TDTypeName += llvm::utostr(TypeInfoString.size());
450 llvm::StructType *&TypeDescriptorType =
451 TypeDescriptorTypeMap[TypeInfoString.size()];
452 if (TypeDescriptorType)
453 return TypeDescriptorType;
457 llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
460 return TypeDescriptorType;
464 if (!isImageRelative())
469 llvm::StructType *getBaseClassDescriptorType() {
470 if (BaseClassDescriptorType)
471 return BaseClassDescriptorType;
473 getImageRelativeType(CGM.Int8PtrTy),
479 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
482 CGM.getLLVMContext(), FieldTypes,
"rtti.BaseClassDescriptor");
483 return BaseClassDescriptorType;
486 llvm::StructType *getClassHierarchyDescriptorType() {
487 if (ClassHierarchyDescriptorType)
488 return ClassHierarchyDescriptorType;
491 CGM.getLLVMContext(),
"rtti.ClassHierarchyDescriptor");
496 getImageRelativeType(
497 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
499 ClassHierarchyDescriptorType->setBody(FieldTypes);
500 return ClassHierarchyDescriptorType;
503 llvm::StructType *getCompleteObjectLocatorType() {
504 if (CompleteObjectLocatorType)
505 return CompleteObjectLocatorType;
507 CGM.getLLVMContext(),
"rtti.CompleteObjectLocator");
512 getImageRelativeType(CGM.Int8PtrTy),
513 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
514 getImageRelativeType(CompleteObjectLocatorType),
517 if (!isImageRelative())
518 FieldTypesRef = FieldTypesRef.drop_back();
519 CompleteObjectLocatorType->setBody(FieldTypesRef);
520 return CompleteObjectLocatorType;
523 llvm::GlobalVariable *getImageBase() {
524 StringRef Name =
"__ImageBase";
525 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
528 auto *GV =
new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
536 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
537 if (!isImageRelative())
540 if (PtrVal->isNullValue())
541 return llvm::Constant::getNullValue(CGM.IntTy);
543 llvm::Constant *ImageBaseAsInt =
544 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
545 llvm::Constant *PtrValAsInt =
546 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
547 llvm::Constant *Diff =
548 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
550 return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
558 llvm::Constant *getZeroInt() {
559 return llvm::ConstantInt::get(CGM.IntTy, 0);
562 llvm::Constant *getAllOnesInt() {
563 return llvm::Constant::getAllOnesValue(CGM.IntTy);
584 int32_t VBTableOffset,
586 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
587 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
588 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
589 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
592 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
605 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
606 bool IsMemberFunction,
609 unsigned VBTableIndex);
618 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
621 llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
624 llvm::Constant *EmitMemberDataPointer(
const CXXRecordDecl *RD,
634 return RD->
hasAttr<MSInheritanceAttr>();
641 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
642 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
648 bool Inequality)
override;
669 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
670 llvm::Constant *Src)
override;
672 llvm::Constant *EmitMemberPointerConversion(
685 llvm::StructType *getCatchableTypeType() {
686 if (CatchableTypeType)
687 return CatchableTypeType;
690 getImageRelativeType(CGM.Int8PtrTy),
695 getImageRelativeType(CGM.Int8PtrTy)
698 CGM.getLLVMContext(), FieldTypes,
"eh.CatchableType");
699 return CatchableTypeType;
702 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
703 llvm::StructType *&CatchableTypeArrayType =
704 CatchableTypeArrayTypeMap[NumEntries];
705 if (CatchableTypeArrayType)
706 return CatchableTypeArrayType;
709 CTATypeName += llvm::utostr(NumEntries);
711 getImageRelativeType(getCatchableTypeType()->getPointerTo());
714 llvm::ArrayType::get(CTType, NumEntries)
716 CatchableTypeArrayType =
718 return CatchableTypeArrayType;
721 llvm::StructType *getThrowInfoType() {
723 return ThrowInfoType;
726 getImageRelativeType(CGM.Int8PtrTy),
727 getImageRelativeType(CGM.Int8PtrTy),
728 getImageRelativeType(CGM.Int8PtrTy)
732 return ThrowInfoType;
738 llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
739 llvm::FunctionType *FTy =
740 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
741 llvm::FunctionCallee Throw =
742 CGM.CreateRuntimeFunction(FTy,
"_CxxThrowException");
744 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
745 if (
auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
746 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
754 llvm::Constant *getCatchableType(
QualType T,
755 uint32_t NVOffset = 0,
756 int32_t VBPtrOffset = -1,
757 uint32_t VBIndex = 0);
759 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
761 llvm::GlobalVariable *getThrowInfo(
QualType T)
override;
763 std::pair<llvm::Value *, const CXXRecordDecl *>
768 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
769 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
770 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
772 VFTablesMapTy VFTablesMap;
773 VTablesMapTy VTablesMap;
776 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
780 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
785 GuardInfo() : Guard(nullptr), BitIndex(0) {}
786 llvm::GlobalVariable *Guard;
792 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
793 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
794 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
796 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
797 llvm::StructType *BaseClassDescriptorType;
798 llvm::StructType *ClassHierarchyDescriptorType;
799 llvm::StructType *CompleteObjectLocatorType;
801 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
803 llvm::StructType *CatchableTypeType;
804 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
805 llvm::StructType *ThrowInfoType;
812 switch (CGM.getTarget().getTriple().getArch()) {
817 case llvm::Triple::thumb:
823 case llvm::Triple::x86:
831 return RAA_DirectInMemory;
837 case llvm::Triple::x86_64:
838 case llvm::Triple::aarch64:
842 llvm_unreachable(
"invalid enum");
854 llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
859 void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
861 llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
862 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
875 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
876 llvm::CatchPadInst *CPI =
877 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
896 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
907 return std::make_tuple(Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
916 PolymorphicBase = BaseDecl;
920 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
923 GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase);
927 return std::make_tuple(
Address(Ptr, VBaseAlign), Offset, PolymorphicBase);
930 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
934 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
940 llvm::FunctionType *FTy =
941 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
948 llvm::CallBase *Call =
950 Call->setDoesNotReturn();
951 CGF.
Builder.CreateUnreachable();
958 std::tie(ThisPtr, std::ignore, std::ignore) =
959 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
964 bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
968 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
982 std::tie(This, Offset, std::ignore) =
983 performBaseAdjustment(CGF, This, SrcRecordTy);
996 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
999 ThisPtr,
Offset, SrcRTTI, DestRTTI,
1009 std::tie(Value, std::ignore, std::ignore) =
1010 performBaseAdjustment(CGF, Value, SrcRecordTy);
1016 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1026 llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1030 int64_t VBPtrChars =
1032 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
1036 CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
1038 llvm::ConstantInt::get(CGM.IntTy, VBTableChars.
getQuantity());
1041 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1043 CGF.
Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
1044 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1047 bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1048 return isa<CXXConstructorDecl>(GD.
getDecl());
1052 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1056 bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1081 if (Ctor->isUserProvided())
1093 bool isAArch64 = CGM.getTarget().getTriple().isAArch64();
1095 bool isIndirectReturn =
1101 if (isIndirectReturn || !isSimple || isInstanceMethod) {
1119 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1120 assert(IsMostDerivedClass &&
1121 "ctor for a class with virtual bases must have an implicit parameter");
1123 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1125 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1126 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1127 CGF.
Builder.CreateCondBr(IsCompleteObject,
1128 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1133 EmitVBPtrStores(CGF, RD);
1137 return SkipVbaseCtorsBB;
1141 MicrosoftCXXABI::EmitDtorCompleteObjectHandler(
CodeGenFunction &CGF) {
1142 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1143 assert(IsMostDerivedClass &&
1144 "ctor for a class with virtual bases must have an implicit parameter");
1146 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1148 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1149 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1150 CGF.
Builder.CreateCondBr(IsCompleteObject,
1151 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1156 return SkipVbaseDtorsBB;
1159 void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1179 unsigned AS = getThisAddress(CGF).getAddressSpace();
1183 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1184 auto I = VBaseMap.find(VBase);
1185 assert(I != VBaseMap.end());
1186 if (!I->second.hasVtorDisp())
1190 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1191 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1195 VBaseOffset, llvm::ConstantInt::get(CGM.PtrDiffTy, ConstantVBaseOffset),
1197 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1201 CGF.
Int8Ty->getPointerTo(AS));
1202 llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset);
1204 VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4);
1206 VtorDispPtr, CGF.
Int32Ty->getPointerTo(AS),
"vtordisp.ptr");
1219 return ExpectedCallingConv == ActualCallingConv;
1233 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1234 CGM.setGVProperties(Fn, D);
1240 Address This = getThisAddress(CGF);
1245 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1246 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1247 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1248 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1253 if (VBT->getVBaseWithVPtr())
1259 "vbptr." + VBT->ObjectWithVPtr->getName());
1265 MicrosoftCXXABI::buildStructorSignature(
GlobalDecl GD,
1267 AddedStructorArgs Added;
1269 if (isa<CXXDestructorDecl>(GD.
getDecl()) &&
1272 ArgTys.push_back(getContext().IntTy);
1286 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1289 ArgTys.push_back(getContext().IntTy);
1297 void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1303 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1306 CGM.setDLLImportDLLExport(GV, ND);
1310 llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1321 return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage,
1327 if (Dtor->
hasAttr<DLLExportAttr>())
1328 return llvm::GlobalValue::WeakODRLinkage;
1329 if (Dtor->
hasAttr<DLLImportAttr>())
1330 return llvm::GlobalValue::AvailableExternallyLinkage;
1331 return llvm::GlobalValue::LinkOnceODRLinkage;
1336 return llvm::GlobalValue::LinkOnceODRLinkage;
1338 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1340 llvm_unreachable(
"invalid dtor type");
1357 MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1372 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1379 if (isa<CXXDestructorDecl>(MD))
1384 getContext().getASTRecordLayout(MD->
getParent());
1391 Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1397 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1420 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1437 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1442 Result =
Address(VBasePtr, VBaseAlign);
1444 if (!StaticOffset.
isZero()) {
1465 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1474 if (FPT->isVariadic())
1475 Params.insert(Params.begin() + 1, IsMostDerived);
1477 Params.push_back(IsMostDerived);
1478 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1484 Params.push_back(ShouldDelete);
1485 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1489 void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1509 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1510 if (!Adjustment.
isZero()) {
1511 unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1513 *thisTy = This->getType();
1516 This = CGF.
Builder.CreateConstInBoundsGEP1_32(CGF.
Int8Ty, This,
1521 setCXXABIThisValue(CGF, This);
1531 if (HasThisReturn(CGF.
CurGD))
1533 else if (hasMostDerivedReturn(CGF.
CurGD))
1538 assert(getStructorImplicitParamDecl(CGF) &&
1539 "no implicit parameter for a constructor with virtual bases?");
1540 getStructorImplicitParamValue(CGF)
1547 assert(getStructorImplicitParamDecl(CGF) &&
1548 "no implicit parameter for a deleting destructor?");
1549 getStructorImplicitParamValue(CGF)
1552 "should_call_delete");
1558 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1563 return AddedStructorArgs{};
1569 MostDerivedArg = getStructorImplicitParamValue(CGF);
1571 MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type ==
Ctor_Complete);
1575 Args.insert(Args.begin() + 1,
CallArg(RV, getContext().IntTy));
1576 return AddedStructorArgs::prefix(1);
1578 Args.
add(RV, getContext().IntTy);
1579 return AddedStructorArgs::suffix(1);
1585 bool Delegating,
Address This,
1598 "The deleting destructor should only be called via a virtual call");
1599 This = adjustThisArgumentForVirtualFunctionCall(CGF,
GlobalDecl(DD, Type),
1603 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1604 if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1605 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1611 if (BaseDtorEndBB) {
1613 CGF.
Builder.CreateBr(BaseDtorEndBB);
1618 void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1620 llvm::GlobalVariable *VTable) {
1621 if (!CGM.getCodeGenOpts().LTOUnit)
1628 getContext().getLangOpts().RTTIData
1629 ? getContext().toCharUnitsFromBits(
1630 getContext().getTargetInfo().getPointerWidth(0))
1634 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1639 CGM.AddVTableTypeMetadata(VTable, AddressPoint,
1649 getContext().getASTRecordLayout(DerivedRD);
1655 Offset = VBI->second.VBaseOffset;
1658 CGM.AddVTableTypeMetadata(VTable, AddressPoint, DerivedRD);
1663 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1666 void MicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables &CGVT,
1671 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1672 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1673 if (VTable->hasInitializer())
1679 llvm::Constant *RTTI =
nullptr;
1682 RTTI = getMSCompleteObjectLocator(RD, *Info);
1687 Components.finishAndSetAsInitializer(VTable);
1689 emitVTableTypeMetadata(*Info, RD, VTable);
1693 bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1698 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1701 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1702 if (!VTableAddressPoint) {
1704 !getContext().getASTRecordLayout(Base.
getBase()).hasOwnVFPtr());
1706 return VTableAddressPoint;
1712 llvm::raw_svector_ostream Out(Name);
1721 return VFTablesMap[
ID];
1724 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1726 llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass);
1727 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1731 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1737 VFTableIdTy
ID(RD, VPtrOffset);
1738 VTablesMapTy::iterator I;
1740 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID,
nullptr));
1744 llvm::GlobalVariable *&VTable = I->second;
1749 if (DeferredVFTables.insert(RD).second) {
1752 CGM.addDeferredVTable(RD);
1757 llvm::StringSet<> ObservedMangledNames;
1758 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1761 if (!ObservedMangledNames.insert(Name.str()).second)
1762 llvm_unreachable(
"Already saw this mangling before?");
1767 const std::unique_ptr<VPtrInfo> *VFPtrI = std::find_if(
1768 VFPtrs.begin(), VFPtrs.end(), [&](
const std::unique_ptr<VPtrInfo>& VPI) {
1769 return VPI->FullOffsetInMDC == VPtrOffset;
1771 if (VFPtrI == VFPtrs.end()) {
1772 VFTablesMap[
ID] =
nullptr;
1775 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1787 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1788 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1789 : CGM.getVTableLinkage(RD);
1790 bool VFTableComesFromAnotherTU =
1791 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1792 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1793 bool VTableAliasIsRequred =
1794 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1796 if (llvm::GlobalValue *VFTable =
1797 CGM.getModule().getNamedGlobal(VFTableName)) {
1798 VFTablesMap[
ID] = VFTable;
1799 VTable = VTableAliasIsRequred
1800 ? cast<llvm::GlobalVariable>(
1801 cast<llvm::GlobalAlias>(VFTable)->getBaseObject())
1802 : cast<llvm::GlobalVariable>(VFTable);
1808 llvm::GlobalValue::LinkageTypes VTableLinkage =
1809 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1811 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1813 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1817 llvm::GlobalValue *VFTable;
1818 VTable =
new llvm::GlobalVariable(CGM.getModule(), VTableType,
1819 true, VTableLinkage,
1820 nullptr, VTableName);
1821 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1823 llvm::Comdat *C =
nullptr;
1824 if (!VFTableComesFromAnotherTU &&
1825 (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1826 (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1827 VTableAliasIsRequred)))
1828 C = CGM.getModule().getOrInsertComdat(VFTableName.str());
1833 if (VTableAliasIsRequred) {
1834 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.Int32Ty, 0),
1835 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1836 llvm::ConstantInt::get(CGM.Int32Ty, 1)};
1839 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1840 VTable->getValueType(), VTable, GEPIndices);
1841 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1844 C->setSelectionKind(llvm::Comdat::Largest);
1848 VFTableName.str(), VTableGEP,
1850 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1859 VTable->setComdat(C);
1861 if (RD->
hasAttr<DLLExportAttr>())
1862 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1864 VFTablesMap[
ID] = VFTable;
1875 Ty = Ty->getPointerTo()->getPointerTo();
1877 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1879 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1887 auto getObjectWithVPtr = [&] {
1890 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1900 getObjectWithVPtr(), VTable,
1901 ML.
Index * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1903 if (CGM.getCodeGenOpts().PrepareForLTO)
1907 Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1915 llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1917 Address This, DeleteOrMemberCallExpr E) {
1920 assert((CE !=
nullptr) ^ (D !=
nullptr));
1921 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
1928 &CGM.getTypes().arrangeCXXStructorDeclaration(GD);
1933 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1939 ThisTy = CE->getObjectType();
1941 ThisTy = D->getDestroyedType();
1944 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1946 ImplicitParam, Context.
IntTy, CE);
1950 const VBTableGlobals &
1951 MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
1954 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
1956 std::tie(Entry, Added) =
1957 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
1958 VBTableGlobals &VBGlobals = Entry->second;
1967 llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
1968 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
1969 E = VBGlobals.VBTables->end();
1971 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
1978 MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
1980 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
1981 "can't form pointers to ctors or virtual dtors");
1985 llvm::raw_svector_ostream Out(ThunkName);
1986 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
1989 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
1990 return cast<llvm::Function>(GV);
1994 CGM.getTypes().arrangeUnprototypedMustTailThunk(MD);
1995 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
1996 llvm::Function *ThunkFn =
1998 ThunkName.str(), &CGM.getModule());
1999 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2002 ? llvm::GlobalValue::LinkOnceODRLinkage
2005 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
2007 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
2008 CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
2014 ThunkFn->addFnAttr(
"thunk");
2027 buildThisParam(CGF, FunctionArgs);
2032 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2037 getThisAddress(CGF), ThunkTy->getPointerTo()->getPointerTo(), MD->
getParent());
2040 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
2049 void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2050 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2051 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2052 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2053 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2054 if (GV->isDeclaration())
2055 emitVBTableDefinition(*VBT, RD, GV);
2059 llvm::GlobalVariable *
2061 llvm::GlobalVariable::LinkageTypes Linkage) {
2063 llvm::raw_svector_ostream Out(OutName);
2064 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2065 StringRef Name = OutName.str();
2067 llvm::ArrayType *VBTableType =
2070 assert(!CGM.getModule().getNamedGlobal(Name) &&
2071 "vbtable with this name already exists: mangling bug?");
2073 CGM.getContext().getTypeAlignInChars(CGM.getContext().IntTy);
2074 llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable(
2075 Name, VBTableType, Linkage, Alignment.getQuantity());
2076 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2078 if (RD->
hasAttr<DLLImportAttr>())
2079 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2080 else if (RD->
hasAttr<DLLExportAttr>())
2081 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2083 if (!GV->hasExternalLinkage())
2084 emitVBTableDefinition(VBT, RD, GV);
2089 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2091 llvm::GlobalVariable *GV)
const {
2095 "should only emit vbtables for classes with vbtables");
2099 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2105 CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2106 Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
2109 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2110 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2117 CompleteVBPtrOffset +=
2119 Offset -= CompleteVBPtrOffset;
2121 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2122 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2123 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.
getQuantity());
2126 assert(Offsets.size() ==
2127 cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
2128 ->getElementType())->getNumElements());
2129 llvm::ArrayType *VBTableType =
2130 llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2131 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2132 GV->setInitializer(Init);
2134 if (RD->
hasAttr<DLLImportAttr>())
2135 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2158 CGF.
Builder.CreateNeg(VtorDisp));
2175 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2192 const ReturnAdjustment &RA) {
2207 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2224 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *expr) {
2251 assert(requiresArrayCookie(expr));
2254 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2270 llvm::FunctionCallee Dtor,
2271 llvm::Constant *Addr) {
2276 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2277 CGF.
IntTy, DtorStub->getType(),
false);
2280 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2281 if (llvm::Function *TLRegDtorFn =
2282 dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2283 TLRegDtorFn->setDoesNotThrow();
2289 llvm::FunctionCallee Dtor,
2290 llvm::Constant *Addr) {
2301 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2305 if (CXXThreadLocalInits.empty())
2310 ?
"/include:___dyn_tls_init@12" 2311 :
"/include:__dyn_tls_init");
2316 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2317 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2318 CGM.
getModule(), InitFunc->getType(),
true,
2320 Twine(InitFunc->getName(),
"$initializer$"));
2321 InitFuncPtr->setSection(
".CRT$XDU");
2328 std::vector<llvm::Function *> NonComdatInits;
2329 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2330 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2332 llvm::Function *F = CXXThreadLocalInits[I];
2335 if (llvm::Comdat *C = GV->getComdat())
2336 AddToXDU(F)->setComdat(C);
2338 NonComdatInits.push_back(F);
2341 if (!NonComdatInits.empty()) {
2342 llvm::FunctionType *FTy =
2343 llvm::FunctionType::get(CGM.
VoidTy,
false);
2361 StringRef VarName(
"_Init_thread_epoch");
2363 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2365 auto *GV =
new llvm::GlobalVariable(
2369 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2375 llvm::FunctionType *FTy =
2376 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2377 CGM.
IntTy->getPointerTo(),
false);
2379 FTy,
"_Init_thread_header",
2381 llvm::AttributeList::FunctionIndex,
2382 llvm::Attribute::NoUnwind),
2387 llvm::FunctionType *FTy =
2388 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2389 CGM.
IntTy->getPointerTo(),
false);
2391 FTy,
"_Init_thread_footer",
2393 llvm::AttributeList::FunctionIndex,
2394 llvm::Attribute::NoUnwind),
2399 llvm::FunctionType *FTy =
2400 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2401 CGM.
IntTy->getPointerTo(),
false);
2403 FTy,
"_Init_thread_abort",
2405 llvm::AttributeList::FunctionIndex,
2406 llvm::Attribute::NoUnwind),
2414 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2415 : Guard(Guard), GuardNum(GuardNum) {}
2421 llvm::LoadInst *LI = Builder.
CreateLoad(Guard);
2422 llvm::ConstantInt *Mask =
2423 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2424 Builder.
CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2440 llvm::GlobalVariable *GV,
2444 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2446 llvm::Function *F = CGF.
CurFn;
2447 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2448 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2454 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2458 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2461 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2462 llvm::ConstantInt *
Zero = llvm::ConstantInt::get(GuardTy, 0);
2466 GuardInfo *GI =
nullptr;
2467 if (ThreadlocalStatic)
2469 else if (!ThreadsafeStatic)
2472 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2477 GuardNum = getContext().getStaticLocalNumber(&D);
2478 assert(GuardNum > 0);
2480 }
else if (HasPerVariableGuard) {
2484 GuardNum = GI->BitIndex++;
2487 if (!HasPerVariableGuard && GuardNum >= 32) {
2489 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2498 llvm::raw_svector_ostream Out(GuardName);
2499 if (HasPerVariableGuard)
2500 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2503 getMangleContext().mangleStaticGuardVariable(&D, Out);
2509 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2510 GV->getLinkage(),
Zero, GuardName.str());
2511 GuardVar->setVisibility(GV->getVisibility());
2512 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2513 GuardVar->setAlignment(GuardAlign.
getAsAlign());
2514 if (GuardVar->isWeakForLinker())
2515 GuardVar->setComdat(
2516 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2518 GuardVar->setThreadLocal(
true);
2519 if (GI && !HasPerVariableGuard)
2520 GI->Guard = GuardVar;
2525 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2526 "static local from the same function had different linkage");
2528 if (!HasPerVariableGuard) {
2536 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2537 llvm::LoadInst *LI = Builder.
CreateLoad(GuardAddr);
2539 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit),
Zero);
2548 Builder.
CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2552 Builder.CreateBr(EndBlock);
2570 llvm::LoadInst *FirstGuardLoad = Builder.
CreateLoad(GuardAddr);
2571 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2572 llvm::LoadInst *InitThreadEpoch =
2575 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2586 llvm::LoadInst *SecondGuardLoad = Builder.
CreateLoad(GuardAddr);
2587 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2589 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2591 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2600 Builder.CreateBr(EndBlock);
2629 fields.push_back(CGM.
IntTy);
2633 fields.push_back(CGM.
IntTy);
2635 fields.push_back(CGM.
IntTy);
2637 fields.push_back(CGM.
IntTy);
2639 if (fields.size() == 1)
2644 void MicrosoftCXXABI::
2647 assert(fields.empty());
2652 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2654 if (RD->nullFieldOffsetIsZero())
2655 fields.push_back(getZeroInt());
2657 fields.push_back(getAllOnesInt());
2662 fields.push_back(getZeroInt());
2664 fields.push_back(getZeroInt());
2666 fields.push_back(getAllOnesInt());
2672 GetNullMemberPointerFields(MPT, fields);
2673 if (fields.size() == 1)
2675 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2676 assert(Res->getType() == ConvertMemberPointerType(MPT));
2681 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2682 bool IsMemberFunction,
2685 unsigned VBTableIndex) {
2694 fields.push_back(FirstField);
2697 fields.push_back(llvm::ConstantInt::get(
2703 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2709 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2711 return llvm::ConstantStruct::getAnon(fields);
2720 llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl *RD,
2724 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2725 llvm::Constant *FirstField =
2727 return EmitFullMemberPointer(FirstField,
false, RD,
2731 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2736 return EmitNullMemberPointer(DstTy);
2742 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2743 C = EmitMemberFunctionPointer(MD);
2752 FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
2755 C = EmitMemberDataPointer(RD, FieldOffset);
2758 if (!MemberPointerPath.empty()) {
2759 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2763 ->castAs<MemberPointerType>();
2771 if (DerivedMember) {
2779 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2781 DerivedToBasePath.push_back(&BS);
2784 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2786 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2787 : CK_BaseToDerivedMemberPointer;
2788 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2789 DerivedToBasePath.end(), C);
2795 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2796 assert(MD->
isInstance() &&
"Member function must not be static!");
2802 unsigned VBTableIndex = 0;
2803 llvm::Constant *FirstField;
2820 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2824 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2827 if (VBTableIndex == 0 &&
2830 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2833 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2834 return EmitFullMemberPointer(FirstField,
true, RD,
2835 NonVirtualBaseAdjustment, VBTableIndex);
2850 llvm::ICmpInst::Predicate Eq;
2851 llvm::Instruction::BinaryOps
And, Or;
2853 Eq = llvm::ICmpInst::ICMP_NE;
2854 And = llvm::Instruction::Or;
2857 Eq = llvm::ICmpInst::ICMP_EQ;
2859 Or = llvm::Instruction::Or;
2868 return Builder.CreateICmp(Eq, L, R);
2871 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
2872 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
2873 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
2877 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
2878 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
2879 llvm::Value *LF = Builder.CreateExtractValue(L, I);
2880 llvm::Value *RF = Builder.CreateExtractValue(R, I);
2881 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
2883 Res = Builder.CreateBinOp(And, Res, Cmp);
2892 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero,
"memptr.cmp.iszero");
2893 Res = Builder.CreateBinOp(Or, Res, IsZero);
2898 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
2909 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2911 GetNullMemberPointerFields(MPT, fields);
2912 assert(!fields.empty());
2914 if (MemPtr->getType()->isStructTy())
2915 FirstField = Builder.CreateExtractValue(MemPtr, 0);
2916 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
2924 for (
int I = 1, E = fields.size(); I < E; ++I) {
2925 llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
2926 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
2927 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
2933 llvm::Constant *Val) {
2936 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
2937 Val->getAggregateElement(0U) : Val;
2938 return FirstField->isNullValue();
2943 if (isZeroInitializable(MPT) && Val->isNullValue())
2949 GetNullMemberPointerFields(MPT, Fields);
2950 if (Fields.size() == 1) {
2951 assert(Val->getType()->isIntegerTy());
2952 return Val == Fields[0];
2956 for (I = 0, E = Fields.size(); I != E; ++I) {
2957 if (Val->getAggregateElement(I) != Fields[I])
2973 Builder.CreateInBoundsGEP(This.
getPointer(), VBPtrOffset,
"vbptr");
2974 if (VBPtrOut) *VBPtrOut = VBPtr;
2979 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
2990 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
2994 llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex);
3007 llvm::BasicBlock *OriginalBB =
nullptr;
3008 llvm::BasicBlock *SkipAdjustBB =
nullptr;
3009 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3016 OriginalBB = Builder.GetInsertBlock();
3020 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3022 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3034 "member pointer representation requires a " 3035 "complete class type for %0 to perform this expression");
3038 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3043 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
3044 llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
3047 if (VBaseAdjustBB) {
3048 Builder.CreateBr(SkipAdjustBB);
3050 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3051 Phi->addIncoming(Base.
getPointer(), OriginalBB);
3052 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3055 return AdjustedBase;
3058 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3072 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3074 if (MemPtr->getType()->isStructTy()) {
3077 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3079 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3081 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3085 if (VirtualBaseAdjustmentOffset) {
3086 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
3096 Addr = Builder.CreateInBoundsGEP(Addr, FieldOffset,
"memptr.offset");
3107 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3108 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3112 if (isa<llvm::Constant>(Src))
3113 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3123 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3124 if (IsReinterpret && IsFunc)
3129 if (IsReinterpret &&
3136 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3137 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3141 if (IsReinterpret) {
3144 assert(Src->getType() == DstNull->getType());
3145 return Builder.CreateSelect(IsNotNull, Src, DstNull);
3148 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3151 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3154 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3158 Builder.CreateBr(ContinueBB);
3162 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3163 Phi->addIncoming(DstNull, OriginalBB);
3164 Phi->addIncoming(Dst, ConvertBB);
3168 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3178 bool IsConstant = isa<llvm::Constant>(Src);
3182 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3183 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3188 FirstField = Builder.CreateExtractValue(Src, I++);
3190 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3192 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3194 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3197 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3203 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3211 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3213 if (int64_t SrcOffsetToFirstVBase =
3214 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3215 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3217 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3219 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3230 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3236 if (IsDerivedToBase)
3237 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3239 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3241 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3248 if (llvm::GlobalVariable *VDispMap =
3249 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3251 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3253 llvm::Constant *Mapping = VDispMap->getInitializer();
3254 VirtualBaseAdjustmentOffset =
3255 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3258 VirtualBaseAdjustmentOffset =
3264 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3271 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3273 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3275 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3282 if (int64_t DstOffsetToFirstVBase =
3283 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3284 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3286 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3288 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3297 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3299 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3301 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3303 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3305 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3311 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3312 llvm::Constant *Src) {
3319 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3323 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3327 assert(CK == CK_DerivedToBaseMemberPointer ||
3328 CK == CK_BaseToDerivedMemberPointer ||
3329 CK == CK_ReinterpretMemberPointer);
3332 if (MemberPointerConstantIsNull(SrcTy, Src))
3333 return EmitNullMemberPointer(DstTy);
3338 if (CK == CK_ReinterpretMemberPointer)
3342 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3343 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3348 CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3366 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3368 if (MemPtr->getType()->isStructTy()) {
3371 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3373 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3375 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3377 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3380 if (VirtualBaseAdjustmentOffset) {
3381 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3382 VirtualBaseAdjustmentOffset, VBPtrOffset);
3387 if (NonVirtualBaseAdjustment) {
3390 Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
3391 ThisPtrForCall = Builder.
CreateBitCast(Ptr, ThisPtrForCall->getType(),
3396 Builder.
CreateBitCast(FunctionPointer, FTy->getPointerTo());
3397 CGCallee Callee(FPT, FunctionPointer);
3402 return new MicrosoftCXXABI(CGM);
3436 StringRef MangledName(
"??_7type_info@@6B@");
3437 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3442 nullptr, MangledName);
3453 struct MSRTTIClass {
3455 IsPrivateOnPath = 1 | 8,
3459 HasHierarchyDescriptor = 64
3465 MSRTTIClass *getFirstChild() {
return this + 1; }
3466 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3467 return Child + 1 + Child->NumBases;
3471 uint32_t Flags, NumBases, OffsetInVBase;
3477 Flags = HasHierarchyDescriptor;
3479 VirtualRoot =
nullptr;
3483 Flags |= IsPrivate | IsPrivateOnPath;
3489 if (Parent->Flags & IsPrivateOnPath)
3490 Flags |= IsPrivateOnPath;
3491 VirtualRoot = Parent->VirtualRoot;
3497 MSRTTIClass *Child = getFirstChild();
3499 NumBases += Child->initialize(
this, &Base) + 1;
3500 Child = getNextChild(Child);
3505 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3516 return llvm::GlobalValue::LinkOnceODRLinkage;
3518 llvm_unreachable(
"Invalid linkage!");
3524 struct MSRTTIBuilder {
3526 HasBranchingHierarchy = 1,
3527 HasVirtualBranchingHierarchy = 2,
3528 HasAmbiguousBases = 4
3531 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3537 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3538 llvm::GlobalVariable *
3540 llvm::GlobalVariable *getClassHierarchyDescriptor();
3541 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3545 llvm::LLVMContext &VMContext;
3548 llvm::GlobalVariable::LinkageTypes
Linkage;
3549 MicrosoftCXXABI &ABI;
3558 Classes.push_back(MSRTTIClass(RD));
3566 llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3567 llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3568 llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3569 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3570 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3571 !VirtualBases.insert(Class->RD).second) {
3572 Class = MSRTTIClass::getNextChild(Class);
3575 if (!UniqueBases.insert(Class->RD).second)
3576 AmbiguousBases.insert(Class->RD);
3579 if (AmbiguousBases.empty())
3581 for (MSRTTIClass &Class : Classes)
3582 if (AmbiguousBases.count(Class.RD))
3583 Class.Flags |= MSRTTIClass::IsAmbiguous;
3586 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3589 llvm::raw_svector_ostream Out(MangledName);
3590 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3594 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3600 Classes.front().initialize(
nullptr,
nullptr);
3603 for (
auto Class : Classes) {
3604 if (Class.RD->getNumBases() > 1)
3605 Flags |= HasBranchingHierarchy;
3608 if (Class.Flags & MSRTTIClass::IsAmbiguous)
3609 Flags |= HasAmbiguousBases;
3611 if ((Flags & HasBranchingHierarchy) && RD->
getNumVBases() != 0)
3612 Flags |= HasVirtualBranchingHierarchy;
3616 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3619 auto Type = ABI.getClassHierarchyDescriptorType();
3620 auto CHD =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3623 if (CHD->isWeakForLinker())
3624 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3626 auto *Bases = getBaseClassArray(Classes);
3629 llvm::Constant *Fields[] = {
3630 llvm::ConstantInt::get(CGM.
IntTy, 0),
3631 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3632 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3633 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3634 Bases->getValueType(), Bases,
3637 CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3641 llvm::GlobalVariable *
3645 llvm::raw_svector_ostream Out(MangledName);
3646 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3654 llvm::Type *PtrType = ABI.getImageRelativeType(
3655 ABI.getBaseClassDescriptorType()->getPointerTo());
3656 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3658 new llvm::GlobalVariable(
Module, ArrType,
3660 nullptr, MangledName);
3661 if (BCA->isWeakForLinker())
3662 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3666 for (MSRTTIClass &Class : Classes)
3667 BaseClassArrayData.push_back(
3668 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3669 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3670 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3674 llvm::GlobalVariable *
3675 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3678 uint32_t OffsetInVBTable = 0;
3679 int32_t VBPtrOffset = -1;
3680 if (Class.VirtualRoot) {
3682 OffsetInVBTable = VTableContext.
getVBTableIndex(RD, Class.VirtualRoot) * 4;
3688 llvm::raw_svector_ostream Out(MangledName);
3689 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3690 Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3695 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3699 auto Type = ABI.getBaseClassDescriptorType();
3701 new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3702 nullptr, MangledName);
3703 if (BCD->isWeakForLinker())
3704 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3707 llvm::Constant *Fields[] = {
3708 ABI.getImageRelativeConstant(
3710 llvm::ConstantInt::get(CGM.
IntTy, Class.NumBases),
3711 llvm::ConstantInt::get(CGM.
IntTy, Class.OffsetInVBase),
3712 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3713 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3714 llvm::ConstantInt::get(CGM.
IntTy, Class.Flags),
3715 ABI.getImageRelativeConstant(
3716 MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3718 BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3722 llvm::GlobalVariable *
3723 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3726 llvm::raw_svector_ostream Out(MangledName);
3727 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3731 if (
auto COL =
Module.getNamedGlobal(MangledName))
3736 int VFPtrOffset = 0;
3742 ->second.hasVtorDisp())
3746 llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3747 auto COL =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3748 nullptr, MangledName);
3751 llvm::Constant *Fields[] = {
3752 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3753 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3754 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3755 ABI.getImageRelativeConstant(
3757 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3758 ABI.getImageRelativeConstant(COL),
3761 if (!ABI.isImageRelative())
3762 FieldsRef = FieldsRef.drop_back();
3763 COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
3764 if (COL->isWeakForLinker())
3765 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3770 bool &IsConst,
bool &IsVolatile,
3771 bool &IsUnaligned) {
3781 IsUnaligned =
false;
3783 if (!PointeeType.
isNull()) {
3804 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3809 bool IsConst, IsVolatile, IsUnaligned;
3825 return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(),
3833 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3836 llvm::raw_svector_ostream Out(MangledName);
3837 getMangleContext().mangleCXXRTTI(Type, Out);
3841 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3842 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3850 llvm::raw_svector_ostream Out(TypeInfoString);
3851 getMangleContext().mangleCXXRTTIName(Type, Out);
3855 llvm::Constant *Fields[] = {
3857 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3858 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
3859 llvm::StructType *TypeDescriptorType =
3860 getTypeDescriptorType(TypeInfoString);
3861 auto *Var =
new llvm::GlobalVariable(
3862 CGM.
getModule(), TypeDescriptorType,
false,
3863 getLinkageForRTTI(Type),
3864 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
3866 if (Var->isWeakForLinker())
3867 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
3868 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
3872 llvm::GlobalVariable *
3873 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
3875 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
3878 void MicrosoftCXXABI::emitCXXStructor(
GlobalDecl GD) {
3879 if (
auto *ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
3881 llvm::Function *Fn =
3887 auto *dtor = cast<CXXDestructorDecl>(GD.
getDecl());
3893 dtor->getParent()->getNumVBases() == 0)
3904 if (Fn->isWeakForLinker())
3905 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
3915 llvm::raw_svector_ostream Out(ThunkName);
3916 getMangleContext().mangleCXXCtor(CD, CT, Out);
3919 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
3920 return cast<llvm::Function>(GV);
3926 QualType RecordTy = getContext().getRecordType(RD);
3928 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
3929 ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
3931 if (ThunkFn->isWeakForLinker())
3932 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
3943 buildThisParam(CGF, FunctionArgs);
3949 &getContext().Idents.get(
"src"),
3950 getContext().getLValueReferenceType(RecordTy,
3954 FunctionArgs.push_back(&SrcParam);
3961 &getContext().Idents.get(
"is_most_derived"),
3965 FunctionArgs.push_back(&IsMostDerived);
3973 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
3993 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
3994 ArgVec.push_back(PD->getDefaultArg());
4000 CGF.
EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
4003 AddedStructorArgs ExtraArgs =
4008 llvm::Constant *CalleePtr =
4013 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4025 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
4027 int32_t VBPtrOffset,
4039 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
4042 llvm::raw_svector_ostream Out(MangledName);
4043 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
4044 VBPtrOffset, VBIndex, Out);
4046 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4047 return getImageRelativeConstant(GV);
4051 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
4055 llvm::Constant *CopyCtor;
4062 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
4064 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4066 CopyCtor = getImageRelativeConstant(CopyCtor);
4068 bool IsScalar = !RD;
4069 bool HasVirtualBases =
false;
4070 bool IsStdBadAlloc =
false;
4075 HasVirtualBases = RD->getNumVBases() > 0;
4077 IsStdBadAlloc = II->isStr(
"bad_alloc") && RD->isInStdNamespace();
4085 if (HasVirtualBases)
4090 llvm::Constant *Fields[] = {
4091 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4093 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4094 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4095 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4096 llvm::ConstantInt::get(CGM.
IntTy, Size),
4099 llvm::StructType *CTType = getCatchableTypeType();
4100 auto *GV =
new llvm::GlobalVariable(
4101 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
4102 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4103 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4104 GV->setSection(
".xdata");
4105 if (GV->isWeakForLinker())
4106 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4107 return getImageRelativeConstant(GV);
4110 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4114 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4139 if (MostDerivedClass) {
4146 Classes.front().initialize(
nullptr,
nullptr);
4148 for (
const MSRTTIClass &Class : Classes) {
4151 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4154 uint32_t OffsetInVBTable = 0;
4155 int32_t VBPtrOffset = -1;
4156 if (Class.VirtualRoot) {
4167 CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
4168 VBPtrOffset, OffsetInVBTable));
4176 CatchableTypes.insert(getCatchableType(T));
4189 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4200 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4202 uint32_t NumEntries = CatchableTypes.size();
4204 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4205 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4206 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4207 llvm::Constant *Fields[] = {
4208 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4209 llvm::ConstantArray::get(
4210 AT, llvm::makeArrayRef(CatchableTypes.begin(),
4211 CatchableTypes.end()))
4215 llvm::raw_svector_ostream Out(MangledName);
4216 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4218 CTA =
new llvm::GlobalVariable(
4219 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4220 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4221 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4222 CTA->setSection(
".xdata");
4223 if (CTA->isWeakForLinker())
4224 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4228 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4229 bool IsConst, IsVolatile, IsUnaligned;
4234 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4239 uint32_t NumEntries =
4240 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
4241 ->getLimitedValue();
4245 llvm::raw_svector_ostream Out(MangledName);
4246 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4252 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4268 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4271 if (!DtorD->isTrivial())
4272 CleanupFn = llvm::ConstantExpr::getBitCast(
4276 llvm::Constant *ForwardCompat =
4277 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4278 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4279 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4280 llvm::StructType *TIType = getThrowInfoType();
4281 llvm::Constant *Fields[] = {
4282 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4283 getImageRelativeConstant(CleanupFn),
4285 PointerToCatchableTypes
4287 auto *GV =
new llvm::GlobalVariable(
4288 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4289 llvm::ConstantStruct::get(TIType, Fields), StringRef(MangledName));
4290 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4291 GV->setSection(
".xdata");
4292 if (GV->isWeakForLinker())
4293 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4308 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4318 std::pair<llvm::Value *, const CXXRecordDecl *>
4321 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
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.
A (possibly-)qualified type.
static llvm::CallBase * emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
unsigned getNumBases() const
Retrieves the number of base classes of this class.
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
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
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.
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.
QualType getThisType() const
Return the type of the this pointer.
const Type * getTypeForDecl() const
llvm::Constant * getAddrOfCXXStructor(GlobalDecl GD, 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 isVariadic() const
Whether this function prototype is variadic.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
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)
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined...
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.
static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM)
Default closure variant of a ctor.
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.
GlobalDecl getWithCtorType(CXXCtorType Type)
Represents a variable declaration or definition.
Address getObjectAddress(CodeGenFunction &CGF) const
Returns the address of the object within this declaration.
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to...
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const T * getAs() const
Member-template getAs<specific type>'.
bool This(InterpState &S, CodePtr OpPC)
A this pointer adjustment.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
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]).
bool hasDefinition() const
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.
void add(RValue rvalue, QualType type)
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
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
bool inheritanceModelHasOnlyOneField(bool IsMemberFunction, MSInheritanceModel Inheritance)
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl *> BasePath, raw_ostream &Out)=0
Mangle vftable symbols.
Represents a member of a struct/union/class.
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
bool Zero(InterpState &S, CodePtr OpPC)
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.
__DEVICE__ int max(int __a, int __b)
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
Describes a module or submodule.
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
bool hasPrivateFields() const
bool hasProtectedFields() const
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
ArrayRef< ParmVarDecl * > parameters() const
static bool hasMicrosoftABIRestrictions(const CXXRecordDecl *RD)
ArrayRef< VTableComponent > vtable_components() const
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.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
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
Concrete class used by the front-end to report problems and issues.
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
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.
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.
GlobalDecl getWithDtorType(CXXDtorType Type)
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
CXXRecordDecl * getMostRecentNonInjectedDecl()
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
CanQualType getReturnType() const
bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
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.
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...
struct clang::ReturnAdjustment::VirtualAdjustment::@136 Microsoft
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
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.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
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...
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 ()'.
static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM)
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
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()
static bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
llvm::LLVMContext & getLLVMContext()
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
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.
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function *> CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
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
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.
ASTContext & getContext() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
The COMDAT used for dtors.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
GlobalDecl - represents a global declaration.
struct clang::ThisAdjustment::VirtualAdjustment::@138 Microsoft
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.
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="")
static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM)
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.
Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name="")
static bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
CastKind getCastKind() const
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **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.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Represents a call to a member function that may be written either with member call syntax (e...
ASTContext & getASTContext() const LLVM_READONLY
static bool IsSizeGreaterThan128(const CXXRecordDecl *RD)
const Decl * getDecl() const
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.
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
MangleContext & getMangleContext()
Gets the mangle context.
llvm::Instruction * CurrentFuncletPad
constexpr XRayInstrMask None
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
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.
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.
External linkage within a unique namespace.
static bool isDeletingDtor(GlobalDecl GD)
uint64_t Index
Method's index in the vftable.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
const VPtrInfoVector & enumerateVBTables(const CXXRecordDecl *RD)
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
Return the parent of this method declaration, which is the class in which this method is defined...
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name. ...
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
llvm::Function * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
union clang::ThisAdjustment::VirtualAdjustment Virtual
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class.copy]p11, C++11 [class.copy]p25)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value *> args)
Emits a call or invoke to the given noreturn runtime function.
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
Returns true if a variable with function scope is a static local variable.
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.
bool isObjectType() const
Determine whether this type is an object type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
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
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).
static bool isInstanceMethod(const Decl *D)
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.
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...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)
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...
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
Struct with all information about dynamic [sub]class needed to set vptr.
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
llvm::Function * codegenCXXStructor(GlobalDecl GD)
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
static RValue get(llvm::Value *V)
GVALinkage
A more specific kind of linkage than enum Linkage.
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)
uint32_t VBIndex
Index of the virtual base in the vbtable.
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
This represents a decl that may have a name.
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
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.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
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.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
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...
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.
bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)
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.
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.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed? If so, the variable need not have a usable destr...