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>();
340 DeleteOrMemberCallExpr E)
override;
345 "Only deleting destructor thunks are available in this ABI");
352 llvm::GlobalVariable *
354 llvm::GlobalVariable::LinkageTypes
Linkage);
356 llvm::GlobalVariable *
360 llvm::raw_svector_ostream Out(OutName);
362 StringRef MangledName = OutName.str();
364 if (
auto *VDispMap = CGM.
getModule().getNamedGlobal(MangledName))
370 llvm::UndefValue::get(CGM.
IntTy));
371 Map[0] = llvm::ConstantInt::get(CGM.
IntTy, 0);
372 bool AnyDifferent =
false;
373 for (
const auto &I : SrcRD->
vbases()) {
374 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
380 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.
IntTy, DstVBIndex * 4);
381 AnyDifferent |= SrcVBIndex != DstVBIndex;
387 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.
IntTy, Map.size());
388 llvm::Constant *
Init = llvm::ConstantArray::get(VDispMapTy, Map);
389 llvm::GlobalValue::LinkageTypes
Linkage =
391 ? llvm::GlobalValue::LinkOnceODRLinkage
392 : llvm::GlobalValue::InternalLinkage;
393 auto *VDispMap =
new llvm::GlobalVariable(
400 llvm::GlobalVariable *GV)
const;
408 Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
410 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
412 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
430 LangOptions::MSVC2019_5) &&
437 llvm::GlobalVariable *DeclPtr,
438 bool PerformInit)
override;
440 llvm::FunctionCallee Dtor,
441 llvm::Constant *Addr)
override;
472 llvm::Value *NumElements,
479 friend struct MSRTTIBuilder;
481 bool isImageRelative()
const {
486 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
488 TDTypeName += llvm::utostr(TypeInfoString.size());
489 llvm::StructType *&TypeDescriptorType =
490 TypeDescriptorTypeMap[TypeInfoString.size()];
491 if (TypeDescriptorType)
492 return TypeDescriptorType;
493 llvm::Type *FieldTypes[] = {
496 llvm::ArrayType::get(CGM.
Int8Ty, TypeInfoString.size() + 1)};
498 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, TDTypeName);
499 return TypeDescriptorType;
502 llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
503 if (!isImageRelative())
508 llvm::StructType *getBaseClassDescriptorType() {
509 if (BaseClassDescriptorType)
510 return BaseClassDescriptorType;
511 llvm::Type *FieldTypes[] = {
518 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
520 BaseClassDescriptorType = llvm::StructType::create(
522 return BaseClassDescriptorType;
525 llvm::StructType *getClassHierarchyDescriptorType() {
526 if (ClassHierarchyDescriptorType)
527 return ClassHierarchyDescriptorType;
529 ClassHierarchyDescriptorType = llvm::StructType::create(
531 llvm::Type *FieldTypes[] = {
535 getImageRelativeType(
536 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
538 ClassHierarchyDescriptorType->setBody(FieldTypes);
539 return ClassHierarchyDescriptorType;
542 llvm::StructType *getCompleteObjectLocatorType() {
543 if (CompleteObjectLocatorType)
544 return CompleteObjectLocatorType;
545 CompleteObjectLocatorType = llvm::StructType::create(
547 llvm::Type *FieldTypes[] = {
552 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
553 getImageRelativeType(CompleteObjectLocatorType),
556 if (!isImageRelative())
557 FieldTypesRef = FieldTypesRef.drop_back();
558 CompleteObjectLocatorType->setBody(FieldTypesRef);
559 return CompleteObjectLocatorType;
562 llvm::GlobalVariable *getImageBase() {
563 StringRef Name =
"__ImageBase";
564 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name))
569 llvm::GlobalValue::ExternalLinkage,
575 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
576 if (!isImageRelative())
579 if (PtrVal->isNullValue())
580 return llvm::Constant::getNullValue(CGM.
IntTy);
582 llvm::Constant *ImageBaseAsInt =
583 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.
IntPtrTy);
584 llvm::Constant *PtrValAsInt =
585 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.
IntPtrTy);
586 llvm::Constant *Diff =
587 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
589 return llvm::ConstantExpr::getTrunc(Diff, CGM.
IntTy);
597 llvm::Constant *getZeroInt() {
598 return llvm::ConstantInt::get(CGM.
IntTy, 0);
601 llvm::Constant *getAllOnesInt() {
602 return llvm::Constant::getAllOnesValue(CGM.
IntTy);
616 llvm::Value *VBPtrOffset,
617 llvm::Value *VBTableOffset,
618 llvm::Value **VBPtr =
nullptr);
623 int32_t VBTableOffset,
624 llvm::Value **VBPtr =
nullptr) {
625 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
626 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
627 *VBTOffset = llvm::ConstantInt::get(CGM.
IntTy, VBTableOffset);
628 return GetVBaseOffsetFromVBPtr(CGF,
Base, VBPOffset, VBTOffset, VBPtr);
631 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
639 llvm::Value *VirtualBaseAdjustmentOffset,
640 llvm::Value *VBPtrOffset );
644 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
645 bool IsMemberFunction,
648 unsigned VBTableIndex);
657 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
660 llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
673 return RD->
hasAttr<MSInheritanceAttr>();
687 bool Inequality)
override;
698 llvm::Value *EmitNonNullMemberPointerConversion(
706 llvm::Value *Src)
override;
709 llvm::Constant *Src)
override;
718 Address This, llvm::Value *&ThisPtrForCall,
724 llvm::StructType *getCatchableTypeType() {
725 if (CatchableTypeType)
726 return CatchableTypeType;
727 llvm::Type *FieldTypes[] = {
736 CatchableTypeType = llvm::StructType::create(
738 return CatchableTypeType;
741 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
742 llvm::StructType *&CatchableTypeArrayType =
743 CatchableTypeArrayTypeMap[NumEntries];
744 if (CatchableTypeArrayType)
745 return CatchableTypeArrayType;
748 CTATypeName += llvm::utostr(NumEntries);
750 getImageRelativeType(getCatchableTypeType()->getPointerTo());
751 llvm::Type *FieldTypes[] = {
753 llvm::ArrayType::get(CTType, NumEntries)
755 CatchableTypeArrayType =
756 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, CTATypeName);
757 return CatchableTypeArrayType;
760 llvm::StructType *getThrowInfoType() {
762 return ThrowInfoType;
763 llvm::Type *FieldTypes[] = {
769 ThrowInfoType = llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes,
771 return ThrowInfoType;
777 llvm::Type *Args[] = {CGM.
Int8PtrTy, getThrowInfoType()->getPointerTo()};
778 llvm::FunctionType *FTy =
779 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
780 llvm::FunctionCallee Throw =
784 if (
auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
785 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
793 llvm::Constant *getCatchableType(
QualType T,
794 uint32_t NVOffset = 0,
795 int32_t VBPtrOffset = -1,
796 uint32_t VBIndex = 0);
798 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
802 std::pair<llvm::Value *, const CXXRecordDecl *>
810 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
811 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
812 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
814 VFTablesMapTy VFTablesMap;
815 VTablesMapTy VTablesMap;
822 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
827 GuardInfo() =
default;
828 llvm::GlobalVariable *Guard =
nullptr;
829 unsigned BitIndex = 0;
834 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
835 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
836 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
838 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
839 llvm::StructType *BaseClassDescriptorType;
840 llvm::StructType *ClassHierarchyDescriptorType;
841 llvm::StructType *CompleteObjectLocatorType;
843 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
845 llvm::StructType *CatchableTypeType;
846 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
847 llvm::StructType *ThrowInfoType;
853MicrosoftCXXABI::getRecordArgABI(
const CXXRecordDecl *RD)
const {
865 case llvm::Triple::thumb:
871 case llvm::Triple::x86: {
882 return RAA_DirectInMemory;
885 case llvm::Triple::x86_64:
886 case llvm::Triple::aarch64:
890 llvm_unreachable(
"invalid enum");
902 llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
907void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
908 llvm::Value *Args[] = {
909 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
910 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
922 VarDecl *CatchParam = S->getExceptionDecl();
923 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
924 llvm::CatchPadInst *CPI =
925 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
936 CPI->setArgOperand(2, var.getObjectAddress(CGF).emitRawPointer(CGF));
944std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
955 return std::make_tuple(
Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
964 PolymorphicBase = BaseDecl;
968 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
970 llvm::Value *Offset =
971 GetVirtualBaseClassOffset(CGF,
Value, SrcDecl, PolymorphicBase);
973 Value.getElementType(),
Value.emitRawPointer(CGF), Offset);
976 return std::make_tuple(
Address(Ptr, CGF.
Int8Ty, VBaseAlign), Offset,
980bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
984 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
988 llvm::Value *Argument) {
989 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
990 llvm::FunctionType *FTy =
991 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
992 llvm::Value *Args[] = {Argument};
998 llvm::CallBase *
Call =
1000 Call->setDoesNotReturn();
1001 CGF.
Builder.CreateUnreachable();
1007 llvm::Type *StdTypeInfoPtrTy) {
1008 std::tie(ThisPtr, std::ignore, std::ignore) =
1009 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
1011 return CGF.
Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
1014bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1018 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1021llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
1023 QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1024 llvm::Value *SrcRTTI =
1026 llvm::Value *DestRTTI =
1029 llvm::Value *Offset;
1030 std::tie(This, Offset, std::ignore) =
1031 performBaseAdjustment(CGF, This, SrcRecordTy);
1032 llvm::Value *ThisPtr =
This.emitRawPointer(CGF);
1044 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1046 llvm::Value *Args[] = {
1047 ThisPtr, Offset, SrcRTTI, DestRTTI,
1052llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(
CodeGenFunction &CGF,
1055 std::tie(
Value, std::ignore, std::ignore) =
1056 performBaseAdjustment(CGF,
Value, SrcRecordTy);
1060 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1062 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1064 llvm::Value *Args[] = {
Value.emitRawPointer(CGF)};
1072llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1078 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.
PtrDiffTy, VBPtrChars);
1083 llvm::Value *VBTableOffset =
1086 llvm::Value *VBPtrToNewBase =
1087 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1090 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1093bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1094 return isa<CXXConstructorDecl>(GD.
getDecl());
1098 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1102bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1112 uint64_t NumElts = 0;
1115 isa<VectorType>(
Base)) {
1135 if (Ctor->isUserProvided())
1142bool MicrosoftCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1153 if (isIndirectReturn) {
1174 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1175 assert(IsMostDerivedClass &&
1176 "ctor for a class with virtual bases must have an implicit parameter");
1177 llvm::Value *IsCompleteObject =
1178 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1180 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1181 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1182 CGF.
Builder.CreateCondBr(IsCompleteObject,
1183 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1188 EmitVBPtrStores(CGF, RD);
1192 return SkipVbaseCtorsBB;
1197 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1198 assert(IsMostDerivedClass &&
1199 "ctor for a class with virtual bases must have an implicit parameter");
1200 llvm::Value *IsCompleteObject =
1201 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1203 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1204 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1205 CGF.
Builder.CreateCondBr(IsCompleteObject,
1206 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1211 return SkipVbaseDtorsBB;
1214void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1234 llvm::Value *Int8This =
nullptr;
1237 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1238 auto I = VBaseMap.find(VBase);
1239 assert(I != VBaseMap.end());
1240 if (!I->second.hasVtorDisp())
1243 llvm::Value *VBaseOffset =
1244 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1245 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1248 llvm::Value *VtorDispValue = Builder.CreateSub(
1249 VBaseOffset, llvm::ConstantInt::get(CGM.
PtrDiffTy, ConstantVBaseOffset),
1251 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1254 Int8This = getThisValue(CGF);
1256 llvm::Value *VtorDispPtr =
1257 Builder.CreateInBoundsGEP(CGF.
Int8Ty, Int8This, VBaseOffset);
1259 VtorDispPtr = Builder.CreateConstGEP1_32(CGF.
Int8Ty, VtorDispPtr, -4);
1261 Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1272 return ExpectedCallingConv == ActualCallingConv;
1287 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1300 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1301 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1302 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1303 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1308 if (VBT->getVBaseWithVPtr())
1311 llvm::Value *GVPtr =
1319MicrosoftCXXABI::buildStructorSignature(
GlobalDecl GD,
1321 AddedStructorArgCounts Added;
1323 if (isa<CXXDestructorDecl>(GD.
getDecl()) &&
1326 ArgTys.push_back(getContext().IntTy);
1329 auto *CD = dyn_cast<CXXConstructorDecl>(GD.
getDecl());
1338 if (
Class->getNumVBases()) {
1340 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1343 ArgTys.push_back(getContext().IntTy);
1351void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1357 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1364llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1369 return llvm::GlobalValue::InternalLinkage;
1380 if (Dtor->
hasAttr<DLLExportAttr>())
1381 return llvm::GlobalValue::WeakODRLinkage;
1382 if (Dtor->
hasAttr<DLLImportAttr>())
1383 return llvm::GlobalValue::AvailableExternallyLinkage;
1384 return llvm::GlobalValue::LinkOnceODRLinkage;
1389 return llvm::GlobalValue::LinkOnceODRLinkage;
1391 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1393 llvm_unreachable(
"invalid dtor type");
1410MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1432 if (isa<CXXDestructorDecl>(MD))
1437 getContext().getASTRecordLayout(MD->
getParent());
1444Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1450 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1485 Result = Result.withElementType(CGF.
Int8Ty);
1489 llvm::Value *VBaseOffset =
1490 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1492 Result.getElementType(), Result.emitRawPointer(CGF), VBaseOffset);
1497 if (!StaticOffset.
isZero()) {
1499 Result = Result.withElementType(CGF.
Int8Ty);
1518 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1523 ImplicitParamKind::Other);
1528 Params.insert(Params.begin() + 1, IsMostDerived);
1530 Params.push_back(IsMostDerived);
1531 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1536 ImplicitParamKind::Other);
1537 Params.push_back(ShouldDelete);
1538 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1542void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1559 llvm::Value *
This = loadIncomingCXXThis(CGF);
1562 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1563 if (!Adjustment.
isZero()) {
1569 setCXXABIThisValue(CGF, This);
1579 if (HasThisReturn(CGF.
CurGD) || hasMostDerivedReturn(CGF.
CurGD))
1583 assert(getStructorImplicitParamDecl(CGF) &&
1584 "no implicit parameter for a constructor with virtual bases?");
1585 getStructorImplicitParamValue(CGF)
1592 assert(getStructorImplicitParamDecl(CGF) &&
1593 "no implicit parameter for a deleting destructor?");
1594 getStructorImplicitParamValue(CGF)
1597 "should_call_delete");
1608 return AddedStructorArgs{};
1612 llvm::Value *MostDerivedArg;
1614 MostDerivedArg = getStructorImplicitParamValue(CGF);
1619 return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1621 return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1624llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
1645 assert(
Type != CXXDtorType::Dtor_Deleting &&
1646 "The deleting destructor should only be called via a virtual call");
1651 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1652 if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1653 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1663 if (BaseDtorEndBB) {
1665 CGF.
Builder.CreateBr(BaseDtorEndBB);
1670void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1672 llvm::GlobalVariable *VTable) {
1684 llvm::GlobalObject::VCallVisibility TypeVis =
1686 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1687 VTable->setVCallVisibilityMetadata(TypeVis);
1694 getContext().getLangOpts().RTTIData
1695 ? getContext().toCharUnitsFromBits(
1696 getContext().getTargetInfo().getPointerWidth(LangAS::Default))
1715 getContext().getASTRecordLayout(DerivedRD);
1721 Offset = VBI->second.VBaseOffset;
1722 if (!Offset.isZero())
1737 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1738 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1739 if (VTable->hasInitializer())
1745 llvm::Constant *RTTI =
nullptr;
1748 RTTI = getMSCompleteObjectLocator(RD, *Info);
1751 auto components = builder.beginStruct();
1753 VTable->hasLocalLinkage());
1754 components.finishAndSetAsInitializer(VTable);
1756 emitVTableTypeMetadata(*Info, RD, VTable);
1760bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1762 return Vptr.NearestVBase !=
nullptr;
1765llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1768 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(
Base, VTableClass);
1769 if (!VTableAddressPoint) {
1770 assert(
Base.getBase()->getNumVBases() &&
1771 !getContext().getASTRecordLayout(
Base.getBase()).hasOwnVFPtr());
1773 return VTableAddressPoint;
1779 llvm::raw_svector_ostream Out(Name);
1786 (void)getAddrOfVTable(VTableClass,
Base.getBaseOffset());
1787 VFTableIdTy
ID(VTableClass,
Base.getBaseOffset());
1788 return VFTablesMap[
ID];
1791llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1797 VFTableIdTy
ID(RD, VPtrOffset);
1798 VTablesMapTy::iterator I;
1800 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID,
nullptr));
1804 llvm::GlobalVariable *&VTable = I->second;
1809 if (DeferredVFTables.insert(RD).second) {
1817 llvm::StringSet<> ObservedMangledNames;
1818 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1821 if (!ObservedMangledNames.insert(Name.str()).second)
1822 llvm_unreachable(
"Already saw this mangling before?");
1827 const std::unique_ptr<VPtrInfo> *VFPtrI =
1828 llvm::find_if(VFPtrs, [&](
const std::unique_ptr<VPtrInfo> &VPI) {
1829 return VPI->FullOffsetInMDC == VPtrOffset;
1831 if (VFPtrI == VFPtrs.end()) {
1832 VFTablesMap[
ID] =
nullptr;
1835 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1847 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1848 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1850 bool VFTableComesFromAnotherTU =
1851 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1852 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1853 bool VTableAliasIsRequred =
1854 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1856 if (llvm::GlobalValue *VFTable =
1857 CGM.
getModule().getNamedGlobal(VFTableName)) {
1858 VFTablesMap[
ID] = VFTable;
1859 VTable = VTableAliasIsRequred
1860 ? cast<llvm::GlobalVariable>(
1861 cast<llvm::GlobalAlias>(VFTable)->getAliaseeObject())
1862 :
cast<
llvm::GlobalVariable>(VFTable);
1868 llvm::GlobalValue::LinkageTypes VTableLinkage =
1869 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1871 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1877 llvm::GlobalValue *VFTable;
1878 VTable =
new llvm::GlobalVariable(CGM.
getModule(), VTableType,
1879 true, VTableLinkage,
1880 nullptr, VTableName);
1881 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1883 llvm::Comdat *
C =
nullptr;
1884 if (!VFTableComesFromAnotherTU &&
1885 llvm::GlobalValue::isWeakForLinker(VFTableLinkage))
1886 C = CGM.
getModule().getOrInsertComdat(VFTableName.str());
1891 if (VTableAliasIsRequred) {
1892 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1893 llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1894 llvm::ConstantInt::get(CGM.
Int32Ty, 1)};
1897 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1898 VTable->getValueType(), VTable, GEPIndices);
1899 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1900 VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1902 C->setSelectionKind(llvm::Comdat::Largest);
1904 VFTable = llvm::GlobalAlias::create(CGM.
Int8PtrTy,
1906 VFTableName.str(), VTableGEP,
1908 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1917 VTable->setComdat(
C);
1919 if (RD->
hasAttr<DLLExportAttr>())
1920 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1922 VFTablesMap[
ID] = VFTable;
1933 Ty = Ty->getPointerTo();
1935 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1937 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1938 llvm::Value *VTable = CGF.
GetVTablePtr(VPtr, Ty->getPointerTo(),
1939 MethodDecl->getParent());
1946 auto getObjectWithVPtr = [&] {
1949 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1950 return Info->FullOffsetInMDC == ML.VFPtrOffset;
1959 getObjectWithVPtr(), VTable, Ty,
1967 llvm::Value *VFuncPtr =
1968 Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.
Index,
"vfn");
1969 VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.
getPointerAlign());
1976llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1978 Address This, DeleteOrMemberCallExpr E) {
1981 assert((CE !=
nullptr) ^ (D !=
nullptr));
1982 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
1994 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
2000 ThisTy = CE->getObjectType();
2002 ThisTy = D->getDestroyedType();
2005 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
2008 ImplicitParam, Context.
IntTy, CE);
2012const VBTableGlobals &
2013MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
2016 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
2018 std::tie(Entry, Added) =
2019 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
2020 VBTableGlobals &VBGlobals = Entry->second;
2025 VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2030 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2031 E = VBGlobals.VBTables->end();
2033 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,
Linkage));
2040MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2042 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
2043 "can't form pointers to ctors or virtual dtors");
2047 llvm::raw_svector_ostream Out(ThunkName);
2048 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2051 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
2052 return cast<llvm::Function>(GV);
2058 llvm::Function *ThunkFn =
2059 llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
2061 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2064 ? llvm::GlobalValue::LinkOnceODRLinkage
2065 : llvm::GlobalValue::InternalLinkage);
2067 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
2076 ThunkFn->addFnAttr(
"thunk");
2079 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
2089 buildThisParam(CGF, FunctionArgs);
2096 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2100 llvm::Type *ThunkPtrTy = ThunkTy->getPointerTo();
2102 getThisAddress(CGF), ThunkPtrTy->getPointerTo(), MD->
getParent());
2104 llvm::Value *VFuncPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2105 ThunkPtrTy, VTable, ML.
Index,
"vfn");
2114void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2115 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2116 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2117 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2118 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2119 if (GV->isDeclaration())
2120 emitVBTableDefinition(*VBT, RD, GV);
2124llvm::GlobalVariable *
2126 llvm::GlobalVariable::LinkageTypes
Linkage) {
2128 llvm::raw_svector_ostream Out(OutName);
2129 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2130 StringRef Name = OutName.str();
2132 llvm::ArrayType *VBTableType =
2135 assert(!CGM.
getModule().getNamedGlobal(Name) &&
2136 "vbtable with this name already exists: mangling bug?");
2141 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2143 if (RD->
hasAttr<DLLImportAttr>())
2144 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2145 else if (RD->
hasAttr<DLLExportAttr>())
2146 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2148 if (!GV->hasExternalLinkage())
2149 emitVBTableDefinition(VBT, RD, GV);
2154void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2156 llvm::GlobalVariable *GV)
const {
2160 "should only emit vbtables for classes with vbtables");
2164 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2171 Offsets[0] = llvm::ConstantInt::get(CGM.
IntTy, -VBPtrOffset.
getQuantity());
2174 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2175 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2177 assert(!Offset.isNegative());
2182 CompleteVBPtrOffset +=
2184 Offset -= CompleteVBPtrOffset;
2186 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2187 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2188 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.
IntTy, Offset.getQuantity());
2191 assert(Offsets.size() ==
2192 cast<llvm::ArrayType>(GV->getValueType())->getNumElements());
2193 llvm::ArrayType *VBTableType =
2194 llvm::ArrayType::get(CGM.
IntTy, Offsets.size());
2195 llvm::Constant *
Init = llvm::ConstantArray::get(VBTableType, Offsets);
2196 GV->setInitializer(
Init);
2198 if (RD->
hasAttr<DLLImportAttr>())
2199 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2202llvm::Value *MicrosoftCXXABI::performThisAdjustment(
CodeGenFunction &CGF,
2206 return This.emitRawPointer(CGF);
2212 V =
This.emitRawPointer(CGF);
2222 CGF.
Builder.CreateNeg(VtorDisp));
2235 llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2258 return Ret.emitRawPointer(CGF);
2262 llvm::Value *
V =
Ret.emitRawPointer(CGF);
2267 llvm::Value *VBaseOffset =
2286bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *
expr) {
2289 return expr->getAllocatedType().isDestructedType();
2300llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(
CodeGenFunction &CGF,
2309 llvm::Value *numElements,
2312 assert(requiresArrayCookie(
expr));
2315 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2330 llvm::FunctionCallee Dtor,
2331 llvm::Constant *Addr) {
2336 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2337 CGF.
IntTy, DtorStub->getType(),
false);
2340 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2341 if (llvm::Function *TLRegDtorFn =
2342 dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2343 TLRegDtorFn->setDoesNotThrow();
2349 llvm::FunctionCallee Dtor,
2350 llvm::Constant *Addr) {
2365void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2369 if (CXXThreadLocalInits.empty())
2374 ?
"/include:___dyn_tls_init@12"
2375 :
"/include:__dyn_tls_init");
2380 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2381 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2382 CGM.
getModule(), InitFunc->getType(),
true,
2383 llvm::GlobalVariable::InternalLinkage, InitFunc,
2384 Twine(InitFunc->getName(),
"$initializer$"));
2385 InitFuncPtr->setSection(
".CRT$XDU");
2392 std::vector<llvm::Function *> NonComdatInits;
2393 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2394 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2396 llvm::Function *F = CXXThreadLocalInits[I];
2399 if (llvm::Comdat *
C = GV->getComdat())
2400 AddToXDU(F)->setComdat(
C);
2402 NonComdatInits.push_back(F);
2405 if (!NonComdatInits.empty()) {
2406 llvm::FunctionType *FTy =
2407 llvm::FunctionType::get(CGM.
VoidTy,
false);
2423 llvm::Constant *TlsGuardConstant =
2425 llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant);
2427 TlsGuard->setThreadLocal(
true);
2435 llvm::FunctionType *FTy =
2436 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()), {},
2439 FTy,
"__dyn_tls_on_demand_init",
2441 llvm::AttributeList::FunctionIndex,
2442 llvm::Attribute::NoUnwind),
2447 llvm::BasicBlock *DynInitBB,
2448 llvm::BasicBlock *ContinueBB) {
2449 llvm::LoadInst *TlsGuardValue =
2451 llvm::Value *CmpResult =
2453 CGF.
Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2457 llvm::GlobalValue *TlsGuard,
2458 llvm::BasicBlock *ContinueBB) {
2460 llvm::Function *InitializerFunction =
2462 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(InitializerFunction);
2463 CallVal->setCallingConv(InitializerFunction->getCallingConv());
2465 CGF.
Builder.CreateBr(ContinueBB);
2469 llvm::BasicBlock *DynInitBB =
2471 llvm::BasicBlock *ContinueBB =
2477 CGF.
Builder.SetInsertPoint(DynInitBB);
2479 CGF.
Builder.SetInsertPoint(ContinueBB);
2498 Address Addr(
V, RealVarTy, Alignment);
2502 AlignmentSource::Decl)
2508 StringRef VarName(
"_Init_thread_epoch");
2510 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2512 auto *GV =
new llvm::GlobalVariable(
2514 false, llvm::GlobalVariable::ExternalLinkage,
2516 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2522 llvm::FunctionType *FTy =
2523 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2524 CGM.
IntTy->getPointerTo(),
false);
2526 FTy,
"_Init_thread_header",
2528 llvm::AttributeList::FunctionIndex,
2529 llvm::Attribute::NoUnwind),
2534 llvm::FunctionType *FTy =
2535 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2536 CGM.
IntTy->getPointerTo(),
false);
2538 FTy,
"_Init_thread_footer",
2540 llvm::AttributeList::FunctionIndex,
2541 llvm::Attribute::NoUnwind),
2546 llvm::FunctionType *FTy =
2547 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2548 CGM.
IntTy->getPointerTo(),
false);
2550 FTy,
"_Init_thread_abort",
2552 llvm::AttributeList::FunctionIndex,
2553 llvm::Attribute::NoUnwind),
2561 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2562 : Guard(Guard), GuardNum(GuardNum) {}
2568 llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2569 llvm::ConstantInt *Mask =
2570 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2571 Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2577 CallInitThreadAbort(
RawAddress Guard) : Guard(Guard.getPointer()) {}
2587 llvm::GlobalVariable *GV,
2591 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2593 llvm::Function *F = CGF.
CurFn;
2594 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2595 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2601 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2605 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2608 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2609 llvm::ConstantInt *
Zero = llvm::ConstantInt::get(GuardTy, 0);
2613 GuardInfo *GI =
nullptr;
2614 if (ThreadlocalStatic)
2616 else if (!ThreadsafeStatic)
2619 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2624 GuardNum = getContext().getStaticLocalNumber(&D);
2625 assert(GuardNum > 0);
2627 }
else if (HasPerVariableGuard) {
2631 GuardNum = GI->BitIndex++;
2634 if (!HasPerVariableGuard && GuardNum >= 32) {
2636 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2645 llvm::raw_svector_ostream Out(GuardName);
2646 if (HasPerVariableGuard)
2647 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2650 getMangleContext().mangleStaticGuardVariable(&D, Out);
2656 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2657 GV->getLinkage(), Zero, GuardName.str());
2658 GuardVar->setVisibility(GV->getVisibility());
2659 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2660 GuardVar->setAlignment(GuardAlign.
getAsAlign());
2661 if (GuardVar->isWeakForLinker())
2662 GuardVar->setComdat(
2663 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2666 if (GI && !HasPerVariableGuard)
2667 GI->Guard = GuardVar;
2672 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2673 "static local from the same function had different linkage");
2675 if (!HasPerVariableGuard) {
2683 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2684 llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2685 llvm::Value *NeedsInit =
2686 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
2690 CodeGenFunction::GuardKind::VariableGuard, &D);
2695 Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2699 Builder.CreateBr(EndBlock);
2717 llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2718 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2719 llvm::LoadInst *InitThreadEpoch =
2721 llvm::Value *IsUninitialized =
2722 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2726 CodeGenFunction::GuardKind::VariableGuard, &D);
2732 GuardAddr.getPointer());
2733 llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2734 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2735 llvm::Value *ShouldDoInit =
2736 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2738 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2746 GuardAddr.getPointer());
2747 Builder.CreateBr(EndBlock);
2776 fields.push_back(CGM.
IntTy);
2780 fields.push_back(CGM.
IntTy);
2782 fields.push_back(CGM.
IntTy);
2784 fields.push_back(CGM.
IntTy);
2786 if (fields.size() == 1)
2791void MicrosoftCXXABI::
2794 assert(fields.empty());
2799 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2802 fields.push_back(getZeroInt());
2804 fields.push_back(getAllOnesInt());
2809 fields.push_back(getZeroInt());
2811 fields.push_back(getZeroInt());
2813 fields.push_back(getAllOnesInt());
2819 GetNullMemberPointerFields(MPT, fields);
2820 if (fields.size() == 1)
2822 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2823 assert(Res->getType() == ConvertMemberPointerType(MPT));
2828MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2829 bool IsMemberFunction,
2832 unsigned VBTableIndex) {
2841 fields.push_back(FirstField);
2844 fields.push_back(llvm::ConstantInt::get(
2850 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2856 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2858 return llvm::ConstantStruct::getAnon(fields);
2867llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl *RD,
2870 MSInheritanceModel::Virtual)
2871 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2872 llvm::Constant *FirstField =
2874 return EmitFullMemberPointer(FirstField,
false, RD,
2878llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2883 return EmitNullMemberPointer(DstTy);
2889 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2890 C = EmitMemberFunctionPointer(MD);
2897 const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2899 FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
2902 C = EmitMemberDataPointer(RD, FieldOffset);
2905 if (!MemberPointerPath.empty()) {
2906 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2918 if (DerivedMember) {
2926 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2927 Base->getCanonicalDecl())
2928 DerivedToBasePath.push_back(&BS);
2931 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2933 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2934 : CK_BaseToDerivedMemberPointer;
2935 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2936 DerivedToBasePath.end(),
C);
2942MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2943 assert(MD->
isInstance() &&
"Member function must not be static!");
2949 unsigned VBTableIndex = 0;
2950 llvm::Constant *FirstField;
2955 if (Types.isFuncTypeConvertible(FPT)) {
2957 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
2967 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2971 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2974 if (VBTableIndex == 0 &&
2976 MSInheritanceModel::Virtual)
2977 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2980 return EmitFullMemberPointer(FirstField,
true, RD,
2981 NonVirtualBaseAdjustment, VBTableIndex);
2996 llvm::ICmpInst::Predicate
Eq;
2997 llvm::Instruction::BinaryOps
And,
Or;
2999 Eq = llvm::ICmpInst::ICMP_NE;
3000 And = llvm::Instruction::Or;
3001 Or = llvm::Instruction::And;
3003 Eq = llvm::ICmpInst::ICMP_EQ;
3004 And = llvm::Instruction::And;
3005 Or = llvm::Instruction::Or;
3014 return Builder.CreateICmp(
Eq, L, R);
3017 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
3018 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
3019 llvm::Value *Cmp0 = Builder.CreateICmp(
Eq, L0, R0,
"memptr.cmp.first");
3022 llvm::Value *Res =
nullptr;
3023 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
3024 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3025 llvm::Value *LF = Builder.CreateExtractValue(L, I);
3026 llvm::Value *RF = Builder.CreateExtractValue(R, I);
3027 llvm::Value *Cmp = Builder.CreateICmp(
Eq, LF, RF,
"memptr.cmp.rest");
3029 Res = Builder.CreateBinOp(
And, Res, Cmp);
3037 llvm::Value *
Zero = llvm::Constant::getNullValue(L0->getType());
3038 llvm::Value *IsZero = Builder.CreateICmp(
Eq, L0, Zero,
"memptr.cmp.iszero");
3039 Res = Builder.CreateBinOp(
Or, Res, IsZero);
3044 return Builder.CreateBinOp(
And, Res, Cmp0,
"memptr.cmp");
3049 llvm::Value *MemPtr,
3055 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
3057 GetNullMemberPointerFields(MPT, fields);
3058 assert(!fields.empty());
3059 llvm::Value *FirstField = MemPtr;
3060 if (MemPtr->getType()->isStructTy())
3061 FirstField = Builder.CreateExtractValue(MemPtr, 0);
3062 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
3070 for (
int I = 1, E = fields.size(); I < E; ++I) {
3071 llvm::Value *
Field = Builder.CreateExtractValue(MemPtr, I);
3072 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
3073 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
3079 llvm::Constant *Val) {
3082 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3083 Val->getAggregateElement(0
U) : Val;
3084 return FirstField->isNullValue();
3089 if (isZeroInitializable(MPT) && Val->isNullValue())
3095 GetNullMemberPointerFields(MPT, Fields);
3096 if (Fields.size() == 1) {
3097 assert(Val->getType()->isIntegerTy());
3098 return Val == Fields[0];
3102 for (I = 0, E = Fields.size(); I != E; ++I) {
3103 if (Val->getAggregateElement(I) != Fields[I])
3112 llvm::Value *VBPtrOffset,
3113 llvm::Value *VBTableOffset,
3114 llvm::Value **VBPtrOut) {
3117 llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3118 CGM.
Int8Ty,
This.emitRawPointer(CGF), VBPtrOffset,
"vbptr");
3123 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3124 VBPtrAlign =
This.getAlignment().alignmentAtOffset(
3130 llvm::Value *VBTable = Builder.CreateAlignedLoad(
3131 CGM.
Int32Ty->getPointerTo(0), VBPtr, VBPtrAlign,
"vbtable");
3134 llvm::Value *VBTableIndex = Builder.CreateAShr(
3135 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3139 llvm::Value *VBaseOffs =
3140 Builder.CreateInBoundsGEP(CGM.
Int32Ty, VBTable, VBTableIndex);
3141 return Builder.CreateAlignedLoad(CGM.
Int32Ty, VBaseOffs,
3147llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3149 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3152 llvm::BasicBlock *OriginalBB =
nullptr;
3153 llvm::BasicBlock *SkipAdjustBB =
nullptr;
3154 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3161 OriginalBB = Builder.GetInsertBlock();
3164 llvm::Value *IsVirtual =
3165 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3167 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3179 "member pointer representation requires a "
3180 "complete class type for %0 to perform this expression");
3183 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3186 llvm::Value *VBPtr =
nullptr;
3187 llvm::Value *VBaseOffs =
3188 GetVBaseOffsetFromVBPtr(CGF,
Base, VBPtrOffset, VBTableOffset, &VBPtr);
3189 llvm::Value *AdjustedBase =
3190 Builder.CreateInBoundsGEP(CGM.
Int8Ty, VBPtr, VBaseOffs);
3193 if (VBaseAdjustBB) {
3194 Builder.CreateBr(SkipAdjustBB);
3196 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3197 Phi->addIncoming(
Base.emitRawPointer(CGF), OriginalBB);
3198 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3201 return AdjustedBase;
3204llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3214 llvm::Value *FieldOffset = MemPtr;
3215 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3216 llvm::Value *VBPtrOffset =
nullptr;
3217 if (MemPtr->getType()->isStructTy()) {
3220 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3222 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3224 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3228 if (VirtualBaseAdjustmentOffset) {
3229 Addr = AdjustVirtualBase(CGF, E, RD,
Base, VirtualBaseAdjustmentOffset,
3232 Addr =
Base.emitRawPointer(CGF);
3236 return Builder.CreateInBoundsGEP(CGF.
Int8Ty, Addr, FieldOffset,
3244 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3245 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3249 if (isa<llvm::Constant>(Src))
3250 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3260 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3261 if (IsReinterpret && IsFunc)
3266 if (IsReinterpret &&
3273 llvm::Value *
IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3274 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3278 if (IsReinterpret) {
3281 assert(Src->getType() == DstNull->getType());
3282 return Builder.CreateSelect(
IsNotNull, Src, DstNull);
3285 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3288 Builder.CreateCondBr(
IsNotNull, ConvertBB, ContinueBB);
3291 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3295 Builder.CreateBr(ContinueBB);
3299 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3300 Phi->addIncoming(DstNull, OriginalBB);
3301 Phi->addIncoming(Dst, ConvertBB);
3305llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3315 bool IsConstant = isa<llvm::Constant>(Src);
3318 llvm::Value *FirstField = Src;
3319 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3320 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3321 llvm::Value *VBPtrOffset = getZeroInt();
3325 FirstField = Builder.CreateExtractValue(Src, I++);
3327 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3329 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3331 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3334 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3340 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3347 llvm::Value *SrcVBIndexEqZero =
3348 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3349 if (SrcInheritance == MSInheritanceModel::Virtual) {
3350 if (int64_t SrcOffsetToFirstVBase =
3351 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3352 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3354 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3356 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3367 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3372 llvm::Value *NVDisp;
3373 if (IsDerivedToBase)
3374 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3376 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3378 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3382 llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3385 if (llvm::GlobalVariable *VDispMap =
3386 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3387 llvm::Value *VBIndex = Builder.CreateExactUDiv(
3388 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3390 llvm::Constant *Mapping = VDispMap->getInitializer();
3391 VirtualBaseAdjustmentOffset =
3392 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3394 llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3395 VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3396 CGM.
IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3402 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3409 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3411 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3413 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3419 if (DstInheritance == MSInheritanceModel::Virtual) {
3420 if (int64_t DstOffsetToFirstVBase =
3421 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3422 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3424 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3426 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3435 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3437 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3439 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3441 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3443 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3449MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3450 llvm::Constant *Src) {
3457 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3461llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3465 assert(CK == CK_DerivedToBaseMemberPointer ||
3466 CK == CK_BaseToDerivedMemberPointer ||
3467 CK == CK_ReinterpretMemberPointer);
3470 if (MemberPointerConstantIsNull(SrcTy, Src))
3471 return EmitNullMemberPointer(DstTy);
3476 if (CK == CK_ReinterpretMemberPointer)
3480 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3481 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3486CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3488 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3500 llvm::Value *FunctionPointer = MemPtr;
3501 llvm::Value *NonVirtualBaseAdjustment =
nullptr;
3502 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3503 llvm::Value *VBPtrOffset =
nullptr;
3504 if (MemPtr->getType()->isStructTy()) {
3507 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3509 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3511 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3513 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3516 if (VirtualBaseAdjustmentOffset) {
3517 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3518 VirtualBaseAdjustmentOffset, VBPtrOffset);
3520 ThisPtrForCall =
This.emitRawPointer(CGF);
3523 if (NonVirtualBaseAdjustment)
3524 ThisPtrForCall = Builder.CreateInBoundsGEP(CGF.
Int8Ty, ThisPtrForCall,
3525 NonVirtualBaseAdjustment);
3532 return new MicrosoftCXXABI(CGM);
3566 StringRef MangledName(
"??_7type_info@@6B@");
3567 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3571 llvm::GlobalVariable::ExternalLinkage,
3572 nullptr, MangledName);
3585 IsPrivateOnPath = 1 | 8,
3589 HasHierarchyDescriptor = 64
3595 MSRTTIClass *getFirstChild() {
return this + 1; }
3596 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3597 return Child + 1 + Child->NumBases;
3601 uint32_t Flags, NumBases, OffsetInVBase;
3605uint32_t MSRTTIClass::initialize(
const MSRTTIClass *
Parent,
3607 Flags = HasHierarchyDescriptor;
3609 VirtualRoot =
nullptr;
3613 Flags |= IsPrivate | IsPrivateOnPath;
3619 if (
Parent->Flags & IsPrivateOnPath)
3620 Flags |= IsPrivateOnPath;
3621 VirtualRoot =
Parent->VirtualRoot;
3622 OffsetInVBase =
Parent->OffsetInVBase + RD->getASTContext()
3623 .getASTRecordLayout(
Parent->RD).getBaseClassOffset(RD).getQuantity();
3627 MSRTTIClass *Child = getFirstChild();
3629 NumBases += Child->initialize(
this, &
Base) + 1;
3630 Child = getNextChild(Child);
3635static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3637 case Linkage::Invalid:
3638 llvm_unreachable(
"Linkage hasn't been computed!");
3641 case Linkage::Internal:
3642 case Linkage::UniqueExternal:
3643 return llvm::GlobalValue::InternalLinkage;
3645 case Linkage::VisibleNone:
3646 case Linkage::Module:
3647 case Linkage::External:
3648 return llvm::GlobalValue::LinkOnceODRLinkage;
3650 llvm_unreachable(
"Invalid linkage!");
3656struct MSRTTIBuilder {
3658 HasBranchingHierarchy = 1,
3659 HasVirtualBranchingHierarchy = 2,
3660 HasAmbiguousBases = 4
3663 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3664 : CGM(ABI.CGM), Context(CGM.getContext()),
3665 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3666 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3669 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3670 llvm::GlobalVariable *
3672 llvm::GlobalVariable *getClassHierarchyDescriptor();
3673 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3677 llvm::LLVMContext &VMContext;
3680 llvm::GlobalVariable::LinkageTypes
Linkage;
3681 MicrosoftCXXABI &ABI;
3690 Classes.push_back(MSRTTIClass(RD));
3701 for (MSRTTIClass *
Class = &Classes.front();
Class <= &Classes.back();) {
3702 if ((
Class->Flags & MSRTTIClass::IsVirtual) &&
3703 !VirtualBases.insert(
Class->RD).second) {
3707 if (!UniqueBases.insert(
Class->RD).second)
3708 AmbiguousBases.insert(
Class->RD);
3711 if (AmbiguousBases.empty())
3713 for (MSRTTIClass &
Class : Classes)
3714 if (AmbiguousBases.count(
Class.RD))
3715 Class.Flags |= MSRTTIClass::IsAmbiguous;
3718llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3721 llvm::raw_svector_ostream Out(MangledName);
3722 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3726 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3732 Classes.front().initialize(
nullptr,
nullptr);
3735 for (
const MSRTTIClass &Class : Classes) {
3736 if (
Class.RD->getNumBases() > 1)
3737 Flags |= HasBranchingHierarchy;
3740 if (
Class.Flags & MSRTTIClass::IsAmbiguous)
3741 Flags |= HasAmbiguousBases;
3743 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3744 Flags |= HasVirtualBranchingHierarchy;
3747 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
IntTy, 0),
3748 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3751 auto Type = ABI.getClassHierarchyDescriptorType();
3755 if (CHD->isWeakForLinker())
3756 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3758 auto *Bases = getBaseClassArray(Classes);
3761 llvm::Constant *Fields[] = {
3762 llvm::ConstantInt::get(CGM.
IntTy, 0),
3763 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3764 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3765 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3766 Bases->getValueType(), Bases,
3769 CHD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3773llvm::GlobalVariable *
3777 llvm::raw_svector_ostream Out(MangledName);
3778 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3786 llvm::Type *PtrType = ABI.getImageRelativeType(
3787 ABI.getBaseClassDescriptorType()->getPointerTo());
3788 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3790 new llvm::GlobalVariable(
Module, ArrType,
3792 nullptr, MangledName);
3793 if (BCA->isWeakForLinker())
3794 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3798 for (MSRTTIClass &Class : Classes)
3799 BaseClassArrayData.push_back(
3800 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3801 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3802 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3806llvm::GlobalVariable *
3807MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3810 uint32_t OffsetInVBTable = 0;
3811 int32_t VBPtrOffset = -1;
3812 if (
Class.VirtualRoot) {
3820 llvm::raw_svector_ostream Out(MangledName);
3821 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3822 Class.RD,
Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3827 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3831 auto Type = ABI.getBaseClassDescriptorType();
3834 nullptr, MangledName);
3835 if (BCD->isWeakForLinker())
3836 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3839 llvm::Constant *Fields[] = {
3840 ABI.getImageRelativeConstant(
3842 llvm::ConstantInt::get(CGM.
IntTy,
Class.NumBases),
3843 llvm::ConstantInt::get(CGM.
IntTy,
Class.OffsetInVBase),
3844 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3845 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3846 llvm::ConstantInt::get(CGM.
IntTy,
Class.Flags),
3847 ABI.getImageRelativeConstant(
3848 MSRTTIBuilder(ABI,
Class.RD).getClassHierarchyDescriptor()),
3850 BCD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3854llvm::GlobalVariable *
3855MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3858 llvm::raw_svector_ostream Out(MangledName);
3859 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3863 if (
auto COL =
Module.getNamedGlobal(MangledName))
3868 int VFPtrOffset = 0;
3874 ->second.hasVtorDisp())
3878 llvm::StructType *
Type = ABI.getCompleteObjectLocatorType();
3880 nullptr, MangledName);
3883 llvm::Constant *Fields[] = {
3884 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3885 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3886 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3887 ABI.getImageRelativeConstant(
3889 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3890 ABI.getImageRelativeConstant(COL),
3893 if (!ABI.isImageRelative())
3894 FieldsRef = FieldsRef.drop_back();
3895 COL->setInitializer(llvm::ConstantStruct::get(
Type, FieldsRef));
3896 if (COL->isWeakForLinker())
3897 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3902 bool &IsConst,
bool &IsVolatile,
3903 bool &IsUnaligned) {
3913 IsUnaligned =
false;
3915 if (!PointeeType.
isNull()) {
3936MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3941 bool IsConst, IsVolatile, IsUnaligned;
3965llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3968 llvm::raw_svector_ostream Out(MangledName);
3969 getMangleContext().mangleCXXRTTI(
Type, Out);
3973 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3982 llvm::raw_svector_ostream Out(TypeInfoString);
3983 getMangleContext().mangleCXXRTTIName(
Type, Out);
3987 llvm::Constant *Fields[] = {
3989 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3990 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
3991 llvm::StructType *TypeDescriptorType =
3992 getTypeDescriptorType(TypeInfoString);
3993 auto *Var =
new llvm::GlobalVariable(
3994 CGM.
getModule(), TypeDescriptorType,
false,
3995 getLinkageForRTTI(
Type),
3996 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
3998 if (Var->isWeakForLinker())
3999 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
4004llvm::GlobalVariable *
4005MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
4007 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
4010void MicrosoftCXXABI::emitCXXStructor(
GlobalDecl GD) {
4011 if (
auto *ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
4013 llvm::Function *Fn =
4019 auto *dtor = cast<CXXDestructorDecl>(GD.
getDecl());
4025 dtor->getParent()->getNumVBases() == 0)
4036 if (Fn->isWeakForLinker())
4037 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
4047 llvm::raw_svector_ostream Out(ThunkName);
4048 getMangleContext().mangleName(
GlobalDecl(CD, CT), Out);
4051 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
4052 return cast<llvm::Function>(GV);
4058 QualType RecordTy = getContext().getRecordType(RD);
4059 llvm::Function *ThunkFn = llvm::Function::Create(
4060 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
4061 ThunkFn->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
4063 if (ThunkFn->isWeakForLinker())
4064 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
4075 buildThisParam(CGF, FunctionArgs);
4081 &getContext().Idents.get(
"src"),
4082 getContext().getLValueReferenceType(RecordTy,
4084 ImplicitParamKind::Other);
4086 FunctionArgs.push_back(&SrcParam);
4093 &getContext().Idents.get(
"is_most_derived"),
4094 getContext().IntTy, ImplicitParamKind::Other);
4097 FunctionArgs.push_back(&IsMostDerived);
4105 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4106 llvm::Value *
This = getThisValue(CGF);
4108 llvm::Value *SrcVal =
4125 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
4126 ArgVec.push_back(PD->getDefaultArg());
4129 CodeGenFunction::RunCleanupsScope Cleanups(CGF);
4135 AddedStructorArgCounts ExtraArgs =
4140 llvm::Constant *CalleePtr =
4145 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4148 Cleanups.ForceCleanup();
4157llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
4159 int32_t VBPtrOffset,
4171 uint32_t
Size = getContext().getTypeSizeInChars(
T).getQuantity();
4174 llvm::raw_svector_ostream Out(MangledName);
4175 getMangleContext().mangleCXXCatchableType(
T, CD, CT, Size, NVOffset,
4176 VBPtrOffset, VBIndex, Out);
4178 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4179 return getImageRelativeConstant(GV);
4183 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(
T));
4187 llvm::Constant *CopyCtor;
4194 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4196 CopyCtor = getImageRelativeConstant(CopyCtor);
4198 bool IsScalar = !RD;
4199 bool HasVirtualBases =
false;
4200 bool IsStdBadAlloc =
false;
4215 if (HasVirtualBases)
4220 llvm::Constant *Fields[] = {
4221 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4223 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4224 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4225 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4226 llvm::ConstantInt::get(CGM.
IntTy, Size),
4229 llvm::StructType *CTType = getCatchableTypeType();
4230 auto *GV =
new llvm::GlobalVariable(
4231 CGM.
getModule(), CTType,
true, getLinkageForRTTI(
T),
4232 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4233 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4234 GV->setSection(
".xdata");
4235 if (GV->isWeakForLinker())
4236 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4237 return getImageRelativeConstant(GV);
4240llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4244 llvm::GlobalVariable *&CTA = CatchableTypeArrays[
T];
4269 if (MostDerivedClass) {
4276 Classes.front().initialize(
nullptr,
nullptr);
4278 for (
const MSRTTIClass &Class : Classes) {
4281 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4284 uint32_t OffsetInVBTable = 0;
4285 int32_t VBPtrOffset = -1;
4286 if (
Class.VirtualRoot) {
4297 CatchableTypes.insert(getCatchableType(RTTITy,
Class.OffsetInVBase,
4298 VBPtrOffset, OffsetInVBTable));
4306 CatchableTypes.insert(getCatchableType(
T));
4319 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4330 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4332 uint32_t NumEntries = CatchableTypes.size();
4333 llvm::Type *CTType =
4334 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4335 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4336 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4337 llvm::Constant *Fields[] = {
4338 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4339 llvm::ConstantArray::get(
4341 CatchableTypes.end()))
4345 llvm::raw_svector_ostream Out(MangledName);
4346 getMangleContext().mangleCXXCatchableTypeArray(
T, NumEntries, Out);
4348 CTA =
new llvm::GlobalVariable(
4349 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(
T),
4350 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4351 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4352 CTA->setSection(
".xdata");
4353 if (CTA->isWeakForLinker())
4354 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4358llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4359 bool IsConst, IsVolatile, IsUnaligned;
4364 llvm::GlobalVariable *CTA = getCatchableTypeArray(
T);
4369 uint32_t NumEntries =
4370 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0
U))
4371 ->getLimitedValue();
4375 llvm::raw_svector_ostream Out(MangledName);
4376 getMangleContext().mangleCXXThrowInfo(
T, IsConst, IsVolatile, IsUnaligned,
4382 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4398 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4401 if (!DtorD->isTrivial())
4404 llvm::Constant *ForwardCompat =
4405 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4406 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(CTA);
4407 llvm::StructType *TIType = getThrowInfoType();
4408 llvm::Constant *Fields[] = {
4409 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4410 getImageRelativeConstant(CleanupFn),
4412 PointerToCatchableTypes
4414 auto *GV =
new llvm::GlobalVariable(
4415 CGM.
getModule(), TIType,
true, getLinkageForRTTI(
T),
4416 llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4417 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4418 GV->setSection(
".xdata");
4419 if (GV->isWeakForLinker())
4420 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4426 assert(SubExpr &&
"SubExpr cannot be null");
4436 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4443std::pair<llvm::Value *, const CXXRecordDecl *>
4446 std::tie(This, std::ignore, RD) =
4451bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4483 if (
const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4484 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.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
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="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, 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 CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const 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 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)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
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.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
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
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()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, llvm::Align Alignment)
Will return a global variable of the given type.
llvm::LLVMContext & getLLVMContext()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void addDeferredVTable(const CXXRecordDecl *RD)
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Function * CreateGlobalInitOrCleanUpFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false, llvm::GlobalVariable::LinkageTypes Linkage=llvm::GlobalVariable::InternalLinkage)
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
const ABIInfo & getABIInfo() const
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)
Arrange a thunk that takes 'this' as the first parameter followed by varargs.
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo & arrangeCXXStructorDeclaration(GlobalDecl GD)
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
llvm::Type * getVTableType(const VTableLayout &layout)
Returns the type of a vtable with the given layout.
A specialization of Address that requires the address to be an LLVM Constant.
The standard implementation of ConstantInitBuilder used in Clang.
Information for lazily generating a cleanup.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
An abstract representation of an aligned address.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isInStdNamespace() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
ArrayRef< ParmVarDecl * > parameters() const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Represents a prototype with parameter type info, e.g.
bool isVariadic() const
Whether this function prototype is variadic.
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
GlobalDecl getWithDtorType(CXXDtorType Type)
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
bool isExplicitDefaultVisibilityExportMapping() const
bool isAllDefaultVisibilityExportMapping() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
QualType getPointeeType() const
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
Describes a module or submodule.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
bool isExternallyVisible() const
Represents a parameter to a function.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstQualified() const
Determine whether this type is const-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool hasUnaligned() const
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
Encodes a location in the source.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
const Type * getTypeForDecl() const
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjectType() const
Determine whether this type is an object type.
Linkage getLinkage() const
Determine the linkage of this type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
Represents a single component in a vtable.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
TLSKind getTLSKind() const
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed? If so, the variable need not have a usable destr...
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)
Creates a Microsoft-family ABI.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
GVALinkage
A more specific kind of linkage than enum Linkage.
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)
bool inheritanceModelHasOnlyOneField(bool IsMemberFunction, MSInheritanceModel Inheritance)
bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)
bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
CXXDtorType
C++ destructor types.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
CastKind
CastKind - The kind of operation required for a conversion.
const FunctionProtoType * T
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Implicit
An implicit conversion.
Diagnostic wrappers for TextAPI types for error reporting.
Similar to AddedStructorArgs, but only notes the number of additional arguments.
Additional implicit arguments to add to the beginning (Prefix) and end (Suffix) of a constructor / de...
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
llvm::PointerType * VoidPtrTy
llvm::PointerType * Int8PtrPtrTy
CharUnits getIntAlign() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getIntSize() const
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
uint64_t Index
Method's index in the vftable.
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
A this pointer adjustment.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
Holds information about the inheritance path to a virtual base or function table pointer.
CharUnits NonVirtualOffset
IntroducingObject is at this offset from its containing complete object or virtual base.
CharUnits FullOffsetInMDC
Static offset from the top of the most derived class to this vfptr, including any virtual base offset...
const CXXRecordDecl * getVBaseWithVPtr() const
The vptr is stored inside the non-virtual component of this virtual base.
const CXXRecordDecl * IntroducingObject
This is the class that introduced the vptr by declaring new virtual methods or virtual bases.
BasePath MangledPath
The bases from the inheritance path that got used to mangle the vbtable name.
BasePath PathToIntroducingObject
This holds the base classes path from the complete type to the first base with the given vfptr offset...
const CXXRecordDecl * ObjectWithVPtr
This is the most derived class that has this vptr at offset zero.
uint32_t VBPtrOffset
The offset (in bytes) of the vbptr, relative to the beginning of the derived class.
struct clang::ReturnAdjustment::VirtualAdjustment::@187 Microsoft
uint32_t VBIndex
Index of the virtual base in the vbtable.
struct clang::ThisAdjustment::VirtualAdjustment::@189 Microsoft
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...