28 #include "llvm/ADT/StringExtras.h"
29 #include "llvm/ADT/StringSet.h"
30 #include "llvm/IR/CallSite.h"
31 #include "llvm/IR/Intrinsics.h"
33 using namespace clang;
34 using namespace CodeGen;
39 struct VBTableGlobals {
44 class MicrosoftCXXABI :
public CGCXXABI {
47 :
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
48 ClassHierarchyDescriptorType(nullptr),
49 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
50 ThrowInfoType(nullptr) {}
52 bool HasThisReturn(
GlobalDecl GD)
const override;
53 bool hasMostDerivedReturn(
GlobalDecl GD)
const override;
59 bool isSRetParameterAfterThis()
const override {
return true; }
61 bool isThisCompleteObject(
GlobalDecl GD)
const override {
64 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
73 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
75 llvm_unreachable(
"bad dtor kind");
84 assert(Args.size() >= 2 &&
85 "expected the arglist to have at least two args!");
94 std::vector<CharUnits> getVBPtrOffsets(
const CXXRecordDecl *RD)
override {
95 std::vector<CharUnits> VBPtrOffsets;
99 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
100 for (
const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
105 if (VBT->getVBaseWithVPtr())
107 VBPtrOffsets.push_back(Offs);
109 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
113 StringRef GetPureVirtualCallName()
override {
return "_purecall"; }
114 StringRef GetDeletedVirtualCallName()
override {
return "_purecall"; }
125 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
128 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
130 getAddrOfCXXCatchHandlerType(
QualType Ty,
QualType CatchHandlerType)
override;
137 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
143 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
149 llvm::BasicBlock *CastEnd)
override;
156 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override {
222 getThisArgumentTypeForMethod(
const CXXMethodDecl *MD)
override {
224 if (MD->
isVirtual() && !isa<CXXDestructorDecl>(MD)) {
226 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
242 bool VirtualCall)
override;
247 llvm::Value *adjustThisParameterInVirtualFunctionPrologue(
259 bool Delegating,
Address This)
override;
262 llvm::GlobalVariable *VTable);
272 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
273 return !VTableClass->
hasAttr<MSNoVTableAttr>();
288 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
304 "Only deleting destructor thunks are available in this ABI");
309 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
311 llvm::GlobalVariable *
313 llvm::GlobalVariable::LinkageTypes
Linkage);
315 llvm::GlobalVariable *
319 llvm::raw_svector_ostream Out(OutName);
320 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
321 StringRef MangledName = OutName.str();
323 if (
auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
329 llvm::UndefValue::get(CGM.IntTy));
330 Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
331 bool AnyDifferent =
false;
332 for (
const auto &
I : SrcRD->
vbases()) {
339 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
340 AnyDifferent |= SrcVBIndex != DstVBIndex;
346 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy,
Map.size());
347 llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy,
Map);
348 llvm::GlobalValue::LinkageTypes
Linkage =
350 ? llvm::GlobalValue::LinkOnceODRLinkage
352 auto *VDispMap =
new llvm::GlobalVariable(
353 CGM.getModule(), VDispMapTy,
true,
Linkage,
359 llvm::GlobalVariable *GV)
const;
361 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
364 Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
367 getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.
getDecl()));
371 else if (ReturnAdjustment)
372 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
374 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
381 const ReturnAdjustment &RA)
override;
383 void EmitThreadLocalInitFuncs(
388 bool usesThreadWrapperFunction()
const override {
return false; }
393 llvm::GlobalVariable *DeclPtr,
394 bool PerformInit)
override;
396 llvm::Constant *Dtor, llvm::Constant *Addr)
override;
434 friend struct MSRTTIBuilder;
436 bool isImageRelative()
const {
437 return CGM.getTarget().getPointerWidth(0) == 64;
441 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
443 TDTypeName += llvm::utostr(TypeInfoString.size());
444 llvm::StructType *&TypeDescriptorType =
445 TypeDescriptorTypeMap[TypeInfoString.size()];
446 if (TypeDescriptorType)
447 return TypeDescriptorType;
451 llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
454 return TypeDescriptorType;
458 if (!isImageRelative())
463 llvm::StructType *getBaseClassDescriptorType() {
464 if (BaseClassDescriptorType)
465 return BaseClassDescriptorType;
467 getImageRelativeType(CGM.Int8PtrTy),
473 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
476 CGM.getLLVMContext(), FieldTypes,
"rtti.BaseClassDescriptor");
477 return BaseClassDescriptorType;
480 llvm::StructType *getClassHierarchyDescriptorType() {
481 if (ClassHierarchyDescriptorType)
482 return ClassHierarchyDescriptorType;
485 CGM.getLLVMContext(),
"rtti.ClassHierarchyDescriptor");
490 getImageRelativeType(
491 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
493 ClassHierarchyDescriptorType->setBody(FieldTypes);
494 return ClassHierarchyDescriptorType;
497 llvm::StructType *getCompleteObjectLocatorType() {
498 if (CompleteObjectLocatorType)
499 return CompleteObjectLocatorType;
501 CGM.getLLVMContext(),
"rtti.CompleteObjectLocator");
506 getImageRelativeType(CGM.Int8PtrTy),
507 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
508 getImageRelativeType(CompleteObjectLocatorType),
511 if (!isImageRelative())
512 FieldTypesRef = FieldTypesRef.drop_back();
513 CompleteObjectLocatorType->setBody(FieldTypesRef);
514 return CompleteObjectLocatorType;
517 llvm::GlobalVariable *getImageBase() {
518 StringRef
Name =
"__ImageBase";
519 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
522 return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
528 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
529 if (!isImageRelative())
532 if (PtrVal->isNullValue())
533 return llvm::Constant::getNullValue(CGM.IntTy);
535 llvm::Constant *ImageBaseAsInt =
536 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
537 llvm::Constant *PtrValAsInt =
538 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
539 llvm::Constant *Diff =
540 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
542 return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
550 llvm::Constant *getZeroInt() {
551 return llvm::ConstantInt::get(CGM.IntTy, 0);
554 llvm::Constant *getAllOnesInt() {
555 return llvm::Constant::getAllOnesValue(CGM.IntTy);
576 int32_t VBTableOffset,
578 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
579 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
580 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
581 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
584 std::pair<Address, llvm::Value *>
597 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
598 bool IsMemberFunction,
601 unsigned VBTableIndex);
610 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
613 llvm::Function *EmitVirtualMemPtrThunk(
624 return RD->
hasAttr<MSInheritanceAttr>();
631 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
632 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
638 bool Inequality)
override;
659 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *
E,
660 llvm::Constant *Src)
override;
662 llvm::Constant *EmitMemberPointerConversion(
675 llvm::StructType *getCatchableTypeType() {
676 if (CatchableTypeType)
677 return CatchableTypeType;
680 getImageRelativeType(CGM.Int8PtrTy),
685 getImageRelativeType(CGM.Int8PtrTy)
688 CGM.getLLVMContext(), FieldTypes,
"eh.CatchableType");
689 return CatchableTypeType;
692 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
693 llvm::StructType *&CatchableTypeArrayType =
694 CatchableTypeArrayTypeMap[NumEntries];
695 if (CatchableTypeArrayType)
696 return CatchableTypeArrayType;
699 CTATypeName += llvm::utostr(NumEntries);
701 getImageRelativeType(getCatchableTypeType()->getPointerTo());
704 llvm::ArrayType::get(CTType, NumEntries)
706 CatchableTypeArrayType =
708 return CatchableTypeArrayType;
711 llvm::StructType *getThrowInfoType() {
713 return ThrowInfoType;
716 getImageRelativeType(CGM.Int8PtrTy),
717 getImageRelativeType(CGM.Int8PtrTy),
718 getImageRelativeType(CGM.Int8PtrTy)
722 return ThrowInfoType;
728 llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
729 llvm::FunctionType *FTy =
730 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
731 auto *Fn = cast<llvm::Function>(
732 CGM.CreateRuntimeFunction(FTy,
"_CxxThrowException"));
734 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86)
735 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
742 llvm::Constant *getCatchableType(
QualType T,
743 uint32_t NVOffset = 0,
744 int32_t VBPtrOffset = -1,
745 uint32_t VBIndex = 0);
747 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
749 llvm::GlobalVariable *getThrowInfo(
QualType T)
override;
752 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
753 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
754 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
756 VFTablesMapTy VFTablesMap;
757 VTablesMapTy VTablesMap;
760 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
764 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
769 GuardInfo() : Guard(nullptr), BitIndex(0) {}
770 llvm::GlobalVariable *Guard;
776 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
777 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
778 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
780 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
781 llvm::StructType *BaseClassDescriptorType;
782 llvm::StructType *ClassHierarchyDescriptorType;
783 llvm::StructType *CompleteObjectLocatorType;
785 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
787 llvm::StructType *CatchableTypeType;
788 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
789 llvm::StructType *ThrowInfoType;
796 switch (CGM.getTarget().getTriple().getArch()) {
801 case llvm::Triple::thumb:
805 return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
807 case llvm::Triple::x86:
814 if (!canCopyArgument(RD))
815 return RAA_DirectInMemory;
821 case llvm::Triple::x86_64:
863 llvm_unreachable(
"invalid enum");
876 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
881 void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
883 llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
884 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
894 llvm::CatchPadInst *CPI;
896 CatchRetScope(llvm::CatchPadInst *CPI) : CPI(CPI) {}
900 CGF.
Builder.CreateCatchRet(CPI, BB);
911 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
912 llvm::CatchPadInst *CPI =
913 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
932 std::pair<Address, llvm::Value *>
943 return std::make_pair(Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0));
951 PolymorphicBase = BaseDecl;
955 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
958 GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase);
962 return std::make_pair(
Address(Ptr, VBaseAlign), Offset);
965 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
969 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
975 llvm::FunctionType *FTy =
976 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
983 llvm::CallSite
Call =
985 Call.setDoesNotReturn();
986 CGF.
Builder.CreateUnreachable();
993 std::tie(ThisPtr, std::ignore) =
994 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
999 bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1003 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1006 llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
1017 std::tie(This, Offset) = performBaseAdjustment(CGF, This, SrcRecordTy);
1030 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1033 ThisPtr,
Offset, SrcRTTI, DestRTTI,
1043 std::tie(Value, std::ignore) = performBaseAdjustment(CGF, Value, SrcRecordTy);
1049 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1059 llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1063 int64_t VBPtrChars =
1065 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
1069 CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
1071 llvm::ConstantInt::get(CGM.IntTy, VBTableChars.
getQuantity());
1074 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1076 CGF.
Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
1077 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1080 bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1081 return isa<CXXConstructorDecl>(GD.
getDecl());
1085 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1089 bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1105 }
else if (!RD->
isPOD()) {
1118 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1119 assert(IsMostDerivedClass &&
1120 "ctor for a class with virtual bases must have an implicit parameter");
1122 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1124 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1125 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1126 CGF.
Builder.CreateCondBr(IsCompleteObject,
1127 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1132 EmitVBPtrStores(CGF, RD);
1136 return SkipVbaseCtorsBB;
1140 MicrosoftCXXABI::EmitDtorCompleteObjectHandler(
CodeGenFunction &CGF) {
1141 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1142 assert(IsMostDerivedClass &&
1143 "ctor for a class with virtual bases must have an implicit parameter");
1145 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1147 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1148 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1149 CGF.
Builder.CreateCondBr(IsCompleteObject,
1150 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1155 return SkipVbaseDtorsBB;
1158 void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1178 unsigned AS = getThisAddress(CGF).getAddressSpace();
1181 for (VBOffsets::const_iterator
I = VBaseMap.begin(),
E = VBaseMap.end();
1183 if (!
I->second.hasVtorDisp())
1187 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD,
I->first);
1188 uint64_t ConstantVBaseOffset =
1193 VBaseOffset, llvm::ConstantInt::get(CGM.PtrDiffTy, ConstantVBaseOffset),
1195 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1199 CGF.
Int8Ty->getPointerTo(AS));
1200 llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset);
1202 VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4);
1204 VtorDispPtr, CGF.
Int32Ty->getPointerTo(AS),
"vtordisp.ptr");
1217 return ExpectedCallingConv == ActualCallingConv;
1231 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1232 Fn->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1238 Address This = getThisAddress(CGF);
1243 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1244 for (
unsigned I = 0,
E = VBGlobals.VBTables->size();
I !=
E; ++
I) {
1245 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[
I];
1246 llvm::GlobalVariable *GV = VBGlobals.Globals[
I];
1251 if (VBT->getVBaseWithVPtr())
1255 CGF.
Builder.CreateConstInBoundsGEP2_32(GV->getValueType(), GV, 0, 0);
1257 "vbptr." + VBT->ObjectWithVPtr->getName());
1265 AddedStructorArgs Added;
1269 ArgTys.push_back(getContext().IntTy);
1283 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1286 ArgTys.push_back(getContext().IntTy);
1301 MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1318 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1325 if (isa<CXXDestructorDecl>(MD))
1330 getContext().getASTRecordLayout(MD->
getParent());
1337 Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1343 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1367 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1384 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1389 Result =
Address(VBasePtr, VBaseAlign);
1391 if (!StaticOffset.
isZero()) {
1412 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1421 if (FPT->isVariadic())
1422 Params.insert(Params.begin() + 1, IsMostDerived);
1424 Params.push_back(IsMostDerived);
1425 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1431 Params.push_back(ShouldDelete);
1432 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1436 llvm::Value *MicrosoftCXXABI::adjustThisParameterInVirtualFunctionPrologue(
1443 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1447 unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1449 *thisTy = This->getType();
1453 This = CGF.
Builder.CreateConstInBoundsGEP1_32(CGF.
Int8Ty, This,
1458 void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1473 if (HasThisReturn(CGF.
CurGD))
1475 else if (hasMostDerivedReturn(CGF.
CurGD))
1481 assert(getStructorImplicitParamDecl(CGF) &&
1482 "no implicit parameter for a constructor with virtual bases?");
1483 getStructorImplicitParamValue(CGF)
1490 assert(getStructorImplicitParamDecl(CGF) &&
1491 "no implicit parameter for a deleting destructor?");
1492 getStructorImplicitParamValue(CGF)
1495 "should_call_delete");
1501 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1506 return AddedStructorArgs{};
1512 MostDerivedArg = getStructorImplicitParamValue(CGF);
1514 MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type ==
Ctor_Complete);
1518 Args.insert(Args.begin() + 1,
1519 CallArg(RV, getContext().IntTy,
false));
1520 return AddedStructorArgs::prefix(1);
1522 Args.
add(RV, getContext().IntTy);
1523 return AddedStructorArgs::suffix(1);
1529 bool Delegating,
Address This) {
1536 "The deleting destructor should only be called via a virtual call");
1537 This = adjustThisArgumentForVirtualFunctionCall(CGF,
GlobalDecl(DD, Type),
1541 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1542 if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1543 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1550 if (BaseDtorEndBB) {
1552 CGF.
Builder.CreateBr(BaseDtorEndBB);
1557 void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1559 llvm::GlobalVariable *VTable) {
1560 if (!CGM.getCodeGenOpts().LTOUnit)
1567 getContext().getLangOpts().RTTIData
1568 ? getContext().toCharUnitsFromBits(
1569 getContext().getTargetInfo().getPointerWidth(0))
1573 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1578 CGM.AddVTableTypeMetadata(VTable, AddressPoint,
1588 getContext().getASTRecordLayout(DerivedRD);
1594 Offset = VBI->second.VBaseOffset;
1597 CGM.AddVTableTypeMetadata(VTable, AddressPoint, DerivedRD);
1602 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1605 void MicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables &CGVT,
1610 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1611 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1612 if (VTable->hasInitializer())
1618 llvm::Constant *RTTI =
nullptr;
1621 RTTI = getMSCompleteObjectLocator(RD, *Info);
1624 auto Components = Builder.beginStruct();
1626 Components.finishAndSetAsInitializer(VTable);
1628 emitVTableTypeMetadata(*Info, RD, VTable);
1632 bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1637 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1640 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1641 if (!VTableAddressPoint) {
1643 !getContext().getASTRecordLayout(Base.
getBase()).hasOwnVFPtr());
1645 return VTableAddressPoint;
1651 llvm::raw_svector_ostream Out(Name);
1660 return VFTablesMap[
ID];
1663 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1665 llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass);
1666 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1670 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1676 VFTableIdTy
ID(RD, VPtrOffset);
1677 VTablesMapTy::iterator
I;
1679 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(
ID,
nullptr));
1683 llvm::GlobalVariable *&VTable = I->second;
1688 if (DeferredVFTables.insert(RD).second) {
1691 CGM.addDeferredVTable(RD);
1696 llvm::StringSet<> ObservedMangledNames;
1697 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1700 if (!ObservedMangledNames.insert(Name.str()).second)
1701 llvm_unreachable(
"Already saw this mangling before?");
1706 const std::unique_ptr<VPtrInfo> *VFPtrI = std::find_if(
1707 VFPtrs.begin(), VFPtrs.end(), [&](
const std::unique_ptr<VPtrInfo>& VPI) {
1708 return VPI->FullOffsetInMDC == VPtrOffset;
1710 if (VFPtrI == VFPtrs.end()) {
1711 VFTablesMap[
ID] =
nullptr;
1714 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1726 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1727 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1728 : CGM.getVTableLinkage(RD);
1729 bool VFTableComesFromAnotherTU =
1730 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1731 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1732 bool VTableAliasIsRequred =
1733 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1735 if (llvm::GlobalValue *VFTable =
1736 CGM.getModule().getNamedGlobal(VFTableName)) {
1737 VFTablesMap[
ID] = VFTable;
1738 VTable = VTableAliasIsRequred
1739 ? cast<llvm::GlobalVariable>(
1740 cast<llvm::GlobalAlias>(VFTable)->getBaseObject())
1741 : cast<llvm::GlobalVariable>(VFTable);
1747 llvm::GlobalValue::LinkageTypes VTableLinkage =
1748 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1750 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1752 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1756 llvm::GlobalValue *VFTable;
1757 VTable =
new llvm::GlobalVariable(CGM.getModule(), VTableType,
1758 true, VTableLinkage,
1759 nullptr, VTableName);
1760 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1762 llvm::Comdat *
C =
nullptr;
1763 if (!VFTableComesFromAnotherTU &&
1764 (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1765 (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1766 VTableAliasIsRequred)))
1767 C = CGM.getModule().getOrInsertComdat(VFTableName.str());
1772 if (VTableAliasIsRequred) {
1773 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.Int32Ty, 0),
1774 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1775 llvm::ConstantInt::get(CGM.Int32Ty, 1)};
1778 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1779 VTable->getValueType(), VTable, GEPIndices);
1780 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1783 C->setSelectionKind(llvm::Comdat::Largest);
1787 VFTableName.str(), VTableGEP,
1789 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1798 VTable->setComdat(C);
1800 if (RD->
hasAttr<DLLExportAttr>())
1801 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1803 VFTablesMap[
ID] = VFTable;
1815 Ty = Ty->getPointerTo()->getPointerTo();
1817 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1819 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1828 auto getObjectWithVPtr = [&] {
1831 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1841 getObjectWithVPtr(), VTable,
1842 ML.
Index * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1844 if (CGM.getCodeGenOpts().PrepareForLTO)
1848 Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1852 CGCallee Callee(MethodDecl, VFunc);
1856 llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1865 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1868 CGCallee Callee = getVirtualFunctionPointer(
1872 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1876 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1883 const VBTableGlobals &
1884 MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
1887 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
1889 std::tie(Entry, Added) =
1890 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
1891 VBTableGlobals &VBGlobals = Entry->second;
1900 llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
1901 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
1902 E = VBGlobals.VBTables->end();
1904 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
1910 llvm::Function *MicrosoftCXXABI::EmitVirtualMemPtrThunk(
1913 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
1914 "can't form pointers to ctors or virtual dtors");
1918 llvm::raw_svector_ostream Out(ThunkName);
1919 getMangleContext().mangleVirtualMemPtrThunk(MD, Out);
1922 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
1923 return cast<llvm::Function>(GV);
1926 const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSMemberPointerThunk(MD);
1927 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
1928 llvm::Function *ThunkFn =
1930 ThunkName.str(), &CGM.getModule());
1931 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
1934 ? llvm::GlobalValue::LinkOnceODRLinkage
1937 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
1939 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
1940 CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
1946 ThunkFn->addFnAttr(
"thunk");
1949 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
1959 buildThisParam(CGF, FunctionArgs);
1969 getThisAddress(CGF), ThunkTy->getPointerTo()->getPointerTo(), MD->
getParent());
1972 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1981 void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1982 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1983 for (
unsigned I = 0,
E = VBGlobals.VBTables->size(); I !=
E; ++
I) {
1984 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
1985 llvm::GlobalVariable *GV = VBGlobals.Globals[
I];
1986 if (GV->isDeclaration())
1987 emitVBTableDefinition(*VBT, RD, GV);
1991 llvm::GlobalVariable *
1993 llvm::GlobalVariable::LinkageTypes Linkage) {
1995 llvm::raw_svector_ostream Out(OutName);
1996 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
1997 StringRef Name = OutName.str();
1999 llvm::ArrayType *VBTableType =
2002 assert(!CGM.getModule().getNamedGlobal(Name) &&
2003 "vbtable with this name already exists: mangling bug?");
2004 llvm::GlobalVariable *GV =
2005 CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, Linkage);
2006 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2008 if (RD->
hasAttr<DLLImportAttr>())
2009 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2010 else if (RD->
hasAttr<DLLExportAttr>())
2011 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2013 if (!GV->hasExternalLinkage())
2014 emitVBTableDefinition(VBT, RD, GV);
2019 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2021 llvm::GlobalVariable *GV)
const {
2025 "should only emit vbtables for classes with vbtables");
2029 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2035 CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2036 Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
2039 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2040 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2047 CompleteVBPtrOffset +=
2049 Offset -= CompleteVBPtrOffset;
2051 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2052 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2053 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.
getQuantity());
2056 assert(Offsets.size() ==
2057 cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
2058 ->getElementType())->getNumElements());
2059 llvm::ArrayType *VBTableType =
2060 llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2061 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2062 GV->setInitializer(Init);
2064 if (RD->
hasAttr<DLLImportAttr>())
2065 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2088 CGF.
Builder.CreateNeg(VtorDisp));
2105 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2122 const ReturnAdjustment &RA) {
2137 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2154 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *expr) {
2181 assert(requiresArrayCookie(expr));
2184 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2200 llvm::Constant *Dtor,
2201 llvm::Constant *Addr) {
2206 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2207 CGF.
IntTy, DtorStub->getType(),
false);
2210 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2211 if (llvm::Function *TLRegDtorFn = dyn_cast<llvm::Function>(TLRegDtor))
2212 TLRegDtorFn->setDoesNotThrow();
2218 llvm::Constant *Dtor,
2219 llvm::Constant *Addr) {
2227 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2231 if (CXXThreadLocalInits.empty())
2236 ?
"/include:___dyn_tls_init@12"
2237 :
"/include:__dyn_tls_init");
2242 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2243 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2244 CGM.
getModule(), InitFunc->getType(),
true,
2246 Twine(InitFunc->getName(),
"$initializer$"));
2247 InitFuncPtr->setSection(
".CRT$XDU");
2254 std::vector<llvm::Function *> NonComdatInits;
2255 for (
size_t I = 0,
E = CXXThreadLocalInitVars.size(); I !=
E; ++
I) {
2256 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2258 llvm::Function *F = CXXThreadLocalInits[
I];
2261 if (llvm::Comdat *C = GV->getComdat())
2262 AddToXDU(F)->setComdat(C);
2264 NonComdatInits.push_back(F);
2267 if (!NonComdatInits.empty()) {
2268 llvm::FunctionType *FTy =
2269 llvm::FunctionType::get(CGM.
VoidTy,
false);
2287 StringRef VarName(
"_Init_thread_epoch");
2289 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2291 auto *GV =
new llvm::GlobalVariable(
2295 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2301 llvm::FunctionType *FTy =
2302 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2303 CGM.
IntTy->getPointerTo(),
false);
2305 FTy,
"_Init_thread_header",
2307 llvm::AttributeList::FunctionIndex,
2308 llvm::Attribute::NoUnwind),
2313 llvm::FunctionType *FTy =
2314 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2315 CGM.
IntTy->getPointerTo(),
false);
2317 FTy,
"_Init_thread_footer",
2319 llvm::AttributeList::FunctionIndex,
2320 llvm::Attribute::NoUnwind),
2325 llvm::FunctionType *FTy =
2326 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2327 CGM.
IntTy->getPointerTo(),
false);
2329 FTy,
"_Init_thread_abort",
2331 llvm::AttributeList::FunctionIndex,
2332 llvm::Attribute::NoUnwind),
2340 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2341 : Guard(Guard), GuardNum(GuardNum) {}
2347 llvm::LoadInst *LI = Builder.
CreateLoad(Guard);
2348 llvm::ConstantInt *Mask =
2349 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2350 Builder.
CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2356 CallInitThreadAbort(
Address Guard) : Guard(Guard.getPointer()) {}
2366 llvm::GlobalVariable *GV,
2370 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2372 llvm::Function *F = CGF.
CurFn;
2373 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2374 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2380 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2384 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2387 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2388 llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
2392 GuardInfo *GI =
nullptr;
2393 if (ThreadlocalStatic)
2395 else if (!ThreadsafeStatic)
2398 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2403 GuardNum = getContext().getStaticLocalNumber(&D);
2404 assert(GuardNum > 0);
2406 }
else if (HasPerVariableGuard) {
2410 GuardNum = GI->BitIndex++;
2413 if (!HasPerVariableGuard && GuardNum >= 32) {
2415 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2424 llvm::raw_svector_ostream Out(GuardName);
2425 if (HasPerVariableGuard)
2426 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2429 getMangleContext().mangleStaticGuardVariable(&D, Out);
2435 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2436 GV->getLinkage(), Zero, GuardName.str());
2437 GuardVar->setVisibility(GV->getVisibility());
2438 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2440 if (GuardVar->isWeakForLinker())
2441 GuardVar->setComdat(
2442 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2444 GuardVar->setThreadLocal(
true);
2445 if (GI && !HasPerVariableGuard)
2446 GI->Guard = GuardVar;
2451 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2452 "static local from the same function had different linkage");
2454 if (!HasPerVariableGuard) {
2462 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2463 llvm::LoadInst *LI = Builder.
CreateLoad(GuardAddr);
2465 Builder.CreateICmpNE(Builder.CreateAnd(LI, Bit), Zero);
2468 Builder.CreateCondBr(IsInitialized, EndBlock, InitBlock);
2473 Builder.
CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2477 Builder.CreateBr(EndBlock);
2495 llvm::LoadInst *FirstGuardLoad = Builder.
CreateLoad(GuardAddr);
2496 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2497 llvm::LoadInst *InitThreadEpoch =
2500 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2503 Builder.CreateCondBr(IsUninitialized, AttemptInitBlock, EndBlock);
2509 GuardAddr.getPointer());
2510 llvm::LoadInst *SecondGuardLoad = Builder.
CreateLoad(GuardAddr);
2511 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2513 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2515 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2523 GuardAddr.getPointer());
2524 Builder.CreateBr(EndBlock);
2541 return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) &&
2553 fields.push_back(CGM.
IntTy);
2557 fields.push_back(CGM.
IntTy);
2558 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2559 fields.push_back(CGM.
IntTy);
2560 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2561 fields.push_back(CGM.
IntTy);
2563 if (fields.size() == 1)
2568 void MicrosoftCXXABI::
2571 assert(fields.empty());
2576 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2578 if (RD->nullFieldOffsetIsZero())
2579 fields.push_back(getZeroInt());
2581 fields.push_back(getAllOnesInt());
2586 fields.push_back(getZeroInt());
2587 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2588 fields.push_back(getZeroInt());
2589 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2590 fields.push_back(getAllOnesInt());
2596 GetNullMemberPointerFields(MPT, fields);
2597 if (fields.size() == 1)
2599 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2600 assert(Res->getType() == ConvertMemberPointerType(MPT));
2605 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2606 bool IsMemberFunction,
2609 unsigned VBTableIndex) {
2614 if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance))
2618 fields.push_back(FirstField);
2620 if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance))
2621 fields.push_back(llvm::ConstantInt::get(
2624 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) {
2627 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2632 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2633 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2635 return llvm::ConstantStruct::getAnon(fields);
2643 MSInheritanceAttr::Keyword_virtual_inheritance)
2644 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2645 llvm::Constant *FirstField =
2647 return EmitFullMemberPointer(FirstField,
false, RD,
2651 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2656 return EmitNullMemberPointer(DstTy);
2662 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2663 C = EmitMemberFunctionPointer(MD);
2666 C = EmitMemberDataPointer(DstTy, FieldOffset);
2669 if (!MemberPointerPath.empty()) {
2670 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2674 ->castAs<MemberPointerType>();
2682 if (DerivedMember) {
2690 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2692 DerivedToBasePath.push_back(&BS);
2695 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2697 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2698 : CK_BaseToDerivedMemberPointer;
2699 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2700 DerivedToBasePath.end(), C);
2706 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2707 assert(MD->
isInstance() &&
"Member function must not be static!");
2714 unsigned VBTableIndex = 0;
2715 llvm::Constant *FirstField;
2717 if (!MD->isVirtual()) {
2732 VTableContext.getMethodVFTableLocation(MD);
2733 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2737 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2740 if (VBTableIndex == 0 &&
2742 MSInheritanceAttr::Keyword_virtual_inheritance)
2743 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2746 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2747 return EmitFullMemberPointer(FirstField,
true, RD,
2748 NonVirtualBaseAdjustment, VBTableIndex);
2763 llvm::ICmpInst::Predicate Eq;
2764 llvm::Instruction::BinaryOps
And, Or;
2766 Eq = llvm::ICmpInst::ICMP_NE;
2767 And = llvm::Instruction::Or;
2770 Eq = llvm::ICmpInst::ICMP_EQ;
2772 Or = llvm::Instruction::Or;
2781 return Builder.CreateICmp(Eq, L, R);
2784 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
2785 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
2786 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
2790 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
2791 for (
unsigned I = 1,
E = LType->getNumElements(); I !=
E; ++
I) {
2792 llvm::Value *LF = Builder.CreateExtractValue(L, I);
2793 llvm::Value *RF = Builder.CreateExtractValue(R, I);
2794 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
2796 Res = Builder.CreateBinOp(And, Res, Cmp);
2804 llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
2805 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero,
"memptr.cmp.iszero");
2806 Res = Builder.CreateBinOp(Or, Res, IsZero);
2811 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
2822 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2824 GetNullMemberPointerFields(MPT, fields);
2825 assert(!fields.empty());
2827 if (MemPtr->getType()->isStructTy())
2828 FirstField = Builder.CreateExtractValue(MemPtr, 0);
2829 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
2837 for (
int I = 1,
E = fields.size(); I <
E; ++
I) {
2839 llvm::Value *
Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
2840 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
2846 llvm::Constant *Val) {
2849 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
2850 Val->getAggregateElement(0U) : Val;
2851 return FirstField->isNullValue();
2856 if (isZeroInitializable(MPT) && Val->isNullValue())
2862 GetNullMemberPointerFields(MPT, Fields);
2863 if (Fields.size() == 1) {
2864 assert(Val->getType()->isIntegerTy());
2865 return Val == Fields[0];
2869 for (I = 0, E = Fields.size(); I !=
E; ++
I) {
2870 if (Val->getAggregateElement(I) != Fields[
I])
2886 Builder.CreateInBoundsGEP(This.
getPointer(), VBPtrOffset,
"vbptr");
2887 if (VBPtrOut) *VBPtrOut = VBPtr;
2892 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
2903 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
2907 llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex);
2920 llvm::BasicBlock *OriginalBB =
nullptr;
2921 llvm::BasicBlock *SkipAdjustBB =
nullptr;
2922 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
2929 OriginalBB = Builder.GetInsertBlock();
2933 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
2935 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
2947 "member pointer representation requires a "
2948 "complete class type for %0 to perform this expression");
2951 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2956 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
2957 llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
2960 if (VBaseAdjustBB) {
2961 Builder.CreateBr(SkipAdjustBB);
2963 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
2964 Phi->addIncoming(Base.
getPointer(), OriginalBB);
2965 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
2968 return AdjustedBase;
2971 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
2985 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
2987 if (MemPtr->getType()->isStructTy()) {
2990 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
2991 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2992 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
2993 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2994 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
2998 if (VirtualBaseAdjustmentOffset) {
2999 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
3009 Addr = Builder.CreateInBoundsGEP(Addr, FieldOffset,
"memptr.offset");
3020 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3021 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3025 if (isa<llvm::Constant>(Src))
3026 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3036 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3037 if (IsReinterpret && IsFunc)
3042 if (IsReinterpret &&
3049 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3050 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3054 if (IsReinterpret) {
3057 assert(Src->getType() == DstNull->getType());
3058 return Builder.CreateSelect(IsNotNull, Src, DstNull);
3061 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3064 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3067 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3071 Builder.CreateBr(ContinueBB);
3075 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3076 Phi->addIncoming(DstNull, OriginalBB);
3077 Phi->addIncoming(Dst, ConvertBB);
3081 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3091 bool IsConstant = isa<llvm::Constant>(Src);
3095 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3096 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3098 if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
3101 FirstField = Builder.CreateExtractValue(Src, I++);
3102 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
3103 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3104 if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
3105 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3106 if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
3107 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3110 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3116 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3124 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3125 if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3126 if (int64_t SrcOffsetToFirstVBase =
3127 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3128 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3130 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3132 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3143 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3149 if (IsDerivedToBase)
3150 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3152 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3154 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3159 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) &&
3160 MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) {
3161 if (llvm::GlobalVariable *VDispMap =
3162 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3164 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3166 llvm::Constant *Mapping = VDispMap->getInitializer();
3167 VirtualBaseAdjustmentOffset =
3168 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3171 VirtualBaseAdjustmentOffset =
3177 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3183 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) {
3184 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3186 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3188 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3194 if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3195 if (int64_t DstOffsetToFirstVBase =
3196 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3197 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3199 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3201 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3207 if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) {
3210 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3212 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3213 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
3214 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3215 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
3216 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3217 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
3218 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3224 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3225 llvm::Constant *Src) {
3232 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3236 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3240 assert(CK == CK_DerivedToBaseMemberPointer ||
3241 CK == CK_BaseToDerivedMemberPointer ||
3242 CK == CK_ReinterpretMemberPointer);
3245 if (MemberPointerConstantIsNull(SrcTy, Src))
3246 return EmitNullMemberPointer(DstTy);
3251 if (CK == CK_ReinterpretMemberPointer)
3255 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3256 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3261 CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3273 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
3279 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3281 if (MemPtr->getType()->isStructTy()) {
3284 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3285 if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance))
3286 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3287 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3288 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3289 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3290 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3293 if (VirtualBaseAdjustmentOffset) {
3294 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3295 VirtualBaseAdjustmentOffset, VBPtrOffset);
3300 if (NonVirtualBaseAdjustment) {
3303 Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
3304 ThisPtrForCall = Builder.
CreateBitCast(Ptr, ThisPtrForCall->getType(),
3309 Builder.
CreateBitCast(FunctionPointer, FTy->getPointerTo());
3310 CGCallee Callee(FPT, FunctionPointer);
3315 return new MicrosoftCXXABI(CGM);
3349 StringRef MangledName(
"\01??_7type_info@@6B@");
3350 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3355 nullptr, MangledName);
3366 struct MSRTTIClass {
3368 IsPrivateOnPath = 1 | 8,
3372 HasHierarchyDescriptor = 64
3375 uint32_t initialize(
const MSRTTIClass *Parent,
3378 MSRTTIClass *getFirstChild() {
return this + 1; }
3379 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3380 return Child + 1 + Child->NumBases;
3384 uint32_t Flags, NumBases, OffsetInVBase;
3388 uint32_t MSRTTIClass::initialize(
const MSRTTIClass *Parent,
3390 Flags = HasHierarchyDescriptor;
3392 VirtualRoot =
nullptr;
3396 Flags |= IsPrivate | IsPrivateOnPath;
3402 if (Parent->Flags & IsPrivateOnPath)
3403 Flags |= IsPrivateOnPath;
3404 VirtualRoot = Parent->VirtualRoot;
3405 OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
3406 .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
3410 MSRTTIClass *Child = getFirstChild();
3412 NumBases += Child->initialize(
this, &Base) + 1;
3413 Child = getNextChild(Child);
3418 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3429 return llvm::GlobalValue::LinkOnceODRLinkage;
3431 llvm_unreachable(
"Invalid linkage!");
3437 struct MSRTTIBuilder {
3439 HasBranchingHierarchy = 1,
3440 HasVirtualBranchingHierarchy = 2,
3441 HasAmbiguousBases = 4
3444 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3445 : CGM(ABI.CGM), Context(CGM.getContext()),
3446 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3447 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3450 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3451 llvm::GlobalVariable *
3453 llvm::GlobalVariable *getClassHierarchyDescriptor();
3454 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3458 llvm::LLVMContext &VMContext;
3461 llvm::GlobalVariable::LinkageTypes
Linkage;
3462 MicrosoftCXXABI &ABI;
3471 Classes.push_back(MSRTTIClass(RD));
3479 llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3480 llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3481 llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3482 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3483 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3484 !VirtualBases.insert(Class->RD).second) {
3485 Class = MSRTTIClass::getNextChild(Class);
3488 if (!UniqueBases.insert(Class->RD).second)
3489 AmbiguousBases.insert(Class->RD);
3492 if (AmbiguousBases.empty())
3494 for (MSRTTIClass &Class : Classes)
3495 if (AmbiguousBases.count(Class.RD))
3496 Class.Flags |= MSRTTIClass::IsAmbiguous;
3499 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3502 llvm::raw_svector_ostream Out(MangledName);
3503 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3507 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3513 Classes.front().initialize(
nullptr,
nullptr);
3516 for (
auto Class : Classes) {
3518 Flags |= HasBranchingHierarchy;
3521 if (Class.Flags & MSRTTIClass::IsAmbiguous)
3522 Flags |= HasAmbiguousBases;
3524 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3525 Flags |= HasVirtualBranchingHierarchy;
3529 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3532 auto Type = ABI.getClassHierarchyDescriptorType();
3533 auto CHD =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3536 if (CHD->isWeakForLinker())
3537 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3539 auto *Bases = getBaseClassArray(Classes);
3542 llvm::Constant *Fields[] = {
3543 llvm::ConstantInt::get(CGM.
IntTy, 0),
3544 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3545 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3546 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3547 Bases->getValueType(), Bases,
3550 CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3554 llvm::GlobalVariable *
3558 llvm::raw_svector_ostream Out(MangledName);
3559 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3567 llvm::Type *PtrType = ABI.getImageRelativeType(
3568 ABI.getBaseClassDescriptorType()->getPointerTo());
3569 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3571 new llvm::GlobalVariable(
Module, ArrType,
3573 nullptr, MangledName);
3574 if (BCA->isWeakForLinker())
3575 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3579 for (MSRTTIClass &Class : Classes)
3580 BaseClassArrayData.push_back(
3581 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3582 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3583 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3587 llvm::GlobalVariable *
3588 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3591 uint32_t OffsetInVBTable = 0;
3592 int32_t VBPtrOffset = -1;
3593 if (Class.VirtualRoot) {
3595 OffsetInVBTable = VTableContext.
getVBTableIndex(RD, Class.VirtualRoot) * 4;
3596 VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
3601 llvm::raw_svector_ostream Out(MangledName);
3602 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3603 Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3608 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3612 auto Type = ABI.getBaseClassDescriptorType();
3614 new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3615 nullptr, MangledName);
3616 if (BCD->isWeakForLinker())
3617 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3620 llvm::Constant *Fields[] = {
3621 ABI.getImageRelativeConstant(
3622 ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))),
3623 llvm::ConstantInt::get(CGM.
IntTy, Class.NumBases),
3624 llvm::ConstantInt::get(CGM.
IntTy, Class.OffsetInVBase),
3625 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3626 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3627 llvm::ConstantInt::get(CGM.
IntTy, Class.Flags),
3628 ABI.getImageRelativeConstant(
3629 MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3631 BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3635 llvm::GlobalVariable *
3636 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3639 llvm::raw_svector_ostream Out(MangledName);
3640 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3644 if (
auto COL =
Module.getNamedGlobal(MangledName))
3649 int VFPtrOffset = 0;
3652 if (Context.getASTRecordLayout(RD)
3653 .getVBaseOffsetsMap()
3655 ->second.hasVtorDisp())
3659 llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3660 auto COL =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3661 nullptr, MangledName);
3664 llvm::Constant *Fields[] = {
3665 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3666 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3667 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3668 ABI.getImageRelativeConstant(
3670 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3671 ABI.getImageRelativeConstant(COL),
3674 if (!ABI.isImageRelative())
3675 FieldsRef = FieldsRef.drop_back();
3676 COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
3677 if (COL->isWeakForLinker())
3678 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3683 bool &IsConst,
bool &IsVolatile,
3684 bool &IsUnaligned) {
3694 IsUnaligned =
false;
3696 if (!PointeeType.
isNull()) {
3717 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3722 bool IsConst, IsVolatile, IsUnaligned;
3738 return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(),
3746 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3749 llvm::raw_svector_ostream Out(MangledName);
3750 getMangleContext().mangleCXXRTTI(Type, Out);
3754 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3755 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3763 llvm::raw_svector_ostream Out(TypeInfoString);
3764 getMangleContext().mangleCXXRTTIName(Type, Out);
3768 llvm::Constant *Fields[] = {
3770 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3771 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
3772 llvm::StructType *TypeDescriptorType =
3773 getTypeDescriptorType(TypeInfoString);
3774 auto *Var =
new llvm::GlobalVariable(
3775 CGM.
getModule(), TypeDescriptorType,
false,
3776 getLinkageForRTTI(Type),
3777 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
3779 if (Var->isWeakForLinker())
3780 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
3781 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
3785 llvm::GlobalVariable *
3786 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
3788 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
3807 if (ProducedAlias) {
3823 if (Fn->isWeakForLinker())
3824 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
3827 void MicrosoftCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3829 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
3843 llvm::raw_svector_ostream Out(ThunkName);
3844 getMangleContext().mangleCXXCtor(CD, CT, Out);
3847 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
3848 return cast<llvm::Function>(GV);
3854 QualType RecordTy = getContext().getRecordType(RD);
3856 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
3857 ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
3859 if (ThunkFn->isWeakForLinker())
3860 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
3871 buildThisParam(CGF, FunctionArgs);
3877 &getContext().Idents.get(
"src"),
3878 getContext().getLValueReferenceType(RecordTy,
3882 FunctionArgs.push_back(&SrcParam);
3889 &getContext().Idents.get(
"is_most_derived"),
3893 FunctionArgs.push_back(&IsMostDerived);
3921 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
3922 ArgVec.push_back(PD->getDefaultArg());
3928 CGF.
EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
3931 AddedStructorArgs ExtraArgs =
3936 llvm::Constant *CalleePtr =
3940 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
3943 Cleanups.ForceCleanup();
3952 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
3954 int32_t VBPtrOffset,
3966 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
3969 llvm::raw_svector_ostream Out(MangledName);
3970 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
3971 VBPtrOffset, VBIndex, Out);
3973 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3974 return getImageRelativeConstant(GV);
3978 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
3982 llvm::Constant *CopyCtor;
3989 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
3991 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3993 CopyCtor = getImageRelativeConstant(CopyCtor);
3995 bool IsScalar = !RD;
3996 bool HasVirtualBases =
false;
3997 bool IsStdBadAlloc =
false;
4002 HasVirtualBases = RD->getNumVBases() > 0;
4004 IsStdBadAlloc = II->isStr(
"bad_alloc") && RD->isInStdNamespace();
4012 if (HasVirtualBases)
4017 llvm::Constant *Fields[] = {
4018 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4020 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4021 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4022 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4023 llvm::ConstantInt::get(CGM.
IntTy, Size),
4026 llvm::StructType *CTType = getCatchableTypeType();
4027 auto *GV =
new llvm::GlobalVariable(
4028 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
4029 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4030 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4031 GV->setSection(
".xdata");
4032 if (GV->isWeakForLinker())
4033 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4034 return getImageRelativeConstant(GV);
4037 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4041 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4066 if (MostDerivedClass) {
4073 Classes.front().initialize(
nullptr,
nullptr);
4075 for (
const MSRTTIClass &Class : Classes) {
4078 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4081 uint32_t OffsetInVBTable = 0;
4082 int32_t VBPtrOffset = -1;
4083 if (Class.VirtualRoot) {
4094 CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
4095 VBPtrOffset, OffsetInVBTable));
4103 CatchableTypes.insert(getCatchableType(T));
4116 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4127 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4129 uint32_t NumEntries = CatchableTypes.size();
4131 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4132 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4133 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4134 llvm::Constant *Fields[] = {
4135 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4136 llvm::ConstantArray::get(
4137 AT, llvm::makeArrayRef(CatchableTypes.begin(),
4138 CatchableTypes.end()))
4142 llvm::raw_svector_ostream Out(MangledName);
4143 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4145 CTA =
new llvm::GlobalVariable(
4146 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4147 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4148 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4149 CTA->setSection(
".xdata");
4150 if (CTA->isWeakForLinker())
4151 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4155 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4156 bool IsConst, IsVolatile, IsUnaligned;
4161 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4166 uint32_t NumEntries =
4167 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
4168 ->getLimitedValue();
4172 llvm::raw_svector_ostream Out(MangledName);
4173 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4179 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4195 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4198 if (!DtorD->isTrivial())
4199 CleanupFn = llvm::ConstantExpr::getBitCast(
4203 llvm::Constant *ForwardCompat =
4204 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4205 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4206 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4207 llvm::StructType *TIType = getThrowInfoType();
4208 llvm::Constant *Fields[] = {
4209 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4210 getImageRelativeConstant(CleanupFn),
4212 PointerToCatchableTypes
4214 auto *GV =
new llvm::GlobalVariable(
4215 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4216 llvm::ConstantStruct::get(TIType, Fields), StringRef(MangledName));
4217 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4218 GV->setSection(
".xdata");
4219 if (GV->isWeakForLinker())
4220 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4235 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.
struct clang::ThisAdjustment::VirtualAdjustment::@119 Microsoft
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
void setSRetAfterThis(bool AfterThis)
External linkage, which indicates that the entity can be referred to from other translation units...
bool isNullPtrType() const
Parameter for captured context.
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.
Internal linkage according to the Modules TS, but can be referred to from other translation units ind...
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.
The standard implementation of ConstantInitBuilder used in Clang.
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...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
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.
const NestedNameSpecifier * Specifier
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)
ParmVarDecl - Represents a parameter to a function.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class...
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.
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
bool isReferenceType() const
llvm::Constant * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the constructor/destructor of the given type.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::IntegerType * SizeTy
StructorType getFromDtorType(CXXDtorType T)
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
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.
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.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
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...
const CXXRecordDecl * IntroducingObject
This is the class that introduced the vptr by declaring new virtual methods or virtual bases...
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)
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
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...
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 defaultedCopyConstructorIsDeleted() const
true if a defaulted copy constructor for this class would be deleted.
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
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...
const TargetInfo & getTarget() const
CastKind
CastKind - The kind of operation required for a conversion.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
Module linkage, which indicates that the entity can be referred to from other translation units withi...
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...
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
bool isMemberPointerToDerivedMember() const
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Represents a C++ destructor within a class.
static llvm::CallSite emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
DeclContext * getDeclContext()
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
unsigned Map[FirstTargetAddressSpace]
The type of a lookup table which maps from language-specific address spaces to target-specific ones...
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 COMDAT used for dtors.
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="")
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
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.
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...
ArrayRef< ParmVarDecl * > parameters() const
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
ArrayRef< VTableComponent > vtable_components() const
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti)
Add vtable components for the given vtable layout to the given global initializer.
const CXXRecordDecl * ObjectWithVPtr
This is the most derived class that has this vptr at offset zero.
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.
All available information about a concrete callee.
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.
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo &VFPtr, SmallString< 256 > &Name)
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.
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.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
detail::InMemoryDirectory::const_iterator E
A pointer to member type per C++ 8.3.3 - Pointers to members.
CharUnits NonVirtualOffset
IntroducingObject is at this offset from its containing complete object or virtual base...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
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.
void EmitThunks(GlobalDecl GD)
EmitThunks - Emit the associated thunks for the given global decl.
union clang::ThisAdjustment::VirtualAdjustment Virtual
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>'.
void AppendLinkerOptions(StringRef Opts)
Appends Opts to the "llvm.linker.options" metadata value.
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
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
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
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)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
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...
struct clang::ReturnAdjustment::VirtualAdjustment::@117 Microsoft
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Copying closure variant of a ctor.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
bool needsImplicitCopyConstructor() const
Determine whether this class needs an implicit copy constructor to be lazily declared.
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.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
CodeGenVTables & getVTables()
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
uint32_t VBIndex
Index of the virtual base in the vbtable.
SourceLocation getLocation() const
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.
BasePath PathToIntroducingObject
This holds the base classes path from the complete type to the first base with the given vfptr offset...
const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
Notes how many arguments were added to the beginning (Prefix) and ending (Suffix) of an arg list...
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...
CallArgList - Type for representing both the value and type of arguments in a call.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...
Address CreateMemTemp(QualType T, const Twine &Name="tmp", bool CastToDefaultAddrSpace=true)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)
Recursively serializes a class hierarchy in pre-order depth first order.
base_class_range vbases()
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
const MethodVFTableLocation & getMethodVFTableLocation(GlobalDecl GD)
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, 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.
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)
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.