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");
1875 CGCallee Callee(MethodDecl->getCanonicalDecl(), VFunc);
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");
1972 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
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?");
2027 llvm::GlobalVariable *GV =
2028 CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, Linkage);
2029 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2031 if (RD->
hasAttr<DLLImportAttr>())
2032 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2033 else if (RD->
hasAttr<DLLExportAttr>())
2034 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2036 if (!GV->hasExternalLinkage())
2037 emitVBTableDefinition(VBT, RD, GV);
2042 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2044 llvm::GlobalVariable *GV)
const {
2048 "should only emit vbtables for classes with vbtables");
2052 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2058 CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
2059 Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
2062 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2063 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2070 CompleteVBPtrOffset +=
2072 Offset -= CompleteVBPtrOffset;
2074 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2075 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2076 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.
getQuantity());
2079 assert(Offsets.size() ==
2080 cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
2081 ->getElementType())->getNumElements());
2082 llvm::ArrayType *VBTableType =
2083 llvm::ArrayType::get(CGM.IntTy, Offsets.size());
2084 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2085 GV->setInitializer(Init);
2087 if (RD->
hasAttr<DLLImportAttr>())
2088 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2111 CGF.
Builder.CreateNeg(VtorDisp));
2128 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2145 const ReturnAdjustment &RA) {
2160 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2177 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *expr) {
2204 assert(requiresArrayCookie(expr));
2207 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2223 llvm::Constant *Dtor,
2224 llvm::Constant *Addr) {
2229 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2230 CGF.
IntTy, DtorStub->getType(),
false);
2233 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2234 if (llvm::Function *TLRegDtorFn = dyn_cast<llvm::Function>(TLRegDtor))
2235 TLRegDtorFn->setDoesNotThrow();
2241 llvm::Constant *Dtor,
2242 llvm::Constant *Addr) {
2250 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2254 if (CXXThreadLocalInits.empty())
2259 ?
"/include:___dyn_tls_init@12" 2260 :
"/include:__dyn_tls_init");
2265 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2266 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2267 CGM.
getModule(), InitFunc->getType(),
true,
2269 Twine(InitFunc->getName(),
"$initializer$"));
2270 InitFuncPtr->setSection(
".CRT$XDU");
2277 std::vector<llvm::Function *> NonComdatInits;
2278 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2279 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2281 llvm::Function *F = CXXThreadLocalInits[I];
2284 if (llvm::Comdat *C = GV->getComdat())
2285 AddToXDU(F)->setComdat(C);
2287 NonComdatInits.push_back(F);
2290 if (!NonComdatInits.empty()) {
2291 llvm::FunctionType *FTy =
2292 llvm::FunctionType::get(CGM.
VoidTy,
false);
2310 StringRef VarName(
"_Init_thread_epoch");
2312 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2314 auto *GV =
new llvm::GlobalVariable(
2318 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2324 llvm::FunctionType *FTy =
2325 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2326 CGM.
IntTy->getPointerTo(),
false);
2328 FTy,
"_Init_thread_header",
2330 llvm::AttributeList::FunctionIndex,
2331 llvm::Attribute::NoUnwind),
2336 llvm::FunctionType *FTy =
2337 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2338 CGM.
IntTy->getPointerTo(),
false);
2340 FTy,
"_Init_thread_footer",
2342 llvm::AttributeList::FunctionIndex,
2343 llvm::Attribute::NoUnwind),
2348 llvm::FunctionType *FTy =
2349 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2350 CGM.
IntTy->getPointerTo(),
false);
2352 FTy,
"_Init_thread_abort",
2354 llvm::AttributeList::FunctionIndex,
2355 llvm::Attribute::NoUnwind),
2363 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2364 : Guard(Guard), GuardNum(GuardNum) {}
2370 llvm::LoadInst *LI = Builder.
CreateLoad(Guard);
2371 llvm::ConstantInt *Mask =
2372 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2373 Builder.
CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2389 llvm::GlobalVariable *GV,
2393 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2395 llvm::Function *F = CGF.
CurFn;
2396 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2397 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2403 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2407 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2410 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2411 llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
2415 GuardInfo *GI =
nullptr;
2416 if (ThreadlocalStatic)
2418 else if (!ThreadsafeStatic)
2421 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2426 GuardNum = getContext().getStaticLocalNumber(&D);
2427 assert(GuardNum > 0);
2429 }
else if (HasPerVariableGuard) {
2433 GuardNum = GI->BitIndex++;
2436 if (!HasPerVariableGuard && GuardNum >= 32) {
2438 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2447 llvm::raw_svector_ostream Out(GuardName);
2448 if (HasPerVariableGuard)
2449 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2452 getMangleContext().mangleStaticGuardVariable(&D, Out);
2458 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2459 GV->getLinkage(), Zero, GuardName.str());
2460 GuardVar->setVisibility(GV->getVisibility());
2461 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2463 if (GuardVar->isWeakForLinker())
2464 GuardVar->setComdat(
2465 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2467 GuardVar->setThreadLocal(
true);
2468 if (GI && !HasPerVariableGuard)
2469 GI->Guard = GuardVar;
2474 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2475 "static local from the same function had different linkage");
2477 if (!HasPerVariableGuard) {
2485 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2486 llvm::LoadInst *LI = Builder.
CreateLoad(GuardAddr);
2488 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
2497 Builder.
CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2501 Builder.CreateBr(EndBlock);
2519 llvm::LoadInst *FirstGuardLoad = Builder.
CreateLoad(GuardAddr);
2520 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2521 llvm::LoadInst *InitThreadEpoch =
2524 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2535 llvm::LoadInst *SecondGuardLoad = Builder.
CreateLoad(GuardAddr);
2536 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2538 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2540 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2549 Builder.CreateBr(EndBlock);
2566 return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) &&
2578 fields.push_back(CGM.
IntTy);
2582 fields.push_back(CGM.
IntTy);
2583 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2584 fields.push_back(CGM.
IntTy);
2585 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2586 fields.push_back(CGM.
IntTy);
2588 if (fields.size() == 1)
2593 void MicrosoftCXXABI::
2596 assert(fields.empty());
2601 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2603 if (RD->nullFieldOffsetIsZero())
2604 fields.push_back(getZeroInt());
2606 fields.push_back(getAllOnesInt());
2611 fields.push_back(getZeroInt());
2612 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2613 fields.push_back(getZeroInt());
2614 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2615 fields.push_back(getAllOnesInt());
2621 GetNullMemberPointerFields(MPT, fields);
2622 if (fields.size() == 1)
2624 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2625 assert(Res->getType() == ConvertMemberPointerType(MPT));
2630 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2631 bool IsMemberFunction,
2634 unsigned VBTableIndex) {
2639 if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance))
2643 fields.push_back(FirstField);
2645 if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance))
2646 fields.push_back(llvm::ConstantInt::get(
2649 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) {
2652 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2657 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2658 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2660 return llvm::ConstantStruct::getAnon(fields);
2668 MSInheritanceAttr::Keyword_virtual_inheritance)
2669 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2670 llvm::Constant *FirstField =
2672 return EmitFullMemberPointer(FirstField,
false, RD,
2676 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2681 return EmitNullMemberPointer(DstTy);
2687 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2688 C = EmitMemberFunctionPointer(MD);
2691 C = EmitMemberDataPointer(DstTy, FieldOffset);
2694 if (!MemberPointerPath.empty()) {
2695 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2699 ->castAs<MemberPointerType>();
2707 if (DerivedMember) {
2715 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2717 DerivedToBasePath.push_back(&BS);
2720 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2722 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2723 : CK_BaseToDerivedMemberPointer;
2724 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2725 DerivedToBasePath.end(), C);
2731 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2732 assert(MD->
isInstance() &&
"Member function must not be static!");
2738 unsigned VBTableIndex = 0;
2739 llvm::Constant *FirstField;
2756 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2760 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2763 if (VBTableIndex == 0 &&
2765 MSInheritanceAttr::Keyword_virtual_inheritance)
2766 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2769 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2770 return EmitFullMemberPointer(FirstField,
true, RD,
2771 NonVirtualBaseAdjustment, VBTableIndex);
2786 llvm::ICmpInst::Predicate Eq;
2787 llvm::Instruction::BinaryOps
And, Or;
2789 Eq = llvm::ICmpInst::ICMP_NE;
2790 And = llvm::Instruction::Or;
2793 Eq = llvm::ICmpInst::ICMP_EQ;
2795 Or = llvm::Instruction::Or;
2804 return Builder.CreateICmp(Eq, L, R);
2807 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
2808 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
2809 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
2813 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
2814 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
2815 llvm::Value *LF = Builder.CreateExtractValue(L, I);
2816 llvm::Value *RF = Builder.CreateExtractValue(R, I);
2817 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
2819 Res = Builder.CreateBinOp(And, Res, Cmp);
2827 llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
2828 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero,
"memptr.cmp.iszero");
2829 Res = Builder.CreateBinOp(Or, Res, IsZero);
2834 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
2845 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2847 GetNullMemberPointerFields(MPT, fields);
2848 assert(!fields.empty());
2850 if (MemPtr->getType()->isStructTy())
2851 FirstField = Builder.CreateExtractValue(MemPtr, 0);
2852 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
2860 for (
int I = 1, E = fields.size(); I < E; ++I) {
2861 llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
2862 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
2863 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
2869 llvm::Constant *Val) {
2872 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
2873 Val->getAggregateElement(0U) : Val;
2874 return FirstField->isNullValue();
2879 if (isZeroInitializable(MPT) && Val->isNullValue())
2885 GetNullMemberPointerFields(MPT, Fields);
2886 if (Fields.size() == 1) {
2887 assert(Val->getType()->isIntegerTy());
2888 return Val == Fields[0];
2892 for (I = 0, E = Fields.size(); I != E; ++I) {
2893 if (Val->getAggregateElement(I) != Fields[I])
2909 Builder.CreateInBoundsGEP(This.
getPointer(), VBPtrOffset,
"vbptr");
2910 if (VBPtrOut) *VBPtrOut = VBPtr;
2915 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
2926 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
2930 llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex);
2943 llvm::BasicBlock *OriginalBB =
nullptr;
2944 llvm::BasicBlock *SkipAdjustBB =
nullptr;
2945 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
2952 OriginalBB = Builder.GetInsertBlock();
2956 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
2958 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
2970 "member pointer representation requires a " 2971 "complete class type for %0 to perform this expression");
2974 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2979 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
2980 llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
2983 if (VBaseAdjustBB) {
2984 Builder.CreateBr(SkipAdjustBB);
2986 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
2987 Phi->addIncoming(Base.
getPointer(), OriginalBB);
2988 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
2991 return AdjustedBase;
2994 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3008 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3010 if (MemPtr->getType()->isStructTy()) {
3013 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3014 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3015 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3016 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3017 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3021 if (VirtualBaseAdjustmentOffset) {
3022 Addr = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
3032 Addr = Builder.CreateInBoundsGEP(Addr, FieldOffset,
"memptr.offset");
3043 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3044 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3048 if (isa<llvm::Constant>(Src))
3049 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3059 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3060 if (IsReinterpret && IsFunc)
3065 if (IsReinterpret &&
3072 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3073 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3077 if (IsReinterpret) {
3080 assert(Src->getType() == DstNull->getType());
3081 return Builder.CreateSelect(IsNotNull, Src, DstNull);
3084 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3087 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3090 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3094 Builder.CreateBr(ContinueBB);
3098 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3099 Phi->addIncoming(DstNull, OriginalBB);
3100 Phi->addIncoming(Dst, ConvertBB);
3104 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3114 bool IsConstant = isa<llvm::Constant>(Src);
3118 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3119 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3121 if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
3124 FirstField = Builder.CreateExtractValue(Src, I++);
3125 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
3126 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3127 if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
3128 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3129 if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
3130 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3133 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3139 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3147 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3148 if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3149 if (int64_t SrcOffsetToFirstVBase =
3150 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3151 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3153 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3155 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3166 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3172 if (IsDerivedToBase)
3173 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3175 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3177 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3182 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) &&
3183 MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) {
3184 if (llvm::GlobalVariable *VDispMap =
3185 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3187 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3189 llvm::Constant *Mapping = VDispMap->getInitializer();
3190 VirtualBaseAdjustmentOffset =
3191 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3194 VirtualBaseAdjustmentOffset =
3200 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3206 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) {
3207 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3209 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3211 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3217 if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3218 if (int64_t DstOffsetToFirstVBase =
3219 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3220 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3222 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3224 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3230 if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) {
3233 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3235 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3236 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
3237 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3238 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
3239 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3240 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
3241 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3247 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3248 llvm::Constant *Src) {
3255 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3259 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3263 assert(CK == CK_DerivedToBaseMemberPointer ||
3264 CK == CK_BaseToDerivedMemberPointer ||
3265 CK == CK_ReinterpretMemberPointer);
3268 if (MemberPointerConstantIsNull(SrcTy, Src))
3269 return EmitNullMemberPointer(DstTy);
3274 if (CK == CK_ReinterpretMemberPointer)
3278 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3279 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3284 CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3296 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
3302 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3304 if (MemPtr->getType()->isStructTy()) {
3307 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3308 if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance))
3309 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3310 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3311 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3312 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3313 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3316 if (VirtualBaseAdjustmentOffset) {
3317 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3318 VirtualBaseAdjustmentOffset, VBPtrOffset);
3323 if (NonVirtualBaseAdjustment) {
3326 Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
3327 ThisPtrForCall = Builder.
CreateBitCast(Ptr, ThisPtrForCall->getType(),
3332 Builder.
CreateBitCast(FunctionPointer, FTy->getPointerTo());
3333 CGCallee Callee(FPT, FunctionPointer);
3338 return new MicrosoftCXXABI(CGM);
3372 StringRef MangledName(
"??_7type_info@@6B@");
3373 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3378 nullptr, MangledName);
3389 struct MSRTTIClass {
3391 IsPrivateOnPath = 1 | 8,
3395 HasHierarchyDescriptor = 64
3401 MSRTTIClass *getFirstChild() {
return this + 1; }
3402 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3403 return Child + 1 + Child->NumBases;
3407 uint32_t Flags, NumBases, OffsetInVBase;
3413 Flags = HasHierarchyDescriptor;
3415 VirtualRoot =
nullptr;
3419 Flags |= IsPrivate | IsPrivateOnPath;
3425 if (Parent->Flags & IsPrivateOnPath)
3426 Flags |= IsPrivateOnPath;
3427 VirtualRoot = Parent->VirtualRoot;
3433 MSRTTIClass *Child = getFirstChild();
3435 NumBases += Child->initialize(
this, &Base) + 1;
3436 Child = getNextChild(Child);
3441 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3452 return llvm::GlobalValue::LinkOnceODRLinkage;
3454 llvm_unreachable(
"Invalid linkage!");
3460 struct MSRTTIBuilder {
3462 HasBranchingHierarchy = 1,
3463 HasVirtualBranchingHierarchy = 2,
3464 HasAmbiguousBases = 4
3467 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3473 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3474 llvm::GlobalVariable *
3476 llvm::GlobalVariable *getClassHierarchyDescriptor();
3477 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3481 llvm::LLVMContext &VMContext;
3484 llvm::GlobalVariable::LinkageTypes
Linkage;
3485 MicrosoftCXXABI &ABI;
3494 Classes.push_back(MSRTTIClass(RD));
3502 llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3503 llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3504 llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3505 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3506 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3507 !VirtualBases.insert(Class->RD).second) {
3508 Class = MSRTTIClass::getNextChild(Class);
3511 if (!UniqueBases.insert(Class->RD).second)
3512 AmbiguousBases.insert(Class->RD);
3515 if (AmbiguousBases.empty())
3517 for (MSRTTIClass &Class : Classes)
3518 if (AmbiguousBases.count(Class.RD))
3519 Class.Flags |= MSRTTIClass::IsAmbiguous;
3522 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3525 llvm::raw_svector_ostream Out(MangledName);
3526 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3530 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3536 Classes.front().initialize(
nullptr,
nullptr);
3539 for (
auto Class : Classes) {
3540 if (Class.RD->getNumBases() > 1)
3541 Flags |= HasBranchingHierarchy;
3544 if (Class.Flags & MSRTTIClass::IsAmbiguous)
3545 Flags |= HasAmbiguousBases;
3547 if ((Flags & HasBranchingHierarchy) && RD->
getNumVBases() != 0)
3548 Flags |= HasVirtualBranchingHierarchy;
3552 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3555 auto Type = ABI.getClassHierarchyDescriptorType();
3556 auto CHD =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3559 if (CHD->isWeakForLinker())
3560 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3562 auto *Bases = getBaseClassArray(Classes);
3565 llvm::Constant *Fields[] = {
3566 llvm::ConstantInt::get(CGM.
IntTy, 0),
3567 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3568 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3569 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3570 Bases->getValueType(), Bases,
3573 CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3577 llvm::GlobalVariable *
3581 llvm::raw_svector_ostream Out(MangledName);
3582 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3590 llvm::Type *PtrType = ABI.getImageRelativeType(
3591 ABI.getBaseClassDescriptorType()->getPointerTo());
3592 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3594 new llvm::GlobalVariable(
Module, ArrType,
3596 nullptr, MangledName);
3597 if (BCA->isWeakForLinker())
3598 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3602 for (MSRTTIClass &Class : Classes)
3603 BaseClassArrayData.push_back(
3604 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3605 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3606 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3610 llvm::GlobalVariable *
3611 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3614 uint32_t OffsetInVBTable = 0;
3615 int32_t VBPtrOffset = -1;
3616 if (Class.VirtualRoot) {
3618 OffsetInVBTable = VTableContext.
getVBTableIndex(RD, Class.VirtualRoot) * 4;
3624 llvm::raw_svector_ostream Out(MangledName);
3625 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3626 Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3631 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3635 auto Type = ABI.getBaseClassDescriptorType();
3637 new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3638 nullptr, MangledName);
3639 if (BCD->isWeakForLinker())
3640 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3643 llvm::Constant *Fields[] = {
3644 ABI.getImageRelativeConstant(
3646 llvm::ConstantInt::get(CGM.
IntTy, Class.NumBases),
3647 llvm::ConstantInt::get(CGM.
IntTy, Class.OffsetInVBase),
3648 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3649 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3650 llvm::ConstantInt::get(CGM.
IntTy, Class.Flags),
3651 ABI.getImageRelativeConstant(
3652 MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3654 BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3658 llvm::GlobalVariable *
3659 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3662 llvm::raw_svector_ostream Out(MangledName);
3663 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3667 if (
auto COL =
Module.getNamedGlobal(MangledName))
3672 int VFPtrOffset = 0;
3678 ->second.hasVtorDisp())
3682 llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3683 auto COL =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3684 nullptr, MangledName);
3687 llvm::Constant *Fields[] = {
3688 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3689 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3690 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3691 ABI.getImageRelativeConstant(
3693 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3694 ABI.getImageRelativeConstant(COL),
3697 if (!ABI.isImageRelative())
3698 FieldsRef = FieldsRef.drop_back();
3699 COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
3700 if (COL->isWeakForLinker())
3701 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3706 bool &IsConst,
bool &IsVolatile,
3707 bool &IsUnaligned) {
3717 IsUnaligned =
false;
3719 if (!PointeeType.
isNull()) {
3740 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3745 bool IsConst, IsVolatile, IsUnaligned;
3761 return CatchTypeInfo{getAddrOfRTTIDescriptor(Type)->stripPointerCasts(),
3769 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3772 llvm::raw_svector_ostream Out(MangledName);
3773 getMangleContext().mangleCXXRTTI(Type, Out);
3777 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3778 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3786 llvm::raw_svector_ostream Out(TypeInfoString);
3787 getMangleContext().mangleCXXRTTIName(Type, Out);
3791 llvm::Constant *Fields[] = {
3793 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3794 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
3795 llvm::StructType *TypeDescriptorType =
3796 getTypeDescriptorType(TypeInfoString);
3797 auto *Var =
new llvm::GlobalVariable(
3798 CGM.
getModule(), TypeDescriptorType,
false,
3799 getLinkageForRTTI(Type),
3800 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
3802 if (Var->isWeakForLinker())
3803 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
3804 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
3808 llvm::GlobalVariable *
3809 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
3811 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
3839 if (Fn->isWeakForLinker())
3840 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
3843 void MicrosoftCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3845 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
3859 llvm::raw_svector_ostream Out(ThunkName);
3860 getMangleContext().mangleCXXCtor(CD, CT, Out);
3863 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
3864 return cast<llvm::Function>(GV);
3870 QualType RecordTy = getContext().getRecordType(RD);
3872 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
3873 ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
3875 if (ThunkFn->isWeakForLinker())
3876 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
3887 buildThisParam(CGF, FunctionArgs);
3893 &getContext().Idents.get(
"src"),
3894 getContext().getLValueReferenceType(RecordTy,
3898 FunctionArgs.push_back(&SrcParam);
3905 &getContext().Idents.get(
"is_most_derived"),
3909 FunctionArgs.push_back(&IsMostDerived);
3917 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
3937 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
3938 ArgVec.push_back(PD->getDefaultArg());
3944 CGF.
EmitCallArgs(Args, FPT, llvm::makeArrayRef(ArgVec), CD, IsCopy ? 1 : 0);
3947 AddedStructorArgs ExtraArgs =
3952 llvm::Constant *CalleePtr =
3956 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
3968 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
3970 int32_t VBPtrOffset,
3982 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
3985 llvm::raw_svector_ostream Out(MangledName);
3986 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
3987 VBPtrOffset, VBIndex, Out);
3989 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3990 return getImageRelativeConstant(GV);
3994 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
3998 llvm::Constant *CopyCtor;
4005 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
4007 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4009 CopyCtor = getImageRelativeConstant(CopyCtor);
4011 bool IsScalar = !RD;
4012 bool HasVirtualBases =
false;
4013 bool IsStdBadAlloc =
false;
4018 HasVirtualBases = RD->getNumVBases() > 0;
4020 IsStdBadAlloc = II->isStr(
"bad_alloc") && RD->isInStdNamespace();
4028 if (HasVirtualBases)
4033 llvm::Constant *Fields[] = {
4034 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4036 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4037 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4038 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4039 llvm::ConstantInt::get(CGM.
IntTy, Size),
4042 llvm::StructType *CTType = getCatchableTypeType();
4043 auto *GV =
new llvm::GlobalVariable(
4044 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
4045 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4046 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4047 GV->setSection(
".xdata");
4048 if (GV->isWeakForLinker())
4049 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4050 return getImageRelativeConstant(GV);
4053 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4057 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4082 if (MostDerivedClass) {
4089 Classes.front().initialize(
nullptr,
nullptr);
4091 for (
const MSRTTIClass &Class : Classes) {
4094 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4097 uint32_t OffsetInVBTable = 0;
4098 int32_t VBPtrOffset = -1;
4099 if (Class.VirtualRoot) {
4110 CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
4111 VBPtrOffset, OffsetInVBTable));
4119 CatchableTypes.insert(getCatchableType(T));
4132 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4143 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4145 uint32_t NumEntries = CatchableTypes.size();
4147 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4148 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4149 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4150 llvm::Constant *Fields[] = {
4151 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4152 llvm::ConstantArray::get(
4153 AT, llvm::makeArrayRef(CatchableTypes.begin(),
4154 CatchableTypes.end()))
4158 llvm::raw_svector_ostream Out(MangledName);
4159 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4161 CTA =
new llvm::GlobalVariable(
4162 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4163 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4164 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4165 CTA->setSection(
".xdata");
4166 if (CTA->isWeakForLinker())
4167 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4171 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4172 bool IsConst, IsVolatile, IsUnaligned;
4177 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4182 uint32_t NumEntries =
4183 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
4184 ->getLimitedValue();
4188 llvm::raw_svector_ostream Out(MangledName);
4189 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4195 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4211 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4214 if (!DtorD->isTrivial())
4215 CleanupFn = llvm::ConstantExpr::getBitCast(
4219 llvm::Constant *ForwardCompat =
4220 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4221 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4222 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4223 llvm::StructType *TIType = getThrowInfoType();
4224 llvm::Constant *Fields[] = {
4225 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4226 getImageRelativeConstant(CleanupFn),
4228 PointerToCatchableTypes
4230 auto *GV =
new llvm::GlobalVariable(
4231 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4232 llvm::ConstantStruct::get(TIType, Fields), StringRef(MangledName));
4233 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4234 GV->setSection(
".xdata");
4235 if (GV->isWeakForLinker())
4236 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4251 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4261 std::pair<llvm::Value *, const CXXRecordDecl *>
4264 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.
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function *> CXXThreadLocals, Address Guard=Address::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
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.
const Type * getTypeForDecl() const
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
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
QualType getThisType(ASTContext &C) const
Returns the type of the this pointer.
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.
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 ...
Expr - 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.
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
struct clang::ReturnAdjustment::VirtualAdjustment::@118 Microsoft
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
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...
struct clang::ThisAdjustment::VirtualAdjustment::@120 Microsoft
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()
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.
void EmitMustTailThunk(const CXXMethodDecl *MD, llvm::Value *AdjustedThisPtr, llvm::Value *Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
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.