30#include "llvm/ADT/StringExtras.h"
31#include "llvm/ADT/StringSet.h"
32#include "llvm/IR/Intrinsics.h"
35using namespace CodeGen;
40struct VBTableGlobals {
45class MicrosoftCXXABI :
public CGCXXABI {
48 :
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
49 ClassHierarchyDescriptorType(nullptr),
50 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
51 ThrowInfoType(nullptr) {
54 "visibility export mapping option unimplemented in this ABI");
69 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
78 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
80 llvm_unreachable(
"bad dtor kind");
89 assert(Args.size() >= 2 &&
90 "expected the arglist to have at least two args!");
100 std::vector<CharUnits> VBPtrOffsets;
104 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
105 for (
const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
110 if (VBT->getVBaseWithVPtr())
112 VBPtrOffsets.push_back(Offs);
114 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
130 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
151 llvm::Type *StdTypeInfoPtrTy)
override;
163 llvm::BasicBlock *CastSuccess,
164 llvm::BasicBlock *CastFail)
override {
165 llvm_unreachable(
"unsupported");
171 llvm::BasicBlock *CastEnd)
override;
230 AddedStructorArgCounts
244 llvm::GlobalValue::LinkageTypes
251 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
253 if (MD->isVirtual()) {
255 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
259 return MD->getParent();
277 return MD->getParent();
283 bool VirtualCall)
override;
308 llvm::GlobalVariable *VTable);
314 CodeGenFunction::VPtr Vptr)
override;
319 return !VTableClass->
hasAttr<MSNoVTableAttr>();
344 DeleteOrMemberCallExpr E)
override;
349 "Only deleting destructor thunks are available in this ABI");
356 llvm::GlobalVariable *
358 llvm::GlobalVariable::LinkageTypes
Linkage);
360 llvm::GlobalVariable *
364 llvm::raw_svector_ostream Out(OutName);
366 StringRef MangledName = OutName.str();
368 if (
auto *VDispMap = CGM.
getModule().getNamedGlobal(MangledName))
374 llvm::UndefValue::get(CGM.
IntTy));
375 Map[0] = llvm::ConstantInt::get(CGM.
IntTy, 0);
376 bool AnyDifferent =
false;
377 for (
const auto &I : SrcRD->
vbases()) {
378 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
384 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.
IntTy, DstVBIndex * 4);
385 AnyDifferent |= SrcVBIndex != DstVBIndex;
391 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.
IntTy, Map.size());
392 llvm::Constant *
Init = llvm::ConstantArray::get(VDispMapTy, Map);
393 llvm::GlobalValue::LinkageTypes
Linkage =
395 ? llvm::GlobalValue::LinkOnceODRLinkage
396 : llvm::GlobalValue::InternalLinkage;
397 auto *VDispMap =
new llvm::GlobalVariable(
404 llvm::GlobalVariable *GV)
const;
412 Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
414 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
416 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
441 llvm::GlobalVariable *DeclPtr,
442 bool PerformInit)
override;
444 llvm::FunctionCallee Dtor,
445 llvm::Constant *Addr)
override;
476 llvm::Value *NumElements,
483 friend struct MSRTTIBuilder;
485 bool isImageRelative()
const {
490 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
492 TDTypeName += llvm::utostr(TypeInfoString.size());
493 llvm::StructType *&TypeDescriptorType =
494 TypeDescriptorTypeMap[TypeInfoString.size()];
495 if (TypeDescriptorType)
496 return TypeDescriptorType;
497 llvm::Type *FieldTypes[] = {
500 llvm::ArrayType::get(CGM.
Int8Ty, TypeInfoString.size() + 1)};
502 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, TDTypeName);
503 return TypeDescriptorType;
506 llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
507 if (!isImageRelative())
512 llvm::StructType *getBaseClassDescriptorType() {
513 if (BaseClassDescriptorType)
514 return BaseClassDescriptorType;
515 llvm::Type *FieldTypes[] = {
522 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
524 BaseClassDescriptorType = llvm::StructType::create(
526 return BaseClassDescriptorType;
529 llvm::StructType *getClassHierarchyDescriptorType() {
530 if (ClassHierarchyDescriptorType)
531 return ClassHierarchyDescriptorType;
533 ClassHierarchyDescriptorType = llvm::StructType::create(
535 llvm::Type *FieldTypes[] = {
539 getImageRelativeType(
540 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
542 ClassHierarchyDescriptorType->setBody(FieldTypes);
543 return ClassHierarchyDescriptorType;
546 llvm::StructType *getCompleteObjectLocatorType() {
547 if (CompleteObjectLocatorType)
548 return CompleteObjectLocatorType;
549 CompleteObjectLocatorType = llvm::StructType::create(
551 llvm::Type *FieldTypes[] = {
556 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
557 getImageRelativeType(CompleteObjectLocatorType),
560 if (!isImageRelative())
561 FieldTypesRef = FieldTypesRef.drop_back();
562 CompleteObjectLocatorType->setBody(FieldTypesRef);
563 return CompleteObjectLocatorType;
566 llvm::GlobalVariable *getImageBase() {
567 StringRef Name =
"__ImageBase";
568 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name))
573 llvm::GlobalValue::ExternalLinkage,
579 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
580 if (!isImageRelative())
583 if (PtrVal->isNullValue())
584 return llvm::Constant::getNullValue(CGM.
IntTy);
586 llvm::Constant *ImageBaseAsInt =
587 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.
IntPtrTy);
588 llvm::Constant *PtrValAsInt =
589 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.
IntPtrTy);
590 llvm::Constant *Diff =
591 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
593 return llvm::ConstantExpr::getTrunc(Diff, CGM.
IntTy);
601 llvm::Constant *getZeroInt() {
602 return llvm::ConstantInt::get(CGM.
IntTy, 0);
605 llvm::Constant *getAllOnesInt() {
606 return llvm::Constant::getAllOnesValue(CGM.
IntTy);
620 llvm::Value *VBPtrOffset,
621 llvm::Value *VBTableOffset,
622 llvm::Value **VBPtr =
nullptr);
627 int32_t VBTableOffset,
628 llvm::Value **VBPtr =
nullptr) {
629 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
630 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
631 *VBTOffset = llvm::ConstantInt::get(CGM.
IntTy, VBTableOffset);
632 return GetVBaseOffsetFromVBPtr(CGF,
Base, VBPOffset, VBTOffset, VBPtr);
635 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
643 llvm::Value *VirtualBaseAdjustmentOffset,
644 llvm::Value *VBPtrOffset );
648 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
649 bool IsMemberFunction,
652 unsigned VBTableIndex);
661 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
664 llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
677 return RD->
hasAttr<MSInheritanceAttr>();
691 bool Inequality)
override;
702 llvm::Value *EmitNonNullMemberPointerConversion(
710 llvm::Value *Src)
override;
713 llvm::Constant *Src)
override;
722 Address This, llvm::Value *&ThisPtrForCall,
728 llvm::StructType *getCatchableTypeType() {
729 if (CatchableTypeType)
730 return CatchableTypeType;
731 llvm::Type *FieldTypes[] = {
740 CatchableTypeType = llvm::StructType::create(
742 return CatchableTypeType;
745 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
746 llvm::StructType *&CatchableTypeArrayType =
747 CatchableTypeArrayTypeMap[NumEntries];
748 if (CatchableTypeArrayType)
749 return CatchableTypeArrayType;
752 CTATypeName += llvm::utostr(NumEntries);
754 getImageRelativeType(getCatchableTypeType()->getPointerTo());
755 llvm::Type *FieldTypes[] = {
757 llvm::ArrayType::get(CTType, NumEntries)
759 CatchableTypeArrayType =
760 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, CTATypeName);
761 return CatchableTypeArrayType;
764 llvm::StructType *getThrowInfoType() {
766 return ThrowInfoType;
767 llvm::Type *FieldTypes[] = {
773 ThrowInfoType = llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes,
775 return ThrowInfoType;
781 llvm::Type *Args[] = {CGM.
Int8PtrTy, getThrowInfoType()->getPointerTo()};
782 llvm::FunctionType *FTy =
783 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
784 llvm::FunctionCallee Throw =
788 if (
auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
789 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
797 llvm::Constant *getCatchableType(
QualType T,
798 uint32_t NVOffset = 0,
799 int32_t VBPtrOffset = -1,
800 uint32_t VBIndex = 0);
802 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
806 std::pair<llvm::Value *, const CXXRecordDecl *>
814 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
815 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
816 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
818 VFTablesMapTy VFTablesMap;
819 VTablesMapTy VTablesMap;
826 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
831 GuardInfo() =
default;
832 llvm::GlobalVariable *Guard =
nullptr;
833 unsigned BitIndex = 0;
838 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
839 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
840 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
842 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
843 llvm::StructType *BaseClassDescriptorType;
844 llvm::StructType *ClassHierarchyDescriptorType;
845 llvm::StructType *CompleteObjectLocatorType;
847 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
849 llvm::StructType *CatchableTypeType;
850 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
851 llvm::StructType *ThrowInfoType;
857MicrosoftCXXABI::getRecordArgABI(
const CXXRecordDecl *RD)
const {
869 case llvm::Triple::thumb:
875 case llvm::Triple::x86: {
886 return RAA_DirectInMemory;
889 case llvm::Triple::x86_64:
890 case llvm::Triple::aarch64:
894 llvm_unreachable(
"invalid enum");
906 llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
911void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
912 llvm::Value *Args[] = {
913 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
914 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
926 VarDecl *CatchParam = S->getExceptionDecl();
927 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
928 llvm::CatchPadInst *CPI =
929 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
940 CPI->setArgOperand(2, var.getObjectAddress(CGF).getPointer());
948std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
959 return std::make_tuple(
Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
968 PolymorphicBase = BaseDecl;
972 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
974 llvm::Value *Offset =
975 GetVirtualBaseClassOffset(CGF,
Value, SrcDecl, PolymorphicBase);
976 llvm::Value *Ptr = CGF.
Builder.CreateInBoundsGEP(
977 Value.getElementType(),
Value.getPointer(), Offset);
980 return std::make_tuple(
Address(Ptr, CGF.
Int8Ty, VBaseAlign), Offset,
984bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
988 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
992 llvm::Value *Argument) {
993 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
994 llvm::FunctionType *FTy =
995 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
996 llvm::Value *Args[] = {Argument};
1002 llvm::CallBase *
Call =
1004 Call->setDoesNotReturn();
1005 CGF.
Builder.CreateUnreachable();
1011 llvm::Type *StdTypeInfoPtrTy) {
1012 std::tie(ThisPtr, std::ignore, std::ignore) =
1013 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
1015 return CGF.
Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
1018bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1022 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1025llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
1027 QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1028 llvm::Value *SrcRTTI =
1030 llvm::Value *DestRTTI =
1033 llvm::Value *Offset;
1034 std::tie(This, Offset, std::ignore) =
1035 performBaseAdjustment(CGF, This, SrcRecordTy);
1036 llvm::Value *ThisPtr =
This.getPointer();
1048 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1050 llvm::Value *Args[] = {
1051 ThisPtr, Offset, SrcRTTI, DestRTTI,
1056llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(
CodeGenFunction &CGF,
1059 std::tie(
Value, std::ignore, std::ignore) =
1060 performBaseAdjustment(CGF,
Value, SrcRecordTy);
1064 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1066 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1068 llvm::Value *Args[] = {
Value.getPointer()};
1076llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1082 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.
PtrDiffTy, VBPtrChars);
1087 llvm::Value *VBTableOffset =
1090 llvm::Value *VBPtrToNewBase =
1091 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1094 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1097bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1098 return isa<CXXConstructorDecl>(GD.
getDecl());
1102 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1106bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1116 uint64_t NumElts = 0;
1119 isa<VectorType>(
Base)) {
1139 if (Ctor->isUserProvided())
1146bool MicrosoftCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1157 if (isIndirectReturn) {
1178 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1179 assert(IsMostDerivedClass &&
1180 "ctor for a class with virtual bases must have an implicit parameter");
1181 llvm::Value *IsCompleteObject =
1182 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1184 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1185 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1186 CGF.
Builder.CreateCondBr(IsCompleteObject,
1187 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1192 EmitVBPtrStores(CGF, RD);
1196 return SkipVbaseCtorsBB;
1201 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1202 assert(IsMostDerivedClass &&
1203 "ctor for a class with virtual bases must have an implicit parameter");
1204 llvm::Value *IsCompleteObject =
1205 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1207 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1208 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1209 CGF.
Builder.CreateCondBr(IsCompleteObject,
1210 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1215 return SkipVbaseDtorsBB;
1218void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1238 llvm::Value *Int8This =
nullptr;
1241 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1242 auto I = VBaseMap.find(VBase);
1243 assert(I != VBaseMap.end());
1244 if (!I->second.hasVtorDisp())
1247 llvm::Value *VBaseOffset =
1248 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1249 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1252 llvm::Value *VtorDispValue = Builder.CreateSub(
1253 VBaseOffset, llvm::ConstantInt::get(CGM.
PtrDiffTy, ConstantVBaseOffset),
1255 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1258 Int8This = getThisValue(CGF);
1260 llvm::Value *VtorDispPtr =
1261 Builder.CreateInBoundsGEP(CGF.
Int8Ty, Int8This, VBaseOffset);
1263 VtorDispPtr = Builder.CreateConstGEP1_32(CGF.
Int8Ty, VtorDispPtr, -4);
1265 Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1276 return ExpectedCallingConv == ActualCallingConv;
1291 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1304 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1305 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1306 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1307 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1312 if (VBT->getVBaseWithVPtr())
1315 llvm::Value *GVPtr =
1323MicrosoftCXXABI::buildStructorSignature(
GlobalDecl GD,
1325 AddedStructorArgCounts Added;
1327 if (isa<CXXDestructorDecl>(GD.
getDecl()) &&
1330 ArgTys.push_back(getContext().IntTy);
1333 auto *CD = dyn_cast<CXXConstructorDecl>(GD.
getDecl());
1342 if (
Class->getNumVBases()) {
1344 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1347 ArgTys.push_back(getContext().IntTy);
1355void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1361 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1368llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1373 return llvm::GlobalValue::InternalLinkage;
1384 if (Dtor->
hasAttr<DLLExportAttr>())
1385 return llvm::GlobalValue::WeakODRLinkage;
1386 if (Dtor->
hasAttr<DLLImportAttr>())
1387 return llvm::GlobalValue::AvailableExternallyLinkage;
1388 return llvm::GlobalValue::LinkOnceODRLinkage;
1393 return llvm::GlobalValue::LinkOnceODRLinkage;
1395 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1397 llvm_unreachable(
"invalid dtor type");
1414MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1436 if (isa<CXXDestructorDecl>(MD))
1441 getContext().getASTRecordLayout(MD->
getParent());
1448Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1454 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1489 Result = Result.withElementType(CGF.
Int8Ty);
1493 llvm::Value *VBaseOffset =
1494 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1495 llvm::Value *VBasePtr = CGF.
Builder.CreateInBoundsGEP(
1496 Result.getElementType(), Result.getPointer(), VBaseOffset);
1501 if (!StaticOffset.
isZero()) {
1503 Result = Result.withElementType(CGF.
Int8Ty);
1522 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1527 ImplicitParamKind::Other);
1532 Params.insert(Params.begin() + 1, IsMostDerived);
1534 Params.push_back(IsMostDerived);
1535 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1540 ImplicitParamKind::Other);
1541 Params.push_back(ShouldDelete);
1542 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1546void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1563 llvm::Value *
This = loadIncomingCXXThis(CGF);
1566 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1567 if (!Adjustment.
isZero()) {
1573 setCXXABIThisValue(CGF, This);
1583 if (HasThisReturn(CGF.
CurGD) || hasMostDerivedReturn(CGF.
CurGD))
1587 assert(getStructorImplicitParamDecl(CGF) &&
1588 "no implicit parameter for a constructor with virtual bases?");
1589 getStructorImplicitParamValue(CGF)
1596 assert(getStructorImplicitParamDecl(CGF) &&
1597 "no implicit parameter for a deleting destructor?");
1598 getStructorImplicitParamValue(CGF)
1601 "should_call_delete");
1612 return AddedStructorArgs{};
1616 llvm::Value *MostDerivedArg;
1618 MostDerivedArg = getStructorImplicitParamValue(CGF);
1623 return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1625 return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1628llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
1649 assert(
Type != CXXDtorType::Dtor_Deleting &&
1650 "The deleting destructor should only be called via a virtual call");
1655 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1656 if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1657 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1666 if (BaseDtorEndBB) {
1668 CGF.
Builder.CreateBr(BaseDtorEndBB);
1673void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1675 llvm::GlobalVariable *VTable) {
1687 llvm::GlobalObject::VCallVisibility TypeVis =
1689 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1690 VTable->setVCallVisibilityMetadata(TypeVis);
1697 getContext().getLangOpts().RTTIData
1698 ? getContext().toCharUnitsFromBits(
1699 getContext().getTargetInfo().getPointerWidth(LangAS::Default))
1718 getContext().getASTRecordLayout(DerivedRD);
1724 Offset = VBI->second.VBaseOffset;
1725 if (!Offset.isZero())
1740 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1741 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1742 if (VTable->hasInitializer())
1748 llvm::Constant *RTTI =
nullptr;
1751 RTTI = getMSCompleteObjectLocator(RD, *Info);
1754 auto components = builder.beginStruct();
1756 VTable->hasLocalLinkage());
1757 components.finishAndSetAsInitializer(VTable);
1759 emitVTableTypeMetadata(*Info, RD, VTable);
1763bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1765 return Vptr.NearestVBase !=
nullptr;
1768llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1771 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(
Base, VTableClass);
1772 if (!VTableAddressPoint) {
1773 assert(
Base.getBase()->getNumVBases() &&
1774 !getContext().getASTRecordLayout(
Base.getBase()).hasOwnVFPtr());
1776 return VTableAddressPoint;
1782 llvm::raw_svector_ostream Out(Name);
1789 (void)getAddrOfVTable(VTableClass,
Base.getBaseOffset());
1790 VFTableIdTy
ID(VTableClass,
Base.getBaseOffset());
1791 return VFTablesMap[
ID];
1794llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1796 llvm::Constant *VFTable = getVTableAddressPoint(
Base, VTableClass);
1797 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1801llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1807 VFTableIdTy
ID(RD, VPtrOffset);
1808 VTablesMapTy::iterator I;
1810 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID,
nullptr));
1814 llvm::GlobalVariable *&VTable = I->second;
1819 if (DeferredVFTables.insert(RD).second) {
1827 llvm::StringSet<> ObservedMangledNames;
1828 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1831 if (!ObservedMangledNames.insert(Name.str()).second)
1832 llvm_unreachable(
"Already saw this mangling before?");
1837 const std::unique_ptr<VPtrInfo> *VFPtrI =
1838 llvm::find_if(VFPtrs, [&](
const std::unique_ptr<VPtrInfo> &VPI) {
1839 return VPI->FullOffsetInMDC == VPtrOffset;
1841 if (VFPtrI == VFPtrs.end()) {
1842 VFTablesMap[
ID] =
nullptr;
1845 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1857 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1858 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1860 bool VFTableComesFromAnotherTU =
1861 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1862 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1863 bool VTableAliasIsRequred =
1864 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1866 if (llvm::GlobalValue *VFTable =
1867 CGM.
getModule().getNamedGlobal(VFTableName)) {
1868 VFTablesMap[
ID] = VFTable;
1869 VTable = VTableAliasIsRequred
1870 ? cast<llvm::GlobalVariable>(
1871 cast<llvm::GlobalAlias>(VFTable)->getAliaseeObject())
1872 :
cast<
llvm::GlobalVariable>(VFTable);
1878 llvm::GlobalValue::LinkageTypes VTableLinkage =
1879 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1881 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1887 llvm::GlobalValue *VFTable;
1888 VTable =
new llvm::GlobalVariable(CGM.
getModule(), VTableType,
1889 true, VTableLinkage,
1890 nullptr, VTableName);
1891 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1893 llvm::Comdat *
C =
nullptr;
1894 if (!VFTableComesFromAnotherTU &&
1895 llvm::GlobalValue::isWeakForLinker(VFTableLinkage))
1896 C = CGM.
getModule().getOrInsertComdat(VFTableName.str());
1901 if (VTableAliasIsRequred) {
1902 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1903 llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1904 llvm::ConstantInt::get(CGM.
Int32Ty, 1)};
1907 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1908 VTable->getValueType(), VTable, GEPIndices);
1909 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1910 VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1912 C->setSelectionKind(llvm::Comdat::Largest);
1914 VFTable = llvm::GlobalAlias::create(CGM.
Int8PtrTy,
1916 VFTableName.str(), VTableGEP,
1918 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1927 VTable->setComdat(
C);
1929 if (RD->
hasAttr<DLLExportAttr>())
1930 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1932 VFTablesMap[
ID] = VFTable;
1943 Ty = Ty->getPointerTo();
1945 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1947 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1948 llvm::Value *VTable = CGF.
GetVTablePtr(VPtr, Ty->getPointerTo(),
1949 MethodDecl->getParent());
1956 auto getObjectWithVPtr = [&] {
1959 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1960 return Info->FullOffsetInMDC == ML.VFPtrOffset;
1969 getObjectWithVPtr(), VTable, Ty,
1977 llvm::Value *VFuncPtr =
1978 Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.
Index,
"vfn");
1979 VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.
getPointerAlign());
1986llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1988 Address This, DeleteOrMemberCallExpr E) {
1991 assert((CE !=
nullptr) ^ (D !=
nullptr));
1992 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
2004 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
2010 ThisTy = CE->getObjectType();
2012 ThisTy = D->getDestroyedType();
2015 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
2017 ImplicitParam, Context.
IntTy, CE);
2021const VBTableGlobals &
2022MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
2025 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
2027 std::tie(Entry, Added) =
2028 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
2029 VBTableGlobals &VBGlobals = Entry->second;
2034 VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2039 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2040 E = VBGlobals.VBTables->end();
2042 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,
Linkage));
2049MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2051 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
2052 "can't form pointers to ctors or virtual dtors");
2056 llvm::raw_svector_ostream Out(ThunkName);
2057 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2060 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
2061 return cast<llvm::Function>(GV);
2067 llvm::Function *ThunkFn =
2068 llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
2070 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2073 ? llvm::GlobalValue::LinkOnceODRLinkage
2074 : llvm::GlobalValue::InternalLinkage);
2076 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
2085 ThunkFn->addFnAttr(
"thunk");
2088 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
2098 buildThisParam(CGF, FunctionArgs);
2105 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2109 llvm::Type *ThunkPtrTy = ThunkTy->getPointerTo();
2111 getThisAddress(CGF), ThunkPtrTy->getPointerTo(), MD->
getParent());
2113 llvm::Value *VFuncPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2114 ThunkPtrTy, VTable, ML.
Index,
"vfn");
2123void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2124 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2125 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2126 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2127 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2128 if (GV->isDeclaration())
2129 emitVBTableDefinition(*VBT, RD, GV);
2133llvm::GlobalVariable *
2135 llvm::GlobalVariable::LinkageTypes
Linkage) {
2137 llvm::raw_svector_ostream Out(OutName);
2138 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2139 StringRef Name = OutName.str();
2141 llvm::ArrayType *VBTableType =
2144 assert(!CGM.
getModule().getNamedGlobal(Name) &&
2145 "vbtable with this name already exists: mangling bug?");
2150 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2152 if (RD->
hasAttr<DLLImportAttr>())
2153 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2154 else if (RD->
hasAttr<DLLExportAttr>())
2155 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2157 if (!GV->hasExternalLinkage())
2158 emitVBTableDefinition(VBT, RD, GV);
2163void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2165 llvm::GlobalVariable *GV)
const {
2169 "should only emit vbtables for classes with vbtables");
2173 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2180 Offsets[0] = llvm::ConstantInt::get(CGM.
IntTy, -VBPtrOffset.
getQuantity());
2183 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2184 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2186 assert(!Offset.isNegative());
2191 CompleteVBPtrOffset +=
2193 Offset -= CompleteVBPtrOffset;
2195 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2196 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2197 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.
IntTy, Offset.getQuantity());
2200 assert(Offsets.size() ==
2201 cast<llvm::ArrayType>(GV->getValueType())->getNumElements());
2202 llvm::ArrayType *VBTableType =
2203 llvm::ArrayType::get(CGM.
IntTy, Offsets.size());
2204 llvm::Constant *
Init = llvm::ConstantArray::get(VBTableType, Offsets);
2205 GV->setInitializer(
Init);
2207 if (RD->
hasAttr<DLLImportAttr>())
2208 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2211llvm::Value *MicrosoftCXXABI::performThisAdjustment(
CodeGenFunction &CGF,
2215 return This.getPointer();
2221 V =
This.getPointer();
2231 CGF.
Builder.CreateNeg(VtorDisp));
2244 llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2248 V = CGF.
Builder.CreateInBoundsGEP(CGF.
Int8Ty, VBPtr, VBaseOffset);
2267 return Ret.getPointer();
2271 llvm::Value *
V =
Ret.getPointer();
2276 llvm::Value *VBaseOffset =
2279 V = CGF.
Builder.CreateInBoundsGEP(CGF.
Int8Ty, VBPtr, VBaseOffset);
2295bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *
expr) {
2298 return expr->getAllocatedType().isDestructedType();
2309llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(
CodeGenFunction &CGF,
2318 llvm::Value *numElements,
2321 assert(requiresArrayCookie(
expr));
2324 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2339 llvm::FunctionCallee Dtor,
2340 llvm::Constant *Addr) {
2345 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2346 CGF.
IntTy, DtorStub->getType(),
false);
2349 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2350 if (llvm::Function *TLRegDtorFn =
2351 dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2352 TLRegDtorFn->setDoesNotThrow();
2358 llvm::FunctionCallee Dtor,
2359 llvm::Constant *Addr) {
2374void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2378 if (CXXThreadLocalInits.empty())
2383 ?
"/include:___dyn_tls_init@12"
2384 :
"/include:__dyn_tls_init");
2389 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2390 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2391 CGM.
getModule(), InitFunc->getType(),
true,
2392 llvm::GlobalVariable::InternalLinkage, InitFunc,
2393 Twine(InitFunc->getName(),
"$initializer$"));
2394 InitFuncPtr->setSection(
".CRT$XDU");
2401 std::vector<llvm::Function *> NonComdatInits;
2402 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2403 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2405 llvm::Function *F = CXXThreadLocalInits[I];
2408 if (llvm::Comdat *
C = GV->getComdat())
2409 AddToXDU(F)->setComdat(
C);
2411 NonComdatInits.push_back(F);
2414 if (!NonComdatInits.empty()) {
2415 llvm::FunctionType *FTy =
2416 llvm::FunctionType::get(CGM.
VoidTy,
false);
2432 llvm::Constant *TlsGuardConstant =
2434 llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant);
2436 TlsGuard->setThreadLocal(
true);
2444 llvm::FunctionType *FTy =
2445 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()), {},
2448 FTy,
"__dyn_tls_on_demand_init",
2450 llvm::AttributeList::FunctionIndex,
2451 llvm::Attribute::NoUnwind),
2456 llvm::BasicBlock *DynInitBB,
2457 llvm::BasicBlock *ContinueBB) {
2458 llvm::LoadInst *TlsGuardValue =
2460 llvm::Value *CmpResult =
2462 CGF.
Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2466 llvm::GlobalValue *TlsGuard,
2467 llvm::BasicBlock *ContinueBB) {
2469 llvm::Function *InitializerFunction =
2471 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(InitializerFunction);
2472 CallVal->setCallingConv(InitializerFunction->getCallingConv());
2474 CGF.
Builder.CreateBr(ContinueBB);
2478 llvm::BasicBlock *DynInitBB =
2480 llvm::BasicBlock *ContinueBB =
2486 CGF.
Builder.SetInsertPoint(DynInitBB);
2488 CGF.
Builder.SetInsertPoint(ContinueBB);
2507 Address Addr(
V, RealVarTy, Alignment);
2511 AlignmentSource::Decl)
2517 StringRef VarName(
"_Init_thread_epoch");
2519 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2521 auto *GV =
new llvm::GlobalVariable(
2523 false, llvm::GlobalVariable::ExternalLinkage,
2525 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2531 llvm::FunctionType *FTy =
2532 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2533 CGM.
IntTy->getPointerTo(),
false);
2535 FTy,
"_Init_thread_header",
2537 llvm::AttributeList::FunctionIndex,
2538 llvm::Attribute::NoUnwind),
2543 llvm::FunctionType *FTy =
2544 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2545 CGM.
IntTy->getPointerTo(),
false);
2547 FTy,
"_Init_thread_footer",
2549 llvm::AttributeList::FunctionIndex,
2550 llvm::Attribute::NoUnwind),
2555 llvm::FunctionType *FTy =
2556 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2557 CGM.
IntTy->getPointerTo(),
false);
2559 FTy,
"_Init_thread_abort",
2561 llvm::AttributeList::FunctionIndex,
2562 llvm::Attribute::NoUnwind),
2570 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2571 : Guard(Guard), GuardNum(GuardNum) {}
2577 llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2578 llvm::ConstantInt *Mask =
2579 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2580 Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2586 CallInitThreadAbort(
Address Guard) : Guard(Guard.getPointer()) {}
2596 llvm::GlobalVariable *GV,
2600 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2602 llvm::Function *F = CGF.
CurFn;
2603 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2604 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2610 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2614 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2617 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2618 llvm::ConstantInt *
Zero = llvm::ConstantInt::get(GuardTy, 0);
2622 GuardInfo *GI =
nullptr;
2623 if (ThreadlocalStatic)
2625 else if (!ThreadsafeStatic)
2628 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2633 GuardNum = getContext().getStaticLocalNumber(&D);
2634 assert(GuardNum > 0);
2636 }
else if (HasPerVariableGuard) {
2640 GuardNum = GI->BitIndex++;
2643 if (!HasPerVariableGuard && GuardNum >= 32) {
2645 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2654 llvm::raw_svector_ostream Out(GuardName);
2655 if (HasPerVariableGuard)
2656 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2659 getMangleContext().mangleStaticGuardVariable(&D, Out);
2665 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2666 GV->getLinkage(), Zero, GuardName.str());
2667 GuardVar->setVisibility(GV->getVisibility());
2668 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2669 GuardVar->setAlignment(GuardAlign.
getAsAlign());
2670 if (GuardVar->isWeakForLinker())
2671 GuardVar->setComdat(
2672 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2675 if (GI && !HasPerVariableGuard)
2676 GI->Guard = GuardVar;
2681 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2682 "static local from the same function had different linkage");
2684 if (!HasPerVariableGuard) {
2692 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2693 llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2694 llvm::Value *NeedsInit =
2695 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
2699 CodeGenFunction::GuardKind::VariableGuard, &D);
2704 Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2708 Builder.CreateBr(EndBlock);
2726 llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2727 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2728 llvm::LoadInst *InitThreadEpoch =
2730 llvm::Value *IsUninitialized =
2731 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2735 CodeGenFunction::GuardKind::VariableGuard, &D);
2741 GuardAddr.getPointer());
2742 llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2743 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2744 llvm::Value *ShouldDoInit =
2745 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2747 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2755 GuardAddr.getPointer());
2756 Builder.CreateBr(EndBlock);
2785 fields.push_back(CGM.
IntTy);
2789 fields.push_back(CGM.
IntTy);
2791 fields.push_back(CGM.
IntTy);
2793 fields.push_back(CGM.
IntTy);
2795 if (fields.size() == 1)
2800void MicrosoftCXXABI::
2803 assert(fields.empty());
2808 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2811 fields.push_back(getZeroInt());
2813 fields.push_back(getAllOnesInt());
2818 fields.push_back(getZeroInt());
2820 fields.push_back(getZeroInt());
2822 fields.push_back(getAllOnesInt());
2828 GetNullMemberPointerFields(MPT, fields);
2829 if (fields.size() == 1)
2831 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2832 assert(Res->getType() == ConvertMemberPointerType(MPT));
2837MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2838 bool IsMemberFunction,
2841 unsigned VBTableIndex) {
2850 fields.push_back(FirstField);
2853 fields.push_back(llvm::ConstantInt::get(
2859 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2865 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2867 return llvm::ConstantStruct::getAnon(fields);
2876llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl *RD,
2879 MSInheritanceModel::Virtual)
2880 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2881 llvm::Constant *FirstField =
2883 return EmitFullMemberPointer(FirstField,
false, RD,
2887llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2892 return EmitNullMemberPointer(DstTy);
2898 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2899 C = EmitMemberFunctionPointer(MD);
2906 const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2908 FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
2911 C = EmitMemberDataPointer(RD, FieldOffset);
2914 if (!MemberPointerPath.empty()) {
2915 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2927 if (DerivedMember) {
2935 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2936 Base->getCanonicalDecl())
2937 DerivedToBasePath.push_back(&BS);
2940 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2942 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2943 : CK_BaseToDerivedMemberPointer;
2944 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2945 DerivedToBasePath.end(),
C);
2951MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2952 assert(MD->
isInstance() &&
"Member function must not be static!");
2958 unsigned VBTableIndex = 0;
2959 llvm::Constant *FirstField;
2964 if (Types.isFuncTypeConvertible(FPT)) {
2966 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
2976 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2980 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2983 if (VBTableIndex == 0 &&
2985 MSInheritanceModel::Virtual)
2986 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2989 return EmitFullMemberPointer(FirstField,
true, RD,
2990 NonVirtualBaseAdjustment, VBTableIndex);
3005 llvm::ICmpInst::Predicate
Eq;
3006 llvm::Instruction::BinaryOps
And, Or;
3008 Eq = llvm::ICmpInst::ICMP_NE;
3009 And = llvm::Instruction::Or;
3010 Or = llvm::Instruction::And;
3012 Eq = llvm::ICmpInst::ICMP_EQ;
3013 And = llvm::Instruction::And;
3014 Or = llvm::Instruction::Or;
3023 return Builder.CreateICmp(
Eq, L, R);
3026 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
3027 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
3028 llvm::Value *Cmp0 = Builder.CreateICmp(
Eq, L0, R0,
"memptr.cmp.first");
3031 llvm::Value *Res =
nullptr;
3032 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
3033 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3034 llvm::Value *LF = Builder.CreateExtractValue(L, I);
3035 llvm::Value *RF = Builder.CreateExtractValue(R, I);
3036 llvm::Value *Cmp = Builder.CreateICmp(
Eq, LF, RF,
"memptr.cmp.rest");
3038 Res = Builder.CreateBinOp(And, Res, Cmp);
3046 llvm::Value *
Zero = llvm::Constant::getNullValue(L0->getType());
3047 llvm::Value *IsZero = Builder.CreateICmp(
Eq, L0, Zero,
"memptr.cmp.iszero");
3048 Res = Builder.CreateBinOp(Or, Res, IsZero);
3053 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
3058 llvm::Value *MemPtr,
3064 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
3066 GetNullMemberPointerFields(MPT, fields);
3067 assert(!fields.empty());
3068 llvm::Value *FirstField = MemPtr;
3069 if (MemPtr->getType()->isStructTy())
3070 FirstField = Builder.CreateExtractValue(MemPtr, 0);
3071 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
3079 for (
int I = 1, E = fields.size(); I < E; ++I) {
3080 llvm::Value *
Field = Builder.CreateExtractValue(MemPtr, I);
3081 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
3082 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
3088 llvm::Constant *Val) {
3091 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3092 Val->getAggregateElement(0
U) : Val;
3093 return FirstField->isNullValue();
3098 if (isZeroInitializable(MPT) && Val->isNullValue())
3104 GetNullMemberPointerFields(MPT, Fields);
3105 if (Fields.size() == 1) {
3106 assert(Val->getType()->isIntegerTy());
3107 return Val == Fields[0];
3111 for (I = 0, E = Fields.size(); I != E; ++I) {
3112 if (Val->getAggregateElement(I) != Fields[I])
3121 llvm::Value *VBPtrOffset,
3122 llvm::Value *VBTableOffset,
3123 llvm::Value **VBPtrOut) {
3126 llvm::Value *VBPtr = Builder.CreateInBoundsGEP(CGM.
Int8Ty,
This.getPointer(),
3127 VBPtrOffset,
"vbptr");
3132 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3133 VBPtrAlign =
This.getAlignment().alignmentAtOffset(
3139 llvm::Value *VBTable = Builder.CreateAlignedLoad(
3140 CGM.
Int32Ty->getPointerTo(0), VBPtr, VBPtrAlign,
"vbtable");
3143 llvm::Value *VBTableIndex = Builder.CreateAShr(
3144 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3148 llvm::Value *VBaseOffs =
3149 Builder.CreateInBoundsGEP(CGM.
Int32Ty, VBTable, VBTableIndex);
3150 return Builder.CreateAlignedLoad(CGM.
Int32Ty, VBaseOffs,
3156llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3158 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3161 llvm::BasicBlock *OriginalBB =
nullptr;
3162 llvm::BasicBlock *SkipAdjustBB =
nullptr;
3163 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3170 OriginalBB = Builder.GetInsertBlock();
3173 llvm::Value *IsVirtual =
3174 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3176 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3188 "member pointer representation requires a "
3189 "complete class type for %0 to perform this expression");
3192 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3195 llvm::Value *VBPtr =
nullptr;
3196 llvm::Value *VBaseOffs =
3197 GetVBaseOffsetFromVBPtr(CGF,
Base, VBPtrOffset, VBTableOffset, &VBPtr);
3198 llvm::Value *AdjustedBase =
3199 Builder.CreateInBoundsGEP(CGM.
Int8Ty, VBPtr, VBaseOffs);
3202 if (VBaseAdjustBB) {
3203 Builder.CreateBr(SkipAdjustBB);
3205 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3206 Phi->addIncoming(
Base.getPointer(), OriginalBB);
3207 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3210 return AdjustedBase;
3213llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3223 llvm::Value *FieldOffset = MemPtr;
3224 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3225 llvm::Value *VBPtrOffset =
nullptr;
3226 if (MemPtr->getType()->isStructTy()) {
3229 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3231 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3233 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3237 if (VirtualBaseAdjustmentOffset) {
3238 Addr = AdjustVirtualBase(CGF, E, RD,
Base, VirtualBaseAdjustmentOffset,
3241 Addr =
Base.getPointer();
3245 return Builder.CreateInBoundsGEP(CGF.
Int8Ty, Addr, FieldOffset,
3253 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3254 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3258 if (isa<llvm::Constant>(Src))
3259 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3269 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3270 if (IsReinterpret && IsFunc)
3275 if (IsReinterpret &&
3282 llvm::Value *
IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3283 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3287 if (IsReinterpret) {
3290 assert(Src->getType() == DstNull->getType());
3291 return Builder.CreateSelect(
IsNotNull, Src, DstNull);
3294 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3297 Builder.CreateCondBr(
IsNotNull, ConvertBB, ContinueBB);
3300 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3304 Builder.CreateBr(ContinueBB);
3308 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3309 Phi->addIncoming(DstNull, OriginalBB);
3310 Phi->addIncoming(Dst, ConvertBB);
3314llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3324 bool IsConstant = isa<llvm::Constant>(Src);
3327 llvm::Value *FirstField = Src;
3328 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3329 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3330 llvm::Value *VBPtrOffset = getZeroInt();
3334 FirstField = Builder.CreateExtractValue(Src, I++);
3336 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3338 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3340 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3343 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3349 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3356 llvm::Value *SrcVBIndexEqZero =
3357 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3358 if (SrcInheritance == MSInheritanceModel::Virtual) {
3359 if (int64_t SrcOffsetToFirstVBase =
3360 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3361 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3363 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3365 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3376 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3381 llvm::Value *NVDisp;
3382 if (IsDerivedToBase)
3383 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3385 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3387 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3391 llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3394 if (llvm::GlobalVariable *VDispMap =
3395 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3396 llvm::Value *VBIndex = Builder.CreateExactUDiv(
3397 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3399 llvm::Constant *Mapping = VDispMap->getInitializer();
3400 VirtualBaseAdjustmentOffset =
3401 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3403 llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3404 VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3405 CGM.
IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3411 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3418 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3420 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3422 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3428 if (DstInheritance == MSInheritanceModel::Virtual) {
3429 if (int64_t DstOffsetToFirstVBase =
3430 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3431 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3433 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3435 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3444 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3446 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3448 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3450 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3452 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3458MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3459 llvm::Constant *Src) {
3466 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3470llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3474 assert(CK == CK_DerivedToBaseMemberPointer ||
3475 CK == CK_BaseToDerivedMemberPointer ||
3476 CK == CK_ReinterpretMemberPointer);
3479 if (MemberPointerConstantIsNull(SrcTy, Src))
3480 return EmitNullMemberPointer(DstTy);
3485 if (CK == CK_ReinterpretMemberPointer)
3489 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3490 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3495CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3497 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3509 llvm::Value *FunctionPointer = MemPtr;
3510 llvm::Value *NonVirtualBaseAdjustment =
nullptr;
3511 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3512 llvm::Value *VBPtrOffset =
nullptr;
3513 if (MemPtr->getType()->isStructTy()) {
3516 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3518 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3520 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3522 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3525 if (VirtualBaseAdjustmentOffset) {
3526 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3527 VirtualBaseAdjustmentOffset, VBPtrOffset);
3529 ThisPtrForCall =
This.getPointer();
3532 if (NonVirtualBaseAdjustment)
3533 ThisPtrForCall = Builder.CreateInBoundsGEP(CGF.
Int8Ty, ThisPtrForCall,
3534 NonVirtualBaseAdjustment);
3541 return new MicrosoftCXXABI(CGM);
3575 StringRef MangledName(
"??_7type_info@@6B@");
3576 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3580 llvm::GlobalVariable::ExternalLinkage,
3581 nullptr, MangledName);
3594 IsPrivateOnPath = 1 | 8,
3598 HasHierarchyDescriptor = 64
3604 MSRTTIClass *getFirstChild() {
return this + 1; }
3605 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3606 return Child + 1 + Child->NumBases;
3610 uint32_t Flags, NumBases, OffsetInVBase;
3614uint32_t MSRTTIClass::initialize(
const MSRTTIClass *
Parent,
3616 Flags = HasHierarchyDescriptor;
3618 VirtualRoot =
nullptr;
3622 Flags |= IsPrivate | IsPrivateOnPath;
3628 if (
Parent->Flags & IsPrivateOnPath)
3629 Flags |= IsPrivateOnPath;
3630 VirtualRoot =
Parent->VirtualRoot;
3631 OffsetInVBase =
Parent->OffsetInVBase + RD->getASTContext()
3632 .getASTRecordLayout(
Parent->RD).getBaseClassOffset(RD).getQuantity();
3636 MSRTTIClass *Child = getFirstChild();
3638 NumBases += Child->initialize(
this, &
Base) + 1;
3639 Child = getNextChild(Child);
3644static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3646 case Linkage::Invalid:
3647 llvm_unreachable(
"Linkage hasn't been computed!");
3650 case Linkage::Internal:
3651 case Linkage::UniqueExternal:
3652 return llvm::GlobalValue::InternalLinkage;
3654 case Linkage::VisibleNone:
3655 case Linkage::Module:
3656 case Linkage::External:
3657 return llvm::GlobalValue::LinkOnceODRLinkage;
3659 llvm_unreachable(
"Invalid linkage!");
3665struct MSRTTIBuilder {
3667 HasBranchingHierarchy = 1,
3668 HasVirtualBranchingHierarchy = 2,
3669 HasAmbiguousBases = 4
3672 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3673 : CGM(ABI.CGM), Context(CGM.getContext()),
3674 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3675 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3678 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3679 llvm::GlobalVariable *
3681 llvm::GlobalVariable *getClassHierarchyDescriptor();
3682 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3686 llvm::LLVMContext &VMContext;
3689 llvm::GlobalVariable::LinkageTypes
Linkage;
3690 MicrosoftCXXABI &ABI;
3699 Classes.push_back(MSRTTIClass(RD));
3710 for (MSRTTIClass *
Class = &Classes.front();
Class <= &Classes.back();) {
3711 if ((
Class->Flags & MSRTTIClass::IsVirtual) &&
3712 !VirtualBases.insert(
Class->RD).second) {
3716 if (!UniqueBases.insert(
Class->RD).second)
3717 AmbiguousBases.insert(
Class->RD);
3720 if (AmbiguousBases.empty())
3722 for (MSRTTIClass &
Class : Classes)
3723 if (AmbiguousBases.count(
Class.RD))
3724 Class.Flags |= MSRTTIClass::IsAmbiguous;
3727llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3730 llvm::raw_svector_ostream Out(MangledName);
3731 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3735 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3741 Classes.front().initialize(
nullptr,
nullptr);
3744 for (
const MSRTTIClass &Class : Classes) {
3745 if (
Class.RD->getNumBases() > 1)
3746 Flags |= HasBranchingHierarchy;
3749 if (
Class.Flags & MSRTTIClass::IsAmbiguous)
3750 Flags |= HasAmbiguousBases;
3752 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3753 Flags |= HasVirtualBranchingHierarchy;
3756 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
IntTy, 0),
3757 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3760 auto Type = ABI.getClassHierarchyDescriptorType();
3764 if (CHD->isWeakForLinker())
3765 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3767 auto *Bases = getBaseClassArray(Classes);
3770 llvm::Constant *Fields[] = {
3771 llvm::ConstantInt::get(CGM.
IntTy, 0),
3772 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3773 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3774 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3775 Bases->getValueType(), Bases,
3778 CHD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3782llvm::GlobalVariable *
3786 llvm::raw_svector_ostream Out(MangledName);
3787 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3795 llvm::Type *PtrType = ABI.getImageRelativeType(
3796 ABI.getBaseClassDescriptorType()->getPointerTo());
3797 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3799 new llvm::GlobalVariable(
Module, ArrType,
3801 nullptr, MangledName);
3802 if (BCA->isWeakForLinker())
3803 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3807 for (MSRTTIClass &Class : Classes)
3808 BaseClassArrayData.push_back(
3809 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3810 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3811 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3815llvm::GlobalVariable *
3816MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3819 uint32_t OffsetInVBTable = 0;
3820 int32_t VBPtrOffset = -1;
3821 if (
Class.VirtualRoot) {
3829 llvm::raw_svector_ostream Out(MangledName);
3830 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3831 Class.RD,
Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3836 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3840 auto Type = ABI.getBaseClassDescriptorType();
3843 nullptr, MangledName);
3844 if (BCD->isWeakForLinker())
3845 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3848 llvm::Constant *Fields[] = {
3849 ABI.getImageRelativeConstant(
3851 llvm::ConstantInt::get(CGM.
IntTy,
Class.NumBases),
3852 llvm::ConstantInt::get(CGM.
IntTy,
Class.OffsetInVBase),
3853 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3854 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3855 llvm::ConstantInt::get(CGM.
IntTy,
Class.Flags),
3856 ABI.getImageRelativeConstant(
3857 MSRTTIBuilder(ABI,
Class.RD).getClassHierarchyDescriptor()),
3859 BCD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3863llvm::GlobalVariable *
3864MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3867 llvm::raw_svector_ostream Out(MangledName);
3868 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3872 if (
auto COL =
Module.getNamedGlobal(MangledName))
3877 int VFPtrOffset = 0;
3883 ->second.hasVtorDisp())
3887 llvm::StructType *
Type = ABI.getCompleteObjectLocatorType();
3889 nullptr, MangledName);
3892 llvm::Constant *Fields[] = {
3893 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3894 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3895 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3896 ABI.getImageRelativeConstant(
3898 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3899 ABI.getImageRelativeConstant(COL),
3902 if (!ABI.isImageRelative())
3903 FieldsRef = FieldsRef.drop_back();
3904 COL->setInitializer(llvm::ConstantStruct::get(
Type, FieldsRef));
3905 if (COL->isWeakForLinker())
3906 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3911 bool &IsConst,
bool &IsVolatile,
3912 bool &IsUnaligned) {
3922 IsUnaligned =
false;
3924 if (!PointeeType.
isNull()) {
3945MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3950 bool IsConst, IsVolatile, IsUnaligned;
3974llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3977 llvm::raw_svector_ostream Out(MangledName);
3978 getMangleContext().mangleCXXRTTI(
Type, Out);
3982 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3991 llvm::raw_svector_ostream Out(TypeInfoString);
3992 getMangleContext().mangleCXXRTTIName(
Type, Out);
3996 llvm::Constant *Fields[] = {
3998 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3999 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
4000 llvm::StructType *TypeDescriptorType =
4001 getTypeDescriptorType(TypeInfoString);
4002 auto *Var =
new llvm::GlobalVariable(
4003 CGM.
getModule(), TypeDescriptorType,
false,
4004 getLinkageForRTTI(
Type),
4005 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
4007 if (Var->isWeakForLinker())
4008 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
4013llvm::GlobalVariable *
4014MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
4016 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
4019void MicrosoftCXXABI::emitCXXStructor(
GlobalDecl GD) {
4020 if (
auto *ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
4022 llvm::Function *Fn =
4028 auto *dtor = cast<CXXDestructorDecl>(GD.
getDecl());
4034 dtor->getParent()->getNumVBases() == 0)
4045 if (Fn->isWeakForLinker())
4046 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
4056 llvm::raw_svector_ostream Out(ThunkName);
4057 getMangleContext().mangleName(
GlobalDecl(CD, CT), Out);
4060 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
4061 return cast<llvm::Function>(GV);
4067 QualType RecordTy = getContext().getRecordType(RD);
4068 llvm::Function *ThunkFn = llvm::Function::Create(
4069 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
4070 ThunkFn->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
4072 if (ThunkFn->isWeakForLinker())
4073 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
4084 buildThisParam(CGF, FunctionArgs);
4090 &getContext().Idents.get(
"src"),
4091 getContext().getLValueReferenceType(RecordTy,
4093 ImplicitParamKind::Other);
4095 FunctionArgs.push_back(&SrcParam);
4102 &getContext().Idents.get(
"is_most_derived"),
4103 getContext().IntTy, ImplicitParamKind::Other);
4106 FunctionArgs.push_back(&IsMostDerived);
4114 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4115 llvm::Value *
This = getThisValue(CGF);
4117 llvm::Value *SrcVal =
4134 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
4135 ArgVec.push_back(PD->getDefaultArg());
4138 CodeGenFunction::RunCleanupsScope Cleanups(CGF);
4144 AddedStructorArgCounts ExtraArgs =
4149 llvm::Constant *CalleePtr =
4154 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4157 Cleanups.ForceCleanup();
4166llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
4168 int32_t VBPtrOffset,
4180 uint32_t
Size = getContext().getTypeSizeInChars(T).getQuantity();
4183 llvm::raw_svector_ostream Out(MangledName);
4184 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
4185 VBPtrOffset, VBIndex, Out);
4187 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4188 return getImageRelativeConstant(GV);
4192 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
4196 llvm::Constant *CopyCtor;
4203 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4205 CopyCtor = getImageRelativeConstant(CopyCtor);
4207 bool IsScalar = !RD;
4208 bool HasVirtualBases =
false;
4209 bool IsStdBadAlloc =
false;
4224 if (HasVirtualBases)
4229 llvm::Constant *Fields[] = {
4230 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4232 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4233 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4234 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4235 llvm::ConstantInt::get(CGM.
IntTy, Size),
4238 llvm::StructType *CTType = getCatchableTypeType();
4239 auto *GV =
new llvm::GlobalVariable(
4240 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
4241 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4242 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4243 GV->setSection(
".xdata");
4244 if (GV->isWeakForLinker())
4245 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4246 return getImageRelativeConstant(GV);
4249llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4253 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4278 if (MostDerivedClass) {
4285 Classes.front().initialize(
nullptr,
nullptr);
4287 for (
const MSRTTIClass &Class : Classes) {
4290 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4293 uint32_t OffsetInVBTable = 0;
4294 int32_t VBPtrOffset = -1;
4295 if (
Class.VirtualRoot) {
4306 CatchableTypes.insert(getCatchableType(RTTITy,
Class.OffsetInVBase,
4307 VBPtrOffset, OffsetInVBTable));
4315 CatchableTypes.insert(getCatchableType(T));
4328 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4339 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4341 uint32_t NumEntries = CatchableTypes.size();
4342 llvm::Type *CTType =
4343 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4344 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4345 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4346 llvm::Constant *Fields[] = {
4347 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4348 llvm::ConstantArray::get(
4350 CatchableTypes.end()))
4354 llvm::raw_svector_ostream Out(MangledName);
4355 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4357 CTA =
new llvm::GlobalVariable(
4358 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4359 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4360 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4361 CTA->setSection(
".xdata");
4362 if (CTA->isWeakForLinker())
4363 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4367llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4368 bool IsConst, IsVolatile, IsUnaligned;
4373 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4378 uint32_t NumEntries =
4379 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0
U))
4380 ->getLimitedValue();
4384 llvm::raw_svector_ostream Out(MangledName);
4385 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4391 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4407 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4410 if (!DtorD->isTrivial())
4413 llvm::Constant *ForwardCompat =
4414 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4415 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(CTA);
4416 llvm::StructType *TIType = getThrowInfoType();
4417 llvm::Constant *Fields[] = {
4418 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4419 getImageRelativeConstant(CleanupFn),
4421 PointerToCatchableTypes
4423 auto *GV =
new llvm::GlobalVariable(
4424 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4425 llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4426 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4427 GV->setSection(
".xdata");
4428 if (GV->isWeakForLinker())
4429 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4435 assert(SubExpr &&
"SubExpr cannot be null");
4445 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4448 llvm::Value *Args[] = {
4455std::pair<llvm::Value *, const CXXRecordDecl *>
4458 std::tie(This, std::ignore, RD) =
4463bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4495 if (
const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4496 if (!isPermittedToBeHomogeneousAggregate(FRD))
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *DynInitBB, llvm::BasicBlock *ContinueBB)
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty, CodeGenModule &CGM)
static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM)
static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM)
static llvm::GlobalValue * getTlsGuardVar(CodeGenModule &CGM)
static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile, bool &IsUnaligned)
static llvm::CallBase * emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM)
static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *ContinueBB)
static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)
Find ambiguity among base classes.
static void emitDynamicTlsInitialization(CodeGenFunction &CGF)
static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)
Recursively serializes a class hierarchy in pre-order depth first order.
static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM)
static bool isDeletingDtor(GlobalDecl GD)
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM)
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo &VFPtr, SmallString< 256 > &Name)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
llvm::DenseSet< const void * > Visited
const NestedNameSpecifier * Specifier
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool isMemberPointerToDerivedMember() const
const ValueDecl * getMemberPointerDecl() const
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
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 ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const LangOptions & getLangOpts() const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getExceptionObjectType(QualType T) const
const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
Represents a base class of a C++ class.
CXXCatchStmt - This represents a C++ catch block.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
Represents a call to a member function that may be written either with member call syntax (e....
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++ struct/union/class.
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class....
bool hasPrivateFields() const
bool hasProtectedFields() const
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
CXXRecordDecl * getMostRecentNonInjectedDecl()
base_class_range vbases()
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
bool hasDefinition() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
bool hasNonTrivialDefaultConstructor() const
Determine whether this class has a non-trivial default constructor (C++11 [class.ctor]p5).
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is virtually derived from the class Base.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
const CXXBaseSpecifier *const * path_const_iterator
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
bool hasProfileIRInstr() const
Check if IR level profile instrumentation is on.
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
void setSRetAfterThis(bool AfterThis)
bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const
isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous aggregate.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::Value * getPointer() const
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateGEP(Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual bool shouldEmitExactDynamicCast(QualType DestRecordTy)=0
llvm::Value *& getStructorImplicitParamValue(CodeGenFunction &CGF)
virtual void EmitCXXConstructors(const CXXConstructorDecl *D)=0
Emit constructor variants required by this ABI.
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
virtual llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const ReturnAdjustment &RA)=0
virtual bool HasThisReturn(GlobalDecl GD) const
Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...
virtual llvm::Value * getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, const CXXRecordDecl *NearestVBase)=0
Get the address point of the vtable for the given base subobject while building a constructor or a de...
virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0
virtual std::vector< CharUnits > getVBPtrOffsets(const CXXRecordDecl *RD)
Gets the offsets of all the virtual base pointers in a given class.
virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn)=0
virtual void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, const CXXRecordDecl *RD)
Emit the code to initialize hidden members required to handle virtual inheritance,...
virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const
Return whether or not a member pointers type is convertible to an IR type.
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
virtual bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr)=0
Checks if ABI requires extra virtual offset for vtable field.
virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)=0
Emits the guarded initializer and destructor setup for the given variable, given that it couldn't be ...
virtual void EmitCXXDestructors(const CXXDestructorDecl *D)=0
Emit destructor variants required by this ABI.
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, CXXDtorType DT) const =0
Returns true if the given destructor type should be emitted as a linkonce delegating thunk,...
virtual CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)
Get the ABI-specific "this" parameter adjustment to apply in the prologue of a virtual function.
virtual void setCXXDestructorDLLStorage(llvm::GlobalValue *GV, const CXXDestructorDecl *Dtor, CXXDtorType DT) const
RecordArgABI
Specify how one should pass an argument of a record type.
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual StringRef GetPureVirtualCallName()=0
Gets the pure virtual member call function.
virtual CharUnits getArrayCookieSizeImpl(QualType elementType)
Returns the extra size required in order to store the array cookie for the given type.
virtual bool isSRetParameterAfterThis() const
Returns true if the implicit 'sret' parameter comes after the implicit 'this' parameter of C++ instan...
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const =0
Determine whether it's possible to emit a vtable for RD, even though we do not know that the vtable h...
virtual StringRef GetDeletedVirtualCallName()=0
Gets the deleted virtual member call name.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType)=0
Emit a reference to a non-local thread_local variable (including triggering the initialization of all...
bool isEmittedWithConstantInitializer(const VarDecl *VD, bool InspectInitForWeakDef=false) const
Determine whether we will definitely emit this variable with a constant initializer,...
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Constant * EmitMemberPointer(const APValue &MP, QualType MPT)
Create a member pointer for the given member pointer constant.
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
virtual llvm::Value * readArrayCookieImpl(CodeGenFunction &IGF, Address ptr, CharUnits cookieSize)
Reads the array cookie for an allocation which is known to have one.
virtual llvm::Value * EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, const MemberPointerType *MPT)
Calculate an l-value from an object and a data member pointer.
virtual llvm::Value * getCXXDestructorImplicitParam(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating)=0
Get the implicit (second) parameter that comes after the "this" pointer, or nullptr if there is isn't...
virtual bool requiresArrayCookie(const CXXDeleteExpr *E, QualType eltType)
virtual CatchTypeInfo getCatchAllTypeInfo()
virtual std::pair< llvm::Value *, const CXXRecordDecl * > LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD)=0
Load a vtable from This, an object of polymorphic type RD, or from one of its virtual bases if it doe...
virtual llvm::Constant * getVTableAddressPointForConstExpr(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject while building a constexpr.
virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment)=0
virtual Address adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD, Address This, bool VirtualCall)
Perform ABI-specific "this" argument adjustment required prior to a call of a virtual function.
virtual llvm::Value * EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E)=0
Emit the ABI-specific virtual destructor call.
bool mayNeedDestruction(const VarDecl *VD) const
virtual llvm::BasicBlock * EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD)
virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)=0
Checks if ABI requires to initialize vptrs for given dynamic class.
virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0
virtual llvm::Value * GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl)=0
virtual bool isThisCompleteObject(GlobalDecl GD) const =0
Determine whether there's something special about the rules of the ABI tell us that 'this' is a compl...
virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, Address This, llvm::Type *Ty, SourceLocation Loc)=0
Build a virtual function pointer in the ABI-specific way.
virtual bool classifyReturnType(CGFunctionInfo &FI) const =0
If the C++ ABI requires the given type be returned in a particular way, this method sets RetAI and re...
virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0
virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0
virtual void EmitThreadLocalInitFuncs(CodeGenModule &CGM, ArrayRef< const VarDecl * > CXXThreadLocals, ArrayRef< llvm::Function * > CXXThreadLocalInits, ArrayRef< const VarDecl * > CXXThreadLocalInitVars)=0
Emits ABI-required functions necessary to initialize thread_local variables in this translation unit.
virtual bool usesThreadWrapperFunction(const VarDecl *VD) const =0
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
virtual llvm::Value * emitExactDynamicCast(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastSuccess, llvm::BasicBlock *CastFail)=0
Emit a dynamic_cast from SrcRecordTy to DestRecordTy.
virtual const CXXRecordDecl * getThisArgumentTypeForMethod(GlobalDecl GD)
Get the type of the implicit "this" parameter used by a method.
virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)=0
Emit the destructor call.
virtual llvm::GlobalVariable * getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset)=0
Get the address of the vtable for the given record decl which should be used for the vptr at the give...
virtual bool EmitBadCastCall(CodeGenFunction &CGF)=0
virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, CallArgList &CallArgs)
virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)
Create a member pointer for the given field.
virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD)=0
Emit any tables needed to implement virtual inheritance.
virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD)=0
Emits the VTable definitions required for the given record type.
virtual CGCallee EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, Address This, llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr, const MemberPointerType *MPT)
Load a member function from an object and a member function pointer.
virtual bool isPermittedToBeHomogeneousAggregate(const CXXRecordDecl *RD) const
Returns true if the ABI permits the argument to be a homogeneous aggregate.
virtual void emitCXXStructor(GlobalDecl GD)=0
Emit a single constructor/destructor with the given type from a C++ constructor Decl.
virtual bool exportThunk()=0
virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0
virtual llvm::Value * emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy)=0
virtual bool isZeroInitializable(const MemberPointerType *MPT)
Return true if the given member pointer can be zero-initialized (in the C++ sense) with an LLVM zeroi...
virtual bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy)=0
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)
Create a member pointer for the given method.
virtual llvm::Value * emitDynamicCastCall(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd)=0
virtual llvm::GlobalVariable * getThrowInfo(QualType T)
virtual llvm::GlobalValue::LinkageTypes getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const
virtual Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType)
Initialize the array cookie for the given allocation.
ASTContext & getContext() const
virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, QualType SrcRecordTy)=0
virtual AddedStructorArgCounts buildStructorSignature(GlobalDecl GD, SmallVectorImpl< CanQualType > &ArgTys)=0
Build the signature of the given constructor or destructor variant by adding any required parameters.
virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA)=0
MangleContext & getMangleContext()
Gets the mangle context.
virtual AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating)=0
All available information about a concrete callee.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool isInstanceMethod() const
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
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...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
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.
llvm::Function * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
CodeGenTypes & getTypes() const
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
LValue EmitLoadOfReferenceLValue(LValue RefLVal)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
llvm::Instruction * CurrentFuncletPad
llvm::LLVMContext & getLLVMContext()
void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, llvm::BasicBlock *InitBlock, llvm::BasicBlock *NoInitBlock, GuardKind Kind, const VarDecl *D)
Emit a branch to select whether or not to perform guarded initialization.
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object)
Add a destructor and object to add to the C++ global destructor function.
void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, const CXXRecordDecl *RD)
Create and attach type metadata for the given vtable.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::GlobalObject::VCallVisibility GetVCallVisibilityLevel(const CXXRecordDecl *RD, llvm::DenseSet< const CXXRecordDecl * > &Visited)
Returns the vcall visibility of the given type.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenVTables & getVTables()
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
DiagnosticsEngine & getDiags() const
llvm::Constant * getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the constructor/destructor of the given type.
llvm::GlobalValue::LinkageTypes getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage)
Returns LLVM linkage for a declarator.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void EmitGlobal(GlobalDecl D)
Emit code for a single global function or var decl.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
void AppendLinkerOptions(StringRef Opts)
Appends Opts to the "llvm.linker.options" metadata value.
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
llvm::Function * codegenCXXStructor(GlobalDecl GD)
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const
Set the TLS mode for the given LLVM GlobalValue for the thread-local variable declaration D.
ASTContext & getContext() const
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
MicrosoftVTableContext & getMicrosoftVTableContext()