28 #include "llvm/ADT/StringExtras.h" 29 #include "llvm/ADT/StringSet.h" 30 #include "llvm/IR/CallSite.h" 31 #include "llvm/IR/Intrinsics.h" 33 using namespace clang;
34 using namespace CodeGen;
39 struct VBTableGlobals {
44 class MicrosoftCXXABI :
public CGCXXABI {
47 :
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
48 ClassHierarchyDescriptorType(nullptr),
49 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
50 ThrowInfoType(nullptr) {}
52 bool HasThisReturn(
GlobalDecl GD)
const override;
53 bool hasMostDerivedReturn(
GlobalDecl GD)
const override;
59 bool isSRetParameterAfterThis()
const override {
return true; }
61 bool isThisCompleteObject(
GlobalDecl GD)
const override {
64 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
73 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
75 llvm_unreachable(
"bad dtor kind");
84 assert(Args.size() >= 2 &&
85 "expected the arglist to have at least two args!");
94 std::vector<CharUnits> getVBPtrOffsets(
const CXXRecordDecl *RD)
override {
95 std::vector<CharUnits> VBPtrOffsets;
99 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
100 for (
const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
105 if (VBT->getVBaseWithVPtr())
107 VBPtrOffsets.push_back(Offs);
109 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
113 StringRef GetPureVirtualCallName()
override {
return "_purecall"; }
114 StringRef GetDeletedVirtualCallName()
override {
return "_purecall"; }
125 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
128 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
130 getAddrOfCXXCatchHandlerType(
QualType Ty,
QualType CatchHandlerType)
override;
137 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
143 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
149 llvm::BasicBlock *CastEnd)
override;
156 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override {
219 void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
223 llvm::GlobalValue::LinkageTypes
230 getThisArgumentTypeForMethod(
const CXXMethodDecl *MD)
override {
231 if (MD->
isVirtual() && !isa<CXXDestructorDecl>(MD)) {
233 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
249 bool VirtualCall)
override;
263 bool Delegating,
Address This)
override;
266 llvm::GlobalVariable *VTable);
276 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
277 return !VTableClass->
hasAttr<MSNoVTableAttr>();
292 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
308 "Only deleting destructor thunks are available in this ABI");
313 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
315 llvm::GlobalVariable *
317 llvm::GlobalVariable::LinkageTypes
Linkage);
319 llvm::GlobalVariable *
323 llvm::raw_svector_ostream Out(OutName);
324 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
325 StringRef MangledName = OutName.str();
327 if (
auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
333 llvm::UndefValue::get(CGM.IntTy));
334 Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
335 bool AnyDifferent =
false;
336 for (
const auto &I : SrcRD->
vbases()) {
337 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
343 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
344 AnyDifferent |= SrcVBIndex != DstVBIndex;
350 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy, Map.size());
351 llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy, Map);
352 llvm::GlobalValue::LinkageTypes
Linkage =
354 ? llvm::GlobalValue::LinkOnceODRLinkage
356 auto *VDispMap =
new llvm::GlobalVariable(
357 CGM.getModule(), VDispMapTy,
true,
Linkage,
363 llvm::GlobalVariable *GV)
const;
365 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
368 getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.
getDecl()));
372 else if (ReturnAdjustment)
373 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
375 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
378 bool exportThunk()
override {
return false; }
384 const ReturnAdjustment &RA)
override;
386 void EmitThreadLocalInitFuncs(
391 bool usesThreadWrapperFunction()
const override {
return false; }
396 llvm::GlobalVariable *DeclPtr,
397 bool PerformInit)
override;
399 llvm::Constant *Dtor, llvm::Constant *Addr)
override;
437 friend struct MSRTTIBuilder;
439 bool isImageRelative()
const {
440 return CGM.getTarget().getPointerWidth(0) == 64;
444 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
446 TDTypeName += llvm::utostr(TypeInfoString.size());
447 llvm::StructType *&TypeDescriptorType =
448 TypeDescriptorTypeMap[TypeInfoString.size()];
449 if (TypeDescriptorType)
450 return TypeDescriptorType;
454 llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
457 return TypeDescriptorType;
461 if (!isImageRelative())
466 llvm::StructType *getBaseClassDescriptorType() {
467 if (BaseClassDescriptorType)
468 return BaseClassDescriptorType;
470 getImageRelativeType(CGM.Int8PtrTy),
476 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
479 CGM.getLLVMContext(), FieldTypes,
"rtti.BaseClassDescriptor");
480 return BaseClassDescriptorType;
483 llvm::StructType *getClassHierarchyDescriptorType() {
484 if (ClassHierarchyDescriptorType)
485 return ClassHierarchyDescriptorType;
488 CGM.getLLVMContext(),
"rtti.ClassHierarchyDescriptor");
493 getImageRelativeType(
494 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
496 ClassHierarchyDescriptorType->setBody(FieldTypes);
497 return ClassHierarchyDescriptorType;
500 llvm::StructType *getCompleteObjectLocatorType() {
501 if (CompleteObjectLocatorType)
502 return CompleteObjectLocatorType;
504 CGM.getLLVMContext(),
"rtti.CompleteObjectLocator");
509 getImageRelativeType(CGM.Int8PtrTy),
510 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
511 getImageRelativeType(CompleteObjectLocatorType),
514 if (!isImageRelative())
515 FieldTypesRef = FieldTypesRef.drop_back();
516 CompleteObjectLocatorType->setBody(FieldTypesRef);
517 return CompleteObjectLocatorType;
520 llvm::GlobalVariable *getImageBase() {
521 StringRef Name =
"__ImageBase";
522 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
525 auto *GV =
new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
533 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
534 if (!isImageRelative())
537 if (PtrVal->isNullValue())
538 return llvm::Constant::getNullValue(CGM.IntTy);
540 llvm::Constant *ImageBaseAsInt =
541 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
542 llvm::Constant *PtrValAsInt =
543 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
544 llvm::Constant *Diff =
545 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
547 return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
555 llvm::Constant *getZeroInt() {
556 return llvm::ConstantInt::get(CGM.IntTy, 0);
559 llvm::Constant *getAllOnesInt() {
560 return llvm::Constant::getAllOnesValue(CGM.IntTy);
581 int32_t VBTableOffset,
583 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
584 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
585 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
586 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
589 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
602 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
603 bool IsMemberFunction,
606 unsigned VBTableIndex);
615 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
618 llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
628 return RD->
hasAttr<MSInheritanceAttr>();
635 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
636 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
642 bool Inequality)
override;
663 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
664 llvm::Constant *Src)
override;
666 llvm::Constant *EmitMemberPointerConversion(
679 llvm::StructType *getCatchableTypeType() {
680 if (CatchableTypeType)
681 return CatchableTypeType;
684 getImageRelativeType(CGM.Int8PtrTy),
689 getImageRelativeType(CGM.Int8PtrTy)
692 CGM.getLLVMContext(), FieldTypes,
"eh.CatchableType");
693 return CatchableTypeType;
696 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
697 llvm::StructType *&CatchableTypeArrayType =
698 CatchableTypeArrayTypeMap[NumEntries];
699 if (CatchableTypeArrayType)
700 return CatchableTypeArrayType;
703 CTATypeName += llvm::utostr(NumEntries);
705 getImageRelativeType(getCatchableTypeType()->getPointerTo());
708 llvm::ArrayType::get(CTType, NumEntries)
710 CatchableTypeArrayType =
712 return CatchableTypeArrayType;
715 llvm::StructType *getThrowInfoType() {
717 return ThrowInfoType;
720 getImageRelativeType(CGM.Int8PtrTy),
721 getImageRelativeType(CGM.Int8PtrTy),
722 getImageRelativeType(CGM.Int8PtrTy)
726 return ThrowInfoType;
732 llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
733 llvm::FunctionType *FTy =
734 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
735 auto *Fn = cast<llvm::Function>(
736 CGM.CreateRuntimeFunction(FTy,
"_CxxThrowException"));
738 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86)
739 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
746 llvm::Constant *getCatchableType(
QualType T,
747 uint32_t NVOffset = 0,
748 int32_t VBPtrOffset = -1,
749 uint32_t VBIndex = 0);
751 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
753 llvm::GlobalVariable *getThrowInfo(
QualType T)
override;
755 std::pair<llvm::Value *, const CXXRecordDecl *>
760 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
761 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
762 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
764 VFTablesMapTy VFTablesMap;
765 VTablesMapTy VTablesMap;
768 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
772 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
777 GuardInfo() : Guard(nullptr), BitIndex(0) {}
778 llvm::GlobalVariable *Guard;
784 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
785 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
786 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
788 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
789 llvm::StructType *BaseClassDescriptorType;
790 llvm::StructType *ClassHierarchyDescriptorType;
791 llvm::StructType *CompleteObjectLocatorType;
793 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
795 llvm::StructType *CatchableTypeType;
796 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
797 llvm::StructType *ThrowInfoType;
804 switch (CGM.getTarget().getTriple().getArch()) {
809 case llvm::Triple::thumb:
813 return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
815 case llvm::Triple::x86:
822 if (!canCopyArgument(RD))
823 return RAA_DirectInMemory;
829 case llvm::Triple::x86_64:
830 case llvm::Triple::aarch64:
831 return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
834 llvm_unreachable(
"invalid enum");
847 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
852 void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
854 llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
855 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
868 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
869 llvm::CatchPadInst *CPI =
870 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
889 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
900 return std::make_tuple(Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
909 PolymorphicBase = BaseDecl;
913 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
916 GetVirtualBaseClassOffset(CGF, Value, SrcDecl, PolymorphicBase);
920 return std::make_tuple(
Address(Ptr, VBaseAlign), Offset, PolymorphicBase);
923 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
927 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
933 llvm::FunctionType *FTy =
934 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
941 llvm::CallSite Call =
943 Call.setDoesNotReturn();
944 CGF.
Builder.CreateUnreachable();
951 std::tie(ThisPtr, std::ignore, std::ignore) =
952 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
957 bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
961 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
975 std::tie(This, Offset, std::ignore) =
976 performBaseAdjustment(CGF, This, SrcRecordTy);
989 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
992 ThisPtr,
Offset, SrcRTTI, DestRTTI,
1002 std::tie(Value, std::ignore, std::ignore) =
1003 performBaseAdjustment(CGF, Value, SrcRecordTy);
1009 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1019 llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1023 int64_t VBPtrChars =
1025 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
1029 CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
1031 llvm::ConstantInt::get(CGM.IntTy, VBTableChars.
getQuantity());
1034 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1036 CGF.
Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
1037 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1040 bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1041 return isa<CXXConstructorDecl>(GD.
getDecl());
1045 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1049 bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1069 llvm::Triple::aarch64);
1071 }
else if (!RD->
isPOD()) {
1079 llvm::Triple::aarch64);
1090 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1091 assert(IsMostDerivedClass &&
1092 "ctor for a class with virtual bases must have an implicit parameter");
1094 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1096 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1097 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1098 CGF.
Builder.CreateCondBr(IsCompleteObject,
1099 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1104 EmitVBPtrStores(CGF, RD);
1108 return SkipVbaseCtorsBB;
1112 MicrosoftCXXABI::EmitDtorCompleteObjectHandler(
CodeGenFunction &CGF) {
1113 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1114 assert(IsMostDerivedClass &&
1115 "ctor for a class with virtual bases must have an implicit parameter");
1117 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1119 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1120 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1121 CGF.
Builder.CreateCondBr(IsCompleteObject,
1122 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1127 return SkipVbaseDtorsBB;
1130 void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1150 unsigned AS = getThisAddress(CGF).getAddressSpace();
1154 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1155 auto I = VBaseMap.find(VBase);
1156 assert(I != VBaseMap.end());
1157 if (!I->second.hasVtorDisp())
1161 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1162 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1166 VBaseOffset, llvm::ConstantInt::get(CGM.PtrDiffTy, ConstantVBaseOffset),
1168 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1172 CGF.
Int8Ty->getPointerTo(AS));
1173 llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset);
1175 VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4);
1177 VtorDispPtr, CGF.
Int32Ty->getPointerTo(AS),
"vtordisp.ptr");
1190 return ExpectedCallingConv == ActualCallingConv;
1204 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1205 CGM.setGVProperties(Fn, D);
1211 Address This = getThisAddress(CGF);
1216 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1217 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1218 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1219 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1224 if (VBT->getVBaseWithVPtr())
1230 "vbptr." + VBT->ObjectWithVPtr->getName());
1238 AddedStructorArgs Added;
1242 ArgTys.push_back(getContext().IntTy);
1256 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1259 ArgTys.push_back(getContext().IntTy);
1267 void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1273 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1276 CGM.setDLLImportDLLExport(GV, ND);
1280 llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1291 return CGM.getLLVMLinkageForDeclarator(Dtor, Linkage,
1297 if (Dtor->
hasAttr<DLLExportAttr>())
1298 return llvm::GlobalValue::WeakODRLinkage;
1299 if (Dtor->
hasAttr<DLLImportAttr>())
1300 return llvm::GlobalValue::AvailableExternallyLinkage;
1301 return llvm::GlobalValue::LinkOnceODRLinkage;
1306 return llvm::GlobalValue::LinkOnceODRLinkage;
1308 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1310 llvm_unreachable(
"invalid dtor type");
1320 MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1335 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1342 if (isa<CXXDestructorDecl>(MD))
1347 getContext().getASTRecordLayout(MD->
getParent());
1354 Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1360 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1383 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1400 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1405 Result =
Address(VBasePtr, VBaseAlign);
1407 if (!StaticOffset.
isZero()) {
1428 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1437 if (FPT->isVariadic())
1438 Params.insert(Params.begin() + 1, IsMostDerived);
1440 Params.push_back(IsMostDerived);
1441 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1447 Params.push_back(ShouldDelete);
1448 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1452 void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1472 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1473 if (!Adjustment.
isZero()) {
1474 unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1476 *thisTy = This->getType();
1479 This = CGF.
Builder.CreateConstInBoundsGEP1_32(CGF.
Int8Ty, This,
1484 setCXXABIThisValue(CGF, This);
1494 if (HasThisReturn(CGF.
CurGD))
1496 else if (hasMostDerivedReturn(CGF.
CurGD))
1501 assert(getStructorImplicitParamDecl(CGF) &&
1502 "no implicit parameter for a constructor with virtual bases?");
1503 getStructorImplicitParamValue(CGF)
1510 assert(getStructorImplicitParamDecl(CGF) &&
1511 "no implicit parameter for a deleting destructor?");
1512 getStructorImplicitParamValue(CGF)
1515 "should_call_delete");
1521 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1526 return AddedStructorArgs{};
1532 MostDerivedArg = getStructorImplicitParamValue(CGF);
1534 MostDerivedArg = llvm::ConstantInt::get(CGM.Int32Ty, Type ==
Ctor_Complete);
1538 Args.insert(Args.begin() + 1,
CallArg(RV, getContext().IntTy));
1539 return AddedStructorArgs::prefix(1);
1541 Args.
add(RV, getContext().IntTy);
1542 return AddedStructorArgs::suffix(1);
1548 bool Delegating,
Address This) {
1561 "The deleting destructor should only be called via a virtual call");
1562 This = adjustThisArgumentForVirtualFunctionCall(CGF,
GlobalDecl(DD, Type),
1566 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1567 if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1568 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1575 if (BaseDtorEndBB) {
1577 CGF.
Builder.CreateBr(BaseDtorEndBB);
1582 void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1584 llvm::GlobalVariable *VTable) {
1585 if (!CGM.getCodeGenOpts().LTOUnit)
1592 getContext().getLangOpts().RTTIData
1593 ? getContext().toCharUnitsFromBits(
1594 getContext().getTargetInfo().getPointerWidth(0))
1598 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1603 CGM.AddVTableTypeMetadata(VTable, AddressPoint,
1613 getContext().getASTRecordLayout(DerivedRD);
1619 Offset = VBI->second.VBaseOffset;
1622 CGM.AddVTableTypeMetadata(VTable, AddressPoint, DerivedRD);
1627 CGM.AddVTableTypeMetadata(VTable, AddressPoint, RD);
1630 void MicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables &CGVT,
1635 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1636 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1637 if (VTable->hasInitializer())
1643 llvm::Constant *RTTI =
nullptr;
1646 RTTI = getMSCompleteObjectLocator(RD, *Info);
1651 Components.finishAndSetAsInitializer(VTable);
1653 emitVTableTypeMetadata(*Info, RD, VTable);
1657 bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1662 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1665 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(Base, VTableClass);
1666 if (!VTableAddressPoint) {
1668 !getContext().getASTRecordLayout(Base.
getBase()).hasOwnVFPtr());
1670 return VTableAddressPoint;
1676 llvm::raw_svector_ostream Out(Name);
1685 return VFTablesMap[
ID];
1688 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1690 llvm::Constant *VFTable = getVTableAddressPoint(Base, VTableClass);
1691 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1695 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1701 VFTableIdTy
ID(RD, VPtrOffset);
1702 VTablesMapTy::iterator I;
1704 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID,
nullptr));
1708 llvm::GlobalVariable *&VTable = I->second;
1713 if (DeferredVFTables.insert(RD).second) {
1716 CGM.addDeferredVTable(RD);
1721 llvm::StringSet<> ObservedMangledNames;
1722 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1725 if (!ObservedMangledNames.insert(Name.str()).second)
1726 llvm_unreachable(
"Already saw this mangling before?");
1731 const std::unique_ptr<VPtrInfo> *VFPtrI = std::find_if(
1732 VFPtrs.begin(), VFPtrs.end(), [&](
const std::unique_ptr<VPtrInfo>& VPI) {
1733 return VPI->FullOffsetInMDC == VPtrOffset;
1735 if (VFPtrI == VFPtrs.end()) {
1736 VFTablesMap[
ID] =
nullptr;
1739 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1751 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1752 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1753 : CGM.getVTableLinkage(RD);
1754 bool VFTableComesFromAnotherTU =
1755 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1756 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1757 bool VTableAliasIsRequred =
1758 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1760 if (llvm::GlobalValue *VFTable =
1761 CGM.getModule().getNamedGlobal(VFTableName)) {
1762 VFTablesMap[
ID] = VFTable;
1763 VTable = VTableAliasIsRequred
1764 ? cast<llvm::GlobalVariable>(
1765 cast<llvm::GlobalAlias>(VFTable)->getBaseObject())
1766 : cast<llvm::GlobalVariable>(VFTable);
1772 llvm::GlobalValue::LinkageTypes VTableLinkage =
1773 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1775 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1777 llvm::Type *VTableType = CGM.getVTables().getVTableType(VTLayout);
1781 llvm::GlobalValue *VFTable;
1782 VTable =
new llvm::GlobalVariable(CGM.getModule(), VTableType,
1783 true, VTableLinkage,
1784 nullptr, VTableName);
1785 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1787 llvm::Comdat *C =
nullptr;
1788 if (!VFTableComesFromAnotherTU &&
1789 (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1790 (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1791 VTableAliasIsRequred)))
1792 C = CGM.getModule().getOrInsertComdat(VFTableName.str());
1797 if (VTableAliasIsRequred) {
1798 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.Int32Ty, 0),
1799 llvm::ConstantInt::get(CGM.Int32Ty, 0),
1800 llvm::ConstantInt::get(CGM.Int32Ty, 1)};
1803 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1804 VTable->getValueType(), VTable, GEPIndices);
1805 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1808 C->setSelectionKind(llvm::Comdat::Largest);
1812 VFTableName.str(), VTableGEP,
1814 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1823 VTable->setComdat(C);
1825 if (RD->
hasAttr<DLLExportAttr>())
1826 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1828 VFTablesMap[
ID] = VFTable;
1839 Ty = Ty->getPointerTo()->getPointerTo();
1841 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1843 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1851 auto getObjectWithVPtr = [&] {
1854 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1864 getObjectWithVPtr(), VTable,
1865 ML.
Index * CGM.getContext().getTargetInfo().getPointerWidth(0) / 8);
1867 if (CGM.getCodeGenOpts().PrepareForLTO)
1871 Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1879 llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1888 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1894 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1898 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1905 const VBTableGlobals &
1906 MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
1909 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
1911 std::tie(Entry, Added) =
1912 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
1913 VBTableGlobals &VBGlobals = Entry->second;
1922 llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
1923 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
1924 E = VBGlobals.VBTables->end();
1926 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
1933 MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
1935 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
1936 "can't form pointers to ctors or virtual dtors");
1940 llvm::raw_svector_ostream Out(ThunkName);
1941 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
1944 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
1945 return cast<llvm::Function>(GV);
1949 CGM.getTypes().arrangeUnprototypedMustTailThunk(MD);
1950 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
1951 llvm::Function *ThunkFn =
1953 ThunkName.str(), &CGM.getModule());
1954 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
1957 ? llvm::GlobalValue::LinkOnceODRLinkage
1960 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
1962 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
1963 CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
1969 ThunkFn->addFnAttr(
"thunk");
1982 buildThisParam(CGF, FunctionArgs);
1987 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
1992 getThisAddress(CGF), ThunkTy->getPointerTo()->getPointerTo(), MD->
getParent());
1995 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
2004 void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2005 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2006 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2007 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2008 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2009 if (GV->isDeclaration())
2010 emitVBTableDefinition(*VBT, RD, GV);
2014 llvm::GlobalVariable *
2016 llvm::GlobalVariable::LinkageTypes Linkage) {
2018 llvm::raw_svector_ostream Out(OutName);
2019 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2020 StringRef Name = OutName.str();
2022 llvm::ArrayType *VBTableType =
2025 assert(!CGM.getModule().getNamedGlobal(Name) &&
2026 "vbtable with this name already exists: mangling bug?");
2028 CGM.getContext().getTypeAlignInChars(CGM.getContext().IntTy);
2029 llvm::GlobalVariable *GV = CGM.CreateOrReplaceCXXRuntimeVariable(
2030 Name, VBTableType, Linkage, Alignment.getQuantity());
2031 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2033 if (RD->
hasAttr<DLLImportAttr>())
2034 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2035 else if (RD->
hasAttr<DLLExportAttr>())
2036 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2038 if (!GV->hasExternalLinkage())
2039 emitVBTableDefinition(VBT, RD, GV);
2044 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2046 llvm::GlobalVariable *GV)
const {
2050 "should only emit vbtables for classes with vbtables");
2054 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2060 CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2061 Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
2064 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2065 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2072 CompleteVBPtrOffset +=
2074 Offset -= CompleteVBPtrOffset;
2076 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2077 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2078 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.
getQuantity());
2081 assert(Offsets.size() ==
2082 cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
2083 ->getElementType())->getNumElements());
2084 llvm::ArrayType *VBTableType =
2085 llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2086 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2087 GV->setInitializer(Init);
2089 if (RD->
hasAttr<DLLImportAttr>())
2090 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2113 CGF.
Builder.CreateNeg(VtorDisp));
2130 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2147 const ReturnAdjustment &RA) {
2162 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2179 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *expr) {
2206 assert(requiresArrayCookie(expr));
2209 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2225 llvm::Constant *Dtor,
2226 llvm::Constant *Addr) {
2231 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2232 CGF.
IntTy, DtorStub->getType(),
false);
2235 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2236 if (llvm::Function *TLRegDtorFn = dyn_cast<llvm::Function>(TLRegDtor))
2237 TLRegDtorFn->setDoesNotThrow();
2243 llvm::Constant *Dtor,
2244 llvm::Constant *Addr) {
2255 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2259 if (CXXThreadLocalInits.empty())
2264 ?
"/include:___dyn_tls_init@12" 2265 :
"/include:__dyn_tls_init");
2270 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2271 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2272 CGM.
getModule(), InitFunc->getType(),
true,
2274 Twine(InitFunc->getName(),
"$initializer$"));
2275 InitFuncPtr->setSection(
".CRT$XDU");
2282 std::vector<llvm::Function *> NonComdatInits;
2283 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2284 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2286 llvm::Function *F = CXXThreadLocalInits[I];
2289 if (llvm::Comdat *C = GV->getComdat())
2290 AddToXDU(F)->setComdat(C);
2292 NonComdatInits.push_back(F);
2295 if (!NonComdatInits.empty()) {
2296 llvm::FunctionType *FTy =
2297 llvm::FunctionType::get(CGM.
VoidTy,
false);
2315 StringRef VarName(
"_Init_thread_epoch");
2317 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2319 auto *GV =
new llvm::GlobalVariable(
2323 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2329 llvm::FunctionType *FTy =
2330 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2331 CGM.
IntTy->getPointerTo(),
false);
2333 FTy,
"_Init_thread_header",
2335 llvm::AttributeList::FunctionIndex,
2336 llvm::Attribute::NoUnwind),
2341 llvm::FunctionType *FTy =
2342 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2343 CGM.
IntTy->getPointerTo(),
false);
2345 FTy,
"_Init_thread_footer",
2347 llvm::AttributeList::FunctionIndex,
2348 llvm::Attribute::NoUnwind),
2353 llvm::FunctionType *FTy =
2354 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2355 CGM.
IntTy->getPointerTo(),
false);
2357 FTy,
"_Init_thread_abort",
2359 llvm::AttributeList::FunctionIndex,
2360 llvm::Attribute::NoUnwind),
2368 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2369 : Guard(Guard), GuardNum(GuardNum) {}
2375 llvm::LoadInst *LI = Builder.
CreateLoad(Guard);
2376 llvm::ConstantInt *Mask =
2377 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2378 Builder.
CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2394 llvm::GlobalVariable *GV,
2398 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2400 llvm::Function *F = CGF.
CurFn;
2401 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2402 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2408 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2412 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2415 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2416 llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
2420 GuardInfo *GI =
nullptr;
2421 if (ThreadlocalStatic)
2423 else if (!ThreadsafeStatic)
2426 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2431 GuardNum = getContext().getStaticLocalNumber(&D);
2432 assert(GuardNum > 0);
2434 }
else if (HasPerVariableGuard) {
2438 GuardNum = GI->BitIndex++;
2441 if (!HasPerVariableGuard && GuardNum >= 32) {
2443 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2452 llvm::raw_svector_ostream Out(GuardName);
2453 if (HasPerVariableGuard)
2454 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2457 getMangleContext().mangleStaticGuardVariable(&D, Out);
2463 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2464 GV->getLinkage(), Zero, GuardName.str());
2465 GuardVar->setVisibility(GV->getVisibility());
2466 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2468 if (GuardVar->isWeakForLinker())
2469 GuardVar->setComdat(
2470 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2472 GuardVar->setThreadLocal(
true);
2473 if (GI && !HasPerVariableGuard)
2474 GI->Guard = GuardVar;
2479 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2480 "static local from the same function had different linkage");
2482 if (!HasPerVariableGuard) {
2490 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2491 llvm::LoadInst *LI = Builder.
CreateLoad(GuardAddr);
2493 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
2502 Builder.
CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2506 Builder.CreateBr(EndBlock);
2524 llvm::LoadInst *FirstGuardLoad = Builder.
CreateLoad(GuardAddr);
2525 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2526 llvm::LoadInst *InitThreadEpoch =
2529 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2540 llvm::LoadInst *SecondGuardLoad = Builder.
CreateLoad(GuardAddr);
2541 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2543 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2545 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2554 Builder.CreateBr(EndBlock);
2571 return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) &&
2583 fields.push_back(CGM.
IntTy);
2587 fields.push_back(CGM.
IntTy);
2588 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2589 fields.push_back(CGM.
IntTy);
2590 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2591 fields.push_back(CGM.
IntTy);
2593 if (fields.size() == 1)
2598 void MicrosoftCXXABI::
2601 assert(fields.empty());
2606 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2608 if (RD->nullFieldOffsetIsZero())
2609 fields.push_back(getZeroInt());
2611 fields.push_back(getAllOnesInt());
2616 fields.push_back(getZeroInt());
2617 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2618 fields.push_back(getZeroInt());
2619 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2620 fields.push_back(getAllOnesInt());
2626 GetNullMemberPointerFields(MPT, fields);
2627 if (fields.size() == 1)
2629 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2630 assert(Res->getType() == ConvertMemberPointerType(MPT));
2635 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2636 bool IsMemberFunction,
2639 unsigned VBTableIndex) {
2644 if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance))
2648 fields.push_back(FirstField);
2650 if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance))
2651 fields.push_back(llvm::ConstantInt::get(
2654 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) {
2657 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2662 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2663 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2665 return llvm::ConstantStruct::getAnon(fields);
2673 MSInheritanceAttr::Keyword_virtual_inheritance)
2674 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2675 llvm::Constant *FirstField =
2677 return EmitFullMemberPointer(FirstField,
false, RD,
2681 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2686 return EmitNullMemberPointer(DstTy);
2692 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2693 C = EmitMemberFunctionPointer(MD);
2696 C = EmitMemberDataPointer(DstTy, FieldOffset);
2699 if (!MemberPointerPath.empty()) {
2700 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2704 ->castAs<MemberPointerType>();
2712 if (DerivedMember) {
2720 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2722 DerivedToBasePath.push_back(&BS);
2725 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2727 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2728 : CK_BaseToDerivedMemberPointer;
2729 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2730 DerivedToBasePath.end(), C);
2736 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2737 assert(MD->
isInstance() &&
"Member function must not be static!");
2743 unsigned VBTableIndex = 0;
2744 llvm::Constant *FirstField;
2761 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2765 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2768 if (VBTableIndex == 0 &&
2770 MSInheritanceAttr::Keyword_virtual_inheritance)
2771 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2774 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2775 return EmitFullMemberPointer(FirstField,
true, RD,
2776 NonVirtualBaseAdjustment, VBTableIndex);
2791 llvm::ICmpInst::Predicate Eq;
2792 llvm::Instruction::BinaryOps
And, Or;
2794 Eq = llvm::ICmpInst::ICMP_NE;
2795 And = llvm::Instruction::Or;
2798 Eq = llvm::ICmpInst::ICMP_EQ;
2800 Or = llvm::Instruction::Or;
2809 return Builder.CreateICmp(Eq, L, R);
2812 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
2813 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
2814 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
2818 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
2819 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
2820 llvm::Value *LF = Builder.CreateExtractValue(L, I);
2821 llvm::Value *RF = Builder.CreateExtractValue(R, I);
2822 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
2824 Res = Builder.CreateBinOp(And, Res, Cmp);
2832 llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
2833 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero,
"memptr.cmp.iszero");
2834 Res = Builder.CreateBinOp(Or, Res, IsZero);
2839 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
2850 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2852 GetNullMemberPointerFields(MPT, fields);
2853 assert(!fields.empty());
2855 if (MemPtr->getType()->isStructTy())
2856 FirstField = Builder.CreateExtractValue(MemPtr, 0);
2857 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
2865 for (
int I = 1, E = fields.size(); I < E; ++I) {
2866 llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
2867 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
2868 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
2874 llvm::Constant *Val) {
2877 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
2878 Val->getAggregateElement(0U) : Val;
2879 return FirstField->isNullValue();
2884 if (isZeroInitializable(MPT) && Val->isNullValue())
2890 GetNullMemberPointerFields(MPT, Fields);
2891 if (Fields.size() == 1) {
2892 assert(Val->getType()->isIntegerTy());
2893 return Val == Fields[0];
2897 for (I = 0, E = Fields.size(); I != E; ++I) {
2898 if (Val->getAggregateElement(I) != Fields[I])
2914 Builder.CreateInBoundsGEP(This.
getPointer(), VBPtrOffset,
"vbptr");
2915 if (VBPtrOut) *VBPtrOut = VBPtr;
2920 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
2931 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
2935 llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex);
2948 llvm::BasicBlock *OriginalBB =
nullptr;
2949 llvm::BasicBlock *SkipAdjustBB =
nullptr;
2950 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
2957 OriginalBB = Builder.GetInsertBlock();
2961 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
2963 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
2975 "member pointer representation requires a " 2976 "complete class type for %0 to perform this expression");
2979 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2984 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
2985 llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
2988 if (VBaseAdjustBB) {
2989 Builder.CreateBr(SkipAdjustBB);
2991 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
2992 Phi->addIncoming(Base.
getPointer(), OriginalBB);
2993 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
2996 return AdjustedBase;
2999 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3013 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3015 if (MemPtr->getType()->isStructTy()) {
3018 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3019 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3020 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3021 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3022 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3026 if (VirtualBaseAdjustmentOffset) {
3027 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
3037 Addr = Builder.CreateInBoundsGEP(Addr, FieldOffset,
"memptr.offset");
3048 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3049 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3053 if (isa<llvm::Constant>(Src))
3054 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3064 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3065 if (IsReinterpret && IsFunc)
3070 if (IsReinterpret &&
3077 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3078 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3082 if (IsReinterpret) {
3085 assert(Src->getType() == DstNull->getType());
3086 return Builder.CreateSelect(IsNotNull, Src, DstNull);
3089 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3092 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3095 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3099 Builder.CreateBr(ContinueBB);
3103 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3104 Phi->addIncoming(DstNull, OriginalBB);
3105 Phi->addIncoming(Dst, ConvertBB);
3109 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3119 bool IsConstant = isa<llvm::Constant>(Src);
3123 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3124 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3126 if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
3129 FirstField = Builder.CreateExtractValue(Src, I++);
3130 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
3131 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3132 if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
3133 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3134 if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
3135 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3138 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3144 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3152 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3153 if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3154 if (int64_t SrcOffsetToFirstVBase =
3155 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3156 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3158 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3160 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3171 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3177 if (IsDerivedToBase)
3178 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3180 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3182 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3187 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) &&
3188 MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) {
3189 if (llvm::GlobalVariable *VDispMap =
3190 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3192 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3194 llvm::Constant *Mapping = VDispMap->getInitializer();
3195 VirtualBaseAdjustmentOffset =
3196 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3199 VirtualBaseAdjustmentOffset =
3205 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3211 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) {
3212 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3214 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3216 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3222 if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3223 if (int64_t DstOffsetToFirstVBase =
3224 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3225 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3227 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3229 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3235 if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) {
3238 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3240 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3241 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
3242 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3243 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
3244 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3245 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
3246 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3252 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3253 llvm::Constant *Src) {
3260 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3264 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3268 assert(CK == CK_DerivedToBaseMemberPointer ||
3269 CK == CK_BaseToDerivedMemberPointer ||
3270 CK == CK_ReinterpretMemberPointer);
3273 if (MemberPointerConstantIsNull(SrcTy, Src))
3274 return EmitNullMemberPointer(DstTy);
3279 if (CK == CK_ReinterpretMemberPointer)
3283 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3284 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3289 CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3301 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
3307 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3309 if (MemPtr->getType()->isStructTy()) {
3312 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3313 if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance))
3314 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3315 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3316 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3317 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3318 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3321 if (VirtualBaseAdjustmentOffset) {
3322 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3323 VirtualBaseAdjustmentOffset, VBPtrOffset);
3328 if (NonVirtualBaseAdjustment) {
3331 Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
3332 ThisPtrForCall = Builder.
CreateBitCast(Ptr, ThisPtrForCall->getType(),
3337 Builder.
CreateBitCast(FunctionPointer, FTy->getPointerTo());
3338 CGCallee Callee(FPT, FunctionPointer);
3343 return new MicrosoftCXXABI(CGM);
3377 StringRef MangledName(
"??_7type_info@@6B@");
3378 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3383 nullptr, MangledName);
3394 struct MSRTTIClass {
3396 IsPrivateOnPath = 1 | 8,
3400 HasHierarchyDescriptor = 64
3406 MSRTTIClass *getFirstChild() {
return this + 1; }
3407 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3408 return Child + 1 + Child->NumBases;
3412 uint32_t Flags, NumBases, OffsetInVBase;
3418 Flags = HasHierarchyDescriptor;
3420 VirtualRoot =
nullptr;
3424 Flags |= IsPrivate | IsPrivateOnPath;
3430 if (Parent->Flags & IsPrivateOnPath)
3431 Flags |= IsPrivateOnPath;
3432 VirtualRoot = Parent->VirtualRoot;
3438 MSRTTIClass *Child = getFirstChild();
3440 NumBases += Child->initialize(
this, &Base) + 1;
3441 Child = getNextChild(Child);
3446 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3457 return llvm::GlobalValue::LinkOnceODRLinkage;
3459 llvm_unreachable(
"Invalid linkage!");
3465 struct MSRTTIBuilder {
3467 HasBranchingHierarchy = 1,
3468 HasVirtualBranchingHierarchy = 2,
3469 HasAmbiguousBases = 4
3472 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3478 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3479 llvm::GlobalVariable *
3481 llvm::GlobalVariable *getClassHierarchyDescriptor();
3482 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3486 llvm::LLVMContext &VMContext;
3489 llvm::GlobalVariable::LinkageTypes
Linkage;
3490 MicrosoftCXXABI &ABI;
3499 Classes.push_back(MSRTTIClass(RD));
3507 llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3508 llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3509 llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3510 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3511 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3512 !VirtualBases.insert(Class->RD).second) {
3513 Class = MSRTTIClass::getNextChild(Class);
3516 if (!UniqueBases.insert(Class->RD).second)
3517 AmbiguousBases.insert(Class->RD);
3520 if (AmbiguousBases.empty())
3522 for (MSRTTIClass &Class : Classes)
3523 if (AmbiguousBases.count(Class.RD))
3524 Class.Flags |= MSRTTIClass::IsAmbiguous;
3527 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3530 llvm::raw_svector_ostream Out(MangledName);
3531 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3535 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3541 Classes.front().initialize(
nullptr,
nullptr);
3544 for (
auto Class : Classes) {
3545 if (Class.RD->getNumBases() > 1)
3546 Flags |= HasBranchingHierarchy;
3549 if (Class.Flags & MSRTTIClass::IsAmbiguous)
3550 Flags |= HasAmbiguousBases;
3552 if ((Flags & HasBranchingHierarchy) && RD->
getNumVBases() != 0)
3553 Flags |= HasVirtualBranchingHierarchy;
3557 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3560 auto Type = ABI.getClassHierarchyDescriptorType();
3561 auto CHD =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3564 if (CHD->isWeakForLinker())
3565 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3567 auto *Bases = getBaseClassArray(Classes);
3570 llvm::Constant *Fields[] = {
3571 llvm::ConstantInt::get(CGM.
IntTy, 0),
3572 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3573 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3574 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3575 Bases->getValueType(), Bases,
3578 CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3582 llvm::GlobalVariable *
3586 llvm::raw_svector_ostream Out(MangledName);
3587 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3595 llvm::Type *PtrType = ABI.getImageRelativeType(
3596 ABI.getBaseClassDescriptorType()->getPointerTo());
3597 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3599 new llvm::GlobalVariable(
Module, ArrType,
3601 nullptr, MangledName);
3602 if (BCA->isWeakForLinker())
3603 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3607 for (MSRTTIClass &Class : Classes)
3608 BaseClassArrayData.push_back(
3609 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3610 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3611 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3615 llvm::GlobalVariable *
3616 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3619 uint32_t OffsetInVBTable = 0;
3620 int32_t VBPtrOffset = -1;
3621 if (Class.VirtualRoot) {
3623 OffsetInVBTable = VTableContext.
getVBTableIndex(RD, Class.VirtualRoot) * 4;
3629 llvm::raw_svector_ostream Out(MangledName);
3630 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3631 Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3636 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3640 auto Type = ABI.getBaseClassDescriptorType();
3642 new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3643 nullptr, MangledName);
3644 if (BCD->isWeakForLinker())
3645 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3648 llvm::Constant *Fields[] = {
3649 ABI.getImageRelativeConstant(
3651 llvm::ConstantInt::get(CGM.
IntTy, Class.NumBases),
3652 llvm::ConstantInt::get(CGM.
IntTy, Class.OffsetInVBase),
3653 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3654 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3655 llvm::ConstantInt::get(CGM.
IntTy, Class.Flags),
3656 ABI.getImageRelativeConstant(
3657 MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3659 BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3663 llvm::GlobalVariable *
3664 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3667 llvm::raw_svector_ostream Out(MangledName);
3668 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3672 if (
auto COL =
Module.getNamedGlobal(MangledName))
3677 int VFPtrOffset = 0;
3683 ->second.hasVtorDisp())
3687 llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3688 auto COL =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3689 nullptr, MangledName);
3692 llvm::Constant *Fields[] = {
3693 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3694 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3695 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3696 ABI.getImageRelativeConstant(
3698 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3699 ABI.getImageRelativeConstant(COL),
3702 if (!ABI.isImageRelative())
3703 FieldsRef = FieldsRef.drop_back();
3704 COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
3705 if (COL->isWeakForLinker())
3706 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3711 bool &IsConst,
bool &IsVolatile,
3712 bool &IsUnaligned) {
3722 IsUnaligned =
false;
3724 if (!PointeeType.
isNull()) {
3745 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3750 bool IsConst, IsVolatile, IsUnaligned;
3766 return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(),
3774 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3777 llvm::raw_svector_ostream Out(MangledName);
3778 getMangleContext().mangleCXXRTTI(Type, Out);
3782 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3783 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3791 llvm::raw_svector_ostream Out(TypeInfoString);
3792 getMangleContext().mangleCXXRTTIName(Type, Out);
3796 llvm::Constant *Fields[] = {
3798 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3799 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
3800 llvm::StructType *TypeDescriptorType =
3801 getTypeDescriptorType(TypeInfoString);
3802 auto *Var =
new llvm::GlobalVariable(
3803 CGM.
getModule(), TypeDescriptorType,
false,
3804 getLinkageForRTTI(Type),
3805 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
3807 if (Var->isWeakForLinker())
3808 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
3809 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
3813 llvm::GlobalVariable *
3814 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
3816 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
3844 if (Fn->isWeakForLinker())
3845 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
3848 void MicrosoftCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3850 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
3864 llvm::raw_svector_ostream Out(ThunkName);
3865 getMangleContext().mangleCXXCtor(CD, CT, Out);
3868 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
3869 return cast<llvm::Function>(GV);
3875 QualType RecordTy = getContext().getRecordType(RD);
3877 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
3878 ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
3880 if (ThunkFn->isWeakForLinker())
3881 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
3892 buildThisParam(CGF, FunctionArgs);
3898 &getContext().Idents.get(
"src"),
3899 getContext().getLValueReferenceType(RecordTy,
3903 FunctionArgs.push_back(&SrcParam);
3910 &getContext().Idents.get(
"is_most_derived"),
3914 FunctionArgs.push_back(&IsMostDerived);
3922 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
3942 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
3943 ArgVec.push_back(PD->getDefaultArg());
3949 CGF.
EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
3952 AddedStructorArgs ExtraArgs =
3957 llvm::Constant *CalleePtr =
3962 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
3974 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
3976 int32_t VBPtrOffset,
3988 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
3991 llvm::raw_svector_ostream Out(MangledName);
3992 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
3993 VBPtrOffset, VBIndex, Out);
3995 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3996 return getImageRelativeConstant(GV);
4000 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
4004 llvm::Constant *CopyCtor;
4011 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
4013 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4015 CopyCtor = getImageRelativeConstant(CopyCtor);
4017 bool IsScalar = !RD;
4018 bool HasVirtualBases =
false;
4019 bool IsStdBadAlloc =
false;
4024 HasVirtualBases = RD->getNumVBases() > 0;
4026 IsStdBadAlloc = II->isStr(
"bad_alloc") && RD->isInStdNamespace();
4034 if (HasVirtualBases)
4039 llvm::Constant *Fields[] = {
4040 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4042 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4043 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4044 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4045 llvm::ConstantInt::get(CGM.
IntTy, Size),
4048 llvm::StructType *CTType = getCatchableTypeType();
4049 auto *GV =
new llvm::GlobalVariable(
4050 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
4051 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4052 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4053 GV->setSection(
".xdata");
4054 if (GV->isWeakForLinker())
4055 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4056 return getImageRelativeConstant(GV);
4059 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4063 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4088 if (MostDerivedClass) {
4095 Classes.front().initialize(
nullptr,
nullptr);
4097 for (
const MSRTTIClass &Class : Classes) {
4100 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4103 uint32_t OffsetInVBTable = 0;
4104 int32_t VBPtrOffset = -1;
4105 if (Class.VirtualRoot) {
4116 CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
4117 VBPtrOffset, OffsetInVBTable));
4125 CatchableTypes.insert(getCatchableType(T));
4138 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4149 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4151 uint32_t NumEntries = CatchableTypes.size();
4153 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4154 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4155 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4156 llvm::Constant *Fields[] = {
4157 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4158 llvm::ConstantArray::get(
4159 AT, llvm::makeArrayRef(CatchableTypes.begin(),
4160 CatchableTypes.end()))
4164 llvm::raw_svector_ostream Out(MangledName);
4165 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4167 CTA =
new llvm::GlobalVariable(
4168 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4169 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4170 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4171 CTA->setSection(
".xdata");
4172 if (CTA->isWeakForLinker())
4173 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4177 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4178 bool IsConst, IsVolatile, IsUnaligned;
4183 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4188 uint32_t NumEntries =
4189 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
4190 ->getLimitedValue();
4194 llvm::raw_svector_ostream Out(MangledName);
4195 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4201 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4217 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4220 if (!DtorD->isTrivial())
4221 CleanupFn = llvm::ConstantExpr::getBitCast(
4225 llvm::Constant *ForwardCompat =
4226 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4227 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4228 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4229 llvm::StructType *TIType = getThrowInfoType();
4230 llvm::Constant *Fields[] = {
4231 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4232 getImageRelativeConstant(CleanupFn),
4234 PointerToCatchableTypes
4236 auto *GV =
new llvm::GlobalVariable(
4237 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4238 llvm::ConstantStruct::get(TIType, Fields), StringRef(MangledName));
4239 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4240 GV->setSection(
".xdata");
4241 if (GV->isWeakForLinker())
4242 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4257 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4267 std::pair<llvm::Value *, const CXXRecordDecl *>
4270 std::tie(This, std::ignore, RD) =
ReturnValueSlot - Contains the address where the return value of a function can be stored...
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.
static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile, bool &IsUnaligned)
llvm::IntegerType * IntTy
int
CharUnits getIntAlign() const
void setSRetAfterThis(bool AfterThis)
External linkage, which indicates that the entity can be referred to from other translation units...
Other implicit parameter.
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
A (possibly-)qualified type.
static llvm::Constant * getInitThreadFooterFn(CodeGenModule &CGM)
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
uint32_t VBPtrOffset
The offset (in bytes) of the vbptr, relative to the beginning of the derived class.
Internal linkage according to the Modules TS, but can be referred to from other translation units ind...
const Expr * getSubExpr() const
Address CreateMemTemp(QualType T, const Twine &Name="tmp", Address *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
llvm::LLVMContext & getLLVMContext()
static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)
Find ambiguity among base classes.
CXXDtorType getDtorType() const
The standard implementation of ConstantInitBuilder used in Clang.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
No linkage, which means that the entity is unique and can only be referred to from within its scope...
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
QualType getThisType() const
Returns the type of the this pointer.
const Type * getTypeForDecl() const
bool isVariadic() const
Whether this function prototype is variadic.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
const CGFunctionInfo & arrangeCXXMethodType(const CXXRecordDecl *RD, const FunctionProtoType *FTP, const CXXMethodDecl *MD)
Arrange the argument and result information for a call to an unknown C++ non-static member function o...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
bool isPOD() const
Whether this class is a POD-type (C++ [class]p4)
The base class of the type hierarchy.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isZero() const
isZero - Test whether the quantity equals zero.
const NestedNameSpecifier * Specifier
bool isFuncTypeConvertible(const FunctionType *FT)
isFuncTypeConvertible - Utility to check whether a function type can be converted to an LLVM type (i...
Linkage getLinkage() const
Determine the linkage of this type.
BasePath MangledPath
The bases from the inheritance path that got used to mangle the vbtable name.
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
Default closure variant of a ctor.
MSInheritanceAttr::Spelling getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
const CXXBaseSpecifier *const * path_const_iterator
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::Instruction **callOrInvoke, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
Represents a variable declaration or definition.
Address getObjectAddress(CodeGenFunction &CGF) const
Returns the address of the object within this declaration.
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to...
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
const T * getAs() const
Member-template getAs<specific type>'.
static llvm::Constant * getInitThreadHeaderFn(CodeGenModule &CGM)
A this pointer adjustment.
DiagnosticsEngine & getDiags() const
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
llvm::Value * getPointer() const
A C++ throw-expression (C++ [except.throw]).
static llvm::Constant * getInitThreadAbortFn(CodeGenModule &CGM)
bool hasDefinition() const
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::Value *Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
Represents a parameter to a function.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
unsigned getAddressSpace() const
Return the address space that this address resides in.
void add(RValue rvalue, QualType type)
const ValueDecl * getMemberPointerDecl() const
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
One of these records is kept for each identifier that is lexed.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const CXXRecordDecl * NearestVBase
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl *> BasePath, raw_ostream &Out)=0
Mangle vftable symbols.
llvm::Constant * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, 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.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::IntegerType * SizeTy
StructorType getFromDtorType(CXXDtorType T)
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
bool isReferenceType() const
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
llvm::Function * codegenCXXStructor(const CXXMethodDecl *MD, StructorType Type)
Describes a module or submodule.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
ArrayRef< ParmVarDecl * > parameters() const
ArrayRef< VTableComponent > vtable_components() const
FunctionDecl * getOperatorDelete() const
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
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...
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
const CXXRecordDecl * IntroducingObject
This is the class that introduced the vptr by declaring new virtual methods or virtual bases...
path_iterator path_begin()
CharUnits getAlignment() const
Return the alignment of this pointer.
llvm::PointerType * VoidPtrTy
Concrete class used by the front-end to report problems and issues.
static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM)
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
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.
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
QualType getExceptionObjectType(QualType T) const
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getPointerAlign() const
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
struct clang::ReturnAdjustment::VirtualAdjustment::@132 Microsoft
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
CXXRecordDecl * getMostRecentNonInjectedDecl()
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
CanQualType getReturnType() const
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Represents a prototype with parameter type info, e.g.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
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...
CastKind
CastKind - The kind of operation required for a conversion.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
union clang::ReturnAdjustment::VirtualAdjustment Virtual
Module linkage, which indicates that the entity can be referred to from other translation units withi...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static void emitCXXConstructor(CodeGenModule &CGM, const CXXConstructorDecl *ctor, StructorType ctorType)
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
CXXDtorType
C++ destructor types.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, 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.
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
const T * castAs() const
Member-template castAs<specific type>.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Represents a C++ destructor within a class.
VarDecl * getExceptionDecl() const
static llvm::CallSite emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
bool isNullPtrType() const
llvm::PointerType * getType() const
Return the type of the pointer value.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
DeclContext * getDeclContext()
TLSKind getTLSKind() const
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
MicrosoftVTableContext & getMicrosoftVTableContext()
static bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
llvm::LLVMContext & getLLVMContext()
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
llvm::IntegerType * Int32Ty
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function *> CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
const TargetInfo & getTarget() const
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
ASTContext & getContext() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
The COMDAT used for dtors.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
GlobalDecl - represents a global declaration.
void setSuppressSRet(bool Suppress)
bool isConstQualified() const
Determine whether this type is const-qualified.
The l-value was considered opaque, so the alignment was determined from a type.
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
CastKind getCastKind() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
Represents a call to a member function that may be written either with member call syntax (e...
ASTContext & getASTContext() const LLVM_READONLY
const Decl * getDecl() const
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
Represents a single component in a vtable.
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
Represents a static or instance method of a struct/union/class.
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
bool isInstanceMethod() const
QualType getAllocatedType() const
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti)
Add vtable components for the given vtable layout to the given global initializer.
const CXXRecordDecl * ObjectWithVPtr
This is the most derived class that has this vptr at offset zero.
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.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
All available information about a concrete callee.
MangleContext & getMangleContext()
Gets the mangle context.
llvm::Instruction * CurrentFuncletPad
constexpr XRayInstrMask None
CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)
Creates a Microsoft-family ABI.
Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::DataLayout &DL, const llvm::Twine &Name="")
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo &VFPtr, SmallString< 256 > &Name)
bool isMemberPointerToDerivedMember() const
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
CXXCtorType
C++ constructor types.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod) const
Retrieves the default calling convention for the current target.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is virtually derived from the class Base.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
Dataflow Directional Tag Classes.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This)
External linkage within a unique namespace.
static bool isDeletingDtor(GlobalDecl GD)
uint64_t Index
Method's index in the vftable.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
const VPtrInfoVector & enumerateVBTables(const CXXRecordDecl *RD)
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value *> args)
Emits a call or invoke to the given noreturn runtime function.
llvm::LoadInst * CreateAlignedLoad(llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
llvm::Constant * getPointer() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
A pointer to member type per C++ 8.3.3 - Pointers to members.
CharUnits NonVirtualOffset
IntroducingObject is at this offset from its containing complete object or virtual base...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::Module & getModule() const
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
union clang::ThisAdjustment::VirtualAdjustment Virtual
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void AppendLinkerOptions(StringRef Opts)
Appends Opts to the "llvm.linker.options" metadata value.
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
StructBuilder beginStruct(llvm::StructType *structTy=nullptr)
const CXXRecordDecl * getVBaseWithVPtr() const
The vptr is stored inside the non-virtual component of this virtual base.
Implements C++ ABI-specific code generation functions.
This class organizes the cross-module state that is used while lowering AST types to LLVM types...
llvm::PointerType * Int8PtrTy
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
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.
StringRef getMangledName(GlobalDecl GD)
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat]...
ABIArgInfo & getReturnInfo()
Represents a base class of a C++ class.
bool isObjectType() const
Determine whether this type is an object type.
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
CharUnits getIntSize() const
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
bool hasUnaligned() const
Represents a C++ struct/union/class.
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false)
CXXCatchStmt - This represents a C++ catch block.
llvm::Type * ConvertType(QualType T)
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor, StructorType dtorType)
A specialization of Address that requires the address to be an LLVM Constant.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
No linkage according to the standard, but is visible from other translation units because of types de...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
bool isGlobalDelete() const
Copying closure variant of a ctor.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CharUnits FullOffsetInMDC
Static offset from the top of the most derived class to this vfptr, including any virtual base offset...
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
__DEVICE__ int max(int __a, int __b)
Struct with all information about dynamic [sub]class needed to set vptr.
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
static RValue get(llvm::Value *V)
GVALinkage
A more specific kind of linkage than enum Linkage.
Holds information about the inheritance path to a virtual base or function table pointer.
bool isPointerType() const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
uint32_t VBIndex
Index of the virtual base in the vbtable.
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
This represents a decl that may have a name.
BasePath PathToIntroducingObject
This holds the base classes path from the complete type to the first base with the given vfptr offset...
const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
Notes how many arguments were added to the beginning (Prefix) and ending (Suffix) of an arg list...
RecordArgABI
Specify how one should pass an argument of a record type.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
CallArgList - Type for representing both the value and type of arguments in a call.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)
Recursively serializes a class hierarchy in pre-order depth first order.
base_class_range vbases()
struct clang::ThisAdjustment::VirtualAdjustment::@134 Microsoft
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
SourceLocation getLocation() const
QualType getPointeeType() const
bool isExternallyVisible() const
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
static llvm::Constant * getThrowFn(CodeGenModule &CGM)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool isNoDestroy(const ASTContext &) const
Do we need to emit an exit-time destructor for this variable?