27 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/ADT/StringSet.h"
29 #include "llvm/IR/CallSite.h"
30 #include "llvm/IR/Intrinsics.h"
32 using namespace clang;
33 using namespace CodeGen;
38 struct VBTableGlobals {
43 class MicrosoftCXXABI :
public CGCXXABI {
46 :
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
47 ClassHierarchyDescriptorType(nullptr),
48 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
49 ThrowInfoType(nullptr) {}
51 bool HasThisReturn(
GlobalDecl GD)
const override;
52 bool hasMostDerivedReturn(
GlobalDecl GD)
const override;
58 bool isSRetParameterAfterThis()
const override {
return true; }
60 bool isThisCompleteObject(
GlobalDecl GD)
const override {
63 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
72 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
74 llvm_unreachable(
"bad dtor kind");
83 assert(Args.size() >= 2 &&
84 "expected the arglist to have at least two args!");
93 std::vector<CharUnits> getVBPtrOffsets(
const CXXRecordDecl *RD)
override {
94 std::vector<CharUnits> VBPtrOffsets;
98 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
99 for (
const VPtrInfo *VBT : *VBGlobals.VBTables) {
106 VBPtrOffsets.push_back(Offs);
108 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
112 StringRef GetPureVirtualCallName()
override {
return "_purecall"; }
113 StringRef GetDeletedVirtualCallName()
override {
return "_purecall"; }
124 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
127 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
129 getAddrOfCXXCatchHandlerType(
QualType Ty,
QualType CatchHandlerType)
override;
136 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
142 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
148 llvm::BasicBlock *CastEnd)
override;
155 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override {
217 getThisArgumentTypeForMethod(
const CXXMethodDecl *MD)
override {
219 if (MD->
isVirtual() && !isa<CXXDestructorDecl>(MD)) {
221 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
237 bool VirtualCall)
override;
242 llvm::Value *adjustThisParameterInVirtualFunctionPrologue(
255 bool Delegating,
Address This)
override;
258 llvm::GlobalVariable *VTable);
268 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
269 return !VTableClass->
hasAttr<MSNoVTableAttr>();
284 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
300 "Only deleting destructor thunks are available in this ABI");
305 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
307 llvm::GlobalVariable *
309 llvm::GlobalVariable::LinkageTypes
Linkage);
311 llvm::GlobalVariable *
315 llvm::raw_svector_ostream Out(OutName);
316 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
317 StringRef MangledName = OutName.str();
319 if (
auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
325 llvm::UndefValue::get(CGM.IntTy));
326 Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
327 bool AnyDifferent =
false;
328 for (
const auto &
I : SrcRD->
vbases()) {
335 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
336 AnyDifferent |= SrcVBIndex != DstVBIndex;
342 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy,
Map.size());
343 llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy,
Map);
344 llvm::GlobalValue::LinkageTypes
Linkage =
346 ? llvm::GlobalValue::LinkOnceODRLinkage
348 auto *VDispMap =
new llvm::GlobalVariable(
349 CGM.getModule(), VDispMapTy,
true,
Linkage,
355 llvm::GlobalVariable *GV)
const;
357 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
360 Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
363 getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.
getDecl()));
367 else if (ReturnAdjustment)
368 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
370 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
377 const ReturnAdjustment &RA)
override;
379 void EmitThreadLocalInitFuncs(
384 bool usesThreadWrapperFunction()
const override {
return false; }
389 llvm::GlobalVariable *DeclPtr,
390 bool PerformInit)
override;
392 llvm::Constant *Dtor, llvm::Constant *Addr)
override;
430 friend struct MSRTTIBuilder;
432 bool isImageRelative()
const {
433 return CGM.getTarget().getPointerWidth(0) == 64;
437 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
439 TDTypeName += llvm::utostr(TypeInfoString.size());
440 llvm::StructType *&TypeDescriptorType =
441 TypeDescriptorTypeMap[TypeInfoString.size()];
442 if (TypeDescriptorType)
443 return TypeDescriptorType;
447 llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
450 return TypeDescriptorType;
454 if (!isImageRelative())
459 llvm::StructType *getBaseClassDescriptorType() {
460 if (BaseClassDescriptorType)
461 return BaseClassDescriptorType;
463 getImageRelativeType(CGM.Int8PtrTy),
469 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
472 CGM.getLLVMContext(), FieldTypes,
"rtti.BaseClassDescriptor");
473 return BaseClassDescriptorType;
476 llvm::StructType *getClassHierarchyDescriptorType() {
477 if (ClassHierarchyDescriptorType)
478 return ClassHierarchyDescriptorType;
481 CGM.getLLVMContext(),
"rtti.ClassHierarchyDescriptor");
486 getImageRelativeType(
487 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
489 ClassHierarchyDescriptorType->setBody(FieldTypes);
490 return ClassHierarchyDescriptorType;
493 llvm::StructType *getCompleteObjectLocatorType() {
494 if (CompleteObjectLocatorType)
495 return CompleteObjectLocatorType;
497 CGM.getLLVMContext(),
"rtti.CompleteObjectLocator");
502 getImageRelativeType(CGM.Int8PtrTy),
503 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
504 getImageRelativeType(CompleteObjectLocatorType),
507 if (!isImageRelative())
508 FieldTypesRef = FieldTypesRef.drop_back();
509 CompleteObjectLocatorType->setBody(FieldTypesRef);
510 return CompleteObjectLocatorType;
513 llvm::GlobalVariable *getImageBase() {
514 StringRef
Name =
"__ImageBase";
515 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
518 return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
524 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
525 if (!isImageRelative())
528 if (PtrVal->isNullValue())
529 return llvm::Constant::getNullValue(CGM.IntTy);
531 llvm::Constant *ImageBaseAsInt =
532 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
533 llvm::Constant *PtrValAsInt =
534 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
535 llvm::Constant *Diff =
536 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
538 return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
546 llvm::Constant *getZeroInt() {
547 return llvm::ConstantInt::get(CGM.IntTy, 0);
550 llvm::Constant *getAllOnesInt() {
551 return llvm::Constant::getAllOnesValue(CGM.IntTy);
572 int32_t VBTableOffset,
574 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
575 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
576 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
577 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
580 std::pair<Address, llvm::Value *>
593 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
594 bool IsMemberFunction,
597 unsigned VBTableIndex);
606 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
609 llvm::Function *EmitVirtualMemPtrThunk(
620 return RD->
hasAttr<MSInheritanceAttr>();
627 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
628 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
634 bool Inequality)
override;
655 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *
E,
656 llvm::Constant *Src)
override;
658 llvm::Constant *EmitMemberPointerConversion(
671 llvm::StructType *getCatchableTypeType() {
672 if (CatchableTypeType)
673 return CatchableTypeType;
676 getImageRelativeType(CGM.Int8PtrTy),
681 getImageRelativeType(CGM.Int8PtrTy)
684 CGM.getLLVMContext(), FieldTypes,
"eh.CatchableType");
685 return CatchableTypeType;
688 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
689 llvm::StructType *&CatchableTypeArrayType =
690 CatchableTypeArrayTypeMap[NumEntries];
691 if (CatchableTypeArrayType)
692 return CatchableTypeArrayType;
695 CTATypeName += llvm::utostr(NumEntries);
697 getImageRelativeType(getCatchableTypeType()->getPointerTo());
700 llvm::ArrayType::get(CTType, NumEntries)
702 CatchableTypeArrayType =
704 return CatchableTypeArrayType;
707 llvm::StructType *getThrowInfoType() {
709 return ThrowInfoType;
712 getImageRelativeType(CGM.Int8PtrTy),
713 getImageRelativeType(CGM.Int8PtrTy),
714 getImageRelativeType(CGM.Int8PtrTy)
718 return ThrowInfoType;
724 llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
725 llvm::FunctionType *FTy =
726 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
727 auto *Fn = cast<llvm::Function>(
728 CGM.CreateRuntimeFunction(FTy,
"_CxxThrowException"));
730 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86)
731 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
738 llvm::Constant *getCatchableType(
QualType T,
739 uint32_t NVOffset = 0,
740 int32_t VBPtrOffset = -1,
741 uint32_t VBIndex = 0);
743 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
745 llvm::GlobalVariable *getThrowInfo(
QualType T)
override;
748 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
749 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
750 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
752 VFTablesMapTy VFTablesMap;
753 VTablesMapTy VTablesMap;
756 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
760 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
765 GuardInfo() : Guard(nullptr), BitIndex(0) {}
766 llvm::GlobalVariable *Guard;
772 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
773 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
774 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
776 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
777 llvm::StructType *BaseClassDescriptorType;
778 llvm::StructType *ClassHierarchyDescriptorType;
779 llvm::StructType *CompleteObjectLocatorType;
781 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
783 llvm::StructType *CatchableTypeType;
784 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
785 llvm::StructType *ThrowInfoType;
792 switch (CGM.getTarget().getTriple().getArch()) {
797 case llvm::Triple::x86:
804 if (!canCopyArgument(RD))
805 return RAA_DirectInMemory;
811 case llvm::Triple::x86_64:
829 bool CopyDeleted =
false;
848 llvm_unreachable(
"invalid enum");
861 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
866 void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
868 llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
869 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
879 llvm::CatchPadInst *CPI;
881 CatchRetScope(llvm::CatchPadInst *CPI) : CPI(CPI) {}
885 CGF.
Builder.CreateCatchRet(CPI, BB);
896 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
897 llvm::CatchPadInst *CPI =
898 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
917 std::pair<Address, llvm::Value *>
928 return std::make_pair(Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0));
936 PolymorphicBase = BaseDecl;
940 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
943 GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase);
948 return std::make_pair(
Address(Ptr, VBaseAlign), Offset);
951 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
955 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
961 llvm::FunctionType *FTy =
962 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
969 llvm::CallSite Call =
971 Call.setDoesNotReturn();
972 CGF.
Builder.CreateUnreachable();
980 std::tie(ThisPtr, Offset) = performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
985 bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
989 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1003 std::tie(This, Offset) = performBaseAdjustment(CGF, This, SrcRecordTy);
1015 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1018 ThisPtr,
Offset, SrcRTTI, DestRTTI,
1029 std::tie(Value, Offset) = performBaseAdjustment(CGF, Value, SrcRecordTy);
1035 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1045 llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1049 int64_t VBPtrChars =
1051 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
1055 CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
1057 llvm::ConstantInt::get(CGM.IntTy, VBTableChars.
getQuantity());
1060 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1062 CGF.
Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
1063 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1066 bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1067 return isa<CXXConstructorDecl>(GD.
getDecl());
1071 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1075 bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1079 bool MicrosoftCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1091 }
else if (!RD->
isPOD()) {
1104 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1105 assert(IsMostDerivedClass &&
1106 "ctor for a class with virtual bases must have an implicit parameter");
1108 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1110 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1111 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1112 CGF.
Builder.CreateCondBr(IsCompleteObject,
1113 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1118 EmitVBPtrStores(CGF, RD);
1122 return SkipVbaseCtorsBB;
1125 void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1145 unsigned AS = getThisAddress(CGF).getAddressSpace();
1148 for (VBOffsets::const_iterator
I = VBaseMap.begin(),
E = VBaseMap.end();
1150 if (!
I->second.hasVtorDisp())
1154 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD,
I->first);
1157 VBaseOffset = Builder.CreateTruncOrBitCast(VBaseOffset, CGF.
Int32Ty);
1158 uint64_t ConstantVBaseOffset =
1163 VBaseOffset, llvm::ConstantInt::get(CGM.Int32Ty, ConstantVBaseOffset),
1168 CGF.
Int8Ty->getPointerTo(AS));
1169 llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset);
1171 VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4);
1173 VtorDispPtr, CGF.
Int32Ty->getPointerTo(AS),
"vtordisp.ptr");
1186 return ExpectedCallingConv == ActualCallingConv;
1200 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1201 Fn->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1207 Address This = getThisAddress(CGF);
1212 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1213 for (
unsigned I = 0,
E = VBGlobals.VBTables->size();
I !=
E; ++
I) {
1214 const VPtrInfo *VBT = (*VBGlobals.VBTables)[
I];
1215 llvm::GlobalVariable *GV = VBGlobals.Globals[
I];
1224 CGF.
Builder.CreateConstInBoundsGEP2_32(GV->getValueType(), GV, 0, 0);
1237 ArgTys.push_back(getContext().IntTy);
1250 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1252 ArgTys.push_back(getContext().IntTy);
1263 MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1280 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1287 if (isa<CXXDestructorDecl>(MD))
1292 getContext().getASTRecordLayout(MD->
getParent());
1299 Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1305 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1329 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1346 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1351 Result =
Address(VBasePtr, VBaseAlign);
1353 if (!StaticOffset.
isZero()) {
1374 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1384 if (FPT->isVariadic())
1385 Params.insert(Params.begin() + 1, IsMostDerived);
1387 Params.push_back(IsMostDerived);
1388 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1393 &Context.
Idents.
get(
"should_call_delete"),
1395 Params.push_back(ShouldDelete);
1396 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1400 llvm::Value *MicrosoftCXXABI::adjustThisParameterInVirtualFunctionPrologue(
1407 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1411 unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1413 *thisTy = This->getType();
1417 This = CGF.
Builder.CreateConstInBoundsGEP1_32(CGF.
Int8Ty, This,
1422 void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1433 if (HasThisReturn(CGF.
CurGD))
1435 else if (hasMostDerivedReturn(CGF.
CurGD))
1441 assert(getStructorImplicitParamDecl(CGF) &&
1442 "no implicit parameter for a constructor with virtual bases?");
1443 getStructorImplicitParamValue(CGF)
1450 assert(getStructorImplicitParamDecl(CGF) &&
1451 "no implicit parameter for a deleting destructor?");
1452 getStructorImplicitParamValue(CGF)
1455 "should_call_delete");
1459 unsigned MicrosoftCXXABI::addImplicitConstructorArgs(
1461 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1473 if (MostDerivedArg) {
1475 Args.insert(Args.begin() + 1,
1476 CallArg(RV, getContext().IntTy,
false));
1478 Args.
add(RV, getContext().IntTy);
1487 bool Delegating,
Address This) {
1492 "The deleting destructor should only be called via a virtual call");
1493 This = adjustThisArgumentForVirtualFunctionCall(CGF,
GlobalDecl(DD, Type),
1503 void MicrosoftCXXABI::emitVTableBitSetEntries(
VPtrInfo *Info,
1505 llvm::GlobalVariable *VTable) {
1506 if (!getContext().getLangOpts().Sanitize.has(SanitizerKind::CFIVCall) &&
1507 !getContext().getLangOpts().Sanitize.has(SanitizerKind::CFINVCall) &&
1508 !getContext().getLangOpts().Sanitize.has(SanitizerKind::CFIDerivedCast) &&
1509 !getContext().getLangOpts().Sanitize.has(SanitizerKind::CFIUnrelatedCast))
1512 llvm::NamedMDNode *BitsetsMD =
1513 CGM.getModule().getOrInsertNamedMetadata(
"llvm.bitsets");
1519 getContext().getLangOpts().RTTIData
1520 ? getContext().toCharUnitsFromBits(
1521 getContext().getTargetInfo().getPointerWidth(0))
1525 if (!CGM.IsCFIBlacklistedRecord(RD))
1526 CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
1532 CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint,
1542 getContext().getASTRecordLayout(DerivedRD);
1548 Offset = VBI->second.VBaseOffset;
1551 if (!CGM.IsCFIBlacklistedRecord(DerivedRD))
1552 CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, DerivedRD);
1557 CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
1560 void MicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables &CGVT,
1566 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1567 if (VTable->hasInitializer())
1570 llvm::Constant *RTTI = getContext().getLangOpts().RTTIData
1571 ? getMSCompleteObjectLocator(RD, Info)
1581 VTable->setInitializer(Init);
1583 emitVTableBitSetEntries(Info, RD, VTable);
1587 bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1592 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1595 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1596 if (!VTableAddressPoint) {
1598 !getContext().getASTRecordLayout(Base.
getBase()).hasOwnVFPtr());
1600 return VTableAddressPoint;
1606 llvm::raw_svector_ostream Out(Name);
1615 return VFTablesMap[
ID];
1618 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1620 llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass);
1621 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1625 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1631 VFTableIdTy
ID(RD, VPtrOffset);
1634 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(
ID,
nullptr));
1638 llvm::GlobalVariable *&VTable = I->second;
1643 if (DeferredVFTables.insert(RD).second) {
1646 CGM.addDeferredVTable(RD);
1651 llvm::StringSet<> ObservedMangledNames;
1652 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1655 if (!ObservedMangledNames.insert(Name.str()).second)
1656 llvm_unreachable(
"Already saw this mangling before?");
1662 std::find_if(VFPtrs.begin(), VFPtrs.end(), [&](
VPtrInfo *VPI) {
1663 return VPI->FullOffsetInMDC == VPtrOffset;
1665 if (VFPtrI == VFPtrs.end()) {
1666 VFTablesMap[
ID] =
nullptr;
1674 llvm::GlobalValue::LinkageTypes VFTableLinkage = CGM.getVTableLinkage(RD);
1675 bool VFTableComesFromAnotherTU =
1676 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1677 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1678 bool VTableAliasIsRequred =
1679 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1681 if (llvm::GlobalValue *VFTable =
1682 CGM.getModule().getNamedGlobal(VFTableName)) {
1683 VFTablesMap[
ID] = VFTable;
1684 VTable = VTableAliasIsRequred
1685 ? cast<llvm::GlobalVariable>(
1686 cast<llvm::GlobalAlias>(VFTable)->getBaseObject())
1687 : cast<llvm::GlobalVariable>(VFTable);
1691 uint64_t NumVTableSlots =
1694 llvm::GlobalValue::LinkageTypes VTableLinkage =
1695 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1697 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1699 llvm::ArrayType *VTableType =
1700 llvm::ArrayType::get(CGM.Int8PtrTy, NumVTableSlots);
1704 llvm::GlobalValue *VFTable;
1705 VTable =
new llvm::GlobalVariable(CGM.getModule(), VTableType,
1706 true, VTableLinkage,
1707 nullptr, VTableName);
1708 VTable->setUnnamedAddr(
true);
1710 llvm::Comdat *
C =
nullptr;
1711 if (!VFTableComesFromAnotherTU &&
1712 (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1713 (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1714 VTableAliasIsRequred)))
1715 C = CGM.getModule().getOrInsertComdat(VFTableName.str());
1720 if (VTableAliasIsRequred) {
1721 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
1722 llvm::ConstantInt::get(CGM.IntTy, 1)};
1725 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1726 VTable->getValueType(), VTable, GEPIndices);
1727 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1730 C->setSelectionKind(llvm::Comdat::Largest);
1734 VFTableName.str(), VTableGEP,
1736 VFTable->setUnnamedAddr(
true);
1745 VTable->setComdat(C);
1747 if (RD->
hasAttr<DLLImportAttr>())
1748 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1749 else if (RD->
hasAttr<DLLExportAttr>())
1750 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1752 VFTablesMap[
ID] = VFTable;
1767 for (
auto &&B : RD->
bases()) {
1768 const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
1770 if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) {
1772 MaxBaseOffset = BaseOffset;
1775 for (
auto &&B : RD->
vbases()) {
1776 const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
1778 if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) {
1780 MaxBaseOffset = BaseOffset;
1794 RD = cast<CXXMethodDecl>(GD.
getDecl())->getParent();
1807 Ty = Ty->getPointerTo()->getPointerTo();
1809 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1811 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1815 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1816 if (CGF.
SanOpts.
has(SanitizerKind::CFIVCall))
1821 Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1825 llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1834 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1841 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1845 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1848 ImplicitParam, Context.IntTy, CE,
1853 const VBTableGlobals &
1854 MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
1859 std::tie(Entry, Added) =
1860 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
1861 VBTableGlobals &VBGlobals = Entry->second;
1870 llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
1871 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
1872 E = VBGlobals.VBTables->end();
1874 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
1880 llvm::Function *MicrosoftCXXABI::EmitVirtualMemPtrThunk(
1883 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
1884 "can't form pointers to ctors or virtual dtors");
1888 llvm::raw_svector_ostream Out(ThunkName);
1889 getMangleContext().mangleVirtualMemPtrThunk(MD, Out);
1892 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
1893 return cast<llvm::Function>(GV);
1896 const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSMemberPointerThunk(MD);
1897 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
1898 llvm::Function *ThunkFn =
1900 ThunkName.str(), &CGM.getModule());
1901 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
1904 ? llvm::GlobalValue::LinkOnceODRLinkage
1907 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
1909 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
1910 CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
1916 ThunkFn->addFnAttr(
"thunk");
1919 ThunkFn->setUnnamedAddr(
false);
1929 buildThisParam(CGF, FunctionArgs);
1939 getThisAddress(CGF), ThunkTy->getPointerTo()->getPointerTo(), MD->
getParent());
1942 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1951 void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1952 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1953 for (
unsigned I = 0,
E = VBGlobals.VBTables->size(); I !=
E; ++
I) {
1954 const VPtrInfo *VBT = (*VBGlobals.VBTables)[I];
1955 llvm::GlobalVariable *GV = VBGlobals.Globals[
I];
1956 if (GV->isDeclaration())
1957 emitVBTableDefinition(*VBT, RD, GV);
1961 llvm::GlobalVariable *
1963 llvm::GlobalVariable::LinkageTypes Linkage) {
1965 llvm::raw_svector_ostream Out(OutName);
1966 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
1967 StringRef Name = OutName.str();
1969 llvm::ArrayType *VBTableType =
1972 assert(!CGM.getModule().getNamedGlobal(Name) &&
1973 "vbtable with this name already exists: mangling bug?");
1974 llvm::GlobalVariable *GV =
1975 CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, Linkage);
1976 GV->setUnnamedAddr(
true);
1978 if (RD->
hasAttr<DLLImportAttr>())
1979 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1980 else if (RD->
hasAttr<DLLExportAttr>())
1981 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1983 if (!GV->hasExternalLinkage())
1984 emitVBTableDefinition(VBT, RD, GV);
1989 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
1991 llvm::GlobalVariable *GV)
const {
1995 "should only emit vbtables for classes with vbtables");
1999 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2005 CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2006 Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
2009 for (
const auto &I : ReusingBase->
vbases()) {
2010 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2017 CompleteVBPtrOffset +=
2019 Offset -= CompleteVBPtrOffset;
2021 unsigned VBIndex = Context.getVBTableIndex(ReusingBase, VBase);
2022 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2023 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.
getQuantity());
2026 assert(Offsets.size() ==
2027 cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
2029 llvm::ArrayType *VBTableType =
2030 llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2031 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2032 GV->setInitializer(Init);
2055 CGF.
Builder.CreateNeg(VtorDisp));
2072 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2089 const ReturnAdjustment &RA) {
2104 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2121 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *expr) {
2148 assert(requiresArrayCookie(expr));
2151 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2167 llvm::Constant *Dtor,
2168 llvm::Constant *Addr) {
2173 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2174 CGF.
IntTy, DtorStub->getType(),
false);
2176 llvm::Constant *TLRegDtor =
2178 if (llvm::Function *TLRegDtorFn = dyn_cast<llvm::Function>(TLRegDtor))
2179 TLRegDtorFn->setDoesNotThrow();
2185 llvm::Constant *Dtor,
2186 llvm::Constant *Addr) {
2194 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2201 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2202 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2203 CGM.
getModule(), InitFunc->getType(),
true,
2205 Twine(InitFunc->getName(),
"$initializer$"));
2206 InitFuncPtr->setSection(
".CRT$XDU");
2213 std::vector<llvm::Function *> NonComdatInits;
2214 for (
size_t I = 0,
E = CXXThreadLocalInitVars.size(); I !=
E; ++
I) {
2215 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2217 llvm::Function *F = CXXThreadLocalInits[
I];
2220 if (llvm::Comdat *C = GV->getComdat())
2221 AddToXDU(F)->setComdat(C);
2223 NonComdatInits.push_back(F);
2226 if (!NonComdatInits.empty()) {
2227 llvm::FunctionType *FTy =
2228 llvm::FunctionType::get(CGM.
VoidTy,
false);
2246 StringRef VarName(
"_Init_thread_epoch");
2248 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2250 auto *GV =
new llvm::GlobalVariable(
2254 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2260 llvm::FunctionType *FTy =
2261 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2262 CGM.
IntTy->getPointerTo(),
false);
2264 FTy,
"_Init_thread_header",
2266 llvm::AttributeSet::FunctionIndex,
2267 llvm::Attribute::NoUnwind));
2271 llvm::FunctionType *FTy =
2272 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2273 CGM.
IntTy->getPointerTo(),
false);
2275 FTy,
"_Init_thread_footer",
2277 llvm::AttributeSet::FunctionIndex,
2278 llvm::Attribute::NoUnwind));
2282 llvm::FunctionType *FTy =
2283 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2284 CGM.
IntTy->getPointerTo(),
false);
2286 FTy,
"_Init_thread_abort",
2288 llvm::AttributeSet::FunctionIndex,
2289 llvm::Attribute::NoUnwind));
2296 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2297 : Guard(Guard), GuardNum(GuardNum) {}
2303 llvm::LoadInst *LI = Builder.
CreateLoad(Guard);
2304 llvm::ConstantInt *Mask =
2305 llvm::ConstantInt::get(CGF.
IntTy, ~(1U << GuardNum));
2306 Builder.
CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2312 CallInitThreadAbort(
Address Guard) : Guard(Guard.getPointer()) {}
2322 llvm::GlobalVariable *GV,
2326 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2328 llvm::Function *F = CGF.
CurFn;
2329 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2330 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2336 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2340 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2343 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2344 llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
2348 GuardInfo *GI =
nullptr;
2349 if (ThreadlocalStatic)
2351 else if (!ThreadsafeStatic)
2354 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2359 GuardNum = getContext().getStaticLocalNumber(&D);
2360 assert(GuardNum > 0);
2362 }
else if (HasPerVariableGuard) {
2366 GuardNum = GI->BitIndex++;
2369 if (!HasPerVariableGuard && GuardNum >= 32) {
2371 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2380 llvm::raw_svector_ostream Out(GuardName);
2381 if (HasPerVariableGuard)
2382 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2385 getMangleContext().mangleStaticGuardVariable(&D, Out);
2391 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2392 GV->getLinkage(), Zero, GuardName.str());
2393 GuardVar->setVisibility(GV->getVisibility());
2394 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2396 if (GuardVar->isWeakForLinker())
2397 GuardVar->setComdat(
2398 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2400 GuardVar->setThreadLocal(
true);
2401 if (GI && !HasPerVariableGuard)
2402 GI->Guard = GuardVar;
2407 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2408 "static local from the same function had different linkage");
2410 if (!HasPerVariableGuard) {
2418 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1U << GuardNum);
2419 llvm::LoadInst *LI = Builder.
CreateLoad(GuardAddr);
2421 Builder.CreateICmpNE(Builder.CreateAnd(LI, Bit), Zero);
2424 Builder.CreateCondBr(IsInitialized, EndBlock, InitBlock);
2429 Builder.
CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2433 Builder.CreateBr(EndBlock);
2451 llvm::LoadInst *FirstGuardLoad = Builder.
CreateLoad(GuardAddr);
2452 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2453 llvm::LoadInst *InitThreadEpoch =
2456 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2459 Builder.CreateCondBr(IsUninitialized, AttemptInitBlock, EndBlock);
2465 GuardAddr.getPointer());
2466 llvm::LoadInst *SecondGuardLoad = Builder.
CreateLoad(GuardAddr);
2467 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2469 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2471 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2479 GuardAddr.getPointer());
2480 Builder.CreateBr(EndBlock);
2497 return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) &&
2509 fields.push_back(CGM.
IntTy);
2513 fields.push_back(CGM.
IntTy);
2514 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2515 fields.push_back(CGM.
IntTy);
2516 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2517 fields.push_back(CGM.
IntTy);
2519 if (fields.size() == 1)
2524 void MicrosoftCXXABI::
2527 assert(fields.empty());
2532 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2534 if (RD->nullFieldOffsetIsZero())
2535 fields.push_back(getZeroInt());
2537 fields.push_back(getAllOnesInt());
2542 fields.push_back(getZeroInt());
2543 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2544 fields.push_back(getZeroInt());
2545 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2546 fields.push_back(getAllOnesInt());
2552 GetNullMemberPointerFields(MPT, fields);
2553 if (fields.size() == 1)
2555 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2556 assert(Res->getType() == ConvertMemberPointerType(MPT));
2561 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2562 bool IsMemberFunction,
2565 unsigned VBTableIndex) {
2570 if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance))
2574 fields.push_back(FirstField);
2576 if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance))
2577 fields.push_back(llvm::ConstantInt::get(
2580 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) {
2583 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2588 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2589 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2591 return llvm::ConstantStruct::getAnon(fields);
2599 MSInheritanceAttr::Keyword_virtual_inheritance)
2600 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2601 llvm::Constant *FirstField =
2603 return EmitFullMemberPointer(FirstField,
false, RD,
2607 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2612 return EmitNullMemberPointer(DstTy);
2618 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2619 C = EmitMemberFunctionPointer(MD);
2622 C = EmitMemberDataPointer(DstTy, FieldOffset);
2625 if (!MemberPointerPath.empty()) {
2626 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2630 ->castAs<MemberPointerType>();
2638 if (DerivedMember) {
2646 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2648 DerivedToBasePath.push_back(&BS);
2651 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2655 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2656 DerivedToBasePath.end(),
C);
2662 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2663 assert(MD->
isInstance() &&
"Member function must not be static!");
2670 unsigned VBTableIndex = 0;
2671 llvm::Constant *FirstField;
2673 if (!MD->isVirtual()) {
2688 VTableContext.getMethodVFTableLocation(MD);
2689 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2693 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2696 if (VBTableIndex == 0 &&
2698 MSInheritanceAttr::Keyword_virtual_inheritance)
2699 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2702 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2703 return EmitFullMemberPointer(FirstField,
true, RD,
2704 NonVirtualBaseAdjustment, VBTableIndex);
2719 llvm::ICmpInst::Predicate Eq;
2720 llvm::Instruction::BinaryOps
And, Or;
2722 Eq = llvm::ICmpInst::ICMP_NE;
2723 And = llvm::Instruction::Or;
2726 Eq = llvm::ICmpInst::ICMP_EQ;
2728 Or = llvm::Instruction::Or;
2737 return Builder.CreateICmp(Eq, L, R);
2740 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
2741 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
2742 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
2746 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
2747 for (
unsigned I = 1,
E = LType->getNumElements(); I !=
E; ++
I) {
2748 llvm::Value *LF = Builder.CreateExtractValue(L, I);
2749 llvm::Value *RF = Builder.CreateExtractValue(R, I);
2750 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
2752 Res = Builder.CreateBinOp(And, Res, Cmp);
2760 llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
2761 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero,
"memptr.cmp.iszero");
2762 Res = Builder.CreateBinOp(Or, Res, IsZero);
2767 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
2778 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2780 GetNullMemberPointerFields(MPT, fields);
2781 assert(!fields.empty());
2783 if (MemPtr->getType()->isStructTy())
2784 FirstField = Builder.CreateExtractValue(MemPtr, 0);
2785 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
2793 for (
int I = 1,
E = fields.size(); I <
E; ++
I) {
2794 llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
2795 llvm::Value *
Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
2796 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
2802 llvm::Constant *Val) {
2805 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
2806 Val->getAggregateElement(0U) : Val;
2807 return FirstField->isNullValue();
2812 if (isZeroInitializable(MPT) && Val->isNullValue())
2818 GetNullMemberPointerFields(MPT, Fields);
2819 if (Fields.size() == 1) {
2820 assert(Val->getType()->isIntegerTy());
2821 return Val == Fields[0];
2825 for (I = 0, E = Fields.size(); I !=
E; ++
I) {
2826 if (Val->getAggregateElement(I) != Fields[
I])
2842 Builder.CreateInBoundsGEP(This.
getPointer(), VBPtrOffset,
"vbptr");
2843 if (VBPtrOut) *VBPtrOut = VBPtr;
2848 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
2859 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
2863 llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex);
2876 llvm::BasicBlock *OriginalBB =
nullptr;
2877 llvm::BasicBlock *SkipAdjustBB =
nullptr;
2878 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
2885 OriginalBB = Builder.GetInsertBlock();
2889 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
2891 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
2903 "member pointer representation requires a "
2904 "complete class type for %0 to perform this expression");
2907 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2912 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
2913 llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
2916 if (VBaseAdjustBB) {
2917 Builder.CreateBr(SkipAdjustBB);
2919 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
2920 Phi->addIncoming(Base.
getPointer(), OriginalBB);
2921 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
2924 return AdjustedBase;
2927 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
2941 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
2943 if (MemPtr->getType()->isStructTy()) {
2946 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
2947 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2948 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
2949 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2950 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
2954 if (VirtualBaseAdjustmentOffset) {
2955 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
2965 Addr = Builder.CreateInBoundsGEP(Addr, FieldOffset,
"memptr.offset");
2981 if (isa<llvm::Constant>(Src))
2982 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
2993 if (IsReinterpret && IsFunc)
2998 if (IsReinterpret &&
3005 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3006 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3010 if (IsReinterpret) {
3013 assert(Src->getType() == DstNull->getType());
3014 return Builder.CreateSelect(IsNotNull, Src, DstNull);
3017 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3020 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3023 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3027 Builder.CreateBr(ContinueBB);
3031 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3032 Phi->addIncoming(DstNull, OriginalBB);
3033 Phi->addIncoming(Dst, ConvertBB);
3037 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3047 bool IsConstant = isa<llvm::Constant>(Src);
3051 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3052 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3054 if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
3057 FirstField = Builder.CreateExtractValue(Src, I++);
3058 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
3059 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3060 if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
3061 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3062 if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
3063 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3072 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3080 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3081 if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3082 if (int64_t SrcOffsetToFirstVBase =
3083 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3084 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3086 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3088 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3099 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3105 if (IsDerivedToBase)
3106 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3108 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3110 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3115 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) &&
3116 MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) {
3117 if (llvm::GlobalVariable *VDispMap =
3118 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3120 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3122 llvm::Constant *Mapping = VDispMap->getInitializer();
3123 VirtualBaseAdjustmentOffset =
3124 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3127 VirtualBaseAdjustmentOffset =
3133 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3139 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) {
3140 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3142 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3144 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3150 if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3151 if (int64_t DstOffsetToFirstVBase =
3152 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3153 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3155 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3157 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3163 if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) {
3166 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3168 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3169 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
3170 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3171 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
3172 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3173 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
3174 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3180 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3181 llvm::Constant *Src) {
3188 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3192 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3201 if (MemberPointerConstantIsNull(SrcTy, Src))
3202 return EmitNullMemberPointer(DstTy);
3211 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3212 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3217 llvm::Value *MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3229 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
3235 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3237 if (MemPtr->getType()->isStructTy()) {
3240 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3241 if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance))
3242 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3243 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3244 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3245 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3246 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3249 if (VirtualBaseAdjustmentOffset) {
3250 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3251 VirtualBaseAdjustmentOffset, VBPtrOffset);
3256 if (NonVirtualBaseAdjustment) {
3259 Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
3260 ThisPtrForCall = Builder.
CreateBitCast(Ptr, ThisPtrForCall->getType(),
3264 return Builder.
CreateBitCast(FunctionPointer, FTy->getPointerTo());
3268 return new MicrosoftCXXABI(CGM);
3302 StringRef MangledName(
"\01??_7type_info@@6B@");
3303 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3308 nullptr, MangledName);
3319 struct MSRTTIClass {
3321 IsPrivateOnPath = 1 | 8,
3325 HasHierarchyDescriptor = 64
3328 uint32_t initialize(
const MSRTTIClass *Parent,
3331 MSRTTIClass *getFirstChild() {
return this + 1; }
3332 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3333 return Child + 1 + Child->NumBases;
3337 uint32_t Flags, NumBases, OffsetInVBase;
3341 uint32_t MSRTTIClass::initialize(
const MSRTTIClass *Parent,
3343 Flags = HasHierarchyDescriptor;
3345 VirtualRoot =
nullptr;
3349 Flags |= IsPrivate | IsPrivateOnPath;
3355 if (Parent->Flags & IsPrivateOnPath)
3356 Flags |= IsPrivateOnPath;
3357 VirtualRoot = Parent->VirtualRoot;
3358 OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
3359 .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
3363 MSRTTIClass *Child = getFirstChild();
3365 NumBases += Child->initialize(
this, &Base) + 1;
3366 Child = getNextChild(Child);
3371 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3380 return llvm::GlobalValue::LinkOnceODRLinkage;
3382 llvm_unreachable(
"Invalid linkage!");
3388 struct MSRTTIBuilder {
3390 HasBranchingHierarchy = 1,
3391 HasVirtualBranchingHierarchy = 2,
3392 HasAmbiguousBases = 4
3395 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3396 : CGM(ABI.CGM), Context(CGM.getContext()),
3397 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3398 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3401 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3402 llvm::GlobalVariable *
3404 llvm::GlobalVariable *getClassHierarchyDescriptor();
3405 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo *Info);
3409 llvm::LLVMContext &VMContext;
3412 llvm::GlobalVariable::LinkageTypes
Linkage;
3413 MicrosoftCXXABI &ABI;
3422 Classes.push_back(MSRTTIClass(RD));
3430 llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3431 llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3432 llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3433 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3434 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3435 !VirtualBases.insert(Class->RD).second) {
3436 Class = MSRTTIClass::getNextChild(Class);
3439 if (!UniqueBases.insert(Class->RD).second)
3440 AmbiguousBases.insert(Class->RD);
3443 if (AmbiguousBases.empty())
3445 for (MSRTTIClass &Class : Classes)
3446 if (AmbiguousBases.count(Class.RD))
3447 Class.Flags |= MSRTTIClass::IsAmbiguous;
3450 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3453 llvm::raw_svector_ostream Out(MangledName);
3454 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3458 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3464 Classes.front().initialize(
nullptr,
nullptr);
3467 for (
auto Class : Classes) {
3469 Flags |= HasBranchingHierarchy;
3472 if (Class.Flags & MSRTTIClass::IsAmbiguous)
3473 Flags |= HasAmbiguousBases;
3475 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3476 Flags |= HasVirtualBranchingHierarchy;
3480 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3483 auto Type = ABI.getClassHierarchyDescriptorType();
3484 auto CHD =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3487 if (CHD->isWeakForLinker())
3488 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3490 auto *Bases = getBaseClassArray(Classes);
3493 llvm::Constant *Fields[] = {
3494 llvm::ConstantInt::get(CGM.
IntTy, 0),
3495 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3496 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3497 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3498 Bases->getValueType(), Bases,
3501 CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3505 llvm::GlobalVariable *
3509 llvm::raw_svector_ostream Out(MangledName);
3510 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3518 llvm::Type *PtrType = ABI.getImageRelativeType(
3519 ABI.getBaseClassDescriptorType()->getPointerTo());
3520 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3522 new llvm::GlobalVariable(
Module, ArrType,
3524 nullptr, MangledName);
3525 if (BCA->isWeakForLinker())
3526 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3530 for (MSRTTIClass &Class : Classes)
3531 BaseClassArrayData.push_back(
3532 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3533 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3534 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3538 llvm::GlobalVariable *
3539 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3542 uint32_t OffsetInVBTable = 0;
3543 int32_t VBPtrOffset = -1;
3544 if (Class.VirtualRoot) {
3546 OffsetInVBTable = VTableContext.
getVBTableIndex(RD, Class.VirtualRoot) * 4;
3547 VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
3552 llvm::raw_svector_ostream Out(MangledName);
3553 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3554 Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3559 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3563 auto Type = ABI.getBaseClassDescriptorType();
3565 new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3566 nullptr, MangledName);
3567 if (BCD->isWeakForLinker())
3568 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3571 llvm::Constant *Fields[] = {
3572 ABI.getImageRelativeConstant(
3573 ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))),
3574 llvm::ConstantInt::get(CGM.
IntTy, Class.NumBases),
3575 llvm::ConstantInt::get(CGM.
IntTy, Class.OffsetInVBase),
3576 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3577 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3578 llvm::ConstantInt::get(CGM.
IntTy, Class.Flags),
3579 ABI.getImageRelativeConstant(
3580 MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3582 BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3586 llvm::GlobalVariable *
3587 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo *Info) {
3590 llvm::raw_svector_ostream Out(MangledName);
3591 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info->
MangledPath, Out);
3595 if (
auto COL =
Module.getNamedGlobal(MangledName))
3600 int VFPtrOffset = 0;
3603 if (Context.getASTRecordLayout(RD)
3604 .getVBaseOffsetsMap()
3606 ->second.hasVtorDisp())
3610 llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3611 auto COL =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3612 nullptr, MangledName);
3615 llvm::Constant *Fields[] = {
3616 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3617 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3618 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3619 ABI.getImageRelativeConstant(
3621 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3622 ABI.getImageRelativeConstant(COL),
3625 if (!ABI.isImageRelative())
3626 FieldsRef = FieldsRef.drop_back();
3627 COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
3628 if (COL->isWeakForLinker())
3629 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3634 bool &IsConst,
bool &IsVolatile) {
3645 if (!PointeeType.
isNull()) {
3665 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3670 bool IsConst, IsVolatile;
3683 return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(),
3691 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3694 llvm::raw_svector_ostream Out(MangledName);
3695 getMangleContext().mangleCXXRTTI(Type, Out);
3699 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3700 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3705 llvm::raw_svector_ostream Out(TypeInfoString);
3706 getMangleContext().mangleCXXRTTIName(Type, Out);
3710 llvm::Constant *Fields[] = {
3712 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3713 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
3714 llvm::StructType *TypeDescriptorType =
3715 getTypeDescriptorType(TypeInfoString);
3716 auto *Var =
new llvm::GlobalVariable(
3717 CGM.
getModule(), TypeDescriptorType,
false,
3718 getLinkageForRTTI(Type),
3719 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
3721 if (Var->isWeakForLinker())
3722 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
3723 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
3727 llvm::GlobalVariable *
3728 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
3730 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
3749 if (ProducedAlias) {
3765 if (Fn->isWeakForLinker())
3766 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
3769 void MicrosoftCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3771 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
3785 llvm::raw_svector_ostream Out(ThunkName);
3786 getMangleContext().mangleCXXCtor(CD, CT, Out);
3789 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
3790 return cast<llvm::Function>(GV);
3796 QualType RecordTy = getContext().getRecordType(RD);
3798 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
3799 ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
3801 if (ThunkFn->isWeakForLinker())
3802 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
3813 buildThisParam(CGF, FunctionArgs);
3818 getContext(),
nullptr,
SourceLocation(), &getContext().Idents.get(
"src"),
3819 getContext().getLValueReferenceType(RecordTy,
3822 FunctionArgs.push_back(&SrcParam);
3828 &getContext().Idents.get(
"is_most_derived"),
3829 getContext().IntTy);
3832 FunctionArgs.push_back(&IsMostDerived);
3854 std::vector<Stmt *> ArgVec;
3855 for (
unsigned I = IsCopy ? 1 : 0, E = CD->
getNumParams(); I !=
E; ++
I) {
3856 Stmt *DefaultArg = getContext().getDefaultArgExprForConstructor(CD, I);
3857 assert(DefaultArg &&
"sema forgot to instantiate default args");
3858 ArgVec.push_back(DefaultArg);
3864 CGF.
EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
3867 unsigned ExtraArgs = addImplicitConstructorArgs(CGF, CD,
Ctor_Complete,
3877 Cleanups.ForceCleanup();
3886 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
3888 int32_t VBPtrOffset,
3900 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
3903 llvm::raw_svector_ostream Out(MangledName);
3904 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
3905 VBPtrOffset, VBIndex, Out);
3907 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3908 return getImageRelativeConstant(GV);
3912 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
3916 llvm::Constant *CopyCtor;
3923 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
3925 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3927 CopyCtor = getImageRelativeConstant(CopyCtor);
3929 bool IsScalar = !RD;
3930 bool HasVirtualBases =
false;
3931 bool IsStdBadAlloc =
false;
3936 HasVirtualBases = RD->getNumVBases() > 0;
3938 IsStdBadAlloc = II->isStr(
"bad_alloc") && RD->isInStdNamespace();
3946 if (HasVirtualBases)
3951 llvm::Constant *Fields[] = {
3952 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3954 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
3955 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3956 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
3957 llvm::ConstantInt::get(CGM.
IntTy, Size),
3960 llvm::StructType *CTType = getCatchableTypeType();
3961 auto *GV =
new llvm::GlobalVariable(
3962 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
3963 llvm::ConstantStruct::get(CTType, Fields), MangledName);
3964 GV->setUnnamedAddr(
true);
3965 GV->setSection(
".xdata");
3966 if (GV->isWeakForLinker())
3967 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
3968 return getImageRelativeConstant(GV);
3971 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
3975 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4000 if (MostDerivedClass) {
4007 Classes.front().initialize(
nullptr,
nullptr);
4009 for (
const MSRTTIClass &Class : Classes) {
4012 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4015 uint32_t OffsetInVBTable = 0;
4016 int32_t VBPtrOffset = -1;
4017 if (Class.VirtualRoot) {
4028 CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
4029 VBPtrOffset, OffsetInVBTable));
4037 CatchableTypes.insert(getCatchableType(T));
4050 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4061 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4063 uint32_t NumEntries = CatchableTypes.size();
4065 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4066 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4067 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4068 llvm::Constant *Fields[] = {
4069 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4070 llvm::ConstantArray::get(
4071 AT, llvm::makeArrayRef(CatchableTypes.begin(),
4072 CatchableTypes.end()))
4076 llvm::raw_svector_ostream Out(MangledName);
4077 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4079 CTA =
new llvm::GlobalVariable(
4080 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4081 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4082 CTA->setUnnamedAddr(
true);
4083 CTA->setSection(
".xdata");
4084 if (CTA->isWeakForLinker())
4085 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4089 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4090 bool IsConst, IsVolatile;
4095 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4100 uint32_t NumEntries =
4101 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
4102 ->getLimitedValue();
4106 llvm::raw_svector_ostream Out(MangledName);
4107 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, NumEntries,
4113 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4127 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4130 if (!DtorD->isTrivial())
4131 CleanupFn = llvm::ConstantExpr::getBitCast(
4135 llvm::Constant *ForwardCompat =
4136 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4137 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4138 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4139 llvm::StructType *TIType = getThrowInfoType();
4140 llvm::Constant *Fields[] = {
4141 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4142 getImageRelativeConstant(CleanupFn),
4144 PointerToCatchableTypes
4146 auto *GV =
new llvm::GlobalVariable(
4147 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4148 llvm::ConstantStruct::get(TIType, Fields), StringRef(MangledName));
4149 GV->setUnnamedAddr(
true);
4150 GV->setSection(
".xdata");
4151 if (GV->isWeakForLinker())
4152 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4167 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.
CastKind getCastKind() const
llvm::IntegerType * IntTy
int
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, Address Guard=Address::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
void setSRetAfterThis(bool AfterThis)
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, const FunctionDecl *CalleeDecl=nullptr, unsigned ParamsToSkip=0)
EmitCallArgs - Emit call arguments for a function.
External linkage, which indicates that the entity can be referred to from other translation units...
bool isNullPtrType() const
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
A (possibly-)qualified type.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
static llvm::Constant * getInitThreadFooterFn(CodeGenModule &CGM)
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
CanQualType getReturnType() const
uint32_t VBPtrOffset
The offset (in bytes) of the vbptr, relative to the beginning of the derived class.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
llvm::Module & getModule() const
llvm::LLVMContext & getLLVMContext()
static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)
Find ambiguity among base classes.
MSInheritanceAttr::Spelling getMSInheritanceModel() const
Returns the inheritance model used for this record.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
bool isGlobalDelete() const
No linkage, which means that the entity is unique and can only be referred to from within its scope...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
const CGFunctionInfo & arrangeCXXMethodType(const CXXRecordDecl *RD, const FunctionProtoType *FTP, const CXXMethodDecl *MD)
Arrange the argument and result information for a call to an unknown C++ non-static member function o...
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
vtable_component_iterator vtable_component_begin() const
bool hasDefinition() const
QualType getPointeeType() const
The base class of the type hierarchy.
CK_BaseToDerivedMemberPointer - Member pointer in base class to member pointer in derived class...
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i...
BasePath MangledPath
The bases from the inheritance path that got used to mangle the vbtable name.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
Default closure variant of a ctor.
const CXXBaseSpecifier *const * path_const_iterator
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
TLSKind getTLSKind() const
struct clang::ThisAdjustment::VirtualAdjustment::@114 Microsoft
static llvm::Constant * getInitThreadHeaderFn(CodeGenModule &CGM)
A this pointer adjustment.
QualType getThisType(ASTContext &C) const
Returns the type of the this pointer.
struct clang::ReturnAdjustment::VirtualAdjustment::@112 Microsoft
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
A C++ throw-expression (C++ [except.throw]).
static llvm::Constant * getInitThreadAbortFn(CodeGenModule &CGM)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo *VFPtr, SmallString< 256 > &Name)
GlobalDecl getCanonicalDecl() const
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
One of these records is kept for each identifier that is lexed.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
const CXXRecordDecl * getVBaseWithVPtr() const
The vptr is stored inside the non-virtual component of this virtual base.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CharUnits getIntSize() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const CXXRecordDecl * NearestVBase
BasePath PathToBaseWithVPtr
This holds the base classes path from the complete type to the first base with the given vfptr offset...
bool hasNonTrivialCopyConstructor() const
Determine whether this class has a non-trivial copy constructor (C++ [class.copy]p6, C++11 [class.copy]p12)
bool isReferenceType() const
static const CXXRecordDecl * getClassAtVTableLocation(ASTContext &Ctx, const CXXRecordDecl *RD, CharUnits Offset)
uint64_t getNumVTableComponents() const
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.
void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for RD using llvm...
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, CGCalleeInfo CalleeInfo=CGCalleeInfo(), llvm::Instruction **callOrInvoke=nullptr)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
llvm::Function * codegenCXXStructor(const CXXMethodDecl *MD, StructorType Type)
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const Decl * getDecl() const
Describes a module or submodule.
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
const ValueDecl * getMemberPointerDecl() const
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
path_iterator path_begin()
llvm::PointerType * VoidPtrTy
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
Concrete class used by the front-end to report problems and issues.
static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM)
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy)
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
Arrange the argument and result information for a declaration or definition of the given C++ non-stat...
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
detail::InMemoryDirectory::const_iterator I
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
FunctionDecl * getOperatorDelete() const
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to...
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
Represents a prototype with parameter type info, e.g.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
CastKind
CastKind - The kind of operation required for a conversion.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
static void emitCXXConstructor(CodeGenModule &CGM, const CXXConstructorDecl *ctor, StructorType ctorType)
ID
Defines the set of possible language-specific address spaces.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
CXXDtorType
C++ destructor types.
llvm::Value * getPointer() const
bool isDeleted() const
Whether this function has been deleted.
const Type * getTypeForDecl() const
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
CXXDtorType getDtorType() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
const CGFunctionInfo & arrangeNullaryFunction()
getNullaryFunctionInfo - Get the function info for a void() function with standard CC...
bool isMemberPointerToDerivedMember() const
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
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
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)
Creates clause with a list of variables VL and a linear step Step.
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
The result type of a method or function.
The COMDAT used for dtors.
const CXXRecordDecl * ReusingBase
The vtable will hold all of the virtual bases or virtual methods of ReusingBase.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
GlobalDecl - represents a global declaration.
bool isObjectType() const
Determine whether this type is an object type.
The l-value was considered opaque, so the alignment was determined from a type.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
uint64_t getNumVTableThunks() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs=llvm::AttributeSet())
Create a new runtime function with the specified type and name.
Encodes a location in the source.
CharUnits getPointerAlign() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
unsigned getNumParams() const
getNumParams - Return the number of parameters this function must have based on its FunctionType...
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
const TemplateArgument * iterator
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Represents a call to a member function that may be written either with member call syntax (e...
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...
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.
CK_ReinterpretMemberPointer - Reinterpret a member pointer as a different kind of member pointer...
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...
SanitizerSet SanOpts
Sanitizers enabled for this function.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
const CXXRecordDecl * BaseWithVPtr
The vptr is stored inside this subobject.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
const T * castAs() const
Member-template castAs<specific type>.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
MangleContext & getMangleContext()
Gets the mangle context.
llvm::Instruction * CurrentFuncletPad
unsigned getAddressSpace() const
Return the address space that this address resides in.
CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)
Creates a Microsoft-family ABI.
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is virtually derived from the class Base.
llvm::Constant * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, bool IsForDefinition=false)
Return the address of the constructor/destructor of the given type.
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
static const Type * getElementType(const Expr *BaseExpr)
Address getObjectAddress(CodeGenFunction &CGF) const
Returns the address of the object within this declaration.
External linkage within a unique namespace.
static bool isDeletingDtor(GlobalDecl GD)
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
bool isZero() const
isZero - Test whether the quantity equals zero.
Address CreateMemTemp(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignment...
const VPtrInfoVector & enumerateVBTables(const CXXRecordDecl *RD)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
bool isInstanceMethod() const
bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target, bool InEveryTU)
Try to emit a definition as a global alias for another definition.
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
QualType getExceptionObjectType(QualType T) const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
detail::InMemoryDirectory::const_iterator E
A pointer to member type per C++ 8.3.3 - Pointers to members.
CharUnits NonVirtualOffset
BaseWithVPtr is at this offset from its containing complete object or virtual base.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
unsigned Map[Count]
The type of a lookup table which maps from language-specific address spaces to target-specific ones...
void EmitThunks(GlobalDecl GD)
EmitThunks - Emit the associated thunks for the given global decl.
union clang::ThisAdjustment::VirtualAdjustment Virtual
vtable_thunk_iterator vtable_thunk_begin() const
void EmitAutoVarCleanups(const AutoVarEmission &emission)
llvm::PointerType * getType() const
Return the type of the pointer value.
const T * getAs() const
Member-template getAs<specific type>'.
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
CharUnits getIntAlign() const
Implements C++ ABI-specific code generation functions.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
llvm::PointerType * Int8PtrTy
SourceLocation getLocStart() const LLVM_READONLY
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
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.
RValue EmitCXXStructorCall(const CXXMethodDecl *MD, llvm::Value *Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E, StructorType Type)
Linkage getLinkage() const
Determine the linkage of this type.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
llvm::IntegerType * PtrDiffTy
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
DiagnosticsEngine & getDiags() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Represents a C++ struct/union/class.
BoundNodesTreeBuilder *const Builder
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false)
CXXCatchStmt - This represents a C++ catch block.
llvm::Type * ConvertType(QualType T)
static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor, StructorType dtorType)
A specialization of Address that requires the address to be an LLVM Constant.
CallingConv getDefaultCallingConvention(bool isVariadic, bool IsCXXMethod) const
Retrieves the default calling convention for the current target.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
No linkage according to the standard, but is visible from other translation units because of types de...
llvm::Constant * CreateVTableInitializer(const CXXRecordDecl *RD, const VTableComponent *Components, unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks, unsigned NumVTableThunks, llvm::Constant *RTTI)
CreateVTableInitializer - Create a vtable initializer for the given record decl.
Copying closure variant of a ctor.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CharUnits FullOffsetInMDC
Static offset from the top of the most derived class to this vfptr, including any virtual base offset...
uint64_t Index
Method's index in the vftable.
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
Struct with all informations about dynamic [sub]class needed to set vptr.
VarDecl * getExceptionDecl() const
static RValue get(llvm::Value *V)
GVALinkage
A more specific kind of linkage than enum Linkage.
CK_DerivedToBaseMemberPointer - Member pointer in derived class to member pointer in base class...
Holds information about the inheritance path to a virtual base or function table pointer.
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
CodeGenVTables & getVTables()
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
uint32_t VBIndex
Index of the virtual base in the vbtable.
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.
const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
bool isConstQualified() const
Determine whether this type is const-qualified.
RecordArgABI
Specify how one should pass an argument of a record type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, bool IsForDefinition=false)
Return the address of the given function.
CallArgList - Type for representing both the value and type of arguments in a call.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)
Recursively serializes a class hierarchy in pre-order depth first order.
base_class_range vbases()
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile)
void EmitMustTailThunk(const CXXMethodDecl *MD, llvm::Value *AdjustedThisPtr, llvm::Value *Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
static llvm::Constant * getThrowFn(CodeGenModule &CGM)
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraArgs)
Arrange a call to a C++ method, passing the given arguments.
bool isPointerType() const
bool isPOD() const
Whether this class is a POD-type (C++ [class]p4)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.