31#include "llvm/ADT/StringExtras.h"
32#include "llvm/ADT/StringSet.h"
33#include "llvm/IR/Intrinsics.h"
41struct VBTableGlobals {
43 SmallVector<llvm::GlobalVariable *, 2> Globals;
46class MicrosoftCXXABI :
public CGCXXABI {
48 MicrosoftCXXABI(CodeGenModule &CGM)
49 : CGCXXABI(CGM), BaseClassDescriptorType(
nullptr),
50 ClassHierarchyDescriptorType(
nullptr),
55 "visibility export mapping option unimplemented in this ABI");
58 bool HasThisReturn(GlobalDecl GD)
const override;
59 bool hasMostDerivedReturn(GlobalDecl GD)
const override;
65 bool isSRetParameterAfterThis()
const override {
return true; }
67 bool isThisCompleteObject(GlobalDecl GD)
const override {
79 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
81 llvm_unreachable(
"unexpected unified dtor type");
83 llvm_unreachable(
"bad dtor kind");
90 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *CD,
91 FunctionArgList &Args)
const override {
92 assert(Args.size() >= 2 &&
93 "expected the arglist to have at least two args!");
102 std::vector<CharUnits> getVBPtrOffsets(
const CXXRecordDecl *RD)
override {
103 std::vector<CharUnits> VBPtrOffsets;
104 const ASTContext &Context = getContext();
105 const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
107 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
108 for (
const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
109 const ASTRecordLayout &SubobjectLayout =
110 Context.getASTRecordLayout(VBT->IntroducingObject);
111 CharUnits Offs = VBT->NonVirtualOffset;
113 if (VBT->getVBaseWithVPtr())
115 VBPtrOffsets.push_back(Offs);
117 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
121 StringRef GetPureVirtualCallName()
override {
return "_purecall"; }
122 StringRef GetDeletedVirtualCallName()
override {
return "_purecall"; }
124 void emitVirtualObjectDelete(CodeGenFunction &CGF,
const CXXDeleteExpr *DE,
125 Address Ptr, QualType ElementType,
126 const CXXDestructorDecl *Dtor)
override;
128 void emitRethrow(CodeGenFunction &CGF,
bool isNoReturn)
override;
129 void emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E)
override;
131 void emitBeginCatch(CodeGenFunction &CGF,
const CXXCatchStmt *
C)
override;
133 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
134 const VPtrInfo &Info);
136 llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty)
override;
138 getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)
override;
141 CatchTypeInfo getCatchAllTypeInfo()
override {
144 if (getContext().getLangOpts().EHAsynch)
145 return CatchTypeInfo{
nullptr, 0};
147 return CatchTypeInfo{
nullptr, 0x40};
150 bool shouldTypeidBeNullChecked(QualType SrcRecordTy)
override;
151 void EmitBadTypeidCall(CodeGenFunction &CGF)
override;
152 llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
154 llvm::Type *StdTypeInfoPtrTy)
override;
156 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
157 QualType SrcRecordTy)
override;
159 bool shouldEmitExactDynamicCast(QualType DestRecordTy)
override {
163 std::optional<ExactDynamicCastInfo>
164 getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy,
165 QualType DestRecordTy)
override {
166 llvm_unreachable(
"unsupported");
168 llvm::Value *emitExactDynamicCast(CodeGenFunction &CGF, Address
Value,
169 QualType SrcRecordTy, QualType DestTy,
170 QualType DestRecordTy,
171 const ExactDynamicCastInfo &CastInfo,
172 llvm::BasicBlock *CastSuccess,
173 llvm::BasicBlock *CastFail)
override {
174 llvm_unreachable(
"unsupported");
177 llvm::Value *emitDynamicCastCall(CodeGenFunction &CGF, Address
Value,
178 QualType SrcRecordTy, QualType DestTy,
179 QualType DestRecordTy,
180 llvm::BasicBlock *CastEnd)
override;
182 llvm::Value *emitDynamicCastToVoid(CodeGenFunction &CGF, Address
Value,
183 QualType SrcRecordTy)
override;
185 bool EmitBadCastCall(CodeGenFunction &CGF)
override;
186 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override {
191 GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This,
192 const CXXRecordDecl *ClassDecl,
193 const CXXRecordDecl *BaseClassDecl)
override;
196 EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
197 const CXXRecordDecl *RD)
override;
200 EmitDtorCompleteObjectHandler(CodeGenFunction &CGF);
202 void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF,
203 const CXXRecordDecl *RD)
override;
205 void EmitCXXConstructors(
const CXXConstructorDecl *D)
override;
239 AddedStructorArgCounts
240 buildStructorSignature(GlobalDecl GD,
241 SmallVectorImpl<CanQualType> &ArgTys)
override;
244 bool useThunkForDtorVariant(
const CXXDestructorDecl *Dtor,
249 void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
250 const CXXDestructorDecl *Dtor,
253 llvm::GlobalValue::LinkageTypes
257 void EmitCXXDestructors(
const CXXDestructorDecl *D)
override;
259 const CXXRecordDecl *getThisArgumentTypeForMethod(GlobalDecl GD)
override {
262 if (MD->isVirtual()) {
263 GlobalDecl LookupGD = GD;
264 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
268 return MD->getParent();
274 MethodVFTableLocation ML =
286 return MD->getParent();
290 adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD,
292 bool VirtualCall)
override;
294 void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
295 FunctionArgList &Params)
override;
297 void EmitInstanceFunctionProlog(CodeGenFunction &CGF)
override;
299 AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF,
300 const CXXConstructorDecl *D,
306 const CXXDestructorDecl *DD,
311 void EmitDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *DD,
314 QualType ThisTy)
override;
316 void emitVTableTypeMetadata(
const VPtrInfo &Info,
const CXXRecordDecl *RD,
317 llvm::GlobalVariable *VTable);
319 void emitVTableDefinitions(CodeGenVTables &CGVT,
320 const CXXRecordDecl *RD)
override;
322 bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF,
323 CodeGenFunction::VPtr Vptr)
override;
327 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
328 return !VTableClass->
hasAttr<MSNoVTableAttr>();
332 getVTableAddressPoint(BaseSubobject Base,
333 const CXXRecordDecl *VTableClass)
override;
335 llvm::Value *getVTableAddressPointInStructor(
336 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass,
337 BaseSubobject Base,
const CXXRecordDecl *NearestVBase)
override;
339 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
340 CharUnits VPtrOffset)
override;
342 CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
343 Address This, llvm::Type *Ty,
344 SourceLocation Loc)
override;
347 EmitVirtualDestructorCall(CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
349 DeleteOrMemberCallExpr E,
350 llvm::CallBase **CallOrInvoke)
override;
352 void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
353 CallArgList &CallArgs)
override {
355 "Only deleting destructor thunks are available in this ABI");
360 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
362 llvm::GlobalVariable *
363 getAddrOfVBTable(
const VPtrInfo &VBT,
const CXXRecordDecl *RD,
364 llvm::GlobalVariable::LinkageTypes
Linkage);
366 llvm::GlobalVariable *
367 getAddrOfVirtualDisplacementMap(
const CXXRecordDecl *SrcRD,
368 const CXXRecordDecl *DstRD) {
369 SmallString<256> OutName;
370 llvm::raw_svector_ostream
Out(OutName);
371 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
372 StringRef MangledName = OutName.str();
374 if (
auto *VDispMap = CGM.
getModule().getNamedGlobal(MangledName))
379 SmallVector<llvm::Constant *, 4> Map(NumEntries,
380 llvm::PoisonValue::get(CGM.
IntTy));
381 Map[0] = llvm::ConstantInt::get(CGM.
IntTy, 0);
382 bool AnyDifferent =
false;
383 for (
const auto &I : SrcRD->
vbases()) {
384 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
390 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.
IntTy, DstVBIndex * 4);
391 AnyDifferent |= SrcVBIndex != DstVBIndex;
397 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.
IntTy, Map.size());
398 llvm::Constant *
Init = llvm::ConstantArray::get(VDispMapTy, Map);
399 llvm::GlobalValue::LinkageTypes
Linkage =
401 ? llvm::GlobalValue::LinkOnceODRLinkage
402 : llvm::GlobalValue::InternalLinkage;
403 auto *VDispMap =
new llvm::GlobalVariable(
409 void emitVBTableDefinition(
const VPtrInfo &VBT,
const CXXRecordDecl *RD,
410 llvm::GlobalVariable *GV)
const;
412 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
413 GlobalDecl GD,
bool ReturnAdjustment)
override {
418 Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
419 else if (ReturnAdjustment)
420 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
422 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
425 bool exportThunk()
override {
return false; }
427 llvm::Value *performThisAdjustment(CodeGenFunction &CGF, Address This,
428 const CXXRecordDecl * ,
429 const ThunkInfo &TI)
override;
431 llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, Address Ret,
432 const CXXRecordDecl * ,
433 const ReturnAdjustment &RA)
override;
435 void EmitThreadLocalInitFuncs(
436 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
437 ArrayRef<llvm::Function *> CXXThreadLocalInits,
438 ArrayRef<const VarDecl *> CXXThreadLocalInitVars)
override;
440 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
441 return getContext().getLangOpts().isCompatibleWithMSVC(
442 LangOptions::MSVC2019_5) &&
444 (!isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD));
446 LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
const VarDecl *VD,
447 QualType LValType)
override;
449 void EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
450 llvm::GlobalVariable *DeclPtr,
451 bool PerformInit)
override;
452 void registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
453 llvm::FunctionCallee Dtor,
454 llvm::Constant *
Addr)
override;
479 bool requiresArrayCookie(
const CXXDeleteExpr *
expr,
480 QualType elementType)
override;
481 bool requiresArrayCookie(
const CXXNewExpr *
expr)
override;
482 CharUnits getArrayCookieSizeImpl(QualType
type)
override;
483 Address InitializeArrayCookie(CodeGenFunction &CGF,
485 llvm::Value *NumElements,
486 const CXXNewExpr *
expr,
487 QualType ElementType)
override;
488 llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
490 CharUnits cookieSize)
override;
492 friend struct MSRTTIBuilder;
494 bool isImageRelative()
const {
499 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
500 llvm::SmallString<32> TDTypeName(
"rtti.TypeDescriptor");
501 TDTypeName += llvm::utostr(TypeInfoString.size());
502 llvm::StructType *&TypeDescriptorType =
503 TypeDescriptorTypeMap[TypeInfoString.size()];
504 if (TypeDescriptorType)
505 return TypeDescriptorType;
506 llvm::Type *FieldTypes[] = {
509 llvm::ArrayType::get(CGM.
Int8Ty, TypeInfoString.size() + 1)};
511 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, TDTypeName);
512 return TypeDescriptorType;
515 llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
516 if (!isImageRelative())
521 llvm::StructType *getBaseClassDescriptorType() {
522 if (BaseClassDescriptorType)
523 return BaseClassDescriptorType;
524 llvm::Type *FieldTypes[] = {
533 BaseClassDescriptorType = llvm::StructType::create(
535 return BaseClassDescriptorType;
538 llvm::StructType *getClassHierarchyDescriptorType() {
539 if (ClassHierarchyDescriptorType)
540 return ClassHierarchyDescriptorType;
544 ClassHierarchyDescriptorType =
545 llvm::StructType::create(FieldTypes,
"rtti.ClassHierarchyDescriptor");
546 return ClassHierarchyDescriptorType;
549 llvm::StructType *getCompleteObjectLocatorType() {
550 if (CompleteObjectLocatorType)
551 return CompleteObjectLocatorType;
552 llvm::Type *FieldTypes[] = {
558 getImageRelativeType(CGM.
VoidTy),
560 llvm::ArrayRef<llvm::Type *> FieldTypesRef(FieldTypes);
561 if (!isImageRelative())
562 FieldTypesRef = FieldTypesRef.drop_back();
563 CompleteObjectLocatorType =
564 llvm::StructType::create(FieldTypesRef,
"rtti.CompleteObjectLocator");
565 return CompleteObjectLocatorType;
568 llvm::GlobalVariable *getImageBase() {
569 StringRef Name =
"__ImageBase";
570 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name))
575 llvm::GlobalValue::ExternalLinkage,
581 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
582 if (!isImageRelative())
585 if (PtrVal->isNullValue())
586 return llvm::Constant::getNullValue(CGM.
IntTy);
588 llvm::Constant *ImageBaseAsInt =
589 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.
IntPtrTy);
590 llvm::Constant *PtrValAsInt =
591 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.
IntPtrTy);
592 llvm::Constant *Diff =
593 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
595 return llvm::ConstantExpr::getTrunc(Diff, CGM.
IntTy);
599 MicrosoftMangleContext &getMangleContext() {
603 llvm::Constant *getZeroInt() {
604 return llvm::ConstantInt::get(CGM.
IntTy, 0);
607 llvm::Constant *getAllOnesInt() {
608 return llvm::Constant::getAllOnesValue(CGM.
IntTy);
611 CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)
override;
614 GetNullMemberPointerFields(
const MemberPointerType *MPT,
615 llvm::SmallVectorImpl<llvm::Constant *> &fields);
620 llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
622 llvm::Value *VBPtrOffset,
623 llvm::Value *VBTableOffset,
624 llvm::Value **VBPtr =
nullptr);
626 llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
629 int32_t VBTableOffset,
630 llvm::Value **VBPtr =
nullptr) {
631 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
632 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
633 *VBTOffset = llvm::ConstantInt::get(CGM.
IntTy, VBTableOffset);
634 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
637 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
638 performBaseAdjustment(CodeGenFunction &CGF, Address
Value,
639 QualType SrcRecordTy);
643 llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF,
const Expr *E,
644 const CXXRecordDecl *RD, Address Base,
645 llvm::Value *VirtualBaseAdjustmentOffset,
646 llvm::Value *VBPtrOffset );
650 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
651 bool IsMemberFunction,
652 const CXXRecordDecl *RD,
653 CharUnits NonVirtualBaseAdjustment,
654 unsigned VBTableIndex);
656 bool MemberPointerConstantIsNull(
const MemberPointerType *MPT,
660 void EmitVBPtrStores(CodeGenFunction &CGF,
const CXXRecordDecl *RD);
663 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
666 llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
667 const MethodVFTableLocation &ML);
669 llvm::Constant *EmitMemberDataPointer(
const CXXRecordDecl *RD,
673 llvm::Type *ConvertMemberPointerType(
const MemberPointerType *MPT)
override;
675 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
677 bool isMemberPointerConvertible(
const MemberPointerType *MPT)
const override {
679 return RD->
hasAttr<MSInheritanceAttr>();
682 llvm::Constant *EmitNullMemberPointer(
const MemberPointerType *MPT)
override;
684 llvm::Constant *EmitMemberDataPointer(
const MemberPointerType *MPT,
685 CharUnits offset)
override;
686 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
687 llvm::Constant *EmitMemberPointer(
const APValue &MP, QualType MPT)
override;
689 llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
692 const MemberPointerType *MPT,
693 bool Inequality)
override;
695 llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
697 const MemberPointerType *MPT)
override;
699 llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
const Expr *E,
700 Address Base, llvm::Value *MemPtr,
701 const MemberPointerType *MPT,
702 bool IsInBounds)
override;
704 llvm::Value *EmitNonNullMemberPointerConversion(
705 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
708 CGBuilderTy &Builder);
710 llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
712 llvm::Value *Src)
override;
714 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
715 llvm::Constant *Src)
override;
717 llvm::Constant *EmitMemberPointerConversion(
718 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
723 EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
const Expr *E,
724 Address This, llvm::Value *&ThisPtrForCall,
726 const MemberPointerType *MPT)
override;
728 void emitCXXStructor(GlobalDecl GD)
override;
730 llvm::StructType *getCatchableTypeType() {
731 if (CatchableTypeType)
732 return CatchableTypeType;
733 llvm::Type *FieldTypes[] = {
742 CatchableTypeType = llvm::StructType::create(
744 return CatchableTypeType;
747 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
748 llvm::StructType *&CatchableTypeArrayType =
749 CatchableTypeArrayTypeMap[NumEntries];
750 if (CatchableTypeArrayType)
751 return CatchableTypeArrayType;
753 llvm::SmallString<23> CTATypeName(
"eh.CatchableTypeArray.");
754 CTATypeName += llvm::utostr(NumEntries);
755 llvm::Type *CTType = getImageRelativeType(CGM.
UnqualPtrTy);
756 llvm::Type *FieldTypes[] = {
758 llvm::ArrayType::get(CTType, NumEntries)
760 CatchableTypeArrayType =
761 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, CTATypeName);
762 return CatchableTypeArrayType;
765 llvm::StructType *getThrowInfoType() {
767 return ThrowInfoType;
768 llvm::Type *FieldTypes[] = {
774 ThrowInfoType = llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes,
776 return ThrowInfoType;
783 llvm::FunctionType *FTy =
784 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
785 llvm::FunctionCallee Throw =
789 if (
auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
790 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
795 llvm::Function *getAddrOfCXXCtorClosure(
const CXXConstructorDecl *CD,
798 llvm::Constant *getCatchableType(QualType
T,
799 uint32_t NVOffset = 0,
800 int32_t VBPtrOffset = -1,
801 uint32_t VBIndex = 0);
803 llvm::GlobalVariable *getCatchableTypeArray(QualType
T);
805 llvm::GlobalVariable *getThrowInfo(QualType
T)
override;
807 std::pair<llvm::Value *, const CXXRecordDecl *>
808 LoadVTablePtr(CodeGenFunction &CGF, Address This,
809 const CXXRecordDecl *RD)
override;
812 isPermittedToBeHomogeneousAggregate(
const CXXRecordDecl *RD)
const override;
815 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
816 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
817 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
819 VFTablesMapTy VFTablesMap;
820 VTablesMapTy VTablesMap;
823 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
827 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
832 GuardInfo() =
default;
833 llvm::GlobalVariable *Guard =
nullptr;
834 unsigned BitIndex = 0;
839 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
840 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
841 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
843 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
844 llvm::StructType *BaseClassDescriptorType;
845 llvm::StructType *ClassHierarchyDescriptorType;
846 llvm::StructType *CompleteObjectLocatorType;
848 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
850 llvm::StructType *CatchableTypeType;
851 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
852 llvm::StructType *ThrowInfoType;
858MicrosoftCXXABI::getRecordArgABI(
const CXXRecordDecl *RD)
const {
870 case llvm::Triple::thumb:
876 case llvm::Triple::x86: {
882 getContext().getTypeInfo(getContext().getCanonicalTagType(RD));
888 return RAA_DirectInMemory;
891 case llvm::Triple::x86_64:
892 case llvm::Triple::aarch64:
896 llvm_unreachable(
"invalid enum");
899void MicrosoftCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
900 const CXXDeleteExpr *DE,
902 QualType ElementType,
903 const CXXDestructorDecl *Dtor) {
908 llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
914void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF,
bool isNoReturn) {
915 llvm::Value *Args[] = {llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
924void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
925 const CXXCatchStmt *S) {
929 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
930 llvm::CatchPadInst *CPI =
942 CPI->setArgOperand(2,
var.getObjectAddress(CGF).emitRawPointer(CGF));
950std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
951MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address
Value,
952 QualType SrcRecordTy) {
955 const ASTContext &Context = getContext();
961 return std::make_tuple(
Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
966 const CXXRecordDecl *PolymorphicBase =
nullptr;
967 for (
auto &Base : SrcDecl->
vbases()) {
968 const CXXRecordDecl *BaseDecl =
Base.getType()->getAsCXXRecordDecl();
970 PolymorphicBase = BaseDecl;
974 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
976 llvm::Value *Offset =
977 GetVirtualBaseClassOffset(CGF,
Value, SrcDecl, PolymorphicBase);
979 Value.getElementType(),
Value.emitRawPointer(CGF), Offset);
980 CharUnits VBaseAlign =
982 return std::make_tuple(Address(Ptr, CGF.
Int8Ty, VBaseAlign), Offset,
986bool MicrosoftCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
988 return !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
992 llvm::Value *Argument) {
993 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
994 llvm::FunctionType *FTy =
995 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
996 llvm::Value *Args[] = {Argument};
1001void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1002 llvm::CallBase *
Call =
1004 Call->setDoesNotReturn();
1005 CGF.
Builder.CreateUnreachable();
1008llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
1009 QualType SrcRecordTy,
1011 llvm::Type *StdTypeInfoPtrTy) {
1012 std::tie(ThisPtr, std::ignore, std::ignore) =
1013 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
1015 return CGF.
Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
1018bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1019 QualType SrcRecordTy) {
1022 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1025llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
1026 CodeGenFunction &CGF, Address This, QualType SrcRecordTy, QualType DestTy,
1027 QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1028 llvm::Value *SrcRTTI =
1030 llvm::Value *DestRTTI =
1033 llvm::Value *Offset;
1034 std::tie(This, Offset, std::ignore) =
1035 performBaseAdjustment(CGF, This, SrcRecordTy);
1036 llvm::Value *ThisPtr =
This.emitRawPointer(CGF);
1048 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1050 llvm::Value *Args[] = {
1051 ThisPtr, Offset, SrcRTTI, DestRTTI,
1056llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
1058 QualType SrcRecordTy) {
1059 std::tie(
Value, std::ignore, std::ignore) =
1060 performBaseAdjustment(CGF,
Value, SrcRecordTy);
1064 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1066 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1068 llvm::Value *Args[] = {
Value.emitRawPointer(CGF)};
1072bool MicrosoftCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1076llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1077 CodeGenFunction &CGF, Address This,
const CXXRecordDecl *ClassDecl,
1078 const CXXRecordDecl *BaseClassDecl) {
1079 const ASTContext &Context = getContext();
1082 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.
PtrDiffTy, VBPtrChars);
1084 CharUnits VBTableChars =
1087 llvm::Value *VBTableOffset =
1090 llvm::Value *VBPtrToNewBase =
1091 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1094 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1097bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD)
const {
1106bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD)
const {
1116 uint64_t NumElts = 0;
1156 if (
auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
1157 if (Ctor->isUserProvided())
1159 }
else if (
auto *
Template = dyn_cast<FunctionTemplateDecl>(D)) {
1162 }
else if (
auto *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
1163 if (MethodDecl->isCopyAssignmentOperator() && MethodDecl->isDeleted())
1172bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI)
const {
1173 const CXXRecordDecl *RD = FI.
getReturnType()->getAsCXXRecordDecl();
1183 if (isIndirectReturn) {
1204MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
1205 const CXXRecordDecl *RD) {
1206 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1207 assert(IsMostDerivedClass &&
1208 "ctor for a class with virtual bases must have an implicit parameter");
1209 llvm::Value *IsCompleteObject =
1210 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1212 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1213 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1214 CGF.
Builder.CreateCondBr(IsCompleteObject,
1215 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1220 EmitVBPtrStores(CGF, RD);
1224 return SkipVbaseCtorsBB;
1228MicrosoftCXXABI::EmitDtorCompleteObjectHandler(CodeGenFunction &CGF) {
1229 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1230 assert(IsMostDerivedClass &&
1231 "ctor for a class with virtual bases must have an implicit parameter");
1232 llvm::Value *IsCompleteObject =
1233 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1235 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1236 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1237 CGF.
Builder.CreateCondBr(IsCompleteObject,
1238 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1243 return SkipVbaseDtorsBB;
1246void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1247 CodeGenFunction &CGF,
const CXXRecordDecl *RD) {
1261 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
1264 CGBuilderTy &Builder = CGF.
Builder;
1266 llvm::Value *Int8This =
nullptr;
1268 for (
const CXXBaseSpecifier &S : RD->
vbases()) {
1269 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1270 auto I = VBaseMap.find(VBase);
1271 assert(I != VBaseMap.end());
1272 if (!I->second.hasVtorDisp())
1275 llvm::Value *VBaseOffset =
1276 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1277 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1280 llvm::Value *VtorDispValue = Builder.CreateSub(
1281 VBaseOffset, llvm::ConstantInt::get(CGM.
PtrDiffTy, ConstantVBaseOffset),
1283 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1286 Int8This = getThisValue(CGF);
1288 llvm::Value *VtorDispPtr =
1289 Builder.CreateInBoundsGEP(CGF.
Int8Ty, Int8This, VBaseOffset);
1291 VtorDispPtr = Builder.CreateConstGEP1_32(CGF.
Int8Ty, VtorDispPtr, -4);
1293 Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1300 CallingConv ExpectedCallingConv = Context.getDefaultCallingConvention(
1304 return ExpectedCallingConv == ActualCallingConv;
1307void MicrosoftCXXABI::EmitCXXConstructors(
const CXXConstructorDecl *D) {
1319 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1325void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
1326 const CXXRecordDecl *RD) {
1327 Address
This = getThisAddress(CGF);
1329 const ASTContext &Context = getContext();
1332 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1333 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1334 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1335 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1336 const ASTRecordLayout &SubobjectLayout =
1338 CharUnits Offs = VBT->NonVirtualOffset;
1340 if (VBT->getVBaseWithVPtr())
1343 llvm::Value *GVPtr =
1350CGCXXABI::AddedStructorArgCounts
1351MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
1352 SmallVectorImpl<CanQualType> &ArgTys) {
1353 AddedStructorArgCounts Added;
1358 ArgTys.push_back(getContext().IntTy);
1361 auto *CD = dyn_cast<CXXConstructorDecl>(GD.
getDecl());
1369 const FunctionProtoType *FPT = CD->
getType()->
castAs<FunctionProtoType>();
1370 if (
Class->getNumVBases()) {
1372 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1375 ArgTys.push_back(getContext().IntTy);
1383void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1384 const CXXDestructorDecl *Dtor,
1389 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1391 const NamedDecl *ND = Dtor;
1396llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1401 return llvm::GlobalValue::InternalLinkage;
1412 if (Dtor->
hasAttr<DLLExportAttr>())
1413 return llvm::GlobalValue::WeakODRLinkage;
1414 if (Dtor->
hasAttr<DLLImportAttr>())
1415 return llvm::GlobalValue::AvailableExternallyLinkage;
1416 return llvm::GlobalValue::LinkOnceODRLinkage;
1421 return llvm::GlobalValue::LinkOnceODRLinkage;
1423 llvm_unreachable(
"MS C++ ABI does not support unified dtors");
1425 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1427 llvm_unreachable(
"invalid dtor type");
1430void MicrosoftCXXABI::EmitCXXDestructors(
const CXXDestructorDecl *D) {
1444MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
1447 if (
const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1458 MethodVFTableLocation ML =
1470 const ASTRecordLayout &DerivedLayout =
1471 getContext().getASTRecordLayout(MD->
getParent());
1478Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1479 CodeGenFunction &CGF, GlobalDecl GD, Address This,
1484 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1495 GlobalDecl LookupGD = GD;
1496 if (
const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1506 MethodVFTableLocation ML =
1521 const CXXRecordDecl *Derived = MD->
getParent();
1522 const CXXRecordDecl *VBase = ML.
VBase;
1523 llvm::Value *VBaseOffset =
1524 GetVirtualBaseClassOffset(CGF,
Result, Derived, VBase);
1526 Result.getElementType(),
Result.emitRawPointer(CGF), VBaseOffset);
1527 CharUnits VBaseAlign =
1531 if (!StaticOffset.
isZero()) {
1547void MicrosoftCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1549 FunctionArgList &Params) {
1550 ASTContext &Context = getContext();
1557 ImplicitParamKind::Other);
1560 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
1562 Params.insert(Params.begin() + 1, IsMostDerived);
1564 Params.push_back(IsMostDerived);
1565 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1570 ImplicitParamKind::Other);
1571 Params.push_back(ShouldDelete);
1572 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1576void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1593 llvm::Value *
This = loadIncomingCXXThis(CGF);
1596 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1597 if (!Adjustment.
isZero()) {
1603 setCXXABIThisValue(CGF, This);
1613 if (HasThisReturn(CGF.
CurGD) || hasMostDerivedReturn(CGF.
CurGD))
1617 assert(getStructorImplicitParamDecl(CGF) &&
1618 "no implicit parameter for a constructor with virtual bases?");
1619 getStructorImplicitParamValue(CGF)
1626 assert(getStructorImplicitParamDecl(CGF) &&
1627 "no implicit parameter for a deleting destructor?");
1628 getStructorImplicitParamValue(CGF)
1631 "should_call_delete");
1635CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs(
1642 return AddedStructorArgs{};
1645 const FunctionProtoType *FPT = D->
getType()->
castAs<FunctionProtoType>();
1646 llvm::Value *MostDerivedArg;
1648 MostDerivedArg = getStructorImplicitParamValue(CGF);
1653 return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1655 return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1658llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
1664void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
1665 const CXXDestructorDecl *DD,
1675 GlobalDecl GD(DD,
Type);
1679 assert(
Type != CXXDtorType::Dtor_Deleting &&
1680 "The deleting destructor should only be called via a virtual call");
1681 This = adjustThisArgumentForVirtualFunctionCall(CGF, GlobalDecl(DD,
Type),
1685 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1687 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1696 QualType(),
nullptr);
1697 if (BaseDtorEndBB) {
1699 CGF.
Builder.CreateBr(BaseDtorEndBB);
1704void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1705 const CXXRecordDecl *RD,
1706 llvm::GlobalVariable *VTable) {
1717 llvm::DenseSet<const CXXRecordDecl *> Visited;
1718 llvm::GlobalObject::VCallVisibility TypeVis =
1720 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1721 VTable->setVCallVisibilityMetadata(TypeVis);
1727 CharUnits AddressPoint =
1728 getContext().getLangOpts().RTTIData
1729 ? getContext().toCharUnitsFromBits(
1730 getContext().getTargetInfo().getPointerWidth(LangAS::Default))
1748 const ASTRecordLayout &Layout =
1749 getContext().getASTRecordLayout(DerivedRD);
1755 Offset = VBI->second.VBaseOffset;
1766void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
1767 const CXXRecordDecl *RD) {
1771 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1772 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1773 if (VTable->hasInitializer())
1776 const VTableLayout &VTLayout =
1779 llvm::Constant *RTTI =
nullptr;
1781 [](
const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
1782 RTTI = getMSCompleteObjectLocator(RD, *Info);
1784 ConstantInitBuilder builder(CGM);
1785 auto components = builder.beginStruct();
1787 VTable->hasLocalLinkage());
1788 components.finishAndSetAsInitializer(VTable);
1790 emitVTableTypeMetadata(*Info, RD, VTable);
1794bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1795 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
1799llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1800 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
1801 const CXXRecordDecl *NearestVBase) {
1802 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1803 if (!VTableAddressPoint) {
1804 assert(
Base.getBase()->getNumVBases() &&
1805 !getContext().getASTRecordLayout(
Base.getBase()).hasOwnVFPtr());
1807 return VTableAddressPoint;
1813 llvm::raw_svector_ostream Out(Name);
1818MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base,
1819 const CXXRecordDecl *VTableClass) {
1820 (void)getAddrOfVTable(VTableClass,
Base.getBaseOffset());
1821 VFTableIdTy
ID(VTableClass,
Base.getBaseOffset());
1822 return VFTablesMap[
ID];
1825llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1826 CharUnits VPtrOffset) {
1831 VFTableIdTy
ID(RD, VPtrOffset);
1832 auto [I, Inserted] = VTablesMap.try_emplace(ID);
1836 llvm::GlobalVariable *&VTable = I->second;
1841 if (DeferredVFTables.insert(RD).second) {
1849 llvm::StringSet<> ObservedMangledNames;
1850 for (
const auto &VFPtr : VFPtrs) {
1851 SmallString<256> Name;
1853 if (!ObservedMangledNames.insert(Name.str()).second)
1854 llvm_unreachable(
"Already saw this mangling before?");
1859 const std::unique_ptr<VPtrInfo> *VFPtrI =
1860 llvm::find_if(VFPtrs, [&](
const std::unique_ptr<VPtrInfo> &VPI) {
1861 return VPI->FullOffsetInMDC == VPtrOffset;
1863 if (VFPtrI == VFPtrs.end()) {
1864 VFTablesMap[
ID] =
nullptr;
1867 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1869 SmallString<256> VFTableName;
1879 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1880 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1881 : CGM.getVTableLinkage(RD);
1882 bool VFTableComesFromAnotherTU =
1883 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1884 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1885 bool VTableAliasIsRequred =
1886 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1888 if (llvm::GlobalValue *VFTable =
1889 CGM.
getModule().getNamedGlobal(VFTableName)) {
1890 VFTablesMap[
ID] = VFTable;
1891 VTable = VTableAliasIsRequred
1894 :
cast<llvm::GlobalVariable>(VFTable);
1898 const VTableLayout &VTLayout =
1900 llvm::GlobalValue::LinkageTypes VTableLinkage =
1901 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1903 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1905 llvm::Type *VTableType = CGM.
getVTables().getVTableType(VTLayout);
1909 llvm::GlobalValue *VFTable;
1910 VTable =
new llvm::GlobalVariable(CGM.
getModule(), VTableType,
1911 true, VTableLinkage,
1912 nullptr, VTableName);
1913 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1915 llvm::Comdat *
C =
nullptr;
1916 if (!VFTableComesFromAnotherTU &&
1917 llvm::GlobalValue::isWeakForLinker(VFTableLinkage))
1918 C = CGM.
getModule().getOrInsertComdat(VFTableName.str());
1923 if (VTableAliasIsRequred) {
1924 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1925 llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1926 llvm::ConstantInt::get(CGM.
Int32Ty, 1)};
1929 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1930 VTable->getValueType(), VTable, GEPIndices);
1931 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1932 VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1934 C->setSelectionKind(llvm::Comdat::Largest);
1936 VFTable = llvm::GlobalAlias::create(CGM.
Int8PtrTy,
1938 VFTableName.str(), VTableGEP,
1940 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1949 VTable->setComdat(
C);
1951 if (RD->
hasAttr<DLLExportAttr>())
1952 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1954 VFTablesMap[
ID] = VFTable;
1958CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
1962 SourceLocation Loc) {
1963 CGBuilderTy &Builder = CGF.
Builder;
1967 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1970 llvm::Value *VTable =
1978 auto getObjectWithVPtr = [&] {
1981 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1982 return Info->FullOffsetInMDC == ML.VFPtrOffset;
1991 getObjectWithVPtr(), VTable, Ty,
1999 llvm::Value *VFuncPtr =
2000 Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.
Index,
"vfn");
2001 VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.
getPointerAlign());
2004 CGCallee
Callee(GD, VFunc);
2008llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
2009 CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
CXXDtorType DtorType,
2010 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
2011 auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
2012 auto *D = dyn_cast<const CXXDeleteExpr *>(E);
2013 assert((CE !=
nullptr) ^ (D !=
nullptr));
2014 assert(CE ==
nullptr || CE->arguments().empty());
2020 const CGFunctionInfo *FInfo =
2025 ASTContext &Context = getContext();
2026 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
2032 ThisTy = CE->getObjectType();
2034 ThisTy = D->getDestroyedType();
2037 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
2040 ImplicitParam, Context.
IntTy, CE, CallOrInvoke);
2044const VBTableGlobals &
2045MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
2048 auto [Entry, Added] = VBTablesMap.try_emplace(RD);
2049 VBTableGlobals &VBGlobals = Entry->second;
2054 VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2059 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2060 E = VBGlobals.VBTables->end();
2062 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,
Linkage));
2069MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2070 const MethodVFTableLocation &ML) {
2072 "can't form pointers to ctors or virtual dtors");
2075 SmallString<256> ThunkName;
2076 llvm::raw_svector_ostream
Out(ThunkName);
2077 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2080 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
2084 const CGFunctionInfo &FnInfo =
2087 llvm::Function *ThunkFn =
2088 llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
2090 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2093 ? llvm::GlobalValue::LinkOnceODRLinkage
2094 : llvm::GlobalValue::InternalLinkage);
2096 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
2105 ThunkFn->addFnAttr(
"thunk");
2108 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
2111 CodeGenFunction CGF(CGM);
2112 CGF.
CurGD = GlobalDecl(MD);
2117 FunctionArgList FunctionArgs;
2118 buildThisParam(CGF, FunctionArgs);
2122 FunctionArgs, MD->
getLocation(), SourceLocation());
2125 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2130 llvm::Value *VTable =
2133 llvm::Value *VFuncPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2134 ThunkPtrTy, VTable, ML.
Index,
"vfn");
2143void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2144 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2145 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2146 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2147 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2148 if (GV->isDeclaration())
2149 emitVBTableDefinition(*VBT, RD, GV);
2153llvm::GlobalVariable *
2154MicrosoftCXXABI::getAddrOfVBTable(
const VPtrInfo &VBT,
const CXXRecordDecl *RD,
2155 llvm::GlobalVariable::LinkageTypes
Linkage) {
2156 SmallString<256> OutName;
2157 llvm::raw_svector_ostream
Out(OutName);
2158 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2159 StringRef Name = OutName.str();
2161 llvm::ArrayType *VBTableType =
2164 assert(!CGM.
getModule().getNamedGlobal(Name) &&
2165 "vbtable with this name already exists: mangling bug?");
2166 CharUnits Alignment =
2170 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2172 if (RD->
hasAttr<DLLImportAttr>())
2173 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2174 else if (RD->
hasAttr<DLLExportAttr>())
2175 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2177 if (!GV->hasExternalLinkage())
2178 emitVBTableDefinition(VBT, RD, GV);
2183void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2184 const CXXRecordDecl *RD,
2185 llvm::GlobalVariable *GV)
const {
2189 "should only emit vbtables for classes with vbtables");
2191 const ASTRecordLayout &BaseLayout =
2193 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2195 SmallVector<llvm::Constant *, 4> Offsets(1 + ObjectWithVPtr->
getNumVBases(),
2200 Offsets[0] = llvm::ConstantInt::get(CGM.
IntTy, -VBPtrOffset.
getQuantity());
2203 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2204 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2211 CompleteVBPtrOffset +=
2213 Offset -= CompleteVBPtrOffset;
2215 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2216 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2217 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.
IntTy, Offset.
getQuantity());
2220 assert(Offsets.size() ==
2222 llvm::ArrayType *VBTableType =
2223 llvm::ArrayType::get(CGM.
IntTy, Offsets.size());
2224 llvm::Constant *
Init = llvm::ConstantArray::get(VBTableType, Offsets);
2225 GV->setInitializer(
Init);
2227 if (RD->
hasAttr<DLLImportAttr>())
2228 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2231llvm::Value *MicrosoftCXXABI::performThisAdjustment(
2232 CodeGenFunction &CGF, Address This,
2233 const CXXRecordDecl * ,
const ThunkInfo &TI) {
2234 const ThisAdjustment &TA = TI.
This;
2236 return This.emitRawPointer(CGF);
2242 V =
This.emitRawPointer(CGF);
2246 Address VtorDispPtr =
2252 CGF.
Builder.CreateNeg(VtorDisp));
2265 llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2284llvm::Value *MicrosoftCXXABI::performReturnAdjustment(
2285 CodeGenFunction &CGF, Address Ret,
2286 const CXXRecordDecl * ,
const ReturnAdjustment &RA) {
2289 return Ret.emitRawPointer(CGF);
2293 llvm::Value *
V =
Ret.emitRawPointer(CGF);
2298 llvm::Value *VBaseOffset =
2310bool MicrosoftCXXABI::requiresArrayCookie(
const CXXDeleteExpr *
expr,
2311 QualType elementType) {
2317bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *
expr) {
2320 return expr->getAllocatedType().isDestructedType();
2323CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType
type) {
2326 ASTContext &Ctx = getContext();
2331llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2333 CharUnits cookieSize) {
2338Address MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2340 llvm::Value *numElements,
2341 const CXXNewExpr *
expr,
2342 QualType elementType) {
2343 assert(requiresArrayCookie(
expr));
2346 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2349 Address cookiePtr = newPtr;
2361 llvm::FunctionCallee Dtor,
2362 llvm::Constant *
Addr) {
2367 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2368 CGF.
IntTy, DtorStub->getType(),
false);
2371 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2372 if (llvm::Function *TLRegDtorFn =
2373 dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2374 TLRegDtorFn->setDoesNotThrow();
2379void MicrosoftCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
2380 llvm::FunctionCallee Dtor,
2381 llvm::Constant *
Addr) {
2396void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2397 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
2398 ArrayRef<llvm::Function *> CXXThreadLocalInits,
2399 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
2400 if (CXXThreadLocalInits.empty())
2405 ?
"/include:___dyn_tls_init@12"
2406 :
"/include:__dyn_tls_init");
2411 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2412 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2413 CGM.
getModule(), InitFunc->getType(),
true,
2414 llvm::GlobalVariable::InternalLinkage, InitFunc,
2415 Twine(InitFunc->getName(),
"$initializer$"));
2416 InitFuncPtr->setSection(
".CRT$XDU");
2423 std::vector<llvm::Function *> NonComdatInits;
2424 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2427 llvm::Function *F = CXXThreadLocalInits[I];
2430 if (llvm::Comdat *
C = GV->getComdat())
2431 AddToXDU(F)->setComdat(
C);
2433 NonComdatInits.push_back(F);
2436 if (!NonComdatInits.empty()) {
2437 llvm::FunctionType *FTy =
2438 llvm::FunctionType::get(CGM.
VoidTy,
false);
2441 SourceLocation(),
true);
2442 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(InitFunc, NonComdatInits);
2454 llvm::Constant *TlsGuardConstant =
2458 TlsGuard->setThreadLocal(
true);
2466 llvm::FunctionType *FTy =
2467 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()), {},
2470 FTy,
"__dyn_tls_on_demand_init",
2472 llvm::AttributeList::FunctionIndex,
2473 llvm::Attribute::NoUnwind),
2478 llvm::BasicBlock *DynInitBB,
2479 llvm::BasicBlock *ContinueBB) {
2480 llvm::LoadInst *TlsGuardValue =
2482 llvm::Value *CmpResult =
2484 CGF.
Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2488 llvm::GlobalValue *TlsGuard,
2489 llvm::BasicBlock *ContinueBB) {
2491 llvm::Function *InitializerFunction =
2493 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(InitializerFunction);
2494 CallVal->setCallingConv(InitializerFunction->getCallingConv());
2496 CGF.
Builder.CreateBr(ContinueBB);
2500 llvm::BasicBlock *DynInitBB =
2502 llvm::BasicBlock *ContinueBB =
2508 CGF.
Builder.SetInsertPoint(DynInitBB);
2510 CGF.
Builder.SetInsertPoint(ContinueBB);
2513LValue MicrosoftCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
2515 QualType LValType) {
2529 Address
Addr(
V, RealVarTy, Alignment);
2533 AlignmentSource::Decl)
2539 StringRef VarName(
"_Init_thread_epoch");
2541 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2543 auto *GV =
new llvm::GlobalVariable(
2545 false, llvm::GlobalVariable::ExternalLinkage,
2547 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2553 llvm::FunctionType *FTy =
2554 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2557 FTy,
"_Init_thread_header",
2559 llvm::AttributeList::FunctionIndex,
2560 llvm::Attribute::NoUnwind),
2565 llvm::FunctionType *FTy =
2566 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2569 FTy,
"_Init_thread_footer",
2571 llvm::AttributeList::FunctionIndex,
2572 llvm::Attribute::NoUnwind),
2577 llvm::FunctionType *FTy =
2578 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2581 FTy,
"_Init_thread_abort",
2583 llvm::AttributeList::FunctionIndex,
2584 llvm::Attribute::NoUnwind),
2589struct ResetGuardBit final : EHScopeStack::Cleanup {
2592 ResetGuardBit(Address Guard,
unsigned GuardNum)
2593 : Guard(Guard), GuardNum(GuardNum) {}
2595 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2598 CGBuilderTy &Builder = CGF.
Builder;
2599 llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2600 llvm::ConstantInt *Mask =
2601 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2602 Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2606struct CallInitThreadAbort final : EHScopeStack::Cleanup {
2608 CallInitThreadAbort(RawAddress Guard) : Guard(Guard.getPointer()) {}
2610 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2617void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
2618 llvm::GlobalVariable *GV,
2622 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2624 llvm::Function *F = CGF.
CurFn;
2625 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2626 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2632 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2636 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2638 CGBuilderTy &Builder = CGF.
Builder;
2639 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2640 llvm::ConstantInt *
Zero = llvm::ConstantInt::get(GuardTy, 0);
2644 GuardInfo *GI =
nullptr;
2645 if (ThreadlocalStatic)
2647 else if (!ThreadsafeStatic)
2650 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2655 GuardNum = getContext().getStaticLocalNumber(&D);
2656 assert(GuardNum > 0);
2658 }
else if (HasPerVariableGuard) {
2662 GuardNum = GI->BitIndex++;
2665 if (!HasPerVariableGuard && GuardNum >= 32) {
2667 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2674 SmallString<256> GuardName;
2676 llvm::raw_svector_ostream
Out(GuardName);
2677 if (HasPerVariableGuard)
2678 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2681 getMangleContext().mangleStaticGuardVariable(&D, Out);
2687 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2688 GV->getLinkage(),
Zero, GuardName.str());
2689 GuardVar->setVisibility(GV->getVisibility());
2690 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2691 GuardVar->setAlignment(GuardAlign.
getAsAlign());
2692 if (GuardVar->isWeakForLinker())
2693 GuardVar->setComdat(
2694 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2697 if (GI && !HasPerVariableGuard)
2698 GI->Guard = GuardVar;
2701 ConstantAddress GuardAddr(GuardVar, GuardTy, GuardAlign);
2703 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2704 "static local from the same function had different linkage");
2706 if (!HasPerVariableGuard) {
2714 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2715 llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2716 llvm::Value *NeedsInit =
2717 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit),
Zero);
2721 CodeGenFunction::GuardKind::VariableGuard, &D);
2726 Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2730 Builder.CreateBr(EndBlock);
2748 llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2749 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2750 llvm::LoadInst *InitThreadEpoch =
2752 llvm::Value *IsUninitialized =
2753 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2757 CodeGenFunction::GuardKind::VariableGuard, &D);
2763 GuardAddr.getPointer());
2764 llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2765 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2766 llvm::Value *ShouldDoInit =
2767 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2769 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2777 GuardAddr.getPointer());
2778 Builder.CreateBr(EndBlock);
2784bool MicrosoftCXXABI::isZeroInitializable(
const MemberPointerType *MPT) {
2800MicrosoftCXXABI::ConvertMemberPointerType(
const MemberPointerType *MPT) {
2803 llvm::SmallVector<llvm::Type *, 4> fields;
2807 fields.push_back(CGM.
IntTy);
2811 fields.push_back(CGM.
IntTy);
2813 fields.push_back(CGM.
IntTy);
2815 fields.push_back(CGM.
IntTy);
2817 if (fields.size() == 1)
2822void MicrosoftCXXABI::
2823GetNullMemberPointerFields(
const MemberPointerType *MPT,
2824 llvm::SmallVectorImpl<llvm::Constant *> &fields) {
2825 assert(fields.empty());
2830 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2833 fields.push_back(getZeroInt());
2835 fields.push_back(getAllOnesInt());
2840 fields.push_back(getZeroInt());
2842 fields.push_back(getZeroInt());
2844 fields.push_back(getAllOnesInt());
2848MicrosoftCXXABI::EmitNullMemberPointer(
const MemberPointerType *MPT) {
2849 llvm::SmallVector<llvm::Constant *, 4> fields;
2850 GetNullMemberPointerFields(MPT, fields);
2851 if (fields.size() == 1)
2853 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2854 assert(Res->getType() == ConvertMemberPointerType(MPT));
2859MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2860 bool IsMemberFunction,
2861 const CXXRecordDecl *RD,
2862 CharUnits NonVirtualBaseAdjustment,
2863 unsigned VBTableIndex) {
2871 llvm::SmallVector<llvm::Constant *, 4> fields;
2872 fields.push_back(FirstField);
2875 fields.push_back(llvm::ConstantInt::get(
2881 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2887 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2889 return llvm::ConstantStruct::getAnon(fields);
2893MicrosoftCXXABI::EmitMemberDataPointer(
const MemberPointerType *MPT,
2898llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl *RD,
2901 MSInheritanceModel::Virtual)
2902 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2903 llvm::Constant *FirstField =
2905 return EmitFullMemberPointer(FirstField,
false, RD,
2909llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2911 const MemberPointerType *DstTy = MPType->
castAs<MemberPointerType>();
2914 return EmitNullMemberPointer(DstTy);
2916 ASTContext &Ctx = getContext();
2920 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2921 C = EmitMemberFunctionPointer(MD);
2928 const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2933 C = EmitMemberDataPointer(RD, FieldOffset);
2936 if (!MemberPointerPath.empty()) {
2938 const MemberPointerType *SrcTy =
2940 std::nullopt, SrcRD)
2941 ->
castAs<MemberPointerType>();
2944 SmallVector<const CXXBaseSpecifier *, 4> DerivedToBasePath;
2945 const CXXRecordDecl *PrevRD = SrcRD;
2946 for (
const CXXRecordDecl *PathElem : MemberPointerPath) {
2947 const CXXRecordDecl *
Base =
nullptr;
2948 const CXXRecordDecl *Derived =
nullptr;
2949 if (DerivedMember) {
2956 for (
const CXXBaseSpecifier &BS : Derived->
bases())
2957 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2958 Base->getCanonicalDecl())
2959 DerivedToBasePath.push_back(&BS);
2962 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2964 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2965 : CK_BaseToDerivedMemberPointer;
2966 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2967 DerivedToBasePath.end(),
C);
2973MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2974 assert(MD->
isInstance() &&
"Member function must not be static!");
2978 CodeGenTypes &Types = CGM.
getTypes();
2980 unsigned VBTableIndex = 0;
2981 llvm::Constant *FirstField;
2982 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
2997 MethodVFTableLocation ML = VTableContext.getMethodVFTableLocation(MD);
2998 FirstField = EmitVirtualMemPtrThunk(MD, ML);
3002 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
3005 if (VBTableIndex == 0 &&
3007 MSInheritanceModel::Virtual)
3008 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
3011 return EmitFullMemberPointer(FirstField,
true, RD,
3012 NonVirtualBaseAdjustment, VBTableIndex);
3019MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
3022 const MemberPointerType *MPT,
3024 CGBuilderTy &Builder = CGF.
Builder;
3027 llvm::ICmpInst::Predicate
Eq;
3028 llvm::Instruction::BinaryOps
And,
Or;
3030 Eq = llvm::ICmpInst::ICMP_NE;
3031 And = llvm::Instruction::Or;
3032 Or = llvm::Instruction::And;
3034 Eq = llvm::ICmpInst::ICMP_EQ;
3035 And = llvm::Instruction::And;
3036 Or = llvm::Instruction::Or;
3045 return Builder.CreateICmp(
Eq, L, R);
3048 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
3049 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
3050 llvm::Value *Cmp0 = Builder.CreateICmp(
Eq, L0, R0,
"memptr.cmp.first");
3053 llvm::Value *Res =
nullptr;
3055 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3056 llvm::Value *LF = Builder.CreateExtractValue(L, I);
3057 llvm::Value *RF = Builder.CreateExtractValue(R, I);
3058 llvm::Value *Cmp = Builder.CreateICmp(
Eq, LF, RF,
"memptr.cmp.rest");
3060 Res = Builder.CreateBinOp(
And, Res, Cmp);
3068 llvm::Value *
Zero = llvm::Constant::getNullValue(L0->getType());
3069 llvm::Value *IsZero = Builder.CreateICmp(
Eq, L0,
Zero,
"memptr.cmp.iszero");
3070 Res = Builder.CreateBinOp(
Or, Res, IsZero);
3075 return Builder.CreateBinOp(
And, Res, Cmp0,
"memptr.cmp");
3079MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
3080 llvm::Value *MemPtr,
3081 const MemberPointerType *MPT) {
3082 CGBuilderTy &Builder = CGF.
Builder;
3083 llvm::SmallVector<llvm::Constant *, 4> fields;
3086 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
3088 GetNullMemberPointerFields(MPT, fields);
3089 assert(!fields.empty());
3090 llvm::Value *FirstField = MemPtr;
3091 if (MemPtr->getType()->isStructTy())
3092 FirstField = Builder.CreateExtractValue(MemPtr, 0);
3093 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
3101 for (
int I = 1, E = fields.size(); I < E; ++I) {
3102 llvm::Value *
Field = Builder.CreateExtractValue(MemPtr, I);
3103 llvm::Value *
Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
3104 Res = Builder.CreateOr(Res,
Next,
"memptr.tobool");
3109bool MicrosoftCXXABI::MemberPointerConstantIsNull(
const MemberPointerType *MPT,
3110 llvm::Constant *Val) {
3113 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3114 Val->getAggregateElement(0U) : Val;
3115 return FirstField->isNullValue();
3120 if (isZeroInitializable(MPT) && Val->isNullValue())
3125 llvm::SmallVector<llvm::Constant *, 4> Fields;
3126 GetNullMemberPointerFields(MPT, Fields);
3127 if (Fields.size() == 1) {
3128 assert(Val->getType()->isIntegerTy());
3129 return Val == Fields[0];
3133 for (I = 0, E = Fields.size(); I != E; ++I) {
3134 if (Val->getAggregateElement(I) != Fields[I])
3141MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
3143 llvm::Value *VBPtrOffset,
3144 llvm::Value *VBTableOffset,
3145 llvm::Value **VBPtrOut) {
3146 CGBuilderTy &Builder = CGF.
Builder;
3148 llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3149 CGM.
Int8Ty,
This.emitRawPointer(CGF), VBPtrOffset,
"vbptr");
3153 CharUnits VBPtrAlign;
3154 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3155 VBPtrAlign =
This.getAlignment().alignmentAtOffset(
3161 llvm::Value *VBTable =
3162 Builder.CreateAlignedLoad(CGM.
UnqualPtrTy, VBPtr, VBPtrAlign,
"vbtable");
3165 llvm::Value *VBTableIndex = Builder.CreateAShr(
3166 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3170 llvm::Value *VBaseOffs =
3171 Builder.CreateInBoundsGEP(CGM.
Int32Ty, VBTable, VBTableIndex);
3172 return Builder.CreateAlignedLoad(CGM.
Int32Ty, VBaseOffs,
3178llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3179 CodeGenFunction &CGF,
const Expr *E,
const CXXRecordDecl *RD,
3180 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3181 CGBuilderTy &Builder = CGF.
Builder;
3183 llvm::BasicBlock *OriginalBB =
nullptr;
3184 llvm::BasicBlock *SkipAdjustBB =
nullptr;
3185 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3192 OriginalBB = Builder.GetInsertBlock();
3195 llvm::Value *IsVirtual =
3196 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3198 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3210 "member pointer representation requires a "
3211 "complete class type for %0 to perform this expression");
3214 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3217 llvm::Value *VBPtr =
nullptr;
3218 llvm::Value *VBaseOffs =
3219 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
3220 llvm::Value *AdjustedBase =
3221 Builder.CreateInBoundsGEP(CGM.
Int8Ty, VBPtr, VBaseOffs);
3224 if (VBaseAdjustBB) {
3225 Builder.CreateBr(SkipAdjustBB);
3227 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3228 Phi->addIncoming(
Base.emitRawPointer(CGF), OriginalBB);
3229 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3232 return AdjustedBase;
3235llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3236 CodeGenFunction &CGF,
const Expr *E, Address Base, llvm::Value *MemPtr,
3237 const MemberPointerType *MPT,
bool IsInBounds) {
3239 CGBuilderTy &Builder = CGF.
Builder;
3245 llvm::Value *FieldOffset = MemPtr;
3246 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3247 llvm::Value *VBPtrOffset =
nullptr;
3248 if (MemPtr->getType()->isStructTy()) {
3251 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3253 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3255 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3259 if (VirtualBaseAdjustmentOffset) {
3260 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
3267 return Builder.CreateGEP(CGF.
Int8Ty,
Addr, FieldOffset,
"memptr.offset",
3268 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
3269 : llvm::GEPNoWrapFlags::none());
3273MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
3276 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3277 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3286 const MemberPointerType *SrcTy =
3288 const MemberPointerType *DstTy = E->
getType()->
castAs<MemberPointerType>();
3292 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3293 if (IsReinterpret && IsFunc)
3297 CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
3298 if (IsReinterpret &&
3302 CGBuilderTy &Builder = CGF.
Builder;
3305 llvm::Value *
IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3306 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3310 if (IsReinterpret) {
3313 assert(Src->getType() == DstNull->getType());
3314 return Builder.CreateSelect(
IsNotNull, Src, DstNull);
3317 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3320 Builder.CreateCondBr(
IsNotNull, ConvertBB, ContinueBB);
3323 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3327 Builder.CreateBr(ContinueBB);
3331 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3332 Phi->addIncoming(DstNull, OriginalBB);
3333 Phi->addIncoming(Dst, ConvertBB);
3337llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3338 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
CastKind CK,
3341 CGBuilderTy &Builder) {
3350 llvm::Value *FirstField = Src;
3351 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3352 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3353 llvm::Value *VBPtrOffset = getZeroInt();
3357 FirstField = Builder.CreateExtractValue(Src, I++);
3359 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3361 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3363 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3366 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3367 const MemberPointerType *DerivedTy = IsDerivedToBase ? SrcTy : DstTy;
3372 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3379 llvm::Value *SrcVBIndexEqZero =
3380 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3381 if (SrcInheritance == MSInheritanceModel::Virtual) {
3382 if (int64_t SrcOffsetToFirstVBase =
3383 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3384 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3386 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3388 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3399 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3404 llvm::Value *NVDisp;
3405 if (IsDerivedToBase)
3406 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3408 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3410 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3414 llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3417 if (llvm::GlobalVariable *VDispMap =
3418 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3419 llvm::Value *VBIndex = Builder.CreateExactUDiv(
3420 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3422 llvm::Constant *Mapping = VDispMap->getInitializer();
3423 VirtualBaseAdjustmentOffset =
3426 llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3427 VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3428 CGM.
IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3434 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3441 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3443 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3445 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3451 if (DstInheritance == MSInheritanceModel::Virtual) {
3452 if (int64_t DstOffsetToFirstVBase =
3453 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3454 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3456 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3458 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3467 Dst = llvm::PoisonValue::get(ConvertMemberPointerType(DstTy));
3469 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3471 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3473 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3475 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3481MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3482 llvm::Constant *Src) {
3483 const MemberPointerType *SrcTy =
3485 const MemberPointerType *DstTy = E->
getType()->
castAs<MemberPointerType>();
3489 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3493llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3494 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
CastKind CK,
3497 assert(CK == CK_DerivedToBaseMemberPointer ||
3498 CK == CK_BaseToDerivedMemberPointer ||
3499 CK == CK_ReinterpretMemberPointer);
3502 if (MemberPointerConstantIsNull(SrcTy, Src))
3503 return EmitNullMemberPointer(DstTy);
3508 if (CK == CK_ReinterpretMemberPointer)
3513 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3518CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3519 CodeGenFunction &CGF,
const Expr *E, Address This,
3520 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3521 const MemberPointerType *MPT) {
3523 const FunctionProtoType *FPT =
3526 CGBuilderTy &Builder = CGF.
Builder;
3532 llvm::Value *FunctionPointer = MemPtr;
3533 llvm::Value *NonVirtualBaseAdjustment =
nullptr;
3534 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3535 llvm::Value *VBPtrOffset =
nullptr;
3536 if (MemPtr->getType()->isStructTy()) {
3539 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3541 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3543 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3545 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3548 if (VirtualBaseAdjustmentOffset) {
3549 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3550 VirtualBaseAdjustmentOffset, VBPtrOffset);
3552 ThisPtrForCall =
This.emitRawPointer(CGF);
3555 if (NonVirtualBaseAdjustment)
3556 ThisPtrForCall = Builder.CreateInBoundsGEP(CGF.
Int8Ty, ThisPtrForCall,
3557 NonVirtualBaseAdjustment);
3559 CGCallee
Callee(FPT, FunctionPointer);
3564 return new MicrosoftCXXABI(CGM);
3598 StringRef MangledName(
"??_7type_info@@6B@");
3599 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3603 llvm::GlobalVariable::ExternalLinkage,
3604 nullptr, MangledName);
3617 IsPrivateOnPath = 1 | 8,
3621 HasHierarchyDescriptor = 64
3623 MSRTTIClass(
const CXXRecordDecl *RD) : RD(RD) {}
3625 const CXXBaseSpecifier *Specifier);
3627 MSRTTIClass *getFirstChild() {
return this + 1; }
3628 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3629 return Child + 1 + Child->NumBases;
3632 const CXXRecordDecl *RD, *VirtualRoot;
3633 uint32_t Flags, NumBases, OffsetInVBase;
3637uint32_t MSRTTIClass::initialize(
const MSRTTIClass *Parent,
3638 const CXXBaseSpecifier *Specifier) {
3639 Flags = HasHierarchyDescriptor;
3641 VirtualRoot =
nullptr;
3645 Flags |= IsPrivate | IsPrivateOnPath;
3651 if (Parent->Flags & IsPrivateOnPath)
3652 Flags |= IsPrivateOnPath;
3653 VirtualRoot = Parent->VirtualRoot;
3654 OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
3655 .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
3659 MSRTTIClass *Child = getFirstChild();
3660 for (
const CXXBaseSpecifier &Base : RD->bases()) {
3661 NumBases += Child->initialize(
this, &Base) + 1;
3662 Child = getNextChild(Child);
3667static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
3669 case Linkage::Invalid:
3670 llvm_unreachable(
"Linkage hasn't been computed!");
3673 case Linkage::Internal:
3674 case Linkage::UniqueExternal:
3675 return llvm::GlobalValue::InternalLinkage;
3677 case Linkage::VisibleNone:
3678 case Linkage::Module:
3679 case Linkage::External:
3680 return llvm::GlobalValue::LinkOnceODRLinkage;
3682 llvm_unreachable(
"Invalid linkage!");
3688struct MSRTTIBuilder {
3690 HasBranchingHierarchy = 1,
3691 HasVirtualBranchingHierarchy = 2,
3692 HasAmbiguousBases = 4
3695 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3696 : CGM(ABI.CGM), Context(CGM.getContext()),
3697 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3698 Linkage(getLinkageForRTTI(CGM.getContext().getCanonicalTagType(RD))),
3701 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3702 llvm::GlobalVariable *
3703 getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
3704 llvm::GlobalVariable *getClassHierarchyDescriptor();
3705 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3708 ASTContext &Context;
3709 llvm::LLVMContext &VMContext;
3711 const CXXRecordDecl *RD;
3712 llvm::GlobalVariable::LinkageTypes
Linkage;
3713 MicrosoftCXXABI &ABI;
3722 Classes.push_back(MSRTTIClass(RD));
3733 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3734 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3735 !VirtualBases.insert(Class->RD).second) {
3736 Class = MSRTTIClass::getNextChild(Class);
3739 if (!UniqueBases.insert(Class->RD).second)
3740 AmbiguousBases.insert(Class->RD);
3743 if (AmbiguousBases.empty())
3745 for (MSRTTIClass &Class : Classes)
3746 if (AmbiguousBases.count(Class.RD))
3747 Class.Flags |= MSRTTIClass::IsAmbiguous;
3750llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3751 SmallString<256> MangledName;
3753 llvm::raw_svector_ostream
Out(MangledName);
3754 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3758 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3762 SmallVector<MSRTTIClass, 8> Classes;
3764 Classes.front().initialize(
nullptr,
nullptr);
3767 for (
const MSRTTIClass &
Class : Classes) {
3768 if (
Class.RD->getNumBases() > 1)
3769 Flags |= HasBranchingHierarchy;
3772 if (
Class.Flags & MSRTTIClass::IsAmbiguous)
3773 Flags |= HasAmbiguousBases;
3775 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3776 Flags |= HasVirtualBranchingHierarchy;
3779 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
IntTy, 0),
3780 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3783 auto Type = ABI.getClassHierarchyDescriptorType();
3787 if (CHD->isWeakForLinker())
3788 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3790 auto *Bases = getBaseClassArray(Classes);
3793 llvm::Constant *Fields[] = {
3794 llvm::ConstantInt::get(CGM.
IntTy, 0),
3795 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3796 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3797 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3798 Bases->getValueType(), Bases,
3799 llvm::ArrayRef<llvm::Value *>(GEPIndices))),
3801 CHD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3805llvm::GlobalVariable *
3806MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
3807 SmallString<256> MangledName;
3809 llvm::raw_svector_ostream
Out(MangledName);
3810 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3818 llvm::Type *PtrType = ABI.getImageRelativeType(CGM.
UnqualPtrTy);
3819 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3821 new llvm::GlobalVariable(
Module, ArrType,
3823 nullptr, MangledName);
3824 if (BCA->isWeakForLinker())
3825 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3828 SmallVector<llvm::Constant *, 8> BaseClassArrayData;
3829 for (MSRTTIClass &
Class : Classes)
3830 BaseClassArrayData.push_back(
3831 ABI.getImageRelativeConstant(getBaseClassDescriptor(
Class)));
3832 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3833 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3837llvm::GlobalVariable *
3838MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &
Class) {
3843 if (
Class.VirtualRoot) {
3845 OffsetInVBTable = VTableContext.getVBTableIndex(RD,
Class.VirtualRoot) * 4;
3849 SmallString<256> MangledName;
3851 llvm::raw_svector_ostream
Out(MangledName);
3852 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3853 Class.RD,
Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3858 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3862 auto Type = ABI.getBaseClassDescriptorType();
3865 nullptr, MangledName);
3866 if (BCD->isWeakForLinker())
3867 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3870 llvm::Constant *Fields[] = {
3871 ABI.getImageRelativeConstant(
3873 llvm::ConstantInt::get(CGM.
IntTy,
Class.NumBases),
3874 llvm::ConstantInt::get(CGM.
IntTy,
Class.OffsetInVBase),
3875 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3876 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3877 llvm::ConstantInt::get(CGM.
IntTy,
Class.Flags),
3878 ABI.getImageRelativeConstant(
3879 MSRTTIBuilder(ABI,
Class.RD).getClassHierarchyDescriptor()),
3881 BCD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3885llvm::GlobalVariable *
3886MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3887 SmallString<256> MangledName;
3889 llvm::raw_svector_ostream
Out(MangledName);
3890 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3894 if (
auto COL =
Module.getNamedGlobal(MangledName))
3899 int VFPtrOffset = 0;
3905 ->second.hasVtorDisp())
3909 llvm::StructType *
Type = ABI.getCompleteObjectLocatorType();
3911 nullptr, MangledName);
3914 llvm::Constant *Fields[] = {
3915 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3916 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3917 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3918 ABI.getImageRelativeConstant(
3920 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3921 ABI.getImageRelativeConstant(COL),
3923 llvm::ArrayRef<llvm::Constant *> FieldsRef(Fields);
3924 if (!ABI.isImageRelative())
3925 FieldsRef = FieldsRef.drop_back();
3926 COL->setInitializer(llvm::ConstantStruct::get(
Type, FieldsRef));
3927 if (COL->isWeakForLinker())
3928 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3933 bool &IsConst,
bool &IsVolatile,
3934 bool &IsUnaligned) {
3935 T = Context.getExceptionObjectType(
T);
3944 IsUnaligned =
false;
3945 QualType PointeeType =
T->getPointeeType();
3946 if (!PointeeType.
isNull()) {
3956 MPTy->getQualifier(),
3957 MPTy->getMostRecentCXXRecordDecl());
3961 if (
T->isPointerType())
3968MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType
Type,
3969 QualType CatchHandlerType) {
3973 bool IsConst, IsVolatile, IsUnaligned;
3989 return CatchTypeInfo{getAddrOfRTTIDescriptor(
Type)->stripPointerCasts(),
3997llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType
Type) {
3998 SmallString<256> MangledName;
4000 llvm::raw_svector_ostream
Out(MangledName);
4001 getMangleContext().mangleCXXRTTI(
Type, Out);
4005 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4012 SmallString<256> TypeInfoString;
4014 llvm::raw_svector_ostream
Out(TypeInfoString);
4015 getMangleContext().mangleCXXRTTIName(
Type, Out);
4019 llvm::Constant *Fields[] = {
4021 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
4022 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
4023 llvm::StructType *TypeDescriptorType =
4024 getTypeDescriptorType(TypeInfoString);
4025 auto *Var =
new llvm::GlobalVariable(
4026 CGM.
getModule(), TypeDescriptorType,
false,
4027 getLinkageForRTTI(
Type),
4028 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
4030 if (Var->isWeakForLinker())
4031 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
4036llvm::GlobalVariable *
4037MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
4038 const VPtrInfo &Info) {
4039 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
4042void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {
4043 if (
auto *ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
4045 llvm::Function *
Fn =
4057 dtor->getParent()->getNumVBases() == 0)
4068 if (
Fn->isWeakForLinker())
4069 Fn->setComdat(CGM.
getModule().getOrInsertComdat(
Fn->getName()));
4073MicrosoftCXXABI::getAddrOfCXXCtorClosure(
const CXXConstructorDecl *CD,
4078 SmallString<256> ThunkName;
4079 llvm::raw_svector_ostream
Out(ThunkName);
4080 getMangleContext().mangleName(GlobalDecl(CD, CT), Out);
4083 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
4089 const CXXRecordDecl *RD = CD->
getParent();
4090 CanQualType RecordTy = getContext().getCanonicalTagType(RD);
4091 llvm::Function *ThunkFn = llvm::Function::Create(
4092 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
4093 ThunkFn->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
4095 if (ThunkFn->isWeakForLinker())
4096 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
4100 CodeGenFunction CGF(CGM);
4104 FunctionArgList FunctionArgs;
4107 buildThisParam(CGF, FunctionArgs);
4111 ImplicitParamDecl SrcParam(
4112 getContext(),
nullptr, SourceLocation(),
4113 &getContext().Idents.get(
"src"),
4114 getContext().getLValueReferenceType(RecordTy,
4116 ImplicitParamKind::Other);
4118 FunctionArgs.push_back(&SrcParam);
4123 ImplicitParamDecl IsMostDerived(getContext(),
nullptr,
4125 &getContext().Idents.get(
"is_most_derived"),
4126 getContext().IntTy, ImplicitParamKind::Other);
4129 FunctionArgs.push_back(&IsMostDerived);
4134 FunctionArgs, CD->
getLocation(), SourceLocation());
4137 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4138 llvm::Value *
This = getThisValue(CGF);
4140 llvm::Value *SrcVal =
4154 SmallVector<const Stmt *, 4> ArgVec;
4155 ArrayRef<ParmVarDecl *> params = CD->
parameters().drop_front(IsCopy ? 1 : 0);
4156 for (
const ParmVarDecl *PD : params) {
4157 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
4158 ArgVec.push_back(PD->getDefaultArg());
4161 CodeGenFunction::RunCleanupsScope Cleanups(CGF);
4163 const auto *FPT = CD->
getType()->
castAs<FunctionProtoType>();
4164 CGF.
EmitCallArgs(Args, FPT, llvm::ArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
4167 AddedStructorArgCounts ExtraArgs =
4172 llvm::Constant *CalleePtr =
4177 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4178 CGF.
EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args);
4180 Cleanups.ForceCleanup();
4189llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType
T,
4191 int32_t VBPtrOffset,
4196 const CXXConstructorDecl *CD =
4203 uint32_t Size = getContext().getTypeSizeInChars(
T).getQuantity();
4204 SmallString<256> MangledName;
4206 llvm::raw_svector_ostream
Out(MangledName);
4207 getMangleContext().mangleCXXCatchableType(
T, CD, CT, Size, NVOffset,
4208 VBPtrOffset, VBIndex, Out);
4210 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4211 return getImageRelativeConstant(GV);
4215 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(
T));
4219 llvm::Constant *CopyCtor;
4226 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4228 CopyCtor = getImageRelativeConstant(CopyCtor);
4230 bool IsScalar = !RD;
4231 bool HasVirtualBases =
false;
4232 bool IsStdBadAlloc =
false;
4233 QualType PointeeType =
T;
4247 if (HasVirtualBases)
4252 llvm::Constant *Fields[] = {
4253 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4255 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4256 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4257 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4258 llvm::ConstantInt::get(CGM.
IntTy, Size),
4261 llvm::StructType *CTType = getCatchableTypeType();
4262 auto *GV =
new llvm::GlobalVariable(
4263 CGM.
getModule(), CTType,
true, getLinkageForRTTI(
T),
4264 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4265 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4266 GV->setSection(
".xdata");
4267 if (GV->isWeakForLinker())
4268 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4269 return getImageRelativeConstant(GV);
4272llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType
T) {
4276 llvm::GlobalVariable *&CTA = CatchableTypeArrays[
T];
4283 llvm::SmallSetVector<llvm::Constant *, 2> CatchableTypes;
4293 const CXXRecordDecl *MostDerivedClass =
nullptr;
4301 if (MostDerivedClass) {
4302 const ASTContext &Context = getContext();
4303 const ASTRecordLayout &MostDerivedLayout =
4306 SmallVector<MSRTTIClass, 8> Classes;
4308 Classes.front().initialize(
nullptr,
nullptr);
4310 for (
const MSRTTIClass &
Class : Classes) {
4313 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4318 if (
Class.VirtualRoot) {
4329 CatchableTypes.insert(getCatchableType(RTTITy,
Class.OffsetInVBase,
4330 VBPtrOffset, OffsetInVBTable));
4338 CatchableTypes.insert(getCatchableType(
T));
4351 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4362 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4364 uint32_t NumEntries = CatchableTypes.size();
4365 llvm::Type *CTType = getImageRelativeType(CGM.
UnqualPtrTy);
4366 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4367 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4368 llvm::Constant *Fields[] = {
4369 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4370 llvm::ConstantArray::get(
4371 AT, llvm::ArrayRef(CatchableTypes.begin(),
4372 CatchableTypes.end()))
4374 SmallString<256> MangledName;
4376 llvm::raw_svector_ostream
Out(MangledName);
4377 getMangleContext().mangleCXXCatchableTypeArray(
T, NumEntries, Out);
4379 CTA =
new llvm::GlobalVariable(
4380 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(
T),
4381 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4382 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4383 CTA->setSection(
".xdata");
4384 if (CTA->isWeakForLinker())
4385 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4389llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType
T) {
4390 bool IsConst, IsVolatile, IsUnaligned;
4395 llvm::GlobalVariable *CTA = getCatchableTypeArray(
T);
4402 ->getLimitedValue();
4404 SmallString<256> MangledName;
4406 llvm::raw_svector_ostream
Out(MangledName);
4407 getMangleContext().mangleCXXThrowInfo(
T, IsConst, IsVolatile, IsUnaligned,
4413 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4429 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4432 if (!DtorD->isTrivial())
4435 llvm::Constant *ForwardCompat =
4436 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4437 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(CTA);
4438 llvm::StructType *TIType = getThrowInfoType();
4439 llvm::Constant *Fields[] = {
4440 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4441 getImageRelativeConstant(CleanupFn),
4443 PointerToCatchableTypes
4445 auto *GV =
new llvm::GlobalVariable(
4446 CGM.
getModule(), TIType,
true, getLinkageForRTTI(
T),
4447 llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4448 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4449 GV->setSection(
".xdata");
4450 if (GV->isWeakForLinker())
4451 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4455void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E) {
4457 assert(SubExpr &&
"SubExpr cannot be null");
4458 QualType ThrowType = SubExpr->
getType();
4467 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4474std::pair<llvm::Value *, const CXXRecordDecl *>
4475MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
4476 const CXXRecordDecl *RD) {
4478 std::tie(This, std::ignore, RD) = performBaseAdjustment(CGF, This,
T);
4482bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4483 const CXXRecordDecl *RD)
const {
4513 for (
const CXXBaseSpecifier &B : RD->
bases()) {
4514 if (
const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4515 if (!isPermittedToBeHomogeneousAggregate(FRD))
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *DynInitBB, llvm::BasicBlock *ContinueBB)
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty, CodeGenModule &CGM)
static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM)
static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM)
static llvm::GlobalValue * getTlsGuardVar(CodeGenModule &CGM)
static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile, bool &IsUnaligned)
static llvm::CallBase * emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM)
static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *ContinueBB)
static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)
Find ambiguity among base classes.
static void emitDynamicTlsInitialization(CodeGenFunction &CGF)
static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)
Recursively serializes a class hierarchy in pre-order depth first order.
static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM)
static bool isDeletingDtor(GlobalDecl GD)
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM)
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo &VFPtr, SmallString< 256 > &Name)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
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.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType 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
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,...
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
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void 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...
llvm::LLVMContext & getLLVMContext()
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()
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
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.
const llvm::DataLayout & getDataLayout() const
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
llvm::Function * codegenCXXStructor(GlobalDecl GD)
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const
Set the TLS mode for the given LLVM GlobalValue for the thread-local variable declaration D.
ASTContext & getContext() const
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
MicrosoftVTableContext & getMicrosoftVTableContext()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, llvm::Align Alignment)
Will return a global variable of the given type.
llvm::LLVMContext & getLLVMContext()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void addDeferredVTable(const CXXRecordDecl *RD)
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Function * CreateGlobalInitOrCleanUpFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false, llvm::GlobalVariable::LinkageTypes Linkage=llvm::GlobalVariable::InternalLinkage)
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.
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.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
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, 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.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
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)
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...
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
SmallVector< std::unique_ptr< VPtrInfo >, 2 > VPtrInfoVector
CXXDtorType
C++ destructor types.
@ 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.
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.
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::PointerType * UnqualPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
uint64_t Index
Method's index in the vftable.
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
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...