32#include "llvm/ADT/StringExtras.h"
33#include "llvm/ADT/StringSet.h"
34#include "llvm/IR/Intrinsics.h"
42struct VBTableGlobals {
44 SmallVector<llvm::GlobalVariable *, 2> Globals;
47class MicrosoftCXXABI :
public CGCXXABI {
49 MicrosoftCXXABI(CodeGenModule &CGM)
50 : CGCXXABI(CGM), BaseClassDescriptorType(
nullptr),
51 ClassHierarchyDescriptorType(
nullptr),
56 "visibility export mapping option unimplemented in this ABI");
59 bool HasThisReturn(GlobalDecl GD)
const override;
60 bool hasMostDerivedReturn(GlobalDecl GD)
const override;
66 bool isSRetParameterAfterThis()
const override {
return true; }
68 bool isThisCompleteObject(GlobalDecl GD)
const override {
80 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
82 llvm_unreachable(
"unexpected unified dtor type");
84 llvm_unreachable(
"bad dtor kind");
91 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *CD,
92 FunctionArgList &Args)
const override {
93 assert(Args.size() >= 2 &&
94 "expected the arglist to have at least two args!");
103 std::vector<CharUnits> getVBPtrOffsets(
const CXXRecordDecl *RD)
override {
104 std::vector<CharUnits> VBPtrOffsets;
105 const ASTContext &Context = getContext();
106 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
108 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
109 for (
const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
110 const ASTRecordLayout &SubobjectLayout =
111 Context.getASTRecordLayout(VBT->IntroducingObject);
112 CharUnits Offs = VBT->NonVirtualOffset;
114 if (VBT->getVBaseWithVPtr())
116 VBPtrOffsets.push_back(Offs);
118 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
122 StringRef GetPureVirtualCallName()
override {
return "_purecall"; }
123 StringRef GetDeletedVirtualCallName()
override {
return "_purecall"; }
125 void emitVirtualObjectDelete(CodeGenFunction &CGF,
const CXXDeleteExpr *DE,
126 Address Ptr, QualType ElementType,
127 const CXXDestructorDecl *Dtor)
override;
129 void emitRethrow(CodeGenFunction &CGF,
bool isNoReturn)
override;
130 void emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E)
override;
132 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
134 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
135 const VPtrInfo &Info);
137 llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty)
override;
139 getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)
override;
142 CatchTypeInfo getCatchAllTypeInfo()
override {
145 if (getContext().getLangOpts().EHAsynch)
146 return CatchTypeInfo{
nullptr, 0};
148 return CatchTypeInfo{
nullptr, 0x40};
151 bool shouldTypeidBeNullChecked(QualType SrcRecordTy)
override;
152 void EmitBadTypeidCall(CodeGenFunction &CGF)
override;
153 llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
155 llvm::Type *StdTypeInfoPtrTy)
override;
157 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
158 QualType SrcRecordTy)
override;
160 bool shouldEmitExactDynamicCast(QualType DestRecordTy)
override {
164 std::optional<ExactDynamicCastInfo>
165 getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
166 QualType DestRecordTy)
override {
167 llvm_unreachable(
"unsupported");
170 QualType SrcRecordTy, QualType DestTy,
171 QualType DestRecordTy,
172 const ExactDynamicCastInfo &CastInfo,
173 llvm::BasicBlock *CastSuccess,
174 llvm::BasicBlock *CastFail)
override {
175 llvm_unreachable(
"unsupported");
178 llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address
Value,
179 QualType SrcRecordTy, QualType DestTy,
180 QualType DestRecordTy,
181 llvm::BasicBlock *CastEnd)
override;
184 QualType SrcRecordTy)
override;
186 bool EmitBadCastCall(CodeGenFunction &CGF)
override;
187 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override {
192 GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
193 const CXXRecordDecl *ClassDecl,
194 const CXXRecordDecl *BaseClassDecl)
override;
197 EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
198 const CXXRecordDecl *RD)
override;
201 EmitDtorCompleteObjectHandler(CodeGenFunction &CGF);
203 void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF,
204 const CXXRecordDecl *RD)
override;
206 void EmitCXXConstructors(
const CXXConstructorDecl *D)
override;
240 AddedStructorArgCounts
241 buildStructorSignature(GlobalDecl GD,
242 SmallVectorImpl<CanQualType> &ArgTys)
override;
245 bool useThunkForDtorVariant(
const CXXDestructorDecl *Dtor,
250 void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
251 const CXXDestructorDecl *Dtor,
254 llvm::GlobalValue::LinkageTypes
258 void EmitCXXDestructors(
const CXXDestructorDecl *D)
override;
260 const CXXRecordDecl *getThisArgumentTypeForMethod(GlobalDecl GD)
override {
263 if (MD->isVirtual()) {
264 GlobalDecl LookupGD = GD;
265 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
269 return MD->getParent();
273 LookupGD = GlobalDecl(
279 MethodVFTableLocation ML =
291 return MD->getParent();
295 adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD,
297 bool VirtualCall)
override;
299 void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
300 FunctionArgList &Params)
override;
302 void EmitInstanceFunctionProlog(CodeGenFunction &CGF)
override;
304 AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
305 const CXXConstructorDecl *D,
311 const CXXDestructorDecl *DD,
316 void EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
319 QualType ThisTy)
override;
321 void emitVTableTypeMetadata(
const VPtrInfo &Info,
const CXXRecordDecl *RD,
322 llvm::GlobalVariable *VTable);
324 void emitVTableDefinitions(CodeGenVTables &CGVT,
325 const CXXRecordDecl *RD)
override;
327 bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
328 CodeGenFunction::VPtr Vptr)
override;
332 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
333 return !VTableClass->
hasAttr<MSNoVTableAttr>();
337 getVTableAddressPoint(BaseSubobject Base,
338 const CXXRecordDecl *VTableClass)
override;
340 llvm::Value *getVTableAddressPointInStructor(
341 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
342 BaseSubobject Base,
const CXXRecordDecl *NearestVBase)
override;
344 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
345 CharUnits VPtrOffset)
override;
347 CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
348 Address This, llvm::Type *Ty,
349 SourceLocation Loc)
override;
352 EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
354 DeleteOrMemberCallExpr E,
355 llvm::CallBase **CallOrInvoke)
override;
357 void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
358 CallArgList &CallArgs)
override {
361 "Only vector deleting destructor thunks are available in this ABI");
366 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
368 llvm::GlobalVariable *
369 getAddrOfVBTable(
const VPtrInfo &VBT,
const CXXRecordDecl *RD,
370 llvm::GlobalVariable::LinkageTypes
Linkage);
372 llvm::GlobalVariable *
373 getAddrOfVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
374 const CXXRecordDecl *DstRD) {
375 SmallString<256> OutName;
376 llvm::raw_svector_ostream
Out(OutName);
377 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
378 StringRef MangledName = OutName.str();
380 if (
auto *VDispMap = CGM.
getModule().getNamedGlobal(MangledName))
385 SmallVector<llvm::Constant *, 4> Map(NumEntries,
386 llvm::PoisonValue::get(CGM.
IntTy));
387 Map[0] = llvm::ConstantInt::get(CGM.
IntTy, 0);
388 bool AnyDifferent =
false;
389 for (
const auto &I : SrcRD->
vbases()) {
390 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
396 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.
IntTy, DstVBIndex * 4);
397 AnyDifferent |= SrcVBIndex != DstVBIndex;
403 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.
IntTy, Map.size());
404 llvm::Constant *
Init = llvm::ConstantArray::get(VDispMapTy, Map);
405 llvm::GlobalValue::LinkageTypes
Linkage =
407 ? llvm::GlobalValue::LinkOnceODRLinkage
408 : llvm::GlobalValue::InternalLinkage;
409 auto *VDispMap =
new llvm::GlobalVariable(
415 void emitVBTableDefinition(
const VPtrInfo &VBT,
const CXXRecordDecl *RD,
416 llvm::GlobalVariable *GV)
const;
418 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
419 GlobalDecl GD,
bool ReturnAdjustment)
override {
424 Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
425 else if (ReturnAdjustment)
426 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
428 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
431 bool exportThunk()
override {
return false; }
433 llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
434 const CXXRecordDecl * ,
435 const ThunkInfo &TI)
override;
438 const CXXRecordDecl * ,
439 const ReturnAdjustment &RA)
override;
441 void EmitThreadLocalInitFuncs(
442 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
443 ArrayRef<llvm::Function *> CXXThreadLocalInits,
444 ArrayRef<const VarDecl *> CXXThreadLocalInitVars)
override;
446 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
447 return getContext().getLangOpts().isCompatibleWithMSVC(
448 LangOptions::MSVC2019_5) &&
450 (!isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD));
452 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
const VarDecl *VD,
453 QualType LValType)
override;
455 void EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
456 llvm::GlobalVariable *DeclPtr,
457 bool PerformInit)
override;
458 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
459 llvm::FunctionCallee Dtor,
460 llvm::Constant *
Addr)
override;
485 bool requiresArrayCookie(
const CXXDeleteExpr *
expr,
486 QualType elementType)
override;
487 bool requiresArrayCookie(
const CXXNewExpr *
expr)
override;
488 CharUnits getArrayCookieSizeImpl(QualType
type)
override;
489 Address InitializeArrayCookie(CodeGenFunction &CGF,
491 llvm::Value *NumElements,
492 const CXXNewExpr *
expr,
493 QualType ElementType)
override;
494 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
496 CharUnits cookieSize)
override;
498 friend struct MSRTTIBuilder;
500 bool isImageRelative()
const {
505 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
506 llvm::SmallString<32> TDTypeName(
"rtti.TypeDescriptor");
507 TDTypeName += llvm::utostr(TypeInfoString.size());
508 llvm::StructType *&TypeDescriptorType =
509 TypeDescriptorTypeMap[TypeInfoString.size()];
510 if (TypeDescriptorType)
511 return TypeDescriptorType;
512 llvm::Type *FieldTypes[] = {
515 llvm::ArrayType::get(CGM.
Int8Ty, TypeInfoString.size() + 1)};
517 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, TDTypeName);
518 return TypeDescriptorType;
521 llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
522 if (!isImageRelative())
527 llvm::StructType *getBaseClassDescriptorType() {
528 if (BaseClassDescriptorType)
529 return BaseClassDescriptorType;
530 llvm::Type *FieldTypes[] = {
539 BaseClassDescriptorType = llvm::StructType::create(
541 return BaseClassDescriptorType;
544 llvm::StructType *getClassHierarchyDescriptorType() {
545 if (ClassHierarchyDescriptorType)
546 return ClassHierarchyDescriptorType;
550 ClassHierarchyDescriptorType =
551 llvm::StructType::create(FieldTypes,
"rtti.ClassHierarchyDescriptor");
552 return ClassHierarchyDescriptorType;
555 llvm::StructType *getCompleteObjectLocatorType() {
556 if (CompleteObjectLocatorType)
557 return CompleteObjectLocatorType;
558 llvm::Type *FieldTypes[] = {
564 getImageRelativeType(CGM.
VoidTy),
566 llvm::ArrayRef<llvm::Type *> FieldTypesRef(FieldTypes);
567 if (!isImageRelative())
568 FieldTypesRef = FieldTypesRef.drop_back();
569 CompleteObjectLocatorType =
570 llvm::StructType::create(FieldTypesRef,
"rtti.CompleteObjectLocator");
571 return CompleteObjectLocatorType;
574 llvm::GlobalVariable *getImageBase() {
575 StringRef Name =
"__ImageBase";
576 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name))
581 llvm::GlobalValue::ExternalLinkage,
587 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
588 if (!isImageRelative())
591 if (PtrVal->isNullValue())
592 return llvm::Constant::getNullValue(CGM.
IntTy);
594 llvm::Constant *ImageBaseAsInt =
595 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.
IntPtrTy);
596 llvm::Constant *PtrValAsInt =
597 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.
IntPtrTy);
598 llvm::Constant *Diff =
599 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
601 return llvm::ConstantExpr::getTrunc(Diff, CGM.
IntTy);
605 MicrosoftMangleContext &getMangleContext() {
609 llvm::Constant *getZeroInt() {
610 return llvm::ConstantInt::get(CGM.
IntTy, 0);
613 llvm::Constant *getAllOnesInt() {
614 return llvm::Constant::getAllOnesValue(CGM.
IntTy);
617 CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)
override;
620 GetNullMemberPointerFields(
const MemberPointerType *MPT,
621 llvm::SmallVectorImpl<llvm::Constant *> &fields);
626 llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
628 llvm::Value *VBPtrOffset,
629 llvm::Value *VBTableOffset,
630 llvm::Value **VBPtr =
nullptr);
632 llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
636 llvm::Value **VBPtr =
nullptr) {
637 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
638 llvm::Value *VBPOffset =
639 llvm::ConstantInt::getSigned(CGM.
IntTy, VBPtrOffset);
640 llvm::Value *VBTOffset = llvm::ConstantInt::get(CGM.
IntTy, VBTableOffset);
641 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
644 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
645 performBaseAdjustment(CodeGenFunction &CGF, Address
Value,
646 QualType SrcRecordTy);
650 llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF,
const Expr *E,
651 const CXXRecordDecl *RD, Address Base,
652 llvm::Value *VirtualBaseAdjustmentOffset,
653 llvm::Value *VBPtrOffset );
657 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
658 bool IsMemberFunction,
659 const CXXRecordDecl *RD,
660 CharUnits NonVirtualBaseAdjustment,
661 unsigned VBTableIndex);
663 bool MemberPointerConstantIsNull(
const MemberPointerType *MPT,
667 void EmitVBPtrStores(CodeGenFunction &CGF,
const CXXRecordDecl *RD);
670 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
673 llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
674 const MethodVFTableLocation &ML);
676 llvm::Constant *EmitMemberDataPointer(
const CXXRecordDecl *RD,
680 llvm::Type *ConvertMemberPointerType(
const MemberPointerType *MPT)
override;
682 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
684 bool isMemberPointerConvertible(
const MemberPointerType *MPT)
const override {
686 return RD->
hasAttr<MSInheritanceAttr>();
689 llvm::Constant *EmitNullMemberPointer(
const MemberPointerType *MPT)
override;
691 llvm::Constant *EmitMemberDataPointer(
const MemberPointerType *MPT,
692 CharUnits offset)
override;
693 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
694 llvm::Constant *EmitMemberPointer(
const APValue &MP, QualType MPT)
override;
696 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
699 const MemberPointerType *MPT,
700 bool Inequality)
override;
702 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
704 const MemberPointerType *MPT)
override;
706 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
const Expr *E,
707 Address Base, llvm::Value *MemPtr,
708 const MemberPointerType *MPT,
709 bool IsInBounds)
override;
711 llvm::Value *EmitNonNullMemberPointerConversion(
712 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
715 CGBuilderTy &Builder);
717 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
719 llvm::Value *Src)
override;
721 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
722 llvm::Constant *Src)
override;
724 llvm::Constant *EmitMemberPointerConversion(
725 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
730 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
const Expr *E,
731 Address This, llvm::Value *&ThisPtrForCall,
733 const MemberPointerType *MPT)
override;
735 void emitCXXStructor(GlobalDecl GD)
override;
737 llvm::StructType *getCatchableTypeType() {
738 if (CatchableTypeType)
739 return CatchableTypeType;
740 llvm::Type *FieldTypes[] = {
749 CatchableTypeType = llvm::StructType::create(
751 return CatchableTypeType;
754 llvm::StructType *getCatchableTypeArrayType(
uint32_t NumEntries) {
755 llvm::StructType *&CatchableTypeArrayType =
756 CatchableTypeArrayTypeMap[NumEntries];
757 if (CatchableTypeArrayType)
758 return CatchableTypeArrayType;
760 llvm::SmallString<23> CTATypeName(
"eh.CatchableTypeArray.");
761 CTATypeName += llvm::utostr(NumEntries);
762 llvm::Type *CTType = getImageRelativeType(CGM.
DefaultPtrTy);
763 llvm::Type *FieldTypes[] = {
765 llvm::ArrayType::get(CTType, NumEntries)
767 CatchableTypeArrayType =
768 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, CTATypeName);
769 return CatchableTypeArrayType;
772 llvm::StructType *getThrowInfoType() {
774 return ThrowInfoType;
775 llvm::Type *FieldTypes[] = {
781 ThrowInfoType = llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes,
783 return ThrowInfoType;
790 llvm::FunctionType *FTy =
791 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
792 llvm::FunctionCallee Throw =
796 if (
auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
797 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
802 llvm::Function *getAddrOfCXXCtorClosure(
const CXXConstructorDecl *CD,
805 llvm::Constant *getCatchableType(QualType T,
810 llvm::GlobalVariable *getCatchableTypeArray(QualType T);
812 llvm::GlobalVariable *getThrowInfo(QualType T)
override;
814 std::pair<llvm::Value *, const CXXRecordDecl *>
815 LoadVTablePtr(CodeGenFunction &CGF, Address This,
816 const CXXRecordDecl *RD)
override;
819 isPermittedToBeHomogeneousAggregate(
const CXXRecordDecl *RD)
const override;
822 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
823 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
824 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
826 VFTablesMapTy VFTablesMap;
827 VTablesMapTy VTablesMap;
830 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
834 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
839 GuardInfo() =
default;
840 llvm::GlobalVariable *Guard =
nullptr;
841 unsigned BitIndex = 0;
846 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
847 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
848 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
850 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
851 llvm::StructType *BaseClassDescriptorType;
852 llvm::StructType *ClassHierarchyDescriptorType;
853 llvm::StructType *CompleteObjectLocatorType;
855 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
857 llvm::StructType *CatchableTypeType;
858 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
859 llvm::StructType *ThrowInfoType;
865MicrosoftCXXABI::getRecordArgABI(
const CXXRecordDecl *RD)
const {
877 case llvm::Triple::thumb:
883 case llvm::Triple::x86: {
889 getContext().getTypeInfo(getContext().getCanonicalTagType(RD));
895 return RAA_DirectInMemory;
898 case llvm::Triple::x86_64:
899 case llvm::Triple::aarch64:
903 llvm_unreachable(
"invalid enum");
906void MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
907 const CXXDeleteExpr *DE,
909 QualType ElementType,
910 const CXXDestructorDecl *Dtor) {
913 if (!getContext().getTargetInfo().callGlobalDeleteInDeletingDtor(
914 getContext().getLangOpts())) {
917 llvm::Value *MDThis =
918 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
928void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF,
bool isNoReturn) {
929 llvm::Value *Args[] = {llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
938void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
939 const CXXCatchStmt *S) {
943 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
944 llvm::CatchPadInst *CPI =
956 CPI->setArgOperand(2,
var.getObjectAddress(CGF).emitRawPointer(CGF));
964std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
965MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address
Value,
966 QualType SrcRecordTy) {
969 const ASTContext &Context = getContext();
975 return std::make_tuple(
Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
980 const CXXRecordDecl *PolymorphicBase =
nullptr;
981 for (
auto &Base : SrcDecl->
vbases()) {
982 const CXXRecordDecl *BaseDecl =
Base.getType()->getAsCXXRecordDecl();
984 PolymorphicBase = BaseDecl;
988 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
990 llvm::Value *Offset =
991 GetVirtualBaseClassOffset(CGF,
Value, SrcDecl, PolymorphicBase);
993 Value.getElementType(),
Value.emitRawPointer(CGF), Offset);
994 CharUnits VBaseAlign =
996 return std::make_tuple(
Address(Ptr, CGF.
Int8Ty, VBaseAlign), Offset,
1000bool MicrosoftCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
1002 return !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1006 llvm::Value *Argument) {
1007 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1008 llvm::FunctionType *FTy =
1009 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
1010 llvm::Value *Args[] = {Argument};
1015void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1016 llvm::CallBase *
Call =
1018 Call->setDoesNotReturn();
1019 CGF.
Builder.CreateUnreachable();
1022llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
1023 QualType SrcRecordTy,
1025 llvm::Type *StdTypeInfoPtrTy) {
1026 std::tie(ThisPtr, std::ignore, std::ignore) =
1027 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
1029 return CGF.
Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
1032bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1033 QualType SrcRecordTy) {
1036 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1039llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
1040 CodeGenFunction &CGF, Address This, QualType SrcRecordTy, QualType DestTy,
1041 QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1042 llvm::Value *SrcRTTI =
1044 llvm::Value *DestRTTI =
1047 llvm::Value *Offset;
1048 std::tie(This, Offset, std::ignore) =
1049 performBaseAdjustment(CGF, This, SrcRecordTy);
1050 llvm::Value *ThisPtr =
This.emitRawPointer(CGF);
1062 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1064 llvm::Value *Args[] = {
1065 ThisPtr, Offset, SrcRTTI, DestRTTI,
1070llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
1072 QualType SrcRecordTy) {
1073 std::tie(
Value, std::ignore, std::ignore) =
1074 performBaseAdjustment(CGF,
Value, SrcRecordTy);
1078 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1080 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1082 llvm::Value *Args[] = {
Value.emitRawPointer(CGF)};
1086bool MicrosoftCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1090llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1091 CodeGenFunction &CGF, Address This,
const CXXRecordDecl *ClassDecl,
1092 const CXXRecordDecl *BaseClassDecl) {
1093 const ASTContext &Context = getContext();
1096 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.
PtrDiffTy, VBPtrChars);
1098 CharUnits VBTableChars =
1101 llvm::Value *VBTableOffset =
1104 llvm::Value *VBPtrToNewBase =
1105 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1108 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1111bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD)
const {
1121bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD)
const {
1131 uint64_t NumElts = 0;
1171 if (
auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
1172 if (Ctor->isUserProvided())
1174 }
else if (
auto *
Template = dyn_cast<FunctionTemplateDecl>(D)) {
1177 }
else if (
auto *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
1178 if (MethodDecl->isCopyAssignmentOperator() && MethodDecl->isDeleted())
1187bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI)
const {
1188 const CXXRecordDecl *RD = FI.
getReturnType()->getAsCXXRecordDecl();
1198 if (isIndirectReturn) {
1220MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
1221 const CXXRecordDecl *RD) {
1222 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1223 assert(IsMostDerivedClass &&
1224 "ctor for a class with virtual bases must have an implicit parameter");
1225 llvm::Value *IsCompleteObject =
1226 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1228 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1229 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1230 CGF.
Builder.CreateCondBr(IsCompleteObject,
1231 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1236 EmitVBPtrStores(CGF, RD);
1240 return SkipVbaseCtorsBB;
1244MicrosoftCXXABI::EmitDtorCompleteObjectHandler(CodeGenFunction &CGF) {
1245 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1246 assert(IsMostDerivedClass &&
1247 "ctor for a class with virtual bases must have an implicit parameter");
1248 llvm::Value *IsCompleteObject =
1249 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1251 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1252 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1253 CGF.
Builder.CreateCondBr(IsCompleteObject,
1254 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1259 return SkipVbaseDtorsBB;
1262void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1263 CodeGenFunction &CGF,
const CXXRecordDecl *RD) {
1277 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
1280 CGBuilderTy &Builder = CGF.
Builder;
1282 llvm::Value *Int8This =
nullptr;
1284 for (
const CXXBaseSpecifier &S : RD->
vbases()) {
1285 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1286 auto I = VBaseMap.find(VBase);
1287 assert(I != VBaseMap.end());
1288 if (!I->second.hasVtorDisp())
1291 llvm::Value *VBaseOffset =
1292 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1293 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1296 llvm::Value *VtorDispValue = Builder.CreateSub(
1297 VBaseOffset, llvm::ConstantInt::get(CGM.
PtrDiffTy, ConstantVBaseOffset),
1299 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1302 Int8This = getThisValue(CGF);
1304 llvm::Value *VtorDispPtr =
1305 Builder.CreateInBoundsGEP(CGF.
Int8Ty, Int8This, VBaseOffset);
1307 VtorDispPtr = Builder.CreateConstGEP1_32(CGF.
Int8Ty, VtorDispPtr, -4);
1309 Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1316 CallingConv ExpectedCallingConv = Context.getDefaultCallingConvention(
1320 return ExpectedCallingConv == ActualCallingConv;
1323void MicrosoftCXXABI::EmitCXXConstructors(
const CXXConstructorDecl *D) {
1335 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1341void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
1342 const CXXRecordDecl *RD) {
1345 const ASTContext &Context = getContext();
1348 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1349 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1350 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1351 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1352 const ASTRecordLayout &SubobjectLayout =
1354 CharUnits Offs = VBT->NonVirtualOffset;
1356 if (VBT->getVBaseWithVPtr())
1359 llvm::Value *GVPtr =
1366CGCXXABI::AddedStructorArgCounts
1367MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
1368 SmallVectorImpl<CanQualType> &ArgTys) {
1369 AddedStructorArgCounts Added;
1375 ArgTys.push_back(getContext().IntTy);
1378 auto *CD = dyn_cast<CXXConstructorDecl>(GD.
getDecl());
1386 const FunctionProtoType *FPT = CD->
getType()->
castAs<FunctionProtoType>();
1387 if (
Class->getNumVBases()) {
1389 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1392 ArgTys.push_back(getContext().IntTy);
1400void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1401 const CXXDestructorDecl *Dtor,
1406 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1408 const NamedDecl *ND = Dtor;
1413llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1418 return llvm::GlobalValue::InternalLinkage;
1429 if (Dtor->
hasAttr<DLLExportAttr>())
1430 return llvm::GlobalValue::WeakODRLinkage;
1431 if (Dtor->
hasAttr<DLLImportAttr>())
1432 return llvm::GlobalValue::AvailableExternallyLinkage;
1433 return llvm::GlobalValue::LinkOnceODRLinkage;
1438 return llvm::GlobalValue::LinkOnceODRLinkage;
1440 llvm_unreachable(
"MS C++ ABI does not support unified dtors");
1446 return llvm::GlobalValue::WeakAnyLinkage;
1448 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1450 llvm_unreachable(
"invalid dtor type");
1453void MicrosoftCXXABI::EmitCXXDestructors(
const CXXDestructorDecl *D) {
1467MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
1470 if (
const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1485 MethodVFTableLocation ML =
1497 const ASTRecordLayout &DerivedLayout =
1498 getContext().getASTRecordLayout(MD->
getParent());
1505Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1506 CodeGenFunction &CGF, GlobalDecl GD, Address This,
1511 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1522 GlobalDecl LookupGD = GD;
1523 if (
const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1537 MethodVFTableLocation ML =
1552 const CXXRecordDecl *Derived = MD->
getParent();
1553 const CXXRecordDecl *VBase = ML.
VBase;
1554 llvm::Value *VBaseOffset =
1555 GetVirtualBaseClassOffset(CGF,
Result, Derived, VBase);
1557 Result.getElementType(),
Result.emitRawPointer(CGF), VBaseOffset);
1558 CharUnits VBaseAlign =
1562 if (!StaticOffset.
isZero()) {
1578void MicrosoftCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1580 FunctionArgList &Params) {
1581 ASTContext &Context = getContext();
1588 ImplicitParamKind::Other);
1591 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
1593 Params.insert(Params.begin() + 1, IsMostDerived);
1595 Params.push_back(IsMostDerived);
1596 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1601 ImplicitParamKind::Other);
1602 Params.push_back(ShouldDelete);
1603 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1607void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1624 llvm::Value *
This = loadIncomingCXXThis(CGF);
1627 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1628 if (!Adjustment.
isZero()) {
1634 setCXXABIThisValue(CGF, This);
1644 if (HasThisReturn(CGF.
CurGD) || hasMostDerivedReturn(CGF.
CurGD))
1648 assert(getStructorImplicitParamDecl(CGF) &&
1649 "no implicit parameter for a constructor with virtual bases?");
1650 getStructorImplicitParamValue(CGF)
1657 assert(getStructorImplicitParamDecl(CGF) &&
1658 "no implicit parameter for a deleting destructor?");
1659 getStructorImplicitParamValue(CGF)
1662 "should_call_delete");
1666CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs(
1673 return AddedStructorArgs{};
1676 const FunctionProtoType *FPT = D->
getType()->
castAs<FunctionProtoType>();
1677 llvm::Value *MostDerivedArg;
1679 MostDerivedArg = getStructorImplicitParamValue(CGF);
1684 return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1686 return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1689llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
1695void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
1696 const CXXDestructorDecl *DD,
1706 GlobalDecl GD(DD,
Type);
1710 assert(
Type != CXXDtorType::Dtor_Deleting &&
1711 "The deleting destructor should only be called via a virtual call");
1712 This = adjustThisArgumentForVirtualFunctionCall(CGF, GlobalDecl(DD,
Type),
1716 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1718 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1727 QualType(),
nullptr);
1728 if (BaseDtorEndBB) {
1730 CGF.
Builder.CreateBr(BaseDtorEndBB);
1735void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1736 const CXXRecordDecl *RD,
1737 llvm::GlobalVariable *VTable) {
1748 llvm::DenseSet<const CXXRecordDecl *> Visited;
1749 llvm::GlobalObject::VCallVisibility TypeVis =
1751 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1752 VTable->setVCallVisibilityMetadata(TypeVis);
1758 CharUnits AddressPoint =
1759 getContext().getLangOpts().RTTIData
1760 ? getContext().toCharUnitsFromBits(
1761 getContext().getTargetInfo().getPointerWidth(LangAS::Default))
1779 const ASTRecordLayout &Layout =
1780 getContext().getASTRecordLayout(DerivedRD);
1786 Offset = VBI->second.VBaseOffset;
1797void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
1798 const CXXRecordDecl *RD) {
1802 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1803 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1804 if (VTable->hasInitializer())
1807 const VTableLayout &VTLayout =
1810 llvm::Constant *RTTI =
nullptr;
1812 [](
const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
1813 RTTI = getMSCompleteObjectLocator(RD, *Info);
1815 ConstantInitBuilder builder(CGM);
1816 auto components = builder.beginStruct();
1818 VTable->hasLocalLinkage());
1819 components.finishAndSetAsInitializer(VTable);
1821 emitVTableTypeMetadata(*Info, RD, VTable);
1825bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1826 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
1830llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1831 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
1832 const CXXRecordDecl *NearestVBase) {
1833 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1834 if (!VTableAddressPoint) {
1835 assert(
Base.getBase()->getNumVBases() &&
1836 !getContext().getASTRecordLayout(
Base.getBase()).hasOwnVFPtr());
1838 return VTableAddressPoint;
1844 llvm::raw_svector_ostream Out(Name);
1849MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base,
1850 const CXXRecordDecl *VTableClass) {
1851 (void)getAddrOfVTable(VTableClass,
Base.getBaseOffset());
1852 VFTableIdTy
ID(VTableClass,
Base.getBaseOffset());
1853 return VFTablesMap[
ID];
1856llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1857 CharUnits VPtrOffset) {
1862 VFTableIdTy
ID(RD, VPtrOffset);
1863 auto [I, Inserted] = VTablesMap.try_emplace(ID);
1867 llvm::GlobalVariable *&VTable = I->second;
1872 if (DeferredVFTables.insert(RD).second) {
1880 llvm::StringSet<> ObservedMangledNames;
1881 for (
const auto &VFPtr : VFPtrs) {
1882 SmallString<256> Name;
1884 if (!ObservedMangledNames.insert(Name.str()).second)
1885 llvm_unreachable(
"Already saw this mangling before?");
1890 const std::unique_ptr<VPtrInfo> *VFPtrI =
1891 llvm::find_if(VFPtrs, [&](
const std::unique_ptr<VPtrInfo> &VPI) {
1892 return VPI->FullOffsetInMDC == VPtrOffset;
1894 if (VFPtrI == VFPtrs.end()) {
1895 VFTablesMap[
ID] =
nullptr;
1898 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1900 SmallString<256> VFTableName;
1910 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1911 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1912 : CGM.getVTableLinkage(RD);
1913 bool VFTableComesFromAnotherTU =
1914 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1915 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1916 bool VTableAliasIsRequred =
1917 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1919 if (llvm::GlobalValue *VFTable =
1920 CGM.
getModule().getNamedGlobal(VFTableName)) {
1921 VFTablesMap[
ID] = VFTable;
1922 VTable = VTableAliasIsRequred
1925 :
cast<llvm::GlobalVariable>(VFTable);
1929 const VTableLayout &VTLayout =
1931 llvm::GlobalValue::LinkageTypes VTableLinkage =
1932 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1934 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1936 llvm::Type *VTableType = CGM.
getVTables().getVTableType(VTLayout);
1940 llvm::GlobalValue *VFTable;
1941 VTable =
new llvm::GlobalVariable(CGM.
getModule(), VTableType,
1942 true, VTableLinkage,
1943 nullptr, VTableName);
1945 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1947 llvm::Comdat *
C =
nullptr;
1948 if (!VFTableComesFromAnotherTU &&
1949 llvm::GlobalValue::isWeakForLinker(VFTableLinkage))
1950 C = CGM.
getModule().getOrInsertComdat(VFTableName.str());
1955 if (VTableAliasIsRequred) {
1956 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1957 llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1958 llvm::ConstantInt::get(CGM.
Int32Ty, 1)};
1961 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1962 VTable->getValueType(), VTable, GEPIndices);
1963 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1964 VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1966 C->setSelectionKind(llvm::Comdat::Largest);
1968 VFTable = llvm::GlobalAlias::create(CGM.
Int8PtrTy,
1970 VFTableName.str(), VTableGEP,
1973 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1982 VTable->setComdat(
C);
1984 if (RD->
hasAttr<DLLExportAttr>())
1985 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1987 VFTablesMap[
ID] = VFTable;
1991CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
1995 SourceLocation Loc) {
1996 CGBuilderTy &Builder = CGF.
Builder;
2000 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
2003 llvm::Value *VTable =
2011 auto getObjectWithVPtr = [&] {
2014 [&](
const std::unique_ptr<VPtrInfo> &Info) {
2015 return Info->FullOffsetInMDC == ML.VFPtrOffset;
2024 getObjectWithVPtr(), VTable, Ty,
2032 llvm::Value *VFuncPtr =
2033 Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.
Index,
"vfn");
2034 VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.
getPointerAlign());
2037 CGCallee
Callee(GD, VFunc);
2041llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
2042 CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
CXXDtorType DtorType,
2043 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
2044 auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
2045 auto *D = dyn_cast<const CXXDeleteExpr *>(E);
2046 assert((CE !=
nullptr) ^ (D !=
nullptr));
2047 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
2053 ASTContext &Context = getContext();
2054 bool VectorDeletingDtorsEnabled =
2058 const CGFunctionInfo *FInfo =
2064 bool IsArrayDelete = D && D->isArrayForm() && VectorDeletingDtorsEnabled;
2065 bool IsGlobalDelete = D && D->isGlobalDelete() &&
2068 llvm::Value *ImplicitParam =
2069 CGF.
Builder.getInt32((IsDeleting ? 1 : 0) | (IsGlobalDelete ? 4 : 0) |
2070 (IsArrayDelete ? 2 : 0));
2074 ThisTy = CE->getObjectType();
2076 ThisTy = D->getDestroyedType();
2080 ThisTy = ATy->getElementType();
2082 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
2085 ImplicitParam, Context.
IntTy, CE, CallOrInvoke);
2089const VBTableGlobals &
2090MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
2093 auto [Entry, Added] = VBTablesMap.try_emplace(RD);
2094 VBTableGlobals &VBGlobals = Entry->second;
2099 VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2104 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2105 E = VBGlobals.VBTables->end();
2107 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,
Linkage));
2114MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2115 const MethodVFTableLocation &ML) {
2117 "can't form pointers to ctors or virtual dtors");
2120 SmallString<256> ThunkName;
2121 llvm::raw_svector_ostream
Out(ThunkName);
2122 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2125 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
2129 const CGFunctionInfo &FnInfo =
2132 llvm::Function *ThunkFn =
2133 llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
2135 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2138 ? llvm::GlobalValue::LinkOnceODRLinkage
2139 : llvm::GlobalValue::InternalLinkage);
2141 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
2150 ThunkFn->addFnAttr(
"thunk");
2153 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
2156 CodeGenFunction CGF(CGM);
2157 CGF.
CurGD = GlobalDecl(MD);
2162 FunctionArgList FunctionArgs;
2163 buildThisParam(CGF, FunctionArgs);
2167 FunctionArgs, MD->
getLocation(), SourceLocation());
2170 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2175 llvm::Value *VTable =
2178 llvm::Value *VFuncPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2179 ThunkPtrTy, VTable, ML.
Index,
"vfn");
2188void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2189 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2190 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2191 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2192 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2193 if (GV->isDeclaration())
2194 emitVBTableDefinition(*VBT, RD, GV);
2198llvm::GlobalVariable *
2199MicrosoftCXXABI::getAddrOfVBTable(
const VPtrInfo &VBT,
const CXXRecordDecl *RD,
2200 llvm::GlobalVariable::LinkageTypes
Linkage) {
2201 SmallString<256> OutName;
2202 llvm::raw_svector_ostream
Out(OutName);
2203 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2204 StringRef Name = OutName.str();
2206 llvm::ArrayType *VBTableType =
2209 assert(!CGM.
getModule().getNamedGlobal(Name) &&
2210 "vbtable with this name already exists: mangling bug?");
2211 CharUnits Alignment =
2215 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2217 if (RD->
hasAttr<DLLImportAttr>())
2218 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2219 else if (RD->
hasAttr<DLLExportAttr>())
2220 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2222 if (!GV->hasExternalLinkage())
2223 emitVBTableDefinition(VBT, RD, GV);
2228void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2229 const CXXRecordDecl *RD,
2230 llvm::GlobalVariable *GV)
const {
2234 "should only emit vbtables for classes with vbtables");
2236 const ASTRecordLayout &BaseLayout =
2238 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2240 SmallVector<llvm::Constant *, 4> Offsets(1 + ObjectWithVPtr->
getNumVBases(),
2249 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2250 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2257 CompleteVBPtrOffset +=
2259 Offset -= CompleteVBPtrOffset;
2261 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2262 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2267 assert(Offsets.size() ==
2269 llvm::ArrayType *VBTableType =
2270 llvm::ArrayType::get(CGM.
IntTy, Offsets.size());
2271 llvm::Constant *
Init = llvm::ConstantArray::get(VBTableType, Offsets);
2272 GV->setInitializer(
Init);
2274 if (RD->
hasAttr<DLLImportAttr>())
2275 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2278llvm::Value *MicrosoftCXXABI::performThisAdjustment(
2279 CodeGenFunction &CGF, Address This,
2280 const CXXRecordDecl * ,
const ThunkInfo &TI) {
2281 const ThisAdjustment &TA = TI.
This;
2283 return This.emitRawPointer(CGF);
2289 V =
This.emitRawPointer(CGF);
2299 CGF.
Builder.CreateNeg(VtorDisp));
2312 llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2331llvm::Value *MicrosoftCXXABI::performReturnAdjustment(
2332 CodeGenFunction &CGF, Address Ret,
2333 const CXXRecordDecl * ,
const ReturnAdjustment &RA) {
2336 return Ret.emitRawPointer(CGF);
2340 llvm::Value *
V =
Ret.emitRawPointer(CGF);
2345 llvm::Value *VBaseOffset =
2357bool MicrosoftCXXABI::requiresArrayCookie(
const CXXDeleteExpr *
expr,
2358 QualType elementType) {
2364bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *
expr) {
2367 return expr->getAllocatedType().isDestructedType();
2370CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType
type) {
2373 ASTContext &Ctx = getContext();
2378llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2380 CharUnits cookieSize) {
2385Address MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2387 llvm::Value *numElements,
2388 const CXXNewExpr *
expr,
2389 QualType elementType) {
2390 assert(requiresArrayCookie(
expr));
2393 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2408 llvm::FunctionCallee Dtor,
2409 llvm::Constant *
Addr) {
2414 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2415 CGF.
IntTy, DtorStub->getType(),
false);
2418 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2419 if (llvm::Function *TLRegDtorFn =
2420 dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2421 TLRegDtorFn->setDoesNotThrow();
2426void MicrosoftCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
2427 llvm::FunctionCallee Dtor,
2428 llvm::Constant *
Addr) {
2443void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2444 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
2445 ArrayRef<llvm::Function *> CXXThreadLocalInits,
2446 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
2447 if (CXXThreadLocalInits.empty())
2452 ?
"/include:___dyn_tls_init@12"
2453 :
"/include:__dyn_tls_init");
2458 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2459 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2460 CGM.
getModule(), InitFunc->getType(),
true,
2461 llvm::GlobalVariable::InternalLinkage, InitFunc,
2462 Twine(InitFunc->getName(),
"$initializer$"));
2463 InitFuncPtr->setSection(
".CRT$XDU");
2470 std::vector<llvm::Function *> NonComdatInits;
2471 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2474 llvm::Function *F = CXXThreadLocalInits[I];
2477 if (llvm::Comdat *
C = GV->getComdat())
2478 AddToXDU(F)->setComdat(
C);
2480 NonComdatInits.push_back(F);
2483 if (!NonComdatInits.empty()) {
2484 llvm::FunctionType *FTy =
2485 llvm::FunctionType::get(CGM.
VoidTy,
false);
2488 SourceLocation(),
true);
2489 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(InitFunc, NonComdatInits);
2501 llvm::Constant *TlsGuardConstant =
2505 TlsGuard->setThreadLocal(
true);
2513 llvm::FunctionType *FTy =
2514 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()), {},
2517 FTy,
"__dyn_tls_on_demand_init",
2519 llvm::AttributeList::FunctionIndex,
2520 llvm::Attribute::NoUnwind),
2525 llvm::BasicBlock *DynInitBB,
2526 llvm::BasicBlock *ContinueBB) {
2527 llvm::LoadInst *TlsGuardValue =
2529 llvm::Value *CmpResult =
2531 CGF.
Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2535 llvm::GlobalValue *TlsGuard,
2536 llvm::BasicBlock *ContinueBB) {
2538 llvm::Function *InitializerFunction =
2540 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(InitializerFunction);
2541 CallVal->setCallingConv(InitializerFunction->getCallingConv());
2543 CGF.
Builder.CreateBr(ContinueBB);
2547 llvm::BasicBlock *DynInitBB =
2549 llvm::BasicBlock *ContinueBB =
2555 CGF.
Builder.SetInsertPoint(DynInitBB);
2557 CGF.
Builder.SetInsertPoint(ContinueBB);
2560LValue MicrosoftCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
2562 QualType LValType) {
2580 AlignmentSource::Decl)
2586 StringRef VarName(
"_Init_thread_epoch");
2588 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2590 auto *GV =
new llvm::GlobalVariable(
2592 false, llvm::GlobalVariable::ExternalLinkage,
2594 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2600 llvm::FunctionType *FTy =
2601 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2604 FTy,
"_Init_thread_header",
2606 llvm::AttributeList::FunctionIndex,
2607 llvm::Attribute::NoUnwind),
2612 llvm::FunctionType *FTy =
2613 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2616 FTy,
"_Init_thread_footer",
2618 llvm::AttributeList::FunctionIndex,
2619 llvm::Attribute::NoUnwind),
2624 llvm::FunctionType *FTy =
2625 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2628 FTy,
"_Init_thread_abort",
2630 llvm::AttributeList::FunctionIndex,
2631 llvm::Attribute::NoUnwind),
2636struct ResetGuardBit final : EHScopeStack::Cleanup {
2639 ResetGuardBit(Address Guard,
unsigned GuardNum)
2640 : Guard(Guard), GuardNum(GuardNum) {}
2642 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2645 CGBuilderTy &Builder = CGF.
Builder;
2646 llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2647 llvm::ConstantInt *Mask =
2648 llvm::ConstantInt::getSigned(CGF.
IntTy, ~(1ULL << GuardNum));
2649 Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2653struct CallInitThreadAbort final : EHScopeStack::Cleanup {
2655 CallInitThreadAbort(RawAddress Guard) : Guard(Guard.getPointer()) {}
2657 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2664void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
2665 llvm::GlobalVariable *GV,
2669 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2671 llvm::Function *F = CGF.
CurFn;
2672 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2673 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2679 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2683 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2685 CGBuilderTy &Builder = CGF.
Builder;
2686 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2687 llvm::ConstantInt *
Zero = llvm::ConstantInt::get(GuardTy, 0);
2691 GuardInfo *GI =
nullptr;
2692 if (ThreadlocalStatic)
2694 else if (!ThreadsafeStatic)
2697 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2702 GuardNum = getContext().getStaticLocalNumber(&D);
2703 assert(GuardNum > 0);
2705 }
else if (HasPerVariableGuard) {
2709 GuardNum = GI->BitIndex++;
2712 if (!HasPerVariableGuard && GuardNum >= 32) {
2714 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2721 SmallString<256> GuardName;
2723 llvm::raw_svector_ostream
Out(GuardName);
2724 if (HasPerVariableGuard)
2725 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2728 getMangleContext().mangleStaticGuardVariable(&D, Out);
2734 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2735 GV->getLinkage(),
Zero, GuardName.str());
2736 GuardVar->setVisibility(GV->getVisibility());
2737 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2738 GuardVar->setAlignment(GuardAlign.
getAsAlign());
2739 if (GuardVar->isWeakForLinker())
2740 GuardVar->setComdat(
2741 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2744 if (GI && !HasPerVariableGuard)
2745 GI->Guard = GuardVar;
2748 ConstantAddress GuardAddr(GuardVar, GuardTy, GuardAlign);
2750 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2751 "static local from the same function had different linkage");
2753 if (!HasPerVariableGuard) {
2761 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2762 llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2763 llvm::Value *NeedsInit =
2764 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit),
Zero);
2768 CodeGenFunction::GuardKind::VariableGuard, &D);
2773 Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2777 Builder.CreateBr(EndBlock);
2795 llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2796 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2797 llvm::LoadInst *InitThreadEpoch =
2799 llvm::Value *IsUninitialized =
2800 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2804 CodeGenFunction::GuardKind::VariableGuard, &D);
2810 GuardAddr.getPointer());
2811 llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2812 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2813 llvm::Value *ShouldDoInit =
2814 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2816 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2824 GuardAddr.getPointer());
2825 Builder.CreateBr(EndBlock);
2831bool MicrosoftCXXABI::isZeroInitializable(
const MemberPointerType *MPT) {
2847MicrosoftCXXABI::ConvertMemberPointerType(
const MemberPointerType *MPT) {
2850 llvm::SmallVector<llvm::Type *, 4> fields;
2854 fields.push_back(CGM.
IntTy);
2858 fields.push_back(CGM.
IntTy);
2860 fields.push_back(CGM.
IntTy);
2862 fields.push_back(CGM.
IntTy);
2864 if (fields.size() == 1)
2869void MicrosoftCXXABI::
2870GetNullMemberPointerFields(
const MemberPointerType *MPT,
2871 llvm::SmallVectorImpl<llvm::Constant *> &fields) {
2872 assert(fields.empty());
2877 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2880 fields.push_back(getZeroInt());
2882 fields.push_back(getAllOnesInt());
2887 fields.push_back(getZeroInt());
2889 fields.push_back(getZeroInt());
2891 fields.push_back(getAllOnesInt());
2895MicrosoftCXXABI::EmitNullMemberPointer(
const MemberPointerType *MPT) {
2896 llvm::SmallVector<llvm::Constant *, 4> fields;
2897 GetNullMemberPointerFields(MPT, fields);
2898 if (fields.size() == 1)
2900 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2901 assert(Res->getType() == ConvertMemberPointerType(MPT));
2906MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2907 bool IsMemberFunction,
2908 const CXXRecordDecl *RD,
2909 CharUnits NonVirtualBaseAdjustment,
2910 unsigned VBTableIndex) {
2918 llvm::SmallVector<llvm::Constant *, 4> fields;
2919 fields.push_back(FirstField);
2922 fields.push_back(llvm::ConstantInt::getSigned(
2928 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2934 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2936 return llvm::ConstantStruct::getAnon(fields);
2940MicrosoftCXXABI::EmitMemberDataPointer(
const MemberPointerType *MPT,
2945llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl *RD,
2948 MSInheritanceModel::Virtual)
2949 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2950 llvm::Constant *FirstField =
2952 return EmitFullMemberPointer(FirstField,
false, RD,
2956llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2958 const MemberPointerType *DstTy = MPType->
castAs<MemberPointerType>();
2961 return EmitNullMemberPointer(DstTy);
2963 ASTContext &Ctx = getContext();
2967 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2968 C = EmitMemberFunctionPointer(MD);
2976 const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2981 C = EmitMemberDataPointer(RD, FieldOffset);
2984 if (!MemberPointerPath.empty()) {
2986 const MemberPointerType *SrcTy =
2988 std::nullopt, SrcRD)
2989 ->
castAs<MemberPointerType>();
2992 SmallVector<const CXXBaseSpecifier *, 4> DerivedToBasePath;
2993 const CXXRecordDecl *PrevRD = SrcRD;
2994 for (
const CXXRecordDecl *PathElem : MemberPointerPath) {
2995 const CXXRecordDecl *
Base =
nullptr;
2996 const CXXRecordDecl *Derived =
nullptr;
2997 if (DerivedMember) {
3004 for (
const CXXBaseSpecifier &BS : Derived->
bases())
3005 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
3006 Base->getCanonicalDecl())
3007 DerivedToBasePath.push_back(&BS);
3010 assert(DerivedToBasePath.size() == MemberPointerPath.size());
3012 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
3013 : CK_BaseToDerivedMemberPointer;
3014 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
3015 DerivedToBasePath.end(),
C);
3021MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
3022 assert(MD->
isInstance() &&
"Member function must not be static!");
3026 CodeGenTypes &Types = CGM.
getTypes();
3028 unsigned VBTableIndex = 0;
3029 llvm::Constant *FirstField;
3030 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
3045 MethodVFTableLocation ML = VTableContext.getMethodVFTableLocation(MD);
3046 FirstField = EmitVirtualMemPtrThunk(MD, ML);
3050 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
3053 if (VBTableIndex == 0 &&
3055 MSInheritanceModel::Virtual)
3056 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
3059 return EmitFullMemberPointer(FirstField,
true, RD,
3060 NonVirtualBaseAdjustment, VBTableIndex);
3067MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
3070 const MemberPointerType *MPT,
3072 CGBuilderTy &Builder = CGF.
Builder;
3075 llvm::ICmpInst::Predicate Eq;
3076 llvm::Instruction::BinaryOps
And,
Or;
3078 Eq = llvm::ICmpInst::ICMP_NE;
3079 And = llvm::Instruction::Or;
3080 Or = llvm::Instruction::And;
3082 Eq = llvm::ICmpInst::ICMP_EQ;
3083 And = llvm::Instruction::And;
3084 Or = llvm::Instruction::Or;
3093 return Builder.CreateICmp(Eq, L, R);
3096 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
3097 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
3098 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
3101 llvm::Value *Res =
nullptr;
3103 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3104 llvm::Value *LF = Builder.CreateExtractValue(L, I);
3105 llvm::Value *RF = Builder.CreateExtractValue(R, I);
3106 llvm::Value *
Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
3108 Res = Builder.CreateBinOp(
And, Res,
Cmp);
3116 llvm::Value *
Zero = llvm::Constant::getNullValue(L0->getType());
3117 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0,
Zero,
"memptr.cmp.iszero");
3118 Res = Builder.CreateBinOp(
Or, Res, IsZero);
3123 return Builder.CreateBinOp(
And, Res, Cmp0,
"memptr.cmp");
3127MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
3128 llvm::Value *MemPtr,
3129 const MemberPointerType *MPT) {
3130 CGBuilderTy &Builder = CGF.
Builder;
3131 llvm::SmallVector<llvm::Constant *, 4> fields;
3134 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
3136 GetNullMemberPointerFields(MPT, fields);
3137 assert(!fields.empty());
3138 llvm::Value *FirstField = MemPtr;
3139 if (MemPtr->getType()->isStructTy())
3140 FirstField = Builder.CreateExtractValue(MemPtr, 0);
3141 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
3149 for (
int I = 1, E = fields.size(); I < E; ++I) {
3150 llvm::Value *
Field = Builder.CreateExtractValue(MemPtr, I);
3151 llvm::Value *
Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
3152 Res = Builder.CreateOr(Res,
Next,
"memptr.tobool");
3157bool MicrosoftCXXABI::MemberPointerConstantIsNull(
const MemberPointerType *MPT,
3158 llvm::Constant *Val) {
3161 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3162 Val->getAggregateElement(0U) : Val;
3163 return FirstField->isNullValue();
3168 if (isZeroInitializable(MPT) && Val->isNullValue())
3173 llvm::SmallVector<llvm::Constant *, 4> Fields;
3174 GetNullMemberPointerFields(MPT, Fields);
3175 if (Fields.size() == 1) {
3176 assert(Val->getType()->isIntegerTy());
3177 return Val == Fields[0];
3181 for (I = 0, E = Fields.size(); I != E; ++I) {
3182 if (Val->getAggregateElement(I) != Fields[I])
3189MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
3191 llvm::Value *VBPtrOffset,
3192 llvm::Value *VBTableOffset,
3193 llvm::Value **VBPtrOut) {
3194 CGBuilderTy &Builder = CGF.
Builder;
3196 llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3197 CGM.
Int8Ty,
This.emitRawPointer(CGF), VBPtrOffset,
"vbptr");
3201 CharUnits VBPtrAlign;
3202 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3203 VBPtrAlign =
This.getAlignment().alignmentAtOffset(
3209 llvm::Value *VBTable =
3210 Builder.CreateAlignedLoad(CGM.
DefaultPtrTy, VBPtr, VBPtrAlign,
"vbtable");
3213 llvm::Value *VBTableIndex = Builder.CreateAShr(
3214 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3218 llvm::Value *VBaseOffs =
3219 Builder.CreateInBoundsGEP(CGM.
Int32Ty, VBTable, VBTableIndex);
3220 return Builder.CreateAlignedLoad(CGM.
Int32Ty, VBaseOffs,
3226llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3227 CodeGenFunction &CGF,
const Expr *E,
const CXXRecordDecl *RD,
3228 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3229 CGBuilderTy &Builder = CGF.
Builder;
3231 llvm::BasicBlock *OriginalBB =
nullptr;
3232 llvm::BasicBlock *SkipAdjustBB =
nullptr;
3233 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3240 OriginalBB = Builder.GetInsertBlock();
3243 llvm::Value *IsVirtual =
3244 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3246 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3259 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3262 llvm::Value *VBPtr =
nullptr;
3263 llvm::Value *VBaseOffs =
3264 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
3265 llvm::Value *AdjustedBase =
3266 Builder.CreateInBoundsGEP(CGM.
Int8Ty, VBPtr, VBaseOffs);
3269 if (VBaseAdjustBB) {
3270 Builder.CreateBr(SkipAdjustBB);
3272 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3273 Phi->addIncoming(
Base.emitRawPointer(CGF), OriginalBB);
3274 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3277 return AdjustedBase;
3280llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3281 CodeGenFunction &CGF,
const Expr *E, Address Base, llvm::Value *MemPtr,
3282 const MemberPointerType *MPT,
bool IsInBounds) {
3284 CGBuilderTy &Builder = CGF.
Builder;
3290 llvm::Value *FieldOffset = MemPtr;
3291 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3292 llvm::Value *VBPtrOffset =
nullptr;
3293 if (MemPtr->getType()->isStructTy()) {
3296 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3298 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3300 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3304 if (VirtualBaseAdjustmentOffset) {
3305 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
3312 return Builder.CreateGEP(CGF.
Int8Ty,
Addr, FieldOffset,
"memptr.offset",
3313 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
3314 : llvm::GEPNoWrapFlags::none());
3318MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
3321 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3322 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3331 const MemberPointerType *SrcTy =
3333 const MemberPointerType *DstTy = E->
getType()->
castAs<MemberPointerType>();
3337 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3338 if (IsReinterpret && IsFunc)
3342 CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
3343 if (IsReinterpret &&
3347 CGBuilderTy &Builder = CGF.
Builder;
3350 llvm::Value *
IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3351 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3355 if (IsReinterpret) {
3358 assert(Src->getType() == DstNull->getType());
3359 return Builder.CreateSelect(
IsNotNull, Src, DstNull);
3362 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3365 Builder.CreateCondBr(
IsNotNull, ConvertBB, ContinueBB);
3368 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3372 Builder.CreateBr(ContinueBB);
3376 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3377 Phi->addIncoming(DstNull, OriginalBB);
3378 Phi->addIncoming(Dst, ConvertBB);
3382llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3383 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
CastKind CK,
3386 CGBuilderTy &Builder) {
3395 llvm::Value *FirstField = Src;
3396 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3397 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3398 llvm::Value *VBPtrOffset = getZeroInt();
3402 FirstField = Builder.CreateExtractValue(Src, I++);
3404 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3406 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3408 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3411 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3412 const MemberPointerType *DerivedTy = IsDerivedToBase ? SrcTy : DstTy;
3417 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3424 llvm::Value *SrcVBIndexEqZero =
3425 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3426 if (SrcInheritance == MSInheritanceModel::Virtual) {
3427 if (int64_t SrcOffsetToFirstVBase =
3428 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3429 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3431 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3433 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3444 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3449 llvm::Value *NVDisp;
3450 if (IsDerivedToBase)
3451 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3453 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3455 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3459 llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3462 if (llvm::GlobalVariable *VDispMap =
3463 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3464 llvm::Value *VBIndex = Builder.CreateExactUDiv(
3465 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3467 llvm::Constant *Mapping = VDispMap->getInitializer();
3468 VirtualBaseAdjustmentOffset =
3471 llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3472 VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3473 CGM.
IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3479 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3486 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::getSigned(
3488 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3490 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3496 if (DstInheritance == MSInheritanceModel::Virtual) {
3497 if (int64_t DstOffsetToFirstVBase =
3498 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3499 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3501 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3503 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3512 Dst = llvm::PoisonValue::get(ConvertMemberPointerType(DstTy));
3514 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3516 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3518 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3520 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3526MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3527 llvm::Constant *Src) {
3528 const MemberPointerType *SrcTy =
3530 const MemberPointerType *DstTy = E->
getType()->
castAs<MemberPointerType>();
3534 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3538llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3539 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
CastKind CK,
3542 assert(CK == CK_DerivedToBaseMemberPointer ||
3543 CK == CK_BaseToDerivedMemberPointer ||
3544 CK == CK_ReinterpretMemberPointer);
3547 if (MemberPointerConstantIsNull(SrcTy, Src))
3548 return EmitNullMemberPointer(DstTy);
3553 if (CK == CK_ReinterpretMemberPointer)
3558 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3563CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3564 CodeGenFunction &CGF,
const Expr *E, Address This,
3565 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3566 const MemberPointerType *MPT) {
3568 const FunctionProtoType *FPT =
3571 CGBuilderTy &Builder = CGF.
Builder;
3577 llvm::Value *FunctionPointer = MemPtr;
3578 llvm::Value *NonVirtualBaseAdjustment =
nullptr;
3579 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3580 llvm::Value *VBPtrOffset =
nullptr;
3581 if (MemPtr->getType()->isStructTy()) {
3584 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3586 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3588 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3590 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3593 if (VirtualBaseAdjustmentOffset) {
3594 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3595 VirtualBaseAdjustmentOffset, VBPtrOffset);
3597 ThisPtrForCall =
This.emitRawPointer(CGF);
3600 if (NonVirtualBaseAdjustment)
3601 ThisPtrForCall = Builder.CreateInBoundsGEP(CGF.
Int8Ty, ThisPtrForCall,
3602 NonVirtualBaseAdjustment);
3604 CGCallee
Callee(FPT, FunctionPointer);
3609 return new MicrosoftCXXABI(CGM);
3643 StringRef MangledName(
"??_7type_info@@6B@");
3644 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3648 llvm::GlobalVariable::ExternalLinkage,
3649 nullptr, MangledName);
3662 IsPrivateOnPath = 1 | 8,
3666 HasHierarchyDescriptor = 64
3668 MSRTTIClass(
const CXXRecordDecl *RD) : RD(RD) {}
3670 const CXXBaseSpecifier *Specifier);
3672 MSRTTIClass *getFirstChild() {
return this + 1; }
3673 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3674 return Child + 1 + Child->NumBases;
3677 const CXXRecordDecl *RD, *VirtualRoot;
3678 uint32_t Flags, NumBases, OffsetInVBase;
3682uint32_t MSRTTIClass::initialize(
const MSRTTIClass *Parent,
3683 const CXXBaseSpecifier *Specifier) {
3684 Flags = HasHierarchyDescriptor;
3686 VirtualRoot =
nullptr;
3690 Flags |= IsPrivate | IsPrivateOnPath;
3696 if (Parent->Flags & IsPrivateOnPath)
3697 Flags |= IsPrivateOnPath;
3698 VirtualRoot = Parent->VirtualRoot;
3699 OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
3700 .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
3704 MSRTTIClass *Child = getFirstChild();
3705 for (
const CXXBaseSpecifier &Base : RD->bases()) {
3706 NumBases += Child->initialize(
this, &Base) + 1;
3707 Child = getNextChild(Child);
3712static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
3714 case Linkage::Invalid:
3715 llvm_unreachable(
"Linkage hasn't been computed!");
3718 case Linkage::Internal:
3719 case Linkage::UniqueExternal:
3720 return llvm::GlobalValue::InternalLinkage;
3722 case Linkage::VisibleNone:
3723 case Linkage::Module:
3724 case Linkage::External:
3725 return llvm::GlobalValue::LinkOnceODRLinkage;
3727 llvm_unreachable(
"Invalid linkage!");
3733struct MSRTTIBuilder {
3735 HasBranchingHierarchy = 1,
3736 HasVirtualBranchingHierarchy = 2,
3737 HasAmbiguousBases = 4
3740 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3741 : CGM(ABI.CGM), Context(CGM.getContext()),
3742 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3743 Linkage(getLinkageForRTTI(CGM.getContext().getCanonicalTagType(RD))),
3746 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3747 llvm::GlobalVariable *
3748 getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
3749 llvm::GlobalVariable *getClassHierarchyDescriptor();
3750 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3753 ASTContext &Context;
3754 llvm::LLVMContext &VMContext;
3756 const CXXRecordDecl *RD;
3757 llvm::GlobalVariable::LinkageTypes
Linkage;
3758 MicrosoftCXXABI &ABI;
3767 Classes.push_back(MSRTTIClass(RD));
3778 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3779 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3780 !VirtualBases.insert(Class->RD).second) {
3781 Class = MSRTTIClass::getNextChild(Class);
3784 if (!UniqueBases.insert(Class->RD).second)
3785 AmbiguousBases.insert(Class->RD);
3788 if (AmbiguousBases.empty())
3790 for (MSRTTIClass &Class : Classes)
3791 if (AmbiguousBases.count(Class.RD))
3792 Class.Flags |= MSRTTIClass::IsAmbiguous;
3795llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3796 SmallString<256> MangledName;
3798 llvm::raw_svector_ostream
Out(MangledName);
3799 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3803 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3807 SmallVector<MSRTTIClass, 8> Classes;
3809 Classes.front().initialize(
nullptr,
nullptr);
3812 for (
const MSRTTIClass &
Class : Classes) {
3813 if (
Class.RD->getNumBases() > 1)
3814 Flags |= HasBranchingHierarchy;
3817 if (
Class.Flags & MSRTTIClass::IsAmbiguous)
3818 Flags |= HasAmbiguousBases;
3820 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3821 Flags |= HasVirtualBranchingHierarchy;
3824 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
IntTy, 0),
3825 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3828 auto Type = ABI.getClassHierarchyDescriptorType();
3832 if (CHD->isWeakForLinker())
3833 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3835 auto *Bases = getBaseClassArray(Classes);
3838 llvm::Constant *Fields[] = {
3839 llvm::ConstantInt::get(CGM.
IntTy, 0),
3840 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3841 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3842 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3843 Bases->getValueType(), Bases,
3844 llvm::ArrayRef<llvm::Value *>(GEPIndices))),
3846 CHD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3850llvm::GlobalVariable *
3851MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
3852 SmallString<256> MangledName;
3854 llvm::raw_svector_ostream
Out(MangledName);
3855 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3863 llvm::Type *PtrType = ABI.getImageRelativeType(CGM.
DefaultPtrTy);
3864 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3866 new llvm::GlobalVariable(
Module, ArrType,
3868 nullptr, MangledName);
3869 if (BCA->isWeakForLinker())
3870 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3873 SmallVector<llvm::Constant *, 8> BaseClassArrayData;
3874 for (MSRTTIClass &
Class : Classes)
3875 BaseClassArrayData.push_back(
3876 ABI.getImageRelativeConstant(getBaseClassDescriptor(
Class)));
3877 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3878 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3882llvm::GlobalVariable *
3883MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &
Class) {
3888 if (
Class.VirtualRoot) {
3890 OffsetInVBTable = VTableContext.getVBTableIndex(RD,
Class.VirtualRoot) * 4;
3894 SmallString<256> MangledName;
3896 llvm::raw_svector_ostream
Out(MangledName);
3897 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3898 Class.RD,
Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3903 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3907 auto Type = ABI.getBaseClassDescriptorType();
3910 nullptr, MangledName);
3911 if (BCD->isWeakForLinker())
3912 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3915 llvm::Constant *Fields[] = {
3916 ABI.getImageRelativeConstant(
3918 llvm::ConstantInt::get(CGM.
IntTy,
Class.NumBases),
3919 llvm::ConstantInt::get(CGM.
IntTy,
Class.OffsetInVBase),
3920 llvm::ConstantInt::getSigned(CGM.
IntTy, VBPtrOffset),
3921 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3922 llvm::ConstantInt::get(CGM.
IntTy,
Class.Flags),
3923 ABI.getImageRelativeConstant(
3924 MSRTTIBuilder(ABI,
Class.RD).getClassHierarchyDescriptor()),
3926 BCD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3930llvm::GlobalVariable *
3931MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3932 SmallString<256> MangledName;
3934 llvm::raw_svector_ostream
Out(MangledName);
3935 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3939 if (
auto COL =
Module.getNamedGlobal(MangledName))
3944 int VFPtrOffset = 0;
3950 ->second.hasVtorDisp())
3954 llvm::StructType *
Type = ABI.getCompleteObjectLocatorType();
3956 nullptr, MangledName);
3959 llvm::Constant *Fields[] = {
3960 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3961 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3962 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3963 ABI.getImageRelativeConstant(
3965 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3966 ABI.getImageRelativeConstant(COL),
3968 llvm::ArrayRef<llvm::Constant *> FieldsRef(Fields);
3969 if (!ABI.isImageRelative())
3970 FieldsRef = FieldsRef.drop_back();
3971 COL->setInitializer(llvm::ConstantStruct::get(
Type, FieldsRef));
3972 if (COL->isWeakForLinker())
3973 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3978 bool &IsConst,
bool &IsVolatile,
3979 bool &IsUnaligned) {
3980 T = Context.getExceptionObjectType(T);
3989 IsUnaligned =
false;
3991 if (!PointeeType.
isNull()) {
4001 MPTy->getQualifier(),
4002 MPTy->getMostRecentCXXRecordDecl());
4006 if (T->isPointerType())
4013MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType
Type,
4014 QualType CatchHandlerType) {
4018 bool IsConst, IsVolatile, IsUnaligned;
4034 return CatchTypeInfo{getAddrOfRTTIDescriptor(
Type)->stripPointerCasts(),
4042llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType
Type) {
4043 SmallString<256> MangledName;
4045 llvm::raw_svector_ostream
Out(MangledName);
4046 getMangleContext().mangleCXXRTTI(
Type, Out);
4050 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4057 SmallString<256> TypeInfoString;
4059 llvm::raw_svector_ostream
Out(TypeInfoString);
4060 getMangleContext().mangleCXXRTTIName(
Type, Out);
4064 llvm::Constant *Fields[] = {
4066 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
4067 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
4068 llvm::StructType *TypeDescriptorType =
4069 getTypeDescriptorType(TypeInfoString);
4070 auto *Var =
new llvm::GlobalVariable(
4071 CGM.
getModule(), TypeDescriptorType,
false,
4072 getLinkageForRTTI(
Type),
4073 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
4075 if (Var->isWeakForLinker())
4076 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
4081llvm::GlobalVariable *
4082MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
4083 const VPtrInfo &Info) {
4084 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
4087void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {
4088 if (
auto *ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
4090 llvm::Function *
Fn =
4102 dtor->getParent()->getNumVBases() == 0)
4125 if (
Fn->isWeakForLinker())
4126 Fn->setComdat(CGM.
getModule().getOrInsertComdat(
Fn->getName()));
4130MicrosoftCXXABI::getAddrOfCXXCtorClosure(
const CXXConstructorDecl *CD,
4135 SmallString<256> ThunkName;
4136 llvm::raw_svector_ostream
Out(ThunkName);
4137 getMangleContext().mangleName(GlobalDecl(CD, CT), Out);
4140 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
4146 const CXXRecordDecl *RD = CD->
getParent();
4147 CanQualType RecordTy = getContext().getCanonicalTagType(RD);
4148 llvm::Function *ThunkFn = llvm::Function::Create(
4149 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
4150 ThunkFn->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
4152 if (ThunkFn->isWeakForLinker())
4153 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
4157 CodeGenFunction CGF(CGM);
4161 FunctionArgList FunctionArgs;
4164 buildThisParam(CGF, FunctionArgs);
4169 getContext(),
nullptr, SourceLocation(),
4170 &getContext().Idents.get(
"src"),
4171 getContext().getLValueReferenceType(RecordTy,
4173 ImplicitParamKind::Other);
4175 FunctionArgs.push_back(SrcParam);
4180 auto *IsMostDerived =
4182 &getContext().Idents.get(
"is_most_derived"),
4183 getContext().IntTy, ImplicitParamKind::Other);
4186 FunctionArgs.push_back(IsMostDerived);
4191 FunctionArgs, CD->
getLocation(), SourceLocation());
4194 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4195 llvm::Value *
This = getThisValue(CGF);
4197 llvm::Value *SrcVal =
4211 SmallVector<const Stmt *, 4> ArgVec;
4212 ArrayRef<ParmVarDecl *> params = CD->
parameters().drop_front(IsCopy ? 1 : 0);
4213 for (
const ParmVarDecl *PD : params) {
4214 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
4215 ArgVec.push_back(PD->getDefaultArg());
4218 CodeGenFunction::RunCleanupsScope Cleanups(CGF);
4220 const auto *FPT = CD->
getType()->
castAs<FunctionProtoType>();
4221 CGF.
EmitCallArgs(Args, FPT, llvm::ArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
4224 AddedStructorArgCounts ExtraArgs =
4229 llvm::Constant *CalleePtr =
4234 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4235 CGF.
EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args);
4237 Cleanups.ForceCleanup();
4246llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType T,
4253 const CXXConstructorDecl *CD =
4260 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
4261 SmallString<256> MangledName;
4263 llvm::raw_svector_ostream
Out(MangledName);
4264 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
4265 VBPtrOffset, VBIndex, Out);
4267 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4268 return getImageRelativeConstant(GV);
4272 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
4276 llvm::Constant *CopyCtor;
4283 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4285 CopyCtor = getImageRelativeConstant(CopyCtor);
4287 bool IsScalar = !RD;
4288 bool HasVirtualBases =
false;
4289 bool IsStdBadAlloc =
false;
4290 QualType PointeeType = T;
4304 if (HasVirtualBases)
4309 llvm::Constant *Fields[] = {
4310 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4312 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4313 llvm::ConstantInt::getSigned(CGM.
IntTy, VBPtrOffset),
4314 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4315 llvm::ConstantInt::get(CGM.
IntTy, Size),
4318 llvm::StructType *CTType = getCatchableTypeType();
4319 auto *GV =
new llvm::GlobalVariable(
4320 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
4321 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4322 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4323 GV->setSection(
".xdata");
4324 if (GV->isWeakForLinker())
4325 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4326 return getImageRelativeConstant(GV);
4329llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) {
4333 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4340 llvm::SmallSetVector<llvm::Constant *, 2> CatchableTypes;
4350 const CXXRecordDecl *MostDerivedClass =
nullptr;
4358 if (MostDerivedClass) {
4359 const ASTContext &Context = getContext();
4360 const ASTRecordLayout &MostDerivedLayout =
4363 SmallVector<MSRTTIClass, 8> Classes;
4365 Classes.front().initialize(
nullptr,
nullptr);
4367 for (
const MSRTTIClass &
Class : Classes) {
4370 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4375 if (
Class.VirtualRoot) {
4386 CatchableTypes.insert(getCatchableType(RTTITy,
Class.OffsetInVBase,
4387 VBPtrOffset, OffsetInVBTable));
4395 CatchableTypes.insert(getCatchableType(T));
4408 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4419 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4421 uint32_t NumEntries = CatchableTypes.size();
4422 llvm::Type *CTType = getImageRelativeType(CGM.
DefaultPtrTy);
4423 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4424 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4425 llvm::Constant *Fields[] = {
4426 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4427 llvm::ConstantArray::get(
4428 AT, llvm::ArrayRef(CatchableTypes.begin(),
4429 CatchableTypes.end()))
4431 SmallString<256> MangledName;
4433 llvm::raw_svector_ostream
Out(MangledName);
4434 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4436 CTA =
new llvm::GlobalVariable(
4437 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4438 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4439 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4440 CTA->setSection(
".xdata");
4441 if (CTA->isWeakForLinker())
4442 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4446llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType T) {
4447 bool IsConst, IsVolatile, IsUnaligned;
4452 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4459 ->getLimitedValue();
4461 SmallString<256> MangledName;
4463 llvm::raw_svector_ostream
Out(MangledName);
4464 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4470 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4486 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4489 if (!DtorD->isTrivial())
4492 llvm::Constant *ForwardCompat =
4493 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4494 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(CTA);
4495 llvm::StructType *TIType = getThrowInfoType();
4496 llvm::Constant *Fields[] = {
4497 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4498 getImageRelativeConstant(CleanupFn),
4500 PointerToCatchableTypes
4502 auto *GV =
new llvm::GlobalVariable(
4503 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4504 llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4505 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4506 GV->setSection(
".xdata");
4507 if (GV->isWeakForLinker())
4508 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4512void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E) {
4514 assert(SubExpr &&
"SubExpr cannot be null");
4515 QualType ThrowType = SubExpr->
getType();
4524 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4531std::pair<llvm::Value *, const CXXRecordDecl *>
4532MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
4533 const CXXRecordDecl *RD) {
4535 std::tie(This, std::ignore, RD) = performBaseAdjustment(CGF, This, T);
4539bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4540 const CXXRecordDecl *RD)
const {
4570 for (
const CXXBaseSpecifier &B : RD->
bases()) {
4571 if (
const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4572 if (!isPermittedToBeHomogeneousAggregate(FRD))
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
static RValue performReturnAdjustment(CIRGenFunction &cgf, QualType resultType, RValue rv, const ThunkInfo &thunk)
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....
Result
Implement __builtin_bit_cast and related operations.
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.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
unsigned getTargetAddressSpace(LangAS AS) const
void recordMemberDataPointerEvaluation(const ValueDecl *VD)
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.
VarDecl * getExceptionDecl() const
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
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 C++ struct/union/class.
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class....
CXXRecordDecl * getMostRecentDecl()
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.
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.
bool needsImplicitCopyAssignment() const
Determine whether this class needs an implicit copy assignment operator to be lazily declared.
bool hasSimpleCopyAssignment() const
true if we know for sure that this class has a single, accessible, unambiguous copy assignment operat...
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
const Expr * getSubExpr() const
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 isNegative() const
isNegative - Test whether the quantity is less than zero.
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, unsigned AddrSpace, 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.
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.
RecordArgABI
Specify how one should pass an argument of a record type.
MangleContext & getMangleContext()
Gets the mangle context.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
bool isInstanceMethod() const
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass, VTableAuthMode AuthMode=VTableAuthMode::Authenticate)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
LValue EmitLoadOfReferenceLValue(LValue RefLVal)
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
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::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
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.
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.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
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 * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
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...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
CodeGenTypes & getTypes() const
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Instruction * CurrentFuncletPad
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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()
bool classNeedsVectorDestructor(const CXXRecordDecl *RD)
Check that class need vector deleting destructor body.
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.
const ABIInfo & getABIInfo()
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
bool shouldEmitRTTI(bool ForEH=false)
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.
void EmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target)
Emit a definition as a global alias for another definition, unconditionally.
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 TargetCodeGenInfo & getTargetCodeGenInfo()
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)
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i....
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)
Arrange a thunk that takes 'this' as the first parameter followed by varargs.
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.
A specialization of Address that requires the address to be an LLVM Constant.
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
virtual LangAS getSRetAddrSpace(const CXXRecordDecl *RD) const
Get the address space for an indirect (sret) return of the given type.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
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
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
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
Note: this can trigger extra deserialization when external AST sources are used.
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)
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
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.
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.
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.
virtual bool emitVectorDeletingDtors(const LangOptions &) const
Controls whether to emit MSVC vector deleting destructors.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool callGlobalDeleteInDeletingDtor(const LangOptions &) const
Controls whether global operator delete is called by the deleting destructor or at the point where de...
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.
bool isNullPtrType() const
ArrayRef< VTableComponent > vtable_components() const
Represents a variable declaration or definition.
TLSKind getTLSKind() const
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
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)
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
@ 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.
constexpr Variable var(Literal L)
Returns the variable of L.
bool This(InterpState &S, CodePtr OpPC)
@ Address
A pointer to a ValueDecl.
PRESERVE_NONE bool Ret(InterpState &S, CodePtr &PC)
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
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.
bool isa(CodeGen::Address addr)
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)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
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.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Template
We are parsing a template declaration.
SmallVector< std::unique_ptr< VPtrInfo >, 2 > VPtrInfoVector
CXXDtorType
C++ destructor types.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
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.
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 int32_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t
const CXXRecordDecl * NearestVBase
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
llvm::PointerType * DefaultPtrTy
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.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
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::@167242364125115315334113104006210160165266060257 Microsoft
uint32_t VBIndex
Index of the virtual base in the vbtable.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
struct clang::ThisAdjustment::VirtualAdjustment::@312251255113040203233347230177110330127151157305 Microsoft
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...