27 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/ADT/StringSet.h"
29 #include "llvm/IR/CallSite.h"
30 #include "llvm/IR/Intrinsics.h"
32 using namespace clang;
33 using namespace CodeGen;
38 struct VBTableGlobals {
43 class MicrosoftCXXABI :
public CGCXXABI {
46 :
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
47 ClassHierarchyDescriptorType(nullptr),
48 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
49 ThrowInfoType(nullptr) {}
51 bool HasThisReturn(
GlobalDecl GD)
const override;
52 bool hasMostDerivedReturn(
GlobalDecl GD)
const override;
58 bool isSRetParameterAfterThis()
const override {
return true; }
60 bool isThisCompleteObject(
GlobalDecl GD)
const override {
63 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
72 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
74 llvm_unreachable(
"bad dtor kind");
83 assert(Args.size() >= 2 &&
84 "expected the arglist to have at least two args!");
93 std::vector<CharUnits> getVBPtrOffsets(
const CXXRecordDecl *RD)
override {
94 std::vector<CharUnits> VBPtrOffsets;
98 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
99 for (
const VPtrInfo *VBT : *VBGlobals.VBTables) {
106 VBPtrOffsets.push_back(Offs);
108 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
112 StringRef GetPureVirtualCallName()
override {
return "_purecall"; }
113 StringRef GetDeletedVirtualCallName()
override {
return "_purecall"; }
124 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
127 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
129 getAddrOfCXXCatchHandlerType(
QualType Ty,
QualType CatchHandlerType)
override;
136 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
142 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
148 llvm::BasicBlock *CastEnd)
override;
155 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override {
217 getThisArgumentTypeForMethod(
const CXXMethodDecl *MD)
override {
219 if (MD->
isVirtual() && !isa<CXXDestructorDecl>(MD)) {
221 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
237 bool VirtualCall)
override;
242 llvm::Value *adjustThisParameterInVirtualFunctionPrologue(
255 bool Delegating,
Address This)
override;
258 llvm::GlobalVariable *VTable);
268 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
269 return !VTableClass->hasAttr<MSNoVTableAttr>();
284 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
300 "Only deleting destructor thunks are available in this ABI");
305 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
307 llvm::GlobalVariable *
309 llvm::GlobalVariable::LinkageTypes
Linkage);
311 llvm::GlobalVariable *
315 llvm::raw_svector_ostream Out(OutName);
316 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
317 StringRef MangledName = OutName.str();
319 if (
auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
325 llvm::UndefValue::get(CGM.IntTy));
326 Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
327 bool AnyDifferent =
false;
328 for (
const auto &
I : SrcRD->
vbases()) {
335 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
336 AnyDifferent |= SrcVBIndex != DstVBIndex;
342 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy,
Map.size());
343 llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy,
Map);
344 llvm::GlobalValue::LinkageTypes
Linkage =
346 ? llvm::GlobalValue::LinkOnceODRLinkage
348 auto *VDispMap =
new llvm::GlobalVariable(
349 CGM.getModule(), VDispMapTy,
true,
Linkage,
355 llvm::GlobalVariable *GV)
const;
357 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
360 Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
363 getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.
getDecl()));
367 else if (ReturnAdjustment)
368 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
370 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
377 const ReturnAdjustment &RA)
override;
379 void EmitThreadLocalInitFuncs(
384 bool usesThreadWrapperFunction()
const override {
return false; }
389 llvm::GlobalVariable *DeclPtr,
390 bool PerformInit)
override;
392 llvm::Constant *Dtor, llvm::Constant *Addr)
override;
430 friend struct MSRTTIBuilder;
432 bool isImageRelative()
const {
433 return CGM.getTarget().getPointerWidth(0) == 64;
437 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
439 TDTypeName += llvm::utostr(TypeInfoString.size());
440 llvm::StructType *&TypeDescriptorType =
441 TypeDescriptorTypeMap[TypeInfoString.size()];
442 if (TypeDescriptorType)
443 return TypeDescriptorType;
447 llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
450 return TypeDescriptorType;
454 if (!isImageRelative())
459 llvm::StructType *getBaseClassDescriptorType() {
460 if (BaseClassDescriptorType)
461 return BaseClassDescriptorType;
463 getImageRelativeType(CGM.Int8PtrTy),
469 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
472 CGM.getLLVMContext(), FieldTypes,
"rtti.BaseClassDescriptor");
473 return BaseClassDescriptorType;
476 llvm::StructType *getClassHierarchyDescriptorType() {
477 if (ClassHierarchyDescriptorType)
478 return ClassHierarchyDescriptorType;
481 CGM.getLLVMContext(),
"rtti.ClassHierarchyDescriptor");
486 getImageRelativeType(
487 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
489 ClassHierarchyDescriptorType->setBody(FieldTypes);
490 return ClassHierarchyDescriptorType;
493 llvm::StructType *getCompleteObjectLocatorType() {
494 if (CompleteObjectLocatorType)
495 return CompleteObjectLocatorType;
497 CGM.getLLVMContext(),
"rtti.CompleteObjectLocator");
502 getImageRelativeType(CGM.Int8PtrTy),
503 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
504 getImageRelativeType(CompleteObjectLocatorType),
507 if (!isImageRelative())
508 FieldTypesRef = FieldTypesRef.drop_back();
509 CompleteObjectLocatorType->setBody(FieldTypesRef);
510 return CompleteObjectLocatorType;
513 llvm::GlobalVariable *getImageBase() {
514 StringRef
Name =
"__ImageBase";
515 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
518 return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
524 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
525 if (!isImageRelative())
528 if (PtrVal->isNullValue())
529 return llvm::Constant::getNullValue(CGM.IntTy);
531 llvm::Constant *ImageBaseAsInt =
532 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
533 llvm::Constant *PtrValAsInt =
534 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
535 llvm::Constant *Diff =
536 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
538 return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
546 llvm::Constant *getZeroInt() {
547 return llvm::ConstantInt::get(CGM.IntTy, 0);
550 llvm::Constant *getAllOnesInt() {
551 return llvm::Constant::getAllOnesValue(CGM.IntTy);
572 int32_t VBTableOffset,
574 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
575 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
576 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
577 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
580 std::pair<Address, llvm::Value *>
593 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
594 bool IsMemberFunction,
597 unsigned VBTableIndex);
606 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
609 llvm::Function *EmitVirtualMemPtrThunk(
620 return RD->hasAttr<MSInheritanceAttr>();
627 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
628 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
634 bool Inequality)
override;
655 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *
E,
656 llvm::Constant *Src)
override;
658 llvm::Constant *EmitMemberPointerConversion(
671 llvm::StructType *getCatchableTypeType() {
672 if (CatchableTypeType)
673 return CatchableTypeType;
676 getImageRelativeType(CGM.Int8PtrTy),
681 getImageRelativeType(CGM.Int8PtrTy)
684 CGM.getLLVMContext(), FieldTypes,
"eh.CatchableType");
685 return CatchableTypeType;
688 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
689 llvm::StructType *&CatchableTypeArrayType =
690 CatchableTypeArrayTypeMap[NumEntries];
691 if (CatchableTypeArrayType)
692 return CatchableTypeArrayType;
695 CTATypeName += llvm::utostr(NumEntries);
697 getImageRelativeType(getCatchableTypeType()->getPointerTo());
700 llvm::ArrayType::get(CTType, NumEntries)
702 CatchableTypeArrayType =
704 return CatchableTypeArrayType;
707 llvm::StructType *getThrowInfoType() {
709 return ThrowInfoType;
712 getImageRelativeType(CGM.Int8PtrTy),
713 getImageRelativeType(CGM.Int8PtrTy),
714 getImageRelativeType(CGM.Int8PtrTy)
718 return ThrowInfoType;
724 llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
725 llvm::FunctionType *FTy =
726 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
727 auto *Fn = cast<llvm::Function>(
728 CGM.CreateRuntimeFunction(FTy,
"_CxxThrowException"));
730 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86)
731 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
738 llvm::Constant *getCatchableType(
QualType T,
739 uint32_t NVOffset = 0,
740 int32_t VBPtrOffset = -1,
741 uint32_t VBIndex = 0);
743 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
745 llvm::GlobalVariable *getThrowInfo(
QualType T)
override;
748 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
749 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
750 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
752 VFTablesMapTy VFTablesMap;
753 VTablesMapTy VTablesMap;
756 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
760 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
765 GuardInfo() : Guard(nullptr), BitIndex(0) {}
766 llvm::GlobalVariable *Guard;
772 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
773 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
774 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
776 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
777 llvm::StructType *BaseClassDescriptorType;
778 llvm::StructType *ClassHierarchyDescriptorType;
779 llvm::StructType *CompleteObjectLocatorType;
781 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
783 llvm::StructType *CatchableTypeType;
784 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
785 llvm::StructType *ThrowInfoType;
792 switch (CGM.getTarget().getTriple().getArch()) {
797 case llvm::Triple::x86:
804 if (!canCopyArgument(RD))
805 return RAA_DirectInMemory;
811 case llvm::Triple::x86_64:
829 bool CopyDeleted =
false;
848 llvm_unreachable(
"invalid enum");
861 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
866 void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
868 llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
869 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
879 llvm::CatchPadInst *CPI;
881 CatchRetScope(llvm::CatchPadInst *CPI) : CPI(CPI) {}
885 CGF.
Builder.CreateCatchRet(CPI, BB);
896 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
897 llvm::CatchPadInst *CPI =
898 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
917 std::pair<Address, llvm::Value *>
928 return std::make_pair(Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0));
936 PolymorphicBase = BaseDecl;
940 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
943 GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase);
947 return std::make_pair(
Address(Ptr, VBaseAlign), Offset);
950 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
954 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
960 llvm::FunctionType *FTy =
961 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
968 llvm::CallSite
Call =
970 Call.setDoesNotReturn();
971 CGF.
Builder.CreateUnreachable();
978 std::tie(ThisPtr, std::ignore) =
979 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
984 bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
988 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1002 std::tie(This, Offset) = performBaseAdjustment(CGF, This, SrcRecordTy);
1015 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1018 ThisPtr,
Offset, SrcRTTI, DestRTTI,
1028 std::tie(Value, std::ignore) = performBaseAdjustment(CGF, Value, SrcRecordTy);
1034 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1044 llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1048 int64_t VBPtrChars =
1050 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
1054 CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
1056 llvm::ConstantInt::get(CGM.IntTy, VBTableChars.
getQuantity());
1059 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1061 CGF.
Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
1062 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1065 bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1066 return isa<CXXConstructorDecl>(GD.
getDecl());
1070 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1074 bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1090 }
else if (!RD->
isPOD()) {
1103 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1104 assert(IsMostDerivedClass &&
1105 "ctor for a class with virtual bases must have an implicit parameter");
1107 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1109 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1110 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1111 CGF.
Builder.CreateCondBr(IsCompleteObject,
1112 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1117 EmitVBPtrStores(CGF, RD);
1121 return SkipVbaseCtorsBB;
1124 void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1144 unsigned AS = getThisAddress(CGF).getAddressSpace();
1147 for (VBOffsets::const_iterator
I = VBaseMap.begin(),
E = VBaseMap.end();
1149 if (!
I->second.hasVtorDisp())
1153 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD,
I->first);
1154 uint64_t ConstantVBaseOffset =
1159 VBaseOffset, llvm::ConstantInt::get(CGM.PtrDiffTy, ConstantVBaseOffset),
1161 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1165 CGF.
Int8Ty->getPointerTo(AS));
1166 llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset);
1168 VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4);
1170 VtorDispPtr, CGF.
Int32Ty->getPointerTo(AS),
"vtordisp.ptr");
1183 return ExpectedCallingConv == ActualCallingConv;
1197 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1198 Fn->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1204 Address This = getThisAddress(CGF);
1209 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1210 for (
unsigned I = 0,
E = VBGlobals.VBTables->size();
I !=
E; ++
I) {
1211 const VPtrInfo *VBT = (*VBGlobals.VBTables)[
I];
1212 llvm::GlobalVariable *GV = VBGlobals.Globals[
I];
1221 CGF.
Builder.CreateConstInBoundsGEP2_32(GV->getValueType(), GV, 0, 0);
1234 ArgTys.push_back(getContext().IntTy);
1247 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1249 ArgTys.push_back(getContext().IntTy);
1260 MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1277 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1284 if (isa<CXXDestructorDecl>(MD))
1289 getContext().getASTRecordLayout(MD->
getParent());
1296 Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1302 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1326 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1343 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1348 Result =
Address(VBasePtr, VBaseAlign);
1350 if (!StaticOffset.
isZero()) {
1371 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1381 if (FPT->isVariadic())
1382 Params.insert(Params.begin() + 1, IsMostDerived);
1384 Params.push_back(IsMostDerived);
1385 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1390 &Context.
Idents.
get(
"should_call_delete"),
1392 Params.push_back(ShouldDelete);
1393 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1397 llvm::Value *MicrosoftCXXABI::adjustThisParameterInVirtualFunctionPrologue(
1404 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1408 unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1410 *thisTy = This->getType();
1414 This = CGF.
Builder.CreateConstInBoundsGEP1_32(CGF.
Int8Ty, This,
1419 void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1430 if (HasThisReturn(CGF.
CurGD))
1432 else if (hasMostDerivedReturn(CGF.
CurGD))
1438 assert(getStructorImplicitParamDecl(CGF) &&
1439 "no implicit parameter for a constructor with virtual bases?");
1440 getStructorImplicitParamValue(CGF)
1447 assert(getStructorImplicitParamDecl(CGF) &&
1448 "no implicit parameter for a deleting destructor?");
1449 getStructorImplicitParamValue(CGF)
1452 "should_call_delete");
1456 unsigned MicrosoftCXXABI::addImplicitConstructorArgs(
1458 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1469 MostDerivedArg = getStructorImplicitParamValue(CGF);
1471 MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type ==
Ctor_Complete);
1475 Args.insert(Args.begin() + 1,
1476 CallArg(RV, getContext().IntTy,
false));
1478 Args.
add(RV, getContext().IntTy);
1486 bool Delegating,
Address This) {
1491 "The deleting destructor should only be called via a virtual call");
1492 This = adjustThisArgumentForVirtualFunctionCall(CGF,
GlobalDecl(DD, Type),
1502 void MicrosoftCXXABI::emitVTableTypeMetadata(
VPtrInfo *Info,
1504 llvm::GlobalVariable *VTable) {
1505 if (!CGM.getCodeGenOpts().PrepareForLTO)
1512 getContext().getLangOpts().RTTIData
1513 ? getContext().toCharUnitsFromBits(
1514 getContext().getTargetInfo().getPointerWidth(0))
1518 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1523 CGM.AddVTableTypeMetadata(VTable, AddressPoint,
1533 getContext().getASTRecordLayout(DerivedRD);
1539 Offset = VBI->second.VBaseOffset;
1542 CGM.AddVTableTypeMetadata(VTable, AddressPoint, DerivedRD);
1547 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1550 void MicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables &CGVT,
1556 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1557 if (VTable->hasInitializer())
1563 llvm::Constant *RTTI =
nullptr;
1566 RTTI = getMSCompleteObjectLocator(RD, Info);
1573 VTable->setInitializer(Init);
1575 emitVTableTypeMetadata(Info, RD, VTable);
1579 bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1584 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1587 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1588 if (!VTableAddressPoint) {
1590 !getContext().getASTRecordLayout(Base.
getBase()).hasOwnVFPtr());
1592 return VTableAddressPoint;
1598 llvm::raw_svector_ostream Out(Name);
1607 return VFTablesMap[
ID];
1610 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1612 llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass);
1613 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1617 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1623 VFTableIdTy
ID(RD, VPtrOffset);
1626 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(
ID,
nullptr));
1630 llvm::GlobalVariable *&VTable = I->second;
1635 if (DeferredVFTables.insert(RD).second) {
1638 CGM.addDeferredVTable(RD);
1643 llvm::StringSet<> ObservedMangledNames;
1644 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1647 if (!ObservedMangledNames.insert(Name.str()).second)
1648 llvm_unreachable(
"Already saw this mangling before?");
1654 std::find_if(VFPtrs.begin(), VFPtrs.end(), [&](
VPtrInfo *VPI) {
1655 return VPI->FullOffsetInMDC == VPtrOffset;
1657 if (VFPtrI == VFPtrs.end()) {
1658 VFTablesMap[
ID] =
nullptr;
1673 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1674 RD->hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1675 : CGM.getVTableLinkage(RD);
1676 bool VFTableComesFromAnotherTU =
1677 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1678 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1679 bool VTableAliasIsRequred =
1680 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1682 if (llvm::GlobalValue *VFTable =
1683 CGM.getModule().getNamedGlobal(VFTableName)) {
1684 VFTablesMap[
ID] = VFTable;
1685 VTable = VTableAliasIsRequred
1686 ? cast<llvm::GlobalVariable>(
1687 cast<llvm::GlobalAlias>(VFTable)->getBaseObject())
1688 : cast<llvm::GlobalVariable>(VFTable);
1692 uint64_t NumVTableSlots =
1695 llvm::GlobalValue::LinkageTypes VTableLinkage =
1696 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1698 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1700 llvm::ArrayType *VTableType =
1701 llvm::ArrayType::get(CGM.Int8PtrTy, NumVTableSlots);
1705 llvm::GlobalValue *VFTable;
1706 VTable =
new llvm::GlobalVariable(CGM.getModule(), VTableType,
1707 true, VTableLinkage,
1708 nullptr, VTableName);
1709 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1711 llvm::Comdat *
C =
nullptr;
1712 if (!VFTableComesFromAnotherTU &&
1713 (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1714 (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1715 VTableAliasIsRequred)))
1716 C = CGM.getModule().getOrInsertComdat(VFTableName.str());
1721 if (VTableAliasIsRequred) {
1722 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
1723 llvm::ConstantInt::get(CGM.IntTy, 1)};
1726 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1727 VTable->getValueType(), VTable, GEPIndices);
1728 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1731 C->setSelectionKind(llvm::Comdat::Largest);
1735 VFTableName.str(), VTableGEP,
1737 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1746 VTable->setComdat(C);
1748 if (RD->hasAttr<DLLExportAttr>())
1749 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1751 VFTablesMap[
ID] = VFTable;
1766 for (
auto &&B : RD->
bases()) {
1767 const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
1769 if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) {
1771 MaxBaseOffset = BaseOffset;
1774 for (
auto &&B : RD->
vbases()) {
1775 const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
1777 if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) {
1779 MaxBaseOffset = BaseOffset;
1793 RD = cast<CXXMethodDecl>(GD.
getDecl())->getParent();
1806 Ty = Ty->getPointerTo()->getPointerTo();
1808 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1810 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1814 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1819 ML.
Index * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1821 if (CGM.getCodeGenOpts().PrepareForLTO)
1826 Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1831 llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1840 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1847 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1851 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1858 const VBTableGlobals &
1859 MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
1864 std::tie(Entry, Added) =
1865 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
1866 VBTableGlobals &VBGlobals = Entry->second;
1875 llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
1876 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
1877 E = VBGlobals.VBTables->end();
1879 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
1885 llvm::Function *MicrosoftCXXABI::EmitVirtualMemPtrThunk(
1888 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
1889 "can't form pointers to ctors or virtual dtors");
1893 llvm::raw_svector_ostream Out(ThunkName);
1894 getMangleContext().mangleVirtualMemPtrThunk(MD, Out);
1897 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
1898 return cast<llvm::Function>(GV);
1901 const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSMemberPointerThunk(MD);
1902 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
1903 llvm::Function *ThunkFn =
1905 ThunkName.str(), &CGM.getModule());
1906 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
1909 ? llvm::GlobalValue::LinkOnceODRLinkage
1912 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
1914 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
1915 CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
1921 ThunkFn->addFnAttr(
"thunk");
1924 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
1934 buildThisParam(CGF, FunctionArgs);
1944 getThisAddress(CGF), ThunkTy->getPointerTo()->getPointerTo(), MD->
getParent());
1947 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1956 void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1957 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1958 for (
unsigned I = 0,
E = VBGlobals.VBTables->size(); I !=
E; ++
I) {
1959 const VPtrInfo *VBT = (*VBGlobals.VBTables)[I];
1960 llvm::GlobalVariable *GV = VBGlobals.Globals[
I];
1961 if (GV->isDeclaration())
1962 emitVBTableDefinition(*VBT, RD, GV);
1966 llvm::GlobalVariable *
1968 llvm::GlobalVariable::LinkageTypes Linkage) {
1970 llvm::raw_svector_ostream Out(OutName);
1971 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
1972 StringRef Name = OutName.str();
1974 llvm::ArrayType *VBTableType =
1977 assert(!CGM.getModule().getNamedGlobal(Name) &&
1978 "vbtable with this name already exists: mangling bug?");
1979 llvm::GlobalVariable *GV =
1980 CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, Linkage);
1981 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1983 if (RD->hasAttr<DLLImportAttr>())
1984 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1985 else if (RD->hasAttr<DLLExportAttr>())
1986 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1988 if (!GV->hasExternalLinkage())
1989 emitVBTableDefinition(VBT, RD, GV);
1994 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
1996 llvm::GlobalVariable *GV)
const {
2000 "should only emit vbtables for classes with vbtables");
2004 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2010 CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2011 Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
2014 for (
const auto &I : ReusingBase->
vbases()) {
2015 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2022 CompleteVBPtrOffset +=
2024 Offset -= CompleteVBPtrOffset;
2026 unsigned VBIndex = Context.getVBTableIndex(ReusingBase, VBase);
2027 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2028 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.
getQuantity());
2031 assert(Offsets.size() ==
2032 cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
2033 ->getElementType())->getNumElements());
2034 llvm::ArrayType *VBTableType =
2035 llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2036 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2037 GV->setInitializer(Init);
2039 if (RD->hasAttr<DLLImportAttr>())
2040 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2063 CGF.
Builder.CreateNeg(VtorDisp));
2080 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2097 const ReturnAdjustment &RA) {
2112 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2129 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *expr) {
2156 assert(requiresArrayCookie(expr));
2159 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2175 llvm::Constant *Dtor,
2176 llvm::Constant *Addr) {
2181 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2182 CGF.
IntTy, DtorStub->getType(),
false);
2184 llvm::Constant *TLRegDtor =
2186 if (llvm::Function *TLRegDtorFn = dyn_cast<llvm::Function>(TLRegDtor))
2187 TLRegDtorFn->setDoesNotThrow();
2193 llvm::Constant *Dtor,
2194 llvm::Constant *Addr) {
2202 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2209 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2210 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2211 CGM.
getModule(), InitFunc->getType(),
true,
2213 Twine(InitFunc->getName(),
"$initializer$"));
2214 InitFuncPtr->setSection(
".CRT$XDU");
2221 std::vector<llvm::Function *> NonComdatInits;
2222 for (
size_t I = 0,
E = CXXThreadLocalInitVars.size(); I !=
E; ++
I) {
2223 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2225 llvm::Function *F = CXXThreadLocalInits[
I];
2228 if (llvm::Comdat *C = GV->getComdat())
2229 AddToXDU(F)->setComdat(C);
2231 NonComdatInits.push_back(F);
2234 if (!NonComdatInits.empty()) {
2235 llvm::FunctionType *FTy =
2236 llvm::FunctionType::get(CGM.
VoidTy,
false);
2254 StringRef VarName(
"_Init_thread_epoch");
2256 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2258 auto *GV =
new llvm::GlobalVariable(
2262 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2268 llvm::FunctionType *FTy =
2269 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2270 CGM.
IntTy->getPointerTo(),
false);
2272 FTy,
"_Init_thread_header",
2274 llvm::AttributeSet::FunctionIndex,
2275 llvm::Attribute::NoUnwind));
2279 llvm::FunctionType *FTy =
2280 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2281 CGM.
IntTy->getPointerTo(),
false);
2283 FTy,
"_Init_thread_footer",
2285 llvm::AttributeSet::FunctionIndex,
2286 llvm::Attribute::NoUnwind));
2290 llvm::FunctionType *FTy =
2291 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2292 CGM.
IntTy->getPointerTo(),
false);
2294 FTy,
"_Init_thread_abort",
2296 llvm::AttributeSet::FunctionIndex,
2297 llvm::Attribute::NoUnwind));
2304 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2305 : Guard(Guard), GuardNum(GuardNum) {}
2311 llvm::LoadInst *LI = Builder.
CreateLoad(Guard);
2312 llvm::ConstantInt *Mask =
2313 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2314 Builder.
CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2320 CallInitThreadAbort(
Address Guard) : Guard(Guard.getPointer()) {}
2330 llvm::GlobalVariable *GV,
2334 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2336 llvm::Function *F = CGF.
CurFn;
2337 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2338 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2344 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2348 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2351 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2352 llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
2356 GuardInfo *GI =
nullptr;
2357 if (ThreadlocalStatic)
2358 GI = &ThreadLocalGuardVariableMap[D.getDeclContext()];
2359 else if (!ThreadsafeStatic)
2360 GI = &GuardVariableMap[D.getDeclContext()];
2362 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2367 GuardNum = getContext().getStaticLocalNumber(&D);
2368 assert(GuardNum > 0);
2370 }
else if (HasPerVariableGuard) {
2371 GuardNum = ThreadSafeGuardNumMap[D.getDeclContext()]++;
2374 GuardNum = GI->BitIndex++;
2377 if (!HasPerVariableGuard && GuardNum >= 32) {
2379 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2388 llvm::raw_svector_ostream Out(GuardName);
2389 if (HasPerVariableGuard)
2390 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2393 getMangleContext().mangleStaticGuardVariable(&D, Out);
2399 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2400 GV->getLinkage(), Zero, GuardName.str());
2401 GuardVar->setVisibility(GV->getVisibility());
2402 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2404 if (GuardVar->isWeakForLinker())
2405 GuardVar->setComdat(
2406 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2408 GuardVar->setThreadLocal(
true);
2409 if (GI && !HasPerVariableGuard)
2410 GI->Guard = GuardVar;
2415 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2416 "static local from the same function had different linkage");
2418 if (!HasPerVariableGuard) {
2426 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2427 llvm::LoadInst *LI = Builder.
CreateLoad(GuardAddr);
2429 Builder.CreateICmpNE(Builder.CreateAnd(LI, Bit), Zero);
2432 Builder.CreateCondBr(IsInitialized, EndBlock, InitBlock);
2437 Builder.
CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2441 Builder.CreateBr(EndBlock);
2459 llvm::LoadInst *FirstGuardLoad = Builder.
CreateLoad(GuardAddr);
2460 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2461 llvm::LoadInst *InitThreadEpoch =
2464 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2467 Builder.CreateCondBr(IsUninitialized, AttemptInitBlock, EndBlock);
2473 GuardAddr.getPointer());
2474 llvm::LoadInst *SecondGuardLoad = Builder.
CreateLoad(GuardAddr);
2475 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2477 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2479 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2487 GuardAddr.getPointer());
2488 Builder.CreateBr(EndBlock);
2505 return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) &&
2517 fields.push_back(CGM.
IntTy);
2521 fields.push_back(CGM.
IntTy);
2522 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2523 fields.push_back(CGM.
IntTy);
2524 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2525 fields.push_back(CGM.
IntTy);
2527 if (fields.size() == 1)
2532 void MicrosoftCXXABI::
2535 assert(fields.empty());
2540 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2542 if (RD->nullFieldOffsetIsZero())
2543 fields.push_back(getZeroInt());
2545 fields.push_back(getAllOnesInt());
2550 fields.push_back(getZeroInt());
2551 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2552 fields.push_back(getZeroInt());
2553 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2554 fields.push_back(getAllOnesInt());
2560 GetNullMemberPointerFields(MPT, fields);
2561 if (fields.size() == 1)
2563 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2564 assert(Res->getType() == ConvertMemberPointerType(MPT));
2569 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2570 bool IsMemberFunction,
2573 unsigned VBTableIndex) {
2578 if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance))
2582 fields.push_back(FirstField);
2584 if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance))
2585 fields.push_back(llvm::ConstantInt::get(
2588 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) {
2591 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2596 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2597 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2599 return llvm::ConstantStruct::getAnon(fields);
2607 MSInheritanceAttr::Keyword_virtual_inheritance)
2608 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2609 llvm::Constant *FirstField =
2611 return EmitFullMemberPointer(FirstField,
false, RD,
2615 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2620 return EmitNullMemberPointer(DstTy);
2626 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2627 C = EmitMemberFunctionPointer(MD);
2630 C = EmitMemberDataPointer(DstTy, FieldOffset);
2633 if (!MemberPointerPath.empty()) {
2634 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2638 ->castAs<MemberPointerType>();
2646 if (DerivedMember) {
2654 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2656 DerivedToBasePath.push_back(&BS);
2659 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2661 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2662 : CK_BaseToDerivedMemberPointer;
2663 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2664 DerivedToBasePath.end(), C);
2670 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2671 assert(MD->
isInstance() &&
"Member function must not be static!");
2678 unsigned VBTableIndex = 0;
2679 llvm::Constant *FirstField;
2681 if (!MD->isVirtual()) {
2696 VTableContext.getMethodVFTableLocation(MD);
2697 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2701 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2704 if (VBTableIndex == 0 &&
2706 MSInheritanceAttr::Keyword_virtual_inheritance)
2707 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2710 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2711 return EmitFullMemberPointer(FirstField,
true, RD,
2712 NonVirtualBaseAdjustment, VBTableIndex);
2727 llvm::ICmpInst::Predicate Eq;
2728 llvm::Instruction::BinaryOps
And, Or;
2730 Eq = llvm::ICmpInst::ICMP_NE;
2731 And = llvm::Instruction::Or;
2734 Eq = llvm::ICmpInst::ICMP_EQ;
2736 Or = llvm::Instruction::Or;
2745 return Builder.CreateICmp(Eq, L, R);
2748 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
2749 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
2750 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
2754 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
2755 for (
unsigned I = 1,
E = LType->getNumElements(); I !=
E; ++
I) {
2756 llvm::Value *LF = Builder.CreateExtractValue(L, I);
2757 llvm::Value *RF = Builder.CreateExtractValue(R, I);
2758 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
2760 Res = Builder.CreateBinOp(And, Res, Cmp);
2768 llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
2769 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero,
"memptr.cmp.iszero");
2770 Res = Builder.CreateBinOp(Or, Res, IsZero);
2775 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
2786 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2788 GetNullMemberPointerFields(MPT, fields);
2789 assert(!fields.empty());
2791 if (MemPtr->getType()->isStructTy())
2792 FirstField = Builder.CreateExtractValue(MemPtr, 0);
2793 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
2801 for (
int I = 1,
E = fields.size(); I <
E; ++
I) {
2803 llvm::Value *
Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
2804 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
2810 llvm::Constant *Val) {
2813 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
2814 Val->getAggregateElement(0U) : Val;
2815 return FirstField->isNullValue();
2820 if (isZeroInitializable(MPT) && Val->isNullValue())
2826 GetNullMemberPointerFields(MPT, Fields);
2827 if (Fields.size() == 1) {
2828 assert(Val->getType()->isIntegerTy());
2829 return Val == Fields[0];
2833 for (I = 0, E = Fields.size(); I !=
E; ++
I) {
2834 if (Val->getAggregateElement(I) != Fields[
I])
2850 Builder.CreateInBoundsGEP(This.
getPointer(), VBPtrOffset,
"vbptr");
2851 if (VBPtrOut) *VBPtrOut = VBPtr;
2856 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
2867 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
2871 llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex);
2884 llvm::BasicBlock *OriginalBB =
nullptr;
2885 llvm::BasicBlock *SkipAdjustBB =
nullptr;
2886 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
2893 OriginalBB = Builder.GetInsertBlock();
2897 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
2899 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
2911 "member pointer representation requires a "
2912 "complete class type for %0 to perform this expression");
2915 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2920 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
2921 llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
2924 if (VBaseAdjustBB) {
2925 Builder.CreateBr(SkipAdjustBB);
2927 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
2928 Phi->addIncoming(Base.
getPointer(), OriginalBB);
2929 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
2932 return AdjustedBase;
2935 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
2949 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
2951 if (MemPtr->getType()->isStructTy()) {
2954 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
2955 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2956 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
2957 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2958 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
2962 if (VirtualBaseAdjustmentOffset) {
2963 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
2973 Addr = Builder.CreateInBoundsGEP(Addr, FieldOffset,
"memptr.offset");
2984 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
2985 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
2989 if (isa<llvm::Constant>(Src))
2990 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3000 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3001 if (IsReinterpret && IsFunc)
3006 if (IsReinterpret &&
3013 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3014 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3018 if (IsReinterpret) {
3021 assert(Src->getType() == DstNull->getType());
3022 return Builder.CreateSelect(IsNotNull, Src, DstNull);
3025 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3028 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3031 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3035 Builder.CreateBr(ContinueBB);
3039 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3040 Phi->addIncoming(DstNull, OriginalBB);
3041 Phi->addIncoming(Dst, ConvertBB);
3045 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3055 bool IsConstant = isa<llvm::Constant>(Src);
3059 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3060 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3062 if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
3065 FirstField = Builder.CreateExtractValue(Src, I++);
3066 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
3067 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3068 if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
3069 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3070 if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
3071 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3074 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3080 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3088 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3089 if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3090 if (int64_t SrcOffsetToFirstVBase =
3091 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3092 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3094 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3096 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3107 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3113 if (IsDerivedToBase)
3114 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3116 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3118 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3123 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) &&
3124 MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) {
3125 if (llvm::GlobalVariable *VDispMap =
3126 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3128 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3130 llvm::Constant *Mapping = VDispMap->getInitializer();
3131 VirtualBaseAdjustmentOffset =
3132 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3135 VirtualBaseAdjustmentOffset =
3141 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3147 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) {
3148 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3150 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3152 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3158 if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3159 if (int64_t DstOffsetToFirstVBase =
3160 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3161 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3163 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3165 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3171 if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) {
3174 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3176 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3177 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
3178 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3179 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
3180 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3181 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
3182 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3188 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3189 llvm::Constant *Src) {
3196 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3200 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3204 assert(CK == CK_DerivedToBaseMemberPointer ||
3205 CK == CK_BaseToDerivedMemberPointer ||
3206 CK == CK_ReinterpretMemberPointer);
3209 if (MemberPointerConstantIsNull(SrcTy, Src))
3210 return EmitNullMemberPointer(DstTy);
3215 if (CK == CK_ReinterpretMemberPointer)
3219 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3220 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3225 llvm::Value *MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3237 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
3243 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3245 if (MemPtr->getType()->isStructTy()) {
3248 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3249 if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance))
3250 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3251 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3252 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3253 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3254 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3257 if (VirtualBaseAdjustmentOffset) {
3258 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3259 VirtualBaseAdjustmentOffset, VBPtrOffset);
3264 if (NonVirtualBaseAdjustment) {
3267 Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
3268 ThisPtrForCall = Builder.
CreateBitCast(Ptr, ThisPtrForCall->getType(),
3272 return Builder.
CreateBitCast(FunctionPointer, FTy->getPointerTo());
3276 return new MicrosoftCXXABI(CGM);
3310 StringRef MangledName(
"\01??_7type_info@@6B@");
3311 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3316 nullptr, MangledName);
3327 struct MSRTTIClass {
3329 IsPrivateOnPath = 1 | 8,
3333 HasHierarchyDescriptor = 64
3336 uint32_t initialize(
const MSRTTIClass *Parent,
3339 MSRTTIClass *getFirstChild() {
return this + 1; }
3340 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3341 return Child + 1 + Child->NumBases;
3345 uint32_t Flags, NumBases, OffsetInVBase;
3349 uint32_t MSRTTIClass::initialize(
const MSRTTIClass *Parent,
3351 Flags = HasHierarchyDescriptor;
3353 VirtualRoot =
nullptr;
3357 Flags |= IsPrivate | IsPrivateOnPath;
3363 if (Parent->Flags & IsPrivateOnPath)
3364 Flags |= IsPrivateOnPath;
3365 VirtualRoot = Parent->VirtualRoot;
3366 OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
3367 .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
3371 MSRTTIClass *Child = getFirstChild();
3373 NumBases += Child->initialize(
this, &Base) + 1;
3374 Child = getNextChild(Child);
3379 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3388 return llvm::GlobalValue::LinkOnceODRLinkage;
3390 llvm_unreachable(
"Invalid linkage!");
3396 struct MSRTTIBuilder {
3398 HasBranchingHierarchy = 1,
3399 HasVirtualBranchingHierarchy = 2,
3400 HasAmbiguousBases = 4
3403 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3404 : CGM(ABI.CGM), Context(CGM.getContext()),
3405 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3406 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3409 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3410 llvm::GlobalVariable *
3412 llvm::GlobalVariable *getClassHierarchyDescriptor();
3413 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo *Info);
3417 llvm::LLVMContext &VMContext;
3420 llvm::GlobalVariable::LinkageTypes
Linkage;
3421 MicrosoftCXXABI &ABI;
3430 Classes.push_back(MSRTTIClass(RD));
3438 llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3439 llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3440 llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3441 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3442 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3443 !VirtualBases.insert(Class->RD).second) {
3444 Class = MSRTTIClass::getNextChild(Class);
3447 if (!UniqueBases.insert(Class->RD).second)
3448 AmbiguousBases.insert(Class->RD);
3451 if (AmbiguousBases.empty())
3453 for (MSRTTIClass &Class : Classes)
3454 if (AmbiguousBases.count(Class.RD))
3455 Class.Flags |= MSRTTIClass::IsAmbiguous;
3458 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3461 llvm::raw_svector_ostream Out(MangledName);
3462 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3466 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3472 Classes.front().initialize(
nullptr,
nullptr);
3475 for (
auto Class : Classes) {
3477 Flags |= HasBranchingHierarchy;
3480 if (Class.Flags & MSRTTIClass::IsAmbiguous)
3481 Flags |= HasAmbiguousBases;
3483 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3484 Flags |= HasVirtualBranchingHierarchy;
3488 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3491 auto Type = ABI.getClassHierarchyDescriptorType();
3492 auto CHD =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3495 if (CHD->isWeakForLinker())
3496 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3498 auto *Bases = getBaseClassArray(Classes);
3501 llvm::Constant *Fields[] = {
3502 llvm::ConstantInt::get(CGM.
IntTy, 0),
3503 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3504 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3505 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3506 Bases->getValueType(), Bases,
3509 CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3513 llvm::GlobalVariable *
3517 llvm::raw_svector_ostream Out(MangledName);
3518 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3526 llvm::Type *PtrType = ABI.getImageRelativeType(
3527 ABI.getBaseClassDescriptorType()->getPointerTo());
3528 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3530 new llvm::GlobalVariable(
Module, ArrType,
3532 nullptr, MangledName);
3533 if (BCA->isWeakForLinker())
3534 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3538 for (MSRTTIClass &Class : Classes)
3539 BaseClassArrayData.push_back(
3540 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3541 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3542 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3546 llvm::GlobalVariable *
3547 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3550 uint32_t OffsetInVBTable = 0;
3551 int32_t VBPtrOffset = -1;
3552 if (Class.VirtualRoot) {
3554 OffsetInVBTable = VTableContext.
getVBTableIndex(RD, Class.VirtualRoot) * 4;
3555 VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
3560 llvm::raw_svector_ostream Out(MangledName);
3561 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3562 Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3567 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3571 auto Type = ABI.getBaseClassDescriptorType();
3573 new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3574 nullptr, MangledName);
3575 if (BCD->isWeakForLinker())
3576 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3579 llvm::Constant *Fields[] = {
3580 ABI.getImageRelativeConstant(
3581 ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))),
3582 llvm::ConstantInt::get(CGM.
IntTy, Class.NumBases),
3583 llvm::ConstantInt::get(CGM.
IntTy, Class.OffsetInVBase),
3584 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3585 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3586 llvm::ConstantInt::get(CGM.
IntTy, Class.Flags),
3587 ABI.getImageRelativeConstant(
3588 MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3590 BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3594 llvm::GlobalVariable *
3595 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo *Info) {
3598 llvm::raw_svector_ostream Out(MangledName);
3599 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info->
MangledPath, Out);
3603 if (
auto COL =
Module.getNamedGlobal(MangledName))
3608 int VFPtrOffset = 0;
3611 if (Context.getASTRecordLayout(RD)
3612 .getVBaseOffsetsMap()
3614 ->second.hasVtorDisp())
3618 llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3619 auto COL =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3620 nullptr, MangledName);
3623 llvm::Constant *Fields[] = {
3624 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3625 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3626 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3627 ABI.getImageRelativeConstant(
3629 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3630 ABI.getImageRelativeConstant(COL),
3633 if (!ABI.isImageRelative())
3634 FieldsRef = FieldsRef.drop_back();
3635 COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
3636 if (COL->isWeakForLinker())
3637 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3642 bool &IsConst,
bool &IsVolatile,
3643 bool &IsUnaligned) {
3653 IsUnaligned =
false;
3655 if (!PointeeType.
isNull()) {
3676 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3681 bool IsConst, IsVolatile, IsUnaligned;
3697 return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(),
3705 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3708 llvm::raw_svector_ostream Out(MangledName);
3709 getMangleContext().mangleCXXRTTI(Type, Out);
3713 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3714 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3719 llvm::raw_svector_ostream Out(TypeInfoString);
3720 getMangleContext().mangleCXXRTTIName(Type, Out);
3724 llvm::Constant *Fields[] = {
3726 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3727 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
3728 llvm::StructType *TypeDescriptorType =
3729 getTypeDescriptorType(TypeInfoString);
3730 auto *Var =
new llvm::GlobalVariable(
3731 CGM.
getModule(), TypeDescriptorType,
false,
3732 getLinkageForRTTI(Type),
3733 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
3735 if (Var->isWeakForLinker())
3736 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
3737 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
3741 llvm::GlobalVariable *
3742 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
3744 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
3763 if (ProducedAlias) {
3779 if (Fn->isWeakForLinker())
3780 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
3783 void MicrosoftCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3785 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
3799 llvm::raw_svector_ostream Out(ThunkName);
3800 getMangleContext().mangleCXXCtor(CD, CT, Out);
3803 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
3804 return cast<llvm::Function>(GV);
3810 QualType RecordTy = getContext().getRecordType(RD);
3812 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
3813 ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
3815 if (ThunkFn->isWeakForLinker())
3816 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
3827 buildThisParam(CGF, FunctionArgs);
3832 getContext(),
nullptr,
SourceLocation(), &getContext().Idents.get(
"src"),
3833 getContext().getLValueReferenceType(RecordTy,
3836 FunctionArgs.push_back(&SrcParam);
3842 &getContext().Idents.get(
"is_most_derived"),
3843 getContext().IntTy);
3846 FunctionArgs.push_back(&IsMostDerived);
3868 std::vector<Stmt *> ArgVec;
3869 for (
unsigned I = IsCopy ? 1 : 0, E = CD->
getNumParams(); I !=
E; ++
I) {
3870 Stmt *DefaultArg = getContext().getDefaultArgExprForConstructor(CD, I);
3871 assert(DefaultArg &&
"sema forgot to instantiate default args");
3872 ArgVec.push_back(DefaultArg);
3878 CGF.
EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
3881 unsigned ExtraArgs = addImplicitConstructorArgs(CGF, CD,
Ctor_Complete,
3891 Cleanups.ForceCleanup();
3900 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
3902 int32_t VBPtrOffset,
3914 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
3917 llvm::raw_svector_ostream Out(MangledName);
3918 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
3919 VBPtrOffset, VBIndex, Out);
3921 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3922 return getImageRelativeConstant(GV);
3926 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
3930 llvm::Constant *CopyCtor;
3937 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
3939 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3941 CopyCtor = getImageRelativeConstant(CopyCtor);
3943 bool IsScalar = !RD;
3944 bool HasVirtualBases =
false;
3945 bool IsStdBadAlloc =
false;
3950 HasVirtualBases = RD->getNumVBases() > 0;
3952 IsStdBadAlloc = II->isStr(
"bad_alloc") && RD->isInStdNamespace();
3960 if (HasVirtualBases)
3965 llvm::Constant *Fields[] = {
3966 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3968 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
3969 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3970 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
3971 llvm::ConstantInt::get(CGM.
IntTy, Size),
3974 llvm::StructType *CTType = getCatchableTypeType();
3975 auto *GV =
new llvm::GlobalVariable(
3976 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
3977 llvm::ConstantStruct::get(CTType, Fields), MangledName);
3978 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3979 GV->setSection(
".xdata");
3980 if (GV->isWeakForLinker())
3981 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
3982 return getImageRelativeConstant(GV);
3985 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
3989 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4014 if (MostDerivedClass) {
4021 Classes.front().initialize(
nullptr,
nullptr);
4023 for (
const MSRTTIClass &Class : Classes) {
4026 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4029 uint32_t OffsetInVBTable = 0;
4030 int32_t VBPtrOffset = -1;
4031 if (Class.VirtualRoot) {
4042 CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
4043 VBPtrOffset, OffsetInVBTable));
4051 CatchableTypes.insert(getCatchableType(T));
4064 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4075 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4077 uint32_t NumEntries = CatchableTypes.size();
4079 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4080 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4081 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4082 llvm::Constant *Fields[] = {
4083 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4084 llvm::ConstantArray::get(
4085 AT, llvm::makeArrayRef(CatchableTypes.begin(),
4086 CatchableTypes.end()))
4090 llvm::raw_svector_ostream Out(MangledName);
4091 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4093 CTA =
new llvm::GlobalVariable(
4094 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4095 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4096 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4097 CTA->setSection(
".xdata");
4098 if (CTA->isWeakForLinker())
4099 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4103 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4104 bool IsConst, IsVolatile, IsUnaligned;
4109 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4114 uint32_t NumEntries =
4115 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
4116 ->getLimitedValue();
4120 llvm::raw_svector_ostream Out(MangledName);
4121 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4127 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4143 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4146 if (!DtorD->isTrivial())
4147 CleanupFn = llvm::ConstantExpr::getBitCast(
4151 llvm::Constant *ForwardCompat =
4152 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4153 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4154 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4155 llvm::StructType *TIType = getThrowInfoType();
4156 llvm::Constant *Fields[] = {
4157 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4158 getImageRelativeConstant(CleanupFn),
4160 PointerToCatchableTypes
4162 auto *GV =
new llvm::GlobalVariable(
4163 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4164 llvm::ConstantStruct::get(TIType, Fields), StringRef(MangledName));
4165 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4166 GV->setSection(
".xdata");
4167 if (GV->isWeakForLinker())
4168 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4183 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
ReturnValueSlot - Contains the address where the return value of a function can be stored...
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile, bool &IsUnaligned)
CastKind getCastKind() const
llvm::IntegerType * IntTy
int
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, Address Guard=Address::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
void setSRetAfterThis(bool AfterThis)
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, const FunctionDecl *CalleeDecl=nullptr, unsigned ParamsToSkip=0)
EmitCallArgs - Emit call arguments for a function.
External linkage, which indicates that the entity can be referred to from other translation units...
bool isNullPtrType() const
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
A (possibly-)qualified type.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
static llvm::Constant * getInitThreadFooterFn(CodeGenModule &CGM)
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
CanQualType getReturnType() const
uint32_t VBPtrOffset
The offset (in bytes) of the vbptr, relative to the beginning of the derived class.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
llvm::Module & getModule() const
llvm::LLVMContext & getLLVMContext()
static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)
Find ambiguity among base classes.
MSInheritanceAttr::Spelling getMSInheritanceModel() const
Returns the inheritance model used for this record.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
bool isGlobalDelete() const
No linkage, which means that the entity is unique and can only be referred to from within its scope...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
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...
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
vtable_component_iterator vtable_component_begin() const
bool hasDefinition() const
QualType getPointeeType() const
The base class of the type hierarchy.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i...
BasePath MangledPath
The bases from the inheritance path that got used to mangle the vbtable name.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
Default closure variant of a ctor.
const CXXBaseSpecifier *const * path_const_iterator
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
TLSKind getTLSKind() const
static llvm::Constant * getInitThreadHeaderFn(CodeGenModule &CGM)
A this pointer adjustment.
QualType getThisType(ASTContext &C) const
Returns the type of the this pointer.
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
A C++ throw-expression (C++ [except.throw]).
static llvm::Constant * getInitThreadAbortFn(CodeGenModule &CGM)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo *VFPtr, SmallString< 256 > &Name)
GlobalDecl getCanonicalDecl() const
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
One of these records is kept for each identifier that is lexed.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
const CXXRecordDecl * getVBaseWithVPtr() const
The vptr is stored inside the non-virtual component of this virtual base.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CharUnits getIntSize() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const CXXRecordDecl * NearestVBase
BasePath PathToBaseWithVPtr
This holds the base classes path from the complete type to the first base with the given vfptr offset...
bool hasNonTrivialCopyConstructor() const
Determine whether this class has a non-trivial copy constructor (C++ [class.copy]p6, C++11 [class.copy]p12)
bool isReferenceType() const
static const CXXRecordDecl * getClassAtVTableLocation(ASTContext &Ctx, const CXXRecordDecl *RD, CharUnits Offset)
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
uint64_t getNumVTableComponents() const
llvm::IntegerType * SizeTy
struct clang::ReturnAdjustment::VirtualAdjustment::@111 Microsoft
StructorType getFromDtorType(CXXDtorType T)
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
CXXMethodDecl * getCanonicalDecl() override
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
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.
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, CGCalleeInfo CalleeInfo=CGCalleeInfo(), llvm::Instruction **callOrInvoke=nullptr)
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.
llvm::Function * codegenCXXStructor(const CXXMethodDecl *MD, StructorType Type)
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const Decl * getDecl() const
Describes a module or submodule.
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
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...
const ValueDecl * getMemberPointerDecl() const
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
path_iterator path_begin()
llvm::PointerType * VoidPtrTy
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
Concrete class used by the front-end to report problems and issues.
static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM)
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
CXXRecordDecl * getCanonicalDecl() override
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
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...
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy)
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
detail::InMemoryDirectory::const_iterator I
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
FunctionDecl * getOperatorDelete() const
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to...
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
Represents a prototype with parameter type info, e.g.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
CastKind
CastKind - The kind of operation required for a conversion.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
static void emitCXXConstructor(CodeGenModule &CGM, const CXXConstructorDecl *ctor, StructorType ctorType)
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
bool hasUnaligned() const
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
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.
llvm::Value * getPointer() const
bool isDeleted() const
Whether this function has been deleted.
const Type * getTypeForDecl() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
CXXDtorType getDtorType() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
bool isMemberPointerToDerivedMember() const
Represents a C++ destructor within a class.
static llvm::CallSite emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
ASTContext & getContext() const
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
MicrosoftVTableContext & getMicrosoftVTableContext()
void add(RValue rvalue, QualType type, bool needscopy=false)
llvm::LLVMContext & getLLVMContext()
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
llvm::IntegerType * Int32Ty
QualType getAllocatedType() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isExternallyVisible() const
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
The result type of a method or function.
The COMDAT used for dtors.
const CXXRecordDecl * ReusingBase
The vtable will hold all of the virtual bases or virtual methods of ReusingBase.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
GlobalDecl - represents a global declaration.
bool isObjectType() const
Determine whether this type is an object type.
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.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
uint64_t getNumVTableThunks() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs=llvm::AttributeSet())
Create a new runtime function with the specified type and name.
Encodes a location in the source.
CharUnits getPointerAlign() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
unsigned getNumParams() const
getNumParams - Return the number of parameters this function must have based on its FunctionType...
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
const TemplateArgument * iterator
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...
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.
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
Represents a single component in a vtable.
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Represents a static or instance method of a struct/union/class.
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
const CXXRecordDecl * BaseWithVPtr
The vptr is stored inside this subobject.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
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.
const T * castAs() const
Member-template castAs<specific type>.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
MangleContext & getMangleContext()
Gets the mangle context.
llvm::Instruction * CurrentFuncletPad
unsigned getAddressSpace() const
Return the address space that this address resides in.
CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)
Creates a Microsoft-family ABI.
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is virtually derived from the class Base.
llvm::Constant * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, bool IsForDefinition=false)
Return the address of the constructor/destructor of the given type.
struct clang::ThisAdjustment::VirtualAdjustment::@113 Microsoft
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl * > BasePath, raw_ostream &Out)=0
Mangle vftable symbols.
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...
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 ...
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.
CharUnits getAlignment() const
Return the alignment of this pointer.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
const Expr * getSubExpr() const
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This)
Address getObjectAddress(CodeGenFunction &CGF) const
Returns the address of the object within this declaration.
External linkage within a unique namespace.
static bool isDeletingDtor(GlobalDecl GD)
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
bool isZero() const
isZero - Test whether the quantity equals zero.
Address CreateMemTemp(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
const VPtrInfoVector & enumerateVBTables(const CXXRecordDecl *RD)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
bool isInstanceMethod() const
bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target, bool InEveryTU)
Try to emit a definition as a global alias for another definition.
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
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="")
QualType getExceptionObjectType(QualType T) const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
detail::InMemoryDirectory::const_iterator E
A pointer to member type per C++ 8.3.3 - Pointers to members.
CharUnits NonVirtualOffset
BaseWithVPtr is at this offset from its containing complete object or virtual base.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
vtable_component_range vtable_components() 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.
unsigned Map[Count]
The type of a lookup table which maps from language-specific address spaces to target-specific ones...
void EmitThunks(GlobalDecl GD)
EmitThunks - Emit the associated thunks for the given global decl.
union clang::ThisAdjustment::VirtualAdjustment Virtual
vtable_thunk_iterator vtable_thunk_begin() const
void EmitAutoVarCleanups(const AutoVarEmission &emission)
llvm::PointerType * getType() const
Return the type of the pointer value.
const T * getAs() const
Member-template getAs<specific type>'.
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
CharUnits getIntAlign() const
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
SourceLocation getLocStart() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
StringRef getMangledName(GlobalDecl GD)
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
ABIArgInfo & getReturnInfo()
Represents a base class of a C++ class.
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
Linkage getLinkage() const
Determine the linkage of this type.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
llvm::IntegerType * PtrDiffTy
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
DiagnosticsEngine & getDiags() const
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="")
Represents a C++ struct/union/class.
BoundNodesTreeBuilder *const Builder
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
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)
static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor, StructorType dtorType)
A specialization of Address that requires the address to be an LLVM Constant.
CallingConv getDefaultCallingConvention(bool isVariadic, bool IsCXXMethod) const
Retrieves the default calling convention for the current target.
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...
llvm::Constant * CreateVTableInitializer(const CXXRecordDecl *RD, const VTableComponent *Components, unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks, unsigned NumVTableThunks, llvm::Constant *RTTI)
CreateVTableInitializer - Create a vtable initializer for the given record decl.
Copying closure variant of a ctor.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CharUnits FullOffsetInMDC
Static offset from the top of the most derived class to this vfptr, including any virtual base offset...
uint64_t Index
Method's index in the vftable.
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
Struct with all informations about dynamic [sub]class needed to set vptr.
VarDecl * getExceptionDecl() const
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.
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
CodeGenVTables & getVTables()
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
uint32_t VBIndex
Index of the virtual base in the vbtable.
LValue - This represents an lvalue references.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Information for lazily generating a cleanup.
const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
bool isConstQualified() const
Determine whether this type is const-qualified.
RecordArgABI
Specify how one should pass an argument of a record type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, bool IsForDefinition=false)
Return the address of the given function.
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.
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.
void EmitMustTailThunk(const CXXMethodDecl *MD, llvm::Value *AdjustedThisPtr, llvm::Value *Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
static llvm::Constant * getThrowFn(CodeGenModule &CGM)
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraArgs)
Arrange a call to a C++ method, passing the given arguments.
bool isPointerType() const
bool isPOD() const
Whether this class is a POD-type (C++ [class]p4)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.