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) {
906 if (!getContext().getTargetInfo().callGlobalDeleteInDeletingDtor(
907 getContext().getLangOpts())) {
910 llvm::Value *MDThis =
911 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
921void MicrosoftCXXABI::emitRethrow(CodeGenFunction &CGF,
bool isNoReturn) {
922 llvm::Value *Args[] = {llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
931void MicrosoftCXXABI::emitBeginCatch(CodeGenFunction &CGF,
932 const CXXCatchStmt *S) {
936 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
937 llvm::CatchPadInst *CPI =
949 CPI->setArgOperand(2,
var.getObjectAddress(CGF).emitRawPointer(CGF));
957std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
958MicrosoftCXXABI::performBaseAdjustment(CodeGenFunction &CGF, Address
Value,
959 QualType SrcRecordTy) {
962 const ASTContext &Context = getContext();
968 return std::make_tuple(
Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
973 const CXXRecordDecl *PolymorphicBase =
nullptr;
974 for (
auto &Base : SrcDecl->
vbases()) {
975 const CXXRecordDecl *BaseDecl =
Base.getType()->getAsCXXRecordDecl();
977 PolymorphicBase = BaseDecl;
981 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
983 llvm::Value *Offset =
984 GetVirtualBaseClassOffset(CGF,
Value, SrcDecl, PolymorphicBase);
986 Value.getElementType(),
Value.emitRawPointer(CGF), Offset);
987 CharUnits VBaseAlign =
989 return std::make_tuple(Address(Ptr, CGF.
Int8Ty, VBaseAlign), Offset,
993bool MicrosoftCXXABI::shouldTypeidBeNullChecked(QualType SrcRecordTy) {
995 return !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
999 llvm::Value *Argument) {
1000 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1001 llvm::FunctionType *FTy =
1002 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
1003 llvm::Value *Args[] = {Argument};
1008void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
1009 llvm::CallBase *
Call =
1011 Call->setDoesNotReturn();
1012 CGF.
Builder.CreateUnreachable();
1015llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
1016 QualType SrcRecordTy,
1018 llvm::Type *StdTypeInfoPtrTy) {
1019 std::tie(ThisPtr, std::ignore, std::ignore) =
1020 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
1022 return CGF.
Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
1025bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1026 QualType SrcRecordTy) {
1029 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1032llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
1033 CodeGenFunction &CGF, Address This, QualType SrcRecordTy, QualType DestTy,
1034 QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1035 llvm::Value *SrcRTTI =
1037 llvm::Value *DestRTTI =
1040 llvm::Value *Offset;
1041 std::tie(This, Offset, std::ignore) =
1042 performBaseAdjustment(CGF, This, SrcRecordTy);
1043 llvm::Value *ThisPtr =
This.emitRawPointer(CGF);
1055 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1057 llvm::Value *Args[] = {
1058 ThisPtr, Offset, SrcRTTI, DestRTTI,
1063llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
1065 QualType SrcRecordTy) {
1066 std::tie(
Value, std::ignore, std::ignore) =
1067 performBaseAdjustment(CGF,
Value, SrcRecordTy);
1071 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1073 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1075 llvm::Value *Args[] = {
Value.emitRawPointer(CGF)};
1079bool MicrosoftCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
1083llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1084 CodeGenFunction &CGF, Address This,
const CXXRecordDecl *ClassDecl,
1085 const CXXRecordDecl *BaseClassDecl) {
1086 const ASTContext &Context = getContext();
1089 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.
PtrDiffTy, VBPtrChars);
1091 CharUnits VBTableChars =
1094 llvm::Value *VBTableOffset =
1097 llvm::Value *VBPtrToNewBase =
1098 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1101 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1104bool MicrosoftCXXABI::HasThisReturn(GlobalDecl GD)
const {
1113bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD)
const {
1123 uint64_t NumElts = 0;
1163 if (
auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
1164 if (Ctor->isUserProvided())
1166 }
else if (
auto *
Template = dyn_cast<FunctionTemplateDecl>(D)) {
1169 }
else if (
auto *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
1170 if (MethodDecl->isCopyAssignmentOperator() && MethodDecl->isDeleted())
1179bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI)
const {
1180 const CXXRecordDecl *RD = FI.
getReturnType()->getAsCXXRecordDecl();
1190 if (isIndirectReturn) {
1211MicrosoftCXXABI::EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
1212 const CXXRecordDecl *RD) {
1213 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1214 assert(IsMostDerivedClass &&
1215 "ctor for a class with virtual bases must have an implicit parameter");
1216 llvm::Value *IsCompleteObject =
1217 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1219 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1220 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1221 CGF.
Builder.CreateCondBr(IsCompleteObject,
1222 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1227 EmitVBPtrStores(CGF, RD);
1231 return SkipVbaseCtorsBB;
1235MicrosoftCXXABI::EmitDtorCompleteObjectHandler(CodeGenFunction &CGF) {
1236 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1237 assert(IsMostDerivedClass &&
1238 "ctor for a class with virtual bases must have an implicit parameter");
1239 llvm::Value *IsCompleteObject =
1240 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1242 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1243 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1244 CGF.
Builder.CreateCondBr(IsCompleteObject,
1245 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1250 return SkipVbaseDtorsBB;
1253void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1254 CodeGenFunction &CGF,
const CXXRecordDecl *RD) {
1268 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
1271 CGBuilderTy &Builder = CGF.
Builder;
1273 llvm::Value *Int8This =
nullptr;
1275 for (
const CXXBaseSpecifier &S : RD->
vbases()) {
1276 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1277 auto I = VBaseMap.find(VBase);
1278 assert(I != VBaseMap.end());
1279 if (!I->second.hasVtorDisp())
1282 llvm::Value *VBaseOffset =
1283 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1284 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1287 llvm::Value *VtorDispValue = Builder.CreateSub(
1288 VBaseOffset, llvm::ConstantInt::get(CGM.
PtrDiffTy, ConstantVBaseOffset),
1290 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1293 Int8This = getThisValue(CGF);
1295 llvm::Value *VtorDispPtr =
1296 Builder.CreateInBoundsGEP(CGF.
Int8Ty, Int8This, VBaseOffset);
1298 VtorDispPtr = Builder.CreateConstGEP1_32(CGF.
Int8Ty, VtorDispPtr, -4);
1300 Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1307 CallingConv ExpectedCallingConv = Context.getDefaultCallingConvention(
1311 return ExpectedCallingConv == ActualCallingConv;
1314void MicrosoftCXXABI::EmitCXXConstructors(
const CXXConstructorDecl *D) {
1326 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1332void MicrosoftCXXABI::EmitVBPtrStores(CodeGenFunction &CGF,
1333 const CXXRecordDecl *RD) {
1334 Address
This = getThisAddress(CGF);
1336 const ASTContext &Context = getContext();
1339 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1340 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1341 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1342 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1343 const ASTRecordLayout &SubobjectLayout =
1345 CharUnits Offs = VBT->NonVirtualOffset;
1347 if (VBT->getVBaseWithVPtr())
1350 llvm::Value *GVPtr =
1357CGCXXABI::AddedStructorArgCounts
1358MicrosoftCXXABI::buildStructorSignature(GlobalDecl GD,
1359 SmallVectorImpl<CanQualType> &ArgTys) {
1360 AddedStructorArgCounts Added;
1365 ArgTys.push_back(getContext().IntTy);
1368 auto *CD = dyn_cast<CXXConstructorDecl>(GD.
getDecl());
1376 const FunctionProtoType *FPT = CD->
getType()->
castAs<FunctionProtoType>();
1377 if (
Class->getNumVBases()) {
1379 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1382 ArgTys.push_back(getContext().IntTy);
1390void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1391 const CXXDestructorDecl *Dtor,
1396 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1398 const NamedDecl *ND = Dtor;
1403llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1408 return llvm::GlobalValue::InternalLinkage;
1419 if (Dtor->
hasAttr<DLLExportAttr>())
1420 return llvm::GlobalValue::WeakODRLinkage;
1421 if (Dtor->
hasAttr<DLLImportAttr>())
1422 return llvm::GlobalValue::AvailableExternallyLinkage;
1423 return llvm::GlobalValue::LinkOnceODRLinkage;
1428 return llvm::GlobalValue::LinkOnceODRLinkage;
1430 llvm_unreachable(
"MS C++ ABI does not support unified dtors");
1432 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1434 llvm_unreachable(
"invalid dtor type");
1437void MicrosoftCXXABI::EmitCXXDestructors(
const CXXDestructorDecl *D) {
1451MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
1454 if (
const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1465 MethodVFTableLocation ML =
1477 const ASTRecordLayout &DerivedLayout =
1478 getContext().getASTRecordLayout(MD->
getParent());
1485Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1486 CodeGenFunction &CGF, GlobalDecl GD, Address This,
1491 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1502 GlobalDecl LookupGD = GD;
1503 if (
const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1513 MethodVFTableLocation ML =
1528 const CXXRecordDecl *Derived = MD->
getParent();
1529 const CXXRecordDecl *VBase = ML.
VBase;
1530 llvm::Value *VBaseOffset =
1531 GetVirtualBaseClassOffset(CGF,
Result, Derived, VBase);
1533 Result.getElementType(),
Result.emitRawPointer(CGF), VBaseOffset);
1534 CharUnits VBaseAlign =
1538 if (!StaticOffset.
isZero()) {
1554void MicrosoftCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
1556 FunctionArgList &Params) {
1557 ASTContext &Context = getContext();
1564 ImplicitParamKind::Other);
1567 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
1569 Params.insert(Params.begin() + 1, IsMostDerived);
1571 Params.push_back(IsMostDerived);
1572 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1577 ImplicitParamKind::Other);
1578 Params.push_back(ShouldDelete);
1579 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1583void MicrosoftCXXABI::EmitInstanceFunctionProlog(CodeGenFunction &CGF) {
1600 llvm::Value *
This = loadIncomingCXXThis(CGF);
1603 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1604 if (!Adjustment.
isZero()) {
1610 setCXXABIThisValue(CGF, This);
1620 if (HasThisReturn(CGF.
CurGD) || hasMostDerivedReturn(CGF.
CurGD))
1624 assert(getStructorImplicitParamDecl(CGF) &&
1625 "no implicit parameter for a constructor with virtual bases?");
1626 getStructorImplicitParamValue(CGF)
1633 assert(getStructorImplicitParamDecl(CGF) &&
1634 "no implicit parameter for a deleting destructor?");
1635 getStructorImplicitParamValue(CGF)
1638 "should_call_delete");
1642CGCXXABI::AddedStructorArgs MicrosoftCXXABI::getImplicitConstructorArgs(
1649 return AddedStructorArgs{};
1652 const FunctionProtoType *FPT = D->
getType()->
castAs<FunctionProtoType>();
1653 llvm::Value *MostDerivedArg;
1655 MostDerivedArg = getStructorImplicitParamValue(CGF);
1660 return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1662 return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1665llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
1671void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
1672 const CXXDestructorDecl *DD,
1682 GlobalDecl GD(DD,
Type);
1686 assert(
Type != CXXDtorType::Dtor_Deleting &&
1687 "The deleting destructor should only be called via a virtual call");
1688 This = adjustThisArgumentForVirtualFunctionCall(CGF, GlobalDecl(DD,
Type),
1692 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1694 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1703 QualType(),
nullptr);
1704 if (BaseDtorEndBB) {
1706 CGF.
Builder.CreateBr(BaseDtorEndBB);
1711void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1712 const CXXRecordDecl *RD,
1713 llvm::GlobalVariable *VTable) {
1724 llvm::DenseSet<const CXXRecordDecl *> Visited;
1725 llvm::GlobalObject::VCallVisibility TypeVis =
1727 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1728 VTable->setVCallVisibilityMetadata(TypeVis);
1734 CharUnits AddressPoint =
1735 getContext().getLangOpts().RTTIData
1736 ? getContext().toCharUnitsFromBits(
1737 getContext().getTargetInfo().getPointerWidth(LangAS::Default))
1755 const ASTRecordLayout &Layout =
1756 getContext().getASTRecordLayout(DerivedRD);
1762 Offset = VBI->second.VBaseOffset;
1773void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
1774 const CXXRecordDecl *RD) {
1778 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1779 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1780 if (VTable->hasInitializer())
1783 const VTableLayout &VTLayout =
1786 llvm::Constant *RTTI =
nullptr;
1788 [](
const VTableComponent &VTC) { return VTC.isRTTIKind(); }))
1789 RTTI = getMSCompleteObjectLocator(RD, *Info);
1791 ConstantInitBuilder builder(CGM);
1792 auto components = builder.beginStruct();
1794 VTable->hasLocalLinkage());
1795 components.finishAndSetAsInitializer(VTable);
1797 emitVTableTypeMetadata(*Info, RD, VTable);
1801bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1802 CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr) {
1806llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1807 CodeGenFunction &CGF,
const CXXRecordDecl *VTableClass, BaseSubobject Base,
1808 const CXXRecordDecl *NearestVBase) {
1809 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1810 if (!VTableAddressPoint) {
1811 assert(
Base.getBase()->getNumVBases() &&
1812 !getContext().getASTRecordLayout(
Base.getBase()).hasOwnVFPtr());
1814 return VTableAddressPoint;
1820 llvm::raw_svector_ostream Out(Name);
1825MicrosoftCXXABI::getVTableAddressPoint(BaseSubobject Base,
1826 const CXXRecordDecl *VTableClass) {
1827 (void)getAddrOfVTable(VTableClass,
Base.getBaseOffset());
1828 VFTableIdTy
ID(VTableClass,
Base.getBaseOffset());
1829 return VFTablesMap[
ID];
1832llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1833 CharUnits VPtrOffset) {
1838 VFTableIdTy
ID(RD, VPtrOffset);
1839 auto [I, Inserted] = VTablesMap.try_emplace(ID);
1843 llvm::GlobalVariable *&VTable = I->second;
1848 if (DeferredVFTables.insert(RD).second) {
1856 llvm::StringSet<> ObservedMangledNames;
1857 for (
const auto &VFPtr : VFPtrs) {
1858 SmallString<256> Name;
1860 if (!ObservedMangledNames.insert(Name.str()).second)
1861 llvm_unreachable(
"Already saw this mangling before?");
1866 const std::unique_ptr<VPtrInfo> *VFPtrI =
1867 llvm::find_if(VFPtrs, [&](
const std::unique_ptr<VPtrInfo> &VPI) {
1868 return VPI->FullOffsetInMDC == VPtrOffset;
1870 if (VFPtrI == VFPtrs.end()) {
1871 VFTablesMap[
ID] =
nullptr;
1874 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1876 SmallString<256> VFTableName;
1886 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1887 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1888 : CGM.getVTableLinkage(RD);
1889 bool VFTableComesFromAnotherTU =
1890 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1891 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1892 bool VTableAliasIsRequred =
1893 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1895 if (llvm::GlobalValue *VFTable =
1896 CGM.
getModule().getNamedGlobal(VFTableName)) {
1897 VFTablesMap[
ID] = VFTable;
1898 VTable = VTableAliasIsRequred
1901 :
cast<llvm::GlobalVariable>(VFTable);
1905 const VTableLayout &VTLayout =
1907 llvm::GlobalValue::LinkageTypes VTableLinkage =
1908 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1910 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1912 llvm::Type *VTableType = CGM.
getVTables().getVTableType(VTLayout);
1916 llvm::GlobalValue *VFTable;
1917 VTable =
new llvm::GlobalVariable(CGM.
getModule(), VTableType,
1918 true, VTableLinkage,
1919 nullptr, VTableName);
1920 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1922 llvm::Comdat *
C =
nullptr;
1923 if (!VFTableComesFromAnotherTU &&
1924 llvm::GlobalValue::isWeakForLinker(VFTableLinkage))
1925 C = CGM.
getModule().getOrInsertComdat(VFTableName.str());
1930 if (VTableAliasIsRequred) {
1931 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1932 llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1933 llvm::ConstantInt::get(CGM.
Int32Ty, 1)};
1936 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1937 VTable->getValueType(), VTable, GEPIndices);
1938 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1939 VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1941 C->setSelectionKind(llvm::Comdat::Largest);
1943 VFTable = llvm::GlobalAlias::create(CGM.
Int8PtrTy,
1945 VFTableName.str(), VTableGEP,
1947 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1956 VTable->setComdat(
C);
1958 if (RD->
hasAttr<DLLExportAttr>())
1959 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1961 VFTablesMap[
ID] = VFTable;
1965CGCallee MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
1969 SourceLocation Loc) {
1970 CGBuilderTy &Builder = CGF.
Builder;
1974 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1977 llvm::Value *VTable =
1985 auto getObjectWithVPtr = [&] {
1988 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1989 return Info->FullOffsetInMDC == ML.VFPtrOffset;
1998 getObjectWithVPtr(), VTable, Ty,
2006 llvm::Value *VFuncPtr =
2007 Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.
Index,
"vfn");
2008 VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.
getPointerAlign());
2011 CGCallee
Callee(GD, VFunc);
2015llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
2016 CodeGenFunction &CGF,
const CXXDestructorDecl *Dtor,
CXXDtorType DtorType,
2017 Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke) {
2018 auto *CE = dyn_cast<const CXXMemberCallExpr *>(E);
2019 auto *D = dyn_cast<const CXXDeleteExpr *>(E);
2020 assert((CE !=
nullptr) ^ (D !=
nullptr));
2021 assert(CE ==
nullptr || CE->arguments().empty());
2027 const CGFunctionInfo *FInfo =
2032 ASTContext &Context = getContext();
2034 bool IsGlobalDelete = D && D->isGlobalDelete() &&
2037 llvm::Value *ImplicitParam =
2038 CGF.
Builder.getInt32((IsDeleting ? 1 : 0) | (IsGlobalDelete ? 4 : 0));
2042 ThisTy = CE->getObjectType();
2044 ThisTy = D->getDestroyedType();
2047 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
2050 ImplicitParam, Context.
IntTy, CE, CallOrInvoke);
2054const VBTableGlobals &
2055MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
2058 auto [Entry, Added] = VBTablesMap.try_emplace(RD);
2059 VBTableGlobals &VBGlobals = Entry->second;
2064 VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2069 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2070 E = VBGlobals.VBTables->end();
2072 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,
Linkage));
2079MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2080 const MethodVFTableLocation &ML) {
2082 "can't form pointers to ctors or virtual dtors");
2085 SmallString<256> ThunkName;
2086 llvm::raw_svector_ostream
Out(ThunkName);
2087 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2090 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
2094 const CGFunctionInfo &FnInfo =
2097 llvm::Function *ThunkFn =
2098 llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
2100 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2103 ? llvm::GlobalValue::LinkOnceODRLinkage
2104 : llvm::GlobalValue::InternalLinkage);
2106 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
2115 ThunkFn->addFnAttr(
"thunk");
2118 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
2121 CodeGenFunction CGF(CGM);
2122 CGF.
CurGD = GlobalDecl(MD);
2127 FunctionArgList FunctionArgs;
2128 buildThisParam(CGF, FunctionArgs);
2132 FunctionArgs, MD->
getLocation(), SourceLocation());
2135 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2140 llvm::Value *VTable =
2143 llvm::Value *VFuncPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2144 ThunkPtrTy, VTable, ML.
Index,
"vfn");
2153void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2154 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2155 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2156 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2157 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2158 if (GV->isDeclaration())
2159 emitVBTableDefinition(*VBT, RD, GV);
2163llvm::GlobalVariable *
2164MicrosoftCXXABI::getAddrOfVBTable(
const VPtrInfo &VBT,
const CXXRecordDecl *RD,
2165 llvm::GlobalVariable::LinkageTypes
Linkage) {
2166 SmallString<256> OutName;
2167 llvm::raw_svector_ostream
Out(OutName);
2168 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2169 StringRef Name = OutName.str();
2171 llvm::ArrayType *VBTableType =
2174 assert(!CGM.
getModule().getNamedGlobal(Name) &&
2175 "vbtable with this name already exists: mangling bug?");
2176 CharUnits Alignment =
2180 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2182 if (RD->
hasAttr<DLLImportAttr>())
2183 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2184 else if (RD->
hasAttr<DLLExportAttr>())
2185 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2187 if (!GV->hasExternalLinkage())
2188 emitVBTableDefinition(VBT, RD, GV);
2193void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2194 const CXXRecordDecl *RD,
2195 llvm::GlobalVariable *GV)
const {
2199 "should only emit vbtables for classes with vbtables");
2201 const ASTRecordLayout &BaseLayout =
2203 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2205 SmallVector<llvm::Constant *, 4> Offsets(1 + ObjectWithVPtr->
getNumVBases(),
2210 Offsets[0] = llvm::ConstantInt::get(CGM.
IntTy, -VBPtrOffset.
getQuantity());
2213 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2214 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2221 CompleteVBPtrOffset +=
2223 Offset -= CompleteVBPtrOffset;
2225 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2226 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2227 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.
IntTy, Offset.
getQuantity());
2230 assert(Offsets.size() ==
2232 llvm::ArrayType *VBTableType =
2233 llvm::ArrayType::get(CGM.
IntTy, Offsets.size());
2234 llvm::Constant *
Init = llvm::ConstantArray::get(VBTableType, Offsets);
2235 GV->setInitializer(
Init);
2237 if (RD->
hasAttr<DLLImportAttr>())
2238 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2241llvm::Value *MicrosoftCXXABI::performThisAdjustment(
2242 CodeGenFunction &CGF, Address This,
2243 const CXXRecordDecl * ,
const ThunkInfo &TI) {
2244 const ThisAdjustment &TA = TI.
This;
2246 return This.emitRawPointer(CGF);
2252 V =
This.emitRawPointer(CGF);
2256 Address VtorDispPtr =
2262 CGF.
Builder.CreateNeg(VtorDisp));
2275 llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2294llvm::Value *MicrosoftCXXABI::performReturnAdjustment(
2295 CodeGenFunction &CGF, Address Ret,
2296 const CXXRecordDecl * ,
const ReturnAdjustment &RA) {
2299 return Ret.emitRawPointer(CGF);
2303 llvm::Value *
V =
Ret.emitRawPointer(CGF);
2308 llvm::Value *VBaseOffset =
2320bool MicrosoftCXXABI::requiresArrayCookie(
const CXXDeleteExpr *
expr,
2321 QualType elementType) {
2327bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *
expr) {
2330 return expr->getAllocatedType().isDestructedType();
2333CharUnits MicrosoftCXXABI::getArrayCookieSizeImpl(QualType
type) {
2336 ASTContext &Ctx = getContext();
2341llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
2343 CharUnits cookieSize) {
2348Address MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
2350 llvm::Value *numElements,
2351 const CXXNewExpr *
expr,
2352 QualType elementType) {
2353 assert(requiresArrayCookie(
expr));
2356 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2359 Address cookiePtr = newPtr;
2371 llvm::FunctionCallee Dtor,
2372 llvm::Constant *
Addr) {
2377 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2378 CGF.
IntTy, DtorStub->getType(),
false);
2381 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2382 if (llvm::Function *TLRegDtorFn =
2383 dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2384 TLRegDtorFn->setDoesNotThrow();
2389void MicrosoftCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
const VarDecl &D,
2390 llvm::FunctionCallee Dtor,
2391 llvm::Constant *
Addr) {
2406void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2407 CodeGenModule &CGM, ArrayRef<const VarDecl *> CXXThreadLocals,
2408 ArrayRef<llvm::Function *> CXXThreadLocalInits,
2409 ArrayRef<const VarDecl *> CXXThreadLocalInitVars) {
2410 if (CXXThreadLocalInits.empty())
2415 ?
"/include:___dyn_tls_init@12"
2416 :
"/include:__dyn_tls_init");
2421 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2422 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2423 CGM.
getModule(), InitFunc->getType(),
true,
2424 llvm::GlobalVariable::InternalLinkage, InitFunc,
2425 Twine(InitFunc->getName(),
"$initializer$"));
2426 InitFuncPtr->setSection(
".CRT$XDU");
2433 std::vector<llvm::Function *> NonComdatInits;
2434 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2437 llvm::Function *F = CXXThreadLocalInits[I];
2440 if (llvm::Comdat *
C = GV->getComdat())
2441 AddToXDU(F)->setComdat(
C);
2443 NonComdatInits.push_back(F);
2446 if (!NonComdatInits.empty()) {
2447 llvm::FunctionType *FTy =
2448 llvm::FunctionType::get(CGM.
VoidTy,
false);
2451 SourceLocation(),
true);
2452 CodeGenFunction(CGM).GenerateCXXGlobalInitFunc(InitFunc, NonComdatInits);
2464 llvm::Constant *TlsGuardConstant =
2468 TlsGuard->setThreadLocal(
true);
2476 llvm::FunctionType *FTy =
2477 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()), {},
2480 FTy,
"__dyn_tls_on_demand_init",
2482 llvm::AttributeList::FunctionIndex,
2483 llvm::Attribute::NoUnwind),
2488 llvm::BasicBlock *DynInitBB,
2489 llvm::BasicBlock *ContinueBB) {
2490 llvm::LoadInst *TlsGuardValue =
2492 llvm::Value *CmpResult =
2494 CGF.
Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2498 llvm::GlobalValue *TlsGuard,
2499 llvm::BasicBlock *ContinueBB) {
2501 llvm::Function *InitializerFunction =
2503 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(InitializerFunction);
2504 CallVal->setCallingConv(InitializerFunction->getCallingConv());
2506 CGF.
Builder.CreateBr(ContinueBB);
2510 llvm::BasicBlock *DynInitBB =
2512 llvm::BasicBlock *ContinueBB =
2518 CGF.
Builder.SetInsertPoint(DynInitBB);
2520 CGF.
Builder.SetInsertPoint(ContinueBB);
2523LValue MicrosoftCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
2525 QualType LValType) {
2539 Address
Addr(
V, RealVarTy, Alignment);
2543 AlignmentSource::Decl)
2549 StringRef VarName(
"_Init_thread_epoch");
2551 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2553 auto *GV =
new llvm::GlobalVariable(
2555 false, llvm::GlobalVariable::ExternalLinkage,
2557 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2563 llvm::FunctionType *FTy =
2564 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2567 FTy,
"_Init_thread_header",
2569 llvm::AttributeList::FunctionIndex,
2570 llvm::Attribute::NoUnwind),
2575 llvm::FunctionType *FTy =
2576 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2579 FTy,
"_Init_thread_footer",
2581 llvm::AttributeList::FunctionIndex,
2582 llvm::Attribute::NoUnwind),
2587 llvm::FunctionType *FTy =
2588 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2591 FTy,
"_Init_thread_abort",
2593 llvm::AttributeList::FunctionIndex,
2594 llvm::Attribute::NoUnwind),
2599struct ResetGuardBit final : EHScopeStack::Cleanup {
2602 ResetGuardBit(Address Guard,
unsigned GuardNum)
2603 : Guard(Guard), GuardNum(GuardNum) {}
2605 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2608 CGBuilderTy &Builder = CGF.
Builder;
2609 llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2610 llvm::ConstantInt *Mask =
2611 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2612 Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2616struct CallInitThreadAbort final : EHScopeStack::Cleanup {
2618 CallInitThreadAbort(RawAddress Guard) : Guard(Guard.getPointer()) {}
2620 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2627void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
const VarDecl &D,
2628 llvm::GlobalVariable *GV,
2632 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2634 llvm::Function *F = CGF.
CurFn;
2635 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2636 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2642 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2646 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2648 CGBuilderTy &Builder = CGF.
Builder;
2649 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2650 llvm::ConstantInt *
Zero = llvm::ConstantInt::get(GuardTy, 0);
2654 GuardInfo *GI =
nullptr;
2655 if (ThreadlocalStatic)
2657 else if (!ThreadsafeStatic)
2660 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2665 GuardNum = getContext().getStaticLocalNumber(&D);
2666 assert(GuardNum > 0);
2668 }
else if (HasPerVariableGuard) {
2672 GuardNum = GI->BitIndex++;
2675 if (!HasPerVariableGuard && GuardNum >= 32) {
2677 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2684 SmallString<256> GuardName;
2686 llvm::raw_svector_ostream
Out(GuardName);
2687 if (HasPerVariableGuard)
2688 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2691 getMangleContext().mangleStaticGuardVariable(&D, Out);
2697 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2698 GV->getLinkage(),
Zero, GuardName.str());
2699 GuardVar->setVisibility(GV->getVisibility());
2700 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2701 GuardVar->setAlignment(GuardAlign.
getAsAlign());
2702 if (GuardVar->isWeakForLinker())
2703 GuardVar->setComdat(
2704 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2707 if (GI && !HasPerVariableGuard)
2708 GI->Guard = GuardVar;
2711 ConstantAddress GuardAddr(GuardVar, GuardTy, GuardAlign);
2713 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2714 "static local from the same function had different linkage");
2716 if (!HasPerVariableGuard) {
2724 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2725 llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2726 llvm::Value *NeedsInit =
2727 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit),
Zero);
2731 CodeGenFunction::GuardKind::VariableGuard, &D);
2736 Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2740 Builder.CreateBr(EndBlock);
2758 llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2759 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2760 llvm::LoadInst *InitThreadEpoch =
2762 llvm::Value *IsUninitialized =
2763 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2767 CodeGenFunction::GuardKind::VariableGuard, &D);
2773 GuardAddr.getPointer());
2774 llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2775 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2776 llvm::Value *ShouldDoInit =
2777 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2779 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2787 GuardAddr.getPointer());
2788 Builder.CreateBr(EndBlock);
2794bool MicrosoftCXXABI::isZeroInitializable(
const MemberPointerType *MPT) {
2810MicrosoftCXXABI::ConvertMemberPointerType(
const MemberPointerType *MPT) {
2813 llvm::SmallVector<llvm::Type *, 4> fields;
2817 fields.push_back(CGM.
IntTy);
2821 fields.push_back(CGM.
IntTy);
2823 fields.push_back(CGM.
IntTy);
2825 fields.push_back(CGM.
IntTy);
2827 if (fields.size() == 1)
2832void MicrosoftCXXABI::
2833GetNullMemberPointerFields(
const MemberPointerType *MPT,
2834 llvm::SmallVectorImpl<llvm::Constant *> &fields) {
2835 assert(fields.empty());
2840 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2843 fields.push_back(getZeroInt());
2845 fields.push_back(getAllOnesInt());
2850 fields.push_back(getZeroInt());
2852 fields.push_back(getZeroInt());
2854 fields.push_back(getAllOnesInt());
2858MicrosoftCXXABI::EmitNullMemberPointer(
const MemberPointerType *MPT) {
2859 llvm::SmallVector<llvm::Constant *, 4> fields;
2860 GetNullMemberPointerFields(MPT, fields);
2861 if (fields.size() == 1)
2863 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2864 assert(Res->getType() == ConvertMemberPointerType(MPT));
2869MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2870 bool IsMemberFunction,
2871 const CXXRecordDecl *RD,
2872 CharUnits NonVirtualBaseAdjustment,
2873 unsigned VBTableIndex) {
2881 llvm::SmallVector<llvm::Constant *, 4> fields;
2882 fields.push_back(FirstField);
2885 fields.push_back(llvm::ConstantInt::get(
2891 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2897 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2899 return llvm::ConstantStruct::getAnon(fields);
2903MicrosoftCXXABI::EmitMemberDataPointer(
const MemberPointerType *MPT,
2908llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl *RD,
2911 MSInheritanceModel::Virtual)
2912 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2913 llvm::Constant *FirstField =
2915 return EmitFullMemberPointer(FirstField,
false, RD,
2919llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2921 const MemberPointerType *DstTy = MPType->
castAs<MemberPointerType>();
2924 return EmitNullMemberPointer(DstTy);
2926 ASTContext &Ctx = getContext();
2930 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2931 C = EmitMemberFunctionPointer(MD);
2938 const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2943 C = EmitMemberDataPointer(RD, FieldOffset);
2946 if (!MemberPointerPath.empty()) {
2948 const MemberPointerType *SrcTy =
2950 std::nullopt, SrcRD)
2951 ->
castAs<MemberPointerType>();
2954 SmallVector<const CXXBaseSpecifier *, 4> DerivedToBasePath;
2955 const CXXRecordDecl *PrevRD = SrcRD;
2956 for (
const CXXRecordDecl *PathElem : MemberPointerPath) {
2957 const CXXRecordDecl *
Base =
nullptr;
2958 const CXXRecordDecl *Derived =
nullptr;
2959 if (DerivedMember) {
2966 for (
const CXXBaseSpecifier &BS : Derived->
bases())
2967 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2968 Base->getCanonicalDecl())
2969 DerivedToBasePath.push_back(&BS);
2972 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2974 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2975 : CK_BaseToDerivedMemberPointer;
2976 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2977 DerivedToBasePath.end(),
C);
2983MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2984 assert(MD->
isInstance() &&
"Member function must not be static!");
2988 CodeGenTypes &Types = CGM.
getTypes();
2990 unsigned VBTableIndex = 0;
2991 llvm::Constant *FirstField;
2992 const FunctionProtoType *FPT = MD->
getType()->
castAs<FunctionProtoType>();
3007 MethodVFTableLocation ML = VTableContext.getMethodVFTableLocation(MD);
3008 FirstField = EmitVirtualMemPtrThunk(MD, ML);
3012 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
3015 if (VBTableIndex == 0 &&
3017 MSInheritanceModel::Virtual)
3018 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
3021 return EmitFullMemberPointer(FirstField,
true, RD,
3022 NonVirtualBaseAdjustment, VBTableIndex);
3029MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF,
3032 const MemberPointerType *MPT,
3034 CGBuilderTy &Builder = CGF.
Builder;
3037 llvm::ICmpInst::Predicate
Eq;
3038 llvm::Instruction::BinaryOps
And,
Or;
3040 Eq = llvm::ICmpInst::ICMP_NE;
3041 And = llvm::Instruction::Or;
3042 Or = llvm::Instruction::And;
3044 Eq = llvm::ICmpInst::ICMP_EQ;
3045 And = llvm::Instruction::And;
3046 Or = llvm::Instruction::Or;
3055 return Builder.CreateICmp(
Eq, L, R);
3058 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
3059 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
3060 llvm::Value *Cmp0 = Builder.CreateICmp(
Eq, L0, R0,
"memptr.cmp.first");
3063 llvm::Value *Res =
nullptr;
3065 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3066 llvm::Value *LF = Builder.CreateExtractValue(L, I);
3067 llvm::Value *RF = Builder.CreateExtractValue(R, I);
3068 llvm::Value *Cmp = Builder.CreateICmp(
Eq, LF, RF,
"memptr.cmp.rest");
3070 Res = Builder.CreateBinOp(
And, Res, Cmp);
3078 llvm::Value *
Zero = llvm::Constant::getNullValue(L0->getType());
3079 llvm::Value *IsZero = Builder.CreateICmp(
Eq, L0,
Zero,
"memptr.cmp.iszero");
3080 Res = Builder.CreateBinOp(
Or, Res, IsZero);
3085 return Builder.CreateBinOp(
And, Res, Cmp0,
"memptr.cmp");
3089MicrosoftCXXABI::EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
3090 llvm::Value *MemPtr,
3091 const MemberPointerType *MPT) {
3092 CGBuilderTy &Builder = CGF.
Builder;
3093 llvm::SmallVector<llvm::Constant *, 4> fields;
3096 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
3098 GetNullMemberPointerFields(MPT, fields);
3099 assert(!fields.empty());
3100 llvm::Value *FirstField = MemPtr;
3101 if (MemPtr->getType()->isStructTy())
3102 FirstField = Builder.CreateExtractValue(MemPtr, 0);
3103 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
3111 for (
int I = 1, E = fields.size(); I < E; ++I) {
3112 llvm::Value *
Field = Builder.CreateExtractValue(MemPtr, I);
3113 llvm::Value *
Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
3114 Res = Builder.CreateOr(Res,
Next,
"memptr.tobool");
3119bool MicrosoftCXXABI::MemberPointerConstantIsNull(
const MemberPointerType *MPT,
3120 llvm::Constant *Val) {
3123 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3124 Val->getAggregateElement(0U) : Val;
3125 return FirstField->isNullValue();
3130 if (isZeroInitializable(MPT) && Val->isNullValue())
3135 llvm::SmallVector<llvm::Constant *, 4> Fields;
3136 GetNullMemberPointerFields(MPT, Fields);
3137 if (Fields.size() == 1) {
3138 assert(Val->getType()->isIntegerTy());
3139 return Val == Fields[0];
3143 for (I = 0, E = Fields.size(); I != E; ++I) {
3144 if (Val->getAggregateElement(I) != Fields[I])
3151MicrosoftCXXABI::GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
3153 llvm::Value *VBPtrOffset,
3154 llvm::Value *VBTableOffset,
3155 llvm::Value **VBPtrOut) {
3156 CGBuilderTy &Builder = CGF.
Builder;
3158 llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3159 CGM.
Int8Ty,
This.emitRawPointer(CGF), VBPtrOffset,
"vbptr");
3163 CharUnits VBPtrAlign;
3164 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3165 VBPtrAlign =
This.getAlignment().alignmentAtOffset(
3171 llvm::Value *VBTable =
3172 Builder.CreateAlignedLoad(CGM.
UnqualPtrTy, VBPtr, VBPtrAlign,
"vbtable");
3175 llvm::Value *VBTableIndex = Builder.CreateAShr(
3176 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3180 llvm::Value *VBaseOffs =
3181 Builder.CreateInBoundsGEP(CGM.
Int32Ty, VBTable, VBTableIndex);
3182 return Builder.CreateAlignedLoad(CGM.
Int32Ty, VBaseOffs,
3188llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3189 CodeGenFunction &CGF,
const Expr *E,
const CXXRecordDecl *RD,
3190 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3191 CGBuilderTy &Builder = CGF.
Builder;
3193 llvm::BasicBlock *OriginalBB =
nullptr;
3194 llvm::BasicBlock *SkipAdjustBB =
nullptr;
3195 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3202 OriginalBB = Builder.GetInsertBlock();
3205 llvm::Value *IsVirtual =
3206 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3208 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3220 "member pointer representation requires a "
3221 "complete class type for %0 to perform this expression");
3224 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3227 llvm::Value *VBPtr =
nullptr;
3228 llvm::Value *VBaseOffs =
3229 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
3230 llvm::Value *AdjustedBase =
3231 Builder.CreateInBoundsGEP(CGM.
Int8Ty, VBPtr, VBaseOffs);
3234 if (VBaseAdjustBB) {
3235 Builder.CreateBr(SkipAdjustBB);
3237 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3238 Phi->addIncoming(
Base.emitRawPointer(CGF), OriginalBB);
3239 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3242 return AdjustedBase;
3245llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3246 CodeGenFunction &CGF,
const Expr *E, Address Base, llvm::Value *MemPtr,
3247 const MemberPointerType *MPT,
bool IsInBounds) {
3249 CGBuilderTy &Builder = CGF.
Builder;
3255 llvm::Value *FieldOffset = MemPtr;
3256 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3257 llvm::Value *VBPtrOffset =
nullptr;
3258 if (MemPtr->getType()->isStructTy()) {
3261 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3263 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3265 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3269 if (VirtualBaseAdjustmentOffset) {
3270 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
3277 return Builder.CreateGEP(CGF.
Int8Ty,
Addr, FieldOffset,
"memptr.offset",
3278 IsInBounds ? llvm::GEPNoWrapFlags::inBounds()
3279 : llvm::GEPNoWrapFlags::none());
3283MicrosoftCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
3286 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3287 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3296 const MemberPointerType *SrcTy =
3298 const MemberPointerType *DstTy = E->
getType()->
castAs<MemberPointerType>();
3302 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3303 if (IsReinterpret && IsFunc)
3307 CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
3308 if (IsReinterpret &&
3312 CGBuilderTy &Builder = CGF.
Builder;
3315 llvm::Value *
IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3316 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3320 if (IsReinterpret) {
3323 assert(Src->getType() == DstNull->getType());
3324 return Builder.CreateSelect(
IsNotNull, Src, DstNull);
3327 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3330 Builder.CreateCondBr(
IsNotNull, ConvertBB, ContinueBB);
3333 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3337 Builder.CreateBr(ContinueBB);
3341 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3342 Phi->addIncoming(DstNull, OriginalBB);
3343 Phi->addIncoming(Dst, ConvertBB);
3347llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3348 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
CastKind CK,
3351 CGBuilderTy &Builder) {
3360 llvm::Value *FirstField = Src;
3361 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3362 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3363 llvm::Value *VBPtrOffset = getZeroInt();
3367 FirstField = Builder.CreateExtractValue(Src, I++);
3369 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3371 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3373 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3376 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3377 const MemberPointerType *DerivedTy = IsDerivedToBase ? SrcTy : DstTy;
3382 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3389 llvm::Value *SrcVBIndexEqZero =
3390 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3391 if (SrcInheritance == MSInheritanceModel::Virtual) {
3392 if (int64_t SrcOffsetToFirstVBase =
3393 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3394 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3396 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3398 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3409 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3414 llvm::Value *NVDisp;
3415 if (IsDerivedToBase)
3416 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3418 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3420 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3424 llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3427 if (llvm::GlobalVariable *VDispMap =
3428 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3429 llvm::Value *VBIndex = Builder.CreateExactUDiv(
3430 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3432 llvm::Constant *Mapping = VDispMap->getInitializer();
3433 VirtualBaseAdjustmentOffset =
3436 llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3437 VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3438 CGM.
IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3444 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3451 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3453 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3455 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3461 if (DstInheritance == MSInheritanceModel::Virtual) {
3462 if (int64_t DstOffsetToFirstVBase =
3463 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3464 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3466 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3468 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3477 Dst = llvm::PoisonValue::get(ConvertMemberPointerType(DstTy));
3479 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3481 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3483 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3485 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3491MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3492 llvm::Constant *Src) {
3493 const MemberPointerType *SrcTy =
3495 const MemberPointerType *DstTy = E->
getType()->
castAs<MemberPointerType>();
3499 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3503llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3504 const MemberPointerType *SrcTy,
const MemberPointerType *DstTy,
CastKind CK,
3507 assert(CK == CK_DerivedToBaseMemberPointer ||
3508 CK == CK_BaseToDerivedMemberPointer ||
3509 CK == CK_ReinterpretMemberPointer);
3512 if (MemberPointerConstantIsNull(SrcTy, Src))
3513 return EmitNullMemberPointer(DstTy);
3518 if (CK == CK_ReinterpretMemberPointer)
3523 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3528CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3529 CodeGenFunction &CGF,
const Expr *E, Address This,
3530 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3531 const MemberPointerType *MPT) {
3533 const FunctionProtoType *FPT =
3536 CGBuilderTy &Builder = CGF.
Builder;
3542 llvm::Value *FunctionPointer = MemPtr;
3543 llvm::Value *NonVirtualBaseAdjustment =
nullptr;
3544 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3545 llvm::Value *VBPtrOffset =
nullptr;
3546 if (MemPtr->getType()->isStructTy()) {
3549 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3551 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3553 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3555 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3558 if (VirtualBaseAdjustmentOffset) {
3559 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3560 VirtualBaseAdjustmentOffset, VBPtrOffset);
3562 ThisPtrForCall =
This.emitRawPointer(CGF);
3565 if (NonVirtualBaseAdjustment)
3566 ThisPtrForCall = Builder.CreateInBoundsGEP(CGF.
Int8Ty, ThisPtrForCall,
3567 NonVirtualBaseAdjustment);
3569 CGCallee
Callee(FPT, FunctionPointer);
3574 return new MicrosoftCXXABI(CGM);
3608 StringRef MangledName(
"??_7type_info@@6B@");
3609 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3613 llvm::GlobalVariable::ExternalLinkage,
3614 nullptr, MangledName);
3627 IsPrivateOnPath = 1 | 8,
3631 HasHierarchyDescriptor = 64
3633 MSRTTIClass(
const CXXRecordDecl *RD) : RD(RD) {}
3635 const CXXBaseSpecifier *Specifier);
3637 MSRTTIClass *getFirstChild() {
return this + 1; }
3638 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3639 return Child + 1 + Child->NumBases;
3642 const CXXRecordDecl *RD, *VirtualRoot;
3643 uint32_t Flags, NumBases, OffsetInVBase;
3647uint32_t MSRTTIClass::initialize(
const MSRTTIClass *Parent,
3648 const CXXBaseSpecifier *Specifier) {
3649 Flags = HasHierarchyDescriptor;
3651 VirtualRoot =
nullptr;
3655 Flags |= IsPrivate | IsPrivateOnPath;
3661 if (Parent->Flags & IsPrivateOnPath)
3662 Flags |= IsPrivateOnPath;
3663 VirtualRoot = Parent->VirtualRoot;
3664 OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
3665 .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
3669 MSRTTIClass *Child = getFirstChild();
3670 for (
const CXXBaseSpecifier &Base : RD->bases()) {
3671 NumBases += Child->initialize(
this, &Base) + 1;
3672 Child = getNextChild(Child);
3677static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
3679 case Linkage::Invalid:
3680 llvm_unreachable(
"Linkage hasn't been computed!");
3683 case Linkage::Internal:
3684 case Linkage::UniqueExternal:
3685 return llvm::GlobalValue::InternalLinkage;
3687 case Linkage::VisibleNone:
3688 case Linkage::Module:
3689 case Linkage::External:
3690 return llvm::GlobalValue::LinkOnceODRLinkage;
3692 llvm_unreachable(
"Invalid linkage!");
3698struct MSRTTIBuilder {
3700 HasBranchingHierarchy = 1,
3701 HasVirtualBranchingHierarchy = 2,
3702 HasAmbiguousBases = 4
3705 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3706 : CGM(ABI.CGM), Context(CGM.getContext()),
3707 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3708 Linkage(getLinkageForRTTI(CGM.getContext().getCanonicalTagType(RD))),
3711 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3712 llvm::GlobalVariable *
3713 getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
3714 llvm::GlobalVariable *getClassHierarchyDescriptor();
3715 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3718 ASTContext &Context;
3719 llvm::LLVMContext &VMContext;
3721 const CXXRecordDecl *RD;
3722 llvm::GlobalVariable::LinkageTypes
Linkage;
3723 MicrosoftCXXABI &ABI;
3732 Classes.push_back(MSRTTIClass(RD));
3743 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3744 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3745 !VirtualBases.insert(Class->RD).second) {
3746 Class = MSRTTIClass::getNextChild(Class);
3749 if (!UniqueBases.insert(Class->RD).second)
3750 AmbiguousBases.insert(Class->RD);
3753 if (AmbiguousBases.empty())
3755 for (MSRTTIClass &Class : Classes)
3756 if (AmbiguousBases.count(Class.RD))
3757 Class.Flags |= MSRTTIClass::IsAmbiguous;
3760llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3761 SmallString<256> MangledName;
3763 llvm::raw_svector_ostream
Out(MangledName);
3764 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3768 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3772 SmallVector<MSRTTIClass, 8> Classes;
3774 Classes.front().initialize(
nullptr,
nullptr);
3777 for (
const MSRTTIClass &
Class : Classes) {
3778 if (
Class.RD->getNumBases() > 1)
3779 Flags |= HasBranchingHierarchy;
3782 if (
Class.Flags & MSRTTIClass::IsAmbiguous)
3783 Flags |= HasAmbiguousBases;
3785 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3786 Flags |= HasVirtualBranchingHierarchy;
3789 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
IntTy, 0),
3790 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3793 auto Type = ABI.getClassHierarchyDescriptorType();
3797 if (CHD->isWeakForLinker())
3798 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3800 auto *Bases = getBaseClassArray(Classes);
3803 llvm::Constant *Fields[] = {
3804 llvm::ConstantInt::get(CGM.
IntTy, 0),
3805 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3806 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3807 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3808 Bases->getValueType(), Bases,
3809 llvm::ArrayRef<llvm::Value *>(GEPIndices))),
3811 CHD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3815llvm::GlobalVariable *
3816MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
3817 SmallString<256> MangledName;
3819 llvm::raw_svector_ostream
Out(MangledName);
3820 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3828 llvm::Type *PtrType = ABI.getImageRelativeType(CGM.
UnqualPtrTy);
3829 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3831 new llvm::GlobalVariable(
Module, ArrType,
3833 nullptr, MangledName);
3834 if (BCA->isWeakForLinker())
3835 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3838 SmallVector<llvm::Constant *, 8> BaseClassArrayData;
3839 for (MSRTTIClass &
Class : Classes)
3840 BaseClassArrayData.push_back(
3841 ABI.getImageRelativeConstant(getBaseClassDescriptor(
Class)));
3842 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3843 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3847llvm::GlobalVariable *
3848MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &
Class) {
3853 if (
Class.VirtualRoot) {
3855 OffsetInVBTable = VTableContext.getVBTableIndex(RD,
Class.VirtualRoot) * 4;
3859 SmallString<256> MangledName;
3861 llvm::raw_svector_ostream
Out(MangledName);
3862 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3863 Class.RD,
Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3868 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3872 auto Type = ABI.getBaseClassDescriptorType();
3875 nullptr, MangledName);
3876 if (BCD->isWeakForLinker())
3877 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3880 llvm::Constant *Fields[] = {
3881 ABI.getImageRelativeConstant(
3883 llvm::ConstantInt::get(CGM.
IntTy,
Class.NumBases),
3884 llvm::ConstantInt::get(CGM.
IntTy,
Class.OffsetInVBase),
3885 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3886 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3887 llvm::ConstantInt::get(CGM.
IntTy,
Class.Flags),
3888 ABI.getImageRelativeConstant(
3889 MSRTTIBuilder(ABI,
Class.RD).getClassHierarchyDescriptor()),
3891 BCD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3895llvm::GlobalVariable *
3896MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3897 SmallString<256> MangledName;
3899 llvm::raw_svector_ostream
Out(MangledName);
3900 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3904 if (
auto COL =
Module.getNamedGlobal(MangledName))
3909 int VFPtrOffset = 0;
3915 ->second.hasVtorDisp())
3919 llvm::StructType *
Type = ABI.getCompleteObjectLocatorType();
3921 nullptr, MangledName);
3924 llvm::Constant *Fields[] = {
3925 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3926 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3927 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3928 ABI.getImageRelativeConstant(
3930 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3931 ABI.getImageRelativeConstant(COL),
3933 llvm::ArrayRef<llvm::Constant *> FieldsRef(Fields);
3934 if (!ABI.isImageRelative())
3935 FieldsRef = FieldsRef.drop_back();
3936 COL->setInitializer(llvm::ConstantStruct::get(
Type, FieldsRef));
3937 if (COL->isWeakForLinker())
3938 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3943 bool &IsConst,
bool &IsVolatile,
3944 bool &IsUnaligned) {
3945 T = Context.getExceptionObjectType(
T);
3954 IsUnaligned =
false;
3955 QualType PointeeType =
T->getPointeeType();
3956 if (!PointeeType.
isNull()) {
3966 MPTy->getQualifier(),
3967 MPTy->getMostRecentCXXRecordDecl());
3971 if (
T->isPointerType())
3978MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(QualType
Type,
3979 QualType CatchHandlerType) {
3983 bool IsConst, IsVolatile, IsUnaligned;
3999 return CatchTypeInfo{getAddrOfRTTIDescriptor(
Type)->stripPointerCasts(),
4007llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType
Type) {
4008 SmallString<256> MangledName;
4010 llvm::raw_svector_ostream
Out(MangledName);
4011 getMangleContext().mangleCXXRTTI(
Type, Out);
4015 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4022 SmallString<256> TypeInfoString;
4024 llvm::raw_svector_ostream
Out(TypeInfoString);
4025 getMangleContext().mangleCXXRTTIName(
Type, Out);
4029 llvm::Constant *Fields[] = {
4031 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
4032 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
4033 llvm::StructType *TypeDescriptorType =
4034 getTypeDescriptorType(TypeInfoString);
4035 auto *Var =
new llvm::GlobalVariable(
4036 CGM.
getModule(), TypeDescriptorType,
false,
4037 getLinkageForRTTI(
Type),
4038 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
4040 if (Var->isWeakForLinker())
4041 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
4046llvm::GlobalVariable *
4047MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
4048 const VPtrInfo &Info) {
4049 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
4052void MicrosoftCXXABI::emitCXXStructor(GlobalDecl GD) {
4053 if (
auto *ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
4055 llvm::Function *
Fn =
4067 dtor->getParent()->getNumVBases() == 0)
4078 if (
Fn->isWeakForLinker())
4079 Fn->setComdat(CGM.
getModule().getOrInsertComdat(
Fn->getName()));
4083MicrosoftCXXABI::getAddrOfCXXCtorClosure(
const CXXConstructorDecl *CD,
4088 SmallString<256> ThunkName;
4089 llvm::raw_svector_ostream
Out(ThunkName);
4090 getMangleContext().mangleName(GlobalDecl(CD, CT), Out);
4093 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
4099 const CXXRecordDecl *RD = CD->
getParent();
4100 CanQualType RecordTy = getContext().getCanonicalTagType(RD);
4101 llvm::Function *ThunkFn = llvm::Function::Create(
4102 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
4103 ThunkFn->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
4105 if (ThunkFn->isWeakForLinker())
4106 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
4110 CodeGenFunction CGF(CGM);
4114 FunctionArgList FunctionArgs;
4117 buildThisParam(CGF, FunctionArgs);
4121 ImplicitParamDecl SrcParam(
4122 getContext(),
nullptr, SourceLocation(),
4123 &getContext().Idents.get(
"src"),
4124 getContext().getLValueReferenceType(RecordTy,
4126 ImplicitParamKind::Other);
4128 FunctionArgs.push_back(&SrcParam);
4133 ImplicitParamDecl IsMostDerived(getContext(),
nullptr,
4135 &getContext().Idents.get(
"is_most_derived"),
4136 getContext().IntTy, ImplicitParamKind::Other);
4139 FunctionArgs.push_back(&IsMostDerived);
4144 FunctionArgs, CD->
getLocation(), SourceLocation());
4147 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4148 llvm::Value *
This = getThisValue(CGF);
4150 llvm::Value *SrcVal =
4164 SmallVector<const Stmt *, 4> ArgVec;
4165 ArrayRef<ParmVarDecl *> params = CD->
parameters().drop_front(IsCopy ? 1 : 0);
4166 for (
const ParmVarDecl *PD : params) {
4167 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
4168 ArgVec.push_back(PD->getDefaultArg());
4171 CodeGenFunction::RunCleanupsScope Cleanups(CGF);
4173 const auto *FPT = CD->
getType()->
castAs<FunctionProtoType>();
4174 CGF.
EmitCallArgs(Args, FPT, llvm::ArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
4177 AddedStructorArgCounts ExtraArgs =
4182 llvm::Constant *CalleePtr =
4187 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4188 CGF.
EmitCall(CalleeInfo, Callee, ReturnValueSlot(), Args);
4190 Cleanups.ForceCleanup();
4199llvm::Constant *MicrosoftCXXABI::getCatchableType(QualType
T,
4201 int32_t VBPtrOffset,
4206 const CXXConstructorDecl *CD =
4213 uint32_t Size = getContext().getTypeSizeInChars(
T).getQuantity();
4214 SmallString<256> MangledName;
4216 llvm::raw_svector_ostream
Out(MangledName);
4217 getMangleContext().mangleCXXCatchableType(
T, CD, CT, Size, NVOffset,
4218 VBPtrOffset, VBIndex, Out);
4220 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4221 return getImageRelativeConstant(GV);
4225 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(
T));
4229 llvm::Constant *CopyCtor;
4236 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4238 CopyCtor = getImageRelativeConstant(CopyCtor);
4240 bool IsScalar = !RD;
4241 bool HasVirtualBases =
false;
4242 bool IsStdBadAlloc =
false;
4243 QualType PointeeType =
T;
4257 if (HasVirtualBases)
4262 llvm::Constant *Fields[] = {
4263 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4265 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4266 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4267 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4268 llvm::ConstantInt::get(CGM.
IntTy, Size),
4271 llvm::StructType *CTType = getCatchableTypeType();
4272 auto *GV =
new llvm::GlobalVariable(
4273 CGM.
getModule(), CTType,
true, getLinkageForRTTI(
T),
4274 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4275 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4276 GV->setSection(
".xdata");
4277 if (GV->isWeakForLinker())
4278 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4279 return getImageRelativeConstant(GV);
4282llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType
T) {
4286 llvm::GlobalVariable *&CTA = CatchableTypeArrays[
T];
4293 llvm::SmallSetVector<llvm::Constant *, 2> CatchableTypes;
4303 const CXXRecordDecl *MostDerivedClass =
nullptr;
4311 if (MostDerivedClass) {
4312 const ASTContext &Context = getContext();
4313 const ASTRecordLayout &MostDerivedLayout =
4316 SmallVector<MSRTTIClass, 8> Classes;
4318 Classes.front().initialize(
nullptr,
nullptr);
4320 for (
const MSRTTIClass &
Class : Classes) {
4323 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4328 if (
Class.VirtualRoot) {
4339 CatchableTypes.insert(getCatchableType(RTTITy,
Class.OffsetInVBase,
4340 VBPtrOffset, OffsetInVBTable));
4348 CatchableTypes.insert(getCatchableType(
T));
4361 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4372 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4374 uint32_t NumEntries = CatchableTypes.size();
4375 llvm::Type *CTType = getImageRelativeType(CGM.
UnqualPtrTy);
4376 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4377 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4378 llvm::Constant *Fields[] = {
4379 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4380 llvm::ConstantArray::get(
4381 AT, llvm::ArrayRef(CatchableTypes.begin(),
4382 CatchableTypes.end()))
4384 SmallString<256> MangledName;
4386 llvm::raw_svector_ostream
Out(MangledName);
4387 getMangleContext().mangleCXXCatchableTypeArray(
T, NumEntries, Out);
4389 CTA =
new llvm::GlobalVariable(
4390 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(
T),
4391 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4392 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4393 CTA->setSection(
".xdata");
4394 if (CTA->isWeakForLinker())
4395 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4399llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(QualType
T) {
4400 bool IsConst, IsVolatile, IsUnaligned;
4405 llvm::GlobalVariable *CTA = getCatchableTypeArray(
T);
4412 ->getLimitedValue();
4414 SmallString<256> MangledName;
4416 llvm::raw_svector_ostream
Out(MangledName);
4417 getMangleContext().mangleCXXThrowInfo(
T, IsConst, IsVolatile, IsUnaligned,
4423 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4439 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4442 if (!DtorD->isTrivial())
4445 llvm::Constant *ForwardCompat =
4446 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4447 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(CTA);
4448 llvm::StructType *TIType = getThrowInfoType();
4449 llvm::Constant *Fields[] = {
4450 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4451 getImageRelativeConstant(CleanupFn),
4453 PointerToCatchableTypes
4455 auto *GV =
new llvm::GlobalVariable(
4456 CGM.
getModule(), TIType,
true, getLinkageForRTTI(
T),
4457 llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4458 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4459 GV->setSection(
".xdata");
4460 if (GV->isWeakForLinker())
4461 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4465void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF,
const CXXThrowExpr *E) {
4467 assert(SubExpr &&
"SubExpr cannot be null");
4468 QualType ThrowType = SubExpr->
getType();
4477 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4484std::pair<llvm::Value *, const CXXRecordDecl *>
4485MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
4486 const CXXRecordDecl *RD) {
4488 std::tie(This, std::ignore, RD) = performBaseAdjustment(CGF, This,
T);
4492bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4493 const CXXRecordDecl *RD)
const {
4523 for (
const CXXBaseSpecifier &B : RD->
bases()) {
4524 if (
const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4525 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.
const LangOptions & getLangOpts() const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
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...
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.
virtual bool callGlobalDeleteInDeletingDtor(const LangOptions &) const
Controls whether global operator delete is called by the deleting destructor or at the point where de...
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjectType() const
Determine whether this type is an object type.
Linkage getLinkage() const
Determine the linkage of this type.
bool isNullPtrType() const
ArrayRef< VTableComponent > vtable_components() const
Represents a variable declaration or definition.
TLSKind getTLSKind() const
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)
Creates a Microsoft-family ABI.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
constexpr Variable var(Literal L)
Returns the variable of L.
bool This(InterpState &S, CodePtr OpPC)
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...