29#include "llvm/ADT/StringExtras.h"
30#include "llvm/ADT/StringSet.h"
31#include "llvm/IR/Intrinsics.h"
34using namespace CodeGen;
39struct VBTableGlobals {
44class MicrosoftCXXABI :
public CGCXXABI {
47 :
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
48 ClassHierarchyDescriptorType(nullptr),
49 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
50 ThrowInfoType(nullptr) {
53 "visibility export mapping option unimplemented in this ABI");
68 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
77 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
79 llvm_unreachable(
"bad dtor kind");
88 assert(Args.size() >= 2 &&
89 "expected the arglist to have at least two args!");
99 std::vector<CharUnits> VBPtrOffsets;
103 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
104 for (
const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
109 if (VBT->getVBaseWithVPtr())
111 VBPtrOffsets.push_back(Offs);
113 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
129 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
150 llvm::Type *StdTypeInfoPtrTy)
override;
158 llvm::BasicBlock *CastEnd)
override;
218 AddedStructorArgCounts
232 llvm::GlobalValue::LinkageTypes
240 if (MD->
isVirtual() && !isa<CXXDestructorDecl>(MD)) {
258 bool VirtualCall)
override;
269 bool Delegating)
override;
275 bool Delegating)
override;
283 llvm::GlobalVariable *VTable);
289 CodeGenFunction::VPtr Vptr)
override;
294 return !VTableClass->
hasAttr<MSNoVTableAttr>();
319 DeleteOrMemberCallExpr E)
override;
324 "Only deleting destructor thunks are available in this ABI");
331 llvm::GlobalVariable *
333 llvm::GlobalVariable::LinkageTypes
Linkage);
335 llvm::GlobalVariable *
339 llvm::raw_svector_ostream Out(OutName);
341 StringRef MangledName = OutName.str();
343 if (
auto *VDispMap = CGM.
getModule().getNamedGlobal(MangledName))
349 llvm::UndefValue::get(CGM.
IntTy));
350 Map[0] = llvm::ConstantInt::get(CGM.
IntTy, 0);
351 bool AnyDifferent =
false;
352 for (
const auto &I : SrcRD->
vbases()) {
353 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
359 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.
IntTy, DstVBIndex * 4);
360 AnyDifferent |= SrcVBIndex != DstVBIndex;
366 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.
IntTy, Map.size());
367 llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy, Map);
368 llvm::GlobalValue::LinkageTypes
Linkage =
370 ? llvm::GlobalValue::LinkOnceODRLinkage
371 : llvm::GlobalValue::InternalLinkage;
372 auto *VDispMap =
new llvm::GlobalVariable(
379 llvm::GlobalVariable *GV)
const;
387 Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
389 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
391 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
416 llvm::GlobalVariable *DeclPtr,
417 bool PerformInit)
override;
419 llvm::FunctionCallee Dtor,
420 llvm::Constant *Addr)
override;
451 llvm::Value *NumElements,
458 friend struct MSRTTIBuilder;
460 bool isImageRelative()
const {
465 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
467 TDTypeName += llvm::utostr(TypeInfoString.size());
468 llvm::StructType *&TypeDescriptorType =
469 TypeDescriptorTypeMap[TypeInfoString.size()];
470 if (TypeDescriptorType)
471 return TypeDescriptorType;
472 llvm::Type *FieldTypes[] = {
475 llvm::ArrayType::get(CGM.
Int8Ty, TypeInfoString.size() + 1)};
477 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, TDTypeName);
478 return TypeDescriptorType;
481 llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
482 if (!isImageRelative())
487 llvm::StructType *getBaseClassDescriptorType() {
488 if (BaseClassDescriptorType)
489 return BaseClassDescriptorType;
490 llvm::Type *FieldTypes[] = {
497 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
499 BaseClassDescriptorType = llvm::StructType::create(
501 return BaseClassDescriptorType;
504 llvm::StructType *getClassHierarchyDescriptorType() {
505 if (ClassHierarchyDescriptorType)
506 return ClassHierarchyDescriptorType;
508 ClassHierarchyDescriptorType = llvm::StructType::create(
510 llvm::Type *FieldTypes[] = {
514 getImageRelativeType(
515 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
517 ClassHierarchyDescriptorType->setBody(FieldTypes);
518 return ClassHierarchyDescriptorType;
521 llvm::StructType *getCompleteObjectLocatorType() {
522 if (CompleteObjectLocatorType)
523 return CompleteObjectLocatorType;
524 CompleteObjectLocatorType = llvm::StructType::create(
526 llvm::Type *FieldTypes[] = {
531 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
532 getImageRelativeType(CompleteObjectLocatorType),
535 if (!isImageRelative())
536 FieldTypesRef = FieldTypesRef.drop_back();
537 CompleteObjectLocatorType->setBody(FieldTypesRef);
538 return CompleteObjectLocatorType;
541 llvm::GlobalVariable *getImageBase() {
542 StringRef Name =
"__ImageBase";
543 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name))
548 llvm::GlobalValue::ExternalLinkage,
554 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
555 if (!isImageRelative())
558 if (PtrVal->isNullValue())
559 return llvm::Constant::getNullValue(CGM.
IntTy);
561 llvm::Constant *ImageBaseAsInt =
562 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.
IntPtrTy);
563 llvm::Constant *PtrValAsInt =
564 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.
IntPtrTy);
565 llvm::Constant *Diff =
566 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
568 return llvm::ConstantExpr::getTrunc(Diff, CGM.
IntTy);
576 llvm::Constant *getZeroInt() {
577 return llvm::ConstantInt::get(CGM.
IntTy, 0);
580 llvm::Constant *getAllOnesInt() {
581 return llvm::Constant::getAllOnesValue(CGM.
IntTy);
595 llvm::Value *VBPtrOffset,
596 llvm::Value *VBTableOffset,
597 llvm::Value **VBPtr =
nullptr);
602 int32_t VBTableOffset,
603 llvm::Value **VBPtr =
nullptr) {
604 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
605 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
606 *VBTOffset = llvm::ConstantInt::get(CGM.
IntTy, VBTableOffset);
607 return GetVBaseOffsetFromVBPtr(CGF,
Base, VBPOffset, VBTOffset, VBPtr);
610 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
618 llvm::Value *VirtualBaseAdjustmentOffset,
619 llvm::Value *VBPtrOffset );
623 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
624 bool IsMemberFunction,
627 unsigned VBTableIndex);
636 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
639 llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
652 return RD->
hasAttr<MSInheritanceAttr>();
666 bool Inequality)
override;
677 llvm::Value *EmitNonNullMemberPointerConversion(
685 llvm::Value *Src)
override;
688 llvm::Constant *Src)
override;
697 Address This, llvm::Value *&ThisPtrForCall,
703 llvm::StructType *getCatchableTypeType() {
704 if (CatchableTypeType)
705 return CatchableTypeType;
706 llvm::Type *FieldTypes[] = {
715 CatchableTypeType = llvm::StructType::create(
717 return CatchableTypeType;
720 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
721 llvm::StructType *&CatchableTypeArrayType =
722 CatchableTypeArrayTypeMap[NumEntries];
723 if (CatchableTypeArrayType)
724 return CatchableTypeArrayType;
727 CTATypeName += llvm::utostr(NumEntries);
729 getImageRelativeType(getCatchableTypeType()->getPointerTo());
730 llvm::Type *FieldTypes[] = {
732 llvm::ArrayType::get(CTType, NumEntries)
734 CatchableTypeArrayType =
735 llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, CTATypeName);
736 return CatchableTypeArrayType;
739 llvm::StructType *getThrowInfoType() {
741 return ThrowInfoType;
742 llvm::Type *FieldTypes[] = {
748 ThrowInfoType = llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes,
750 return ThrowInfoType;
756 llvm::Type *Args[] = {CGM.
Int8PtrTy, getThrowInfoType()->getPointerTo()};
757 llvm::FunctionType *FTy =
758 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
759 llvm::FunctionCallee Throw =
763 if (
auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
764 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
772 llvm::Constant *getCatchableType(
QualType T,
773 uint32_t NVOffset = 0,
774 int32_t VBPtrOffset = -1,
775 uint32_t VBIndex = 0);
777 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
781 std::pair<llvm::Value *, const CXXRecordDecl *>
789 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
790 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
791 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
793 VFTablesMapTy VFTablesMap;
794 VTablesMapTy VTablesMap;
801 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
806 GuardInfo() : Guard(nullptr), BitIndex(0) {}
807 llvm::GlobalVariable *Guard;
813 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
814 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
815 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
817 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
818 llvm::StructType *BaseClassDescriptorType;
819 llvm::StructType *ClassHierarchyDescriptorType;
820 llvm::StructType *CompleteObjectLocatorType;
822 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
824 llvm::StructType *CatchableTypeType;
825 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
826 llvm::StructType *ThrowInfoType;
832MicrosoftCXXABI::getRecordArgABI(
const CXXRecordDecl *RD)
const {
844 case llvm::Triple::thumb:
850 case llvm::Triple::x86: {
861 return RAA_DirectInMemory;
864 case llvm::Triple::x86_64:
865 case llvm::Triple::aarch64:
869 llvm_unreachable(
"invalid enum");
881 llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
886void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
887 llvm::Value *Args[] = {
888 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
889 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
901 VarDecl *CatchParam = S->getExceptionDecl();
902 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
903 llvm::CatchPadInst *CPI =
904 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
915 CPI->setArgOperand(2, var.getObjectAddress(CGF).getPointer());
923std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
934 return std::make_tuple(
Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
943 PolymorphicBase = BaseDecl;
947 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
950 GetVirtualBaseClassOffset(CGF,
Value, SrcDecl, PolymorphicBase);
951 llvm::Value *Ptr = CGF.
Builder.CreateInBoundsGEP(
959bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
963 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
967 llvm::Value *Argument) {
968 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
969 llvm::FunctionType *FTy =
970 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
971 llvm::Value *Args[] = {Argument};
977 llvm::CallBase *
Call =
979 Call->setDoesNotReturn();
980 CGF.
Builder.CreateUnreachable();
986 llvm::Type *StdTypeInfoPtrTy) {
987 std::tie(ThisPtr, std::ignore, std::ignore) =
988 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
990 return CGF.
Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
993bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
997 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1000llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
1005 llvm::Value *SrcRTTI =
1007 llvm::Value *DestRTTI =
1011 std::tie(This,
Offset, std::ignore) =
1012 performBaseAdjustment(CGF, This, SrcRecordTy);
1013 llvm::Value *ThisPtr =
This.getPointer();
1025 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1027 llvm::Value *Args[] = {
1028 ThisPtr,
Offset, SrcRTTI, DestRTTI,
1031 return CGF.
Builder.CreateBitCast(ThisPtr, DestLTy);
1038 std::tie(
Value, std::ignore, std::ignore) =
1039 performBaseAdjustment(CGF,
Value, SrcRecordTy);
1043 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1045 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1047 llvm::Value *Args[] = {
Value.getPointer()};
1055llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1061 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.
PtrDiffTy, VBPtrChars);
1066 llvm::Value *VBTableOffset =
1069 llvm::Value *VBPtrToNewBase =
1070 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1073 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1076bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1077 return isa<CXXConstructorDecl>(GD.
getDecl());
1081 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1085bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1106 if (Ctor->isUserProvided())
1113bool MicrosoftCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1123 if (isIndirectReturn) {
1144 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1145 assert(IsMostDerivedClass &&
1146 "ctor for a class with virtual bases must have an implicit parameter");
1147 llvm::Value *IsCompleteObject =
1148 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1150 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1151 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1152 CGF.
Builder.CreateCondBr(IsCompleteObject,
1153 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1158 EmitVBPtrStores(CGF, RD);
1162 return SkipVbaseCtorsBB;
1167 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1168 assert(IsMostDerivedClass &&
1169 "ctor for a class with virtual bases must have an implicit parameter");
1170 llvm::Value *IsCompleteObject =
1171 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1173 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1174 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1175 CGF.
Builder.CreateCondBr(IsCompleteObject,
1176 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1181 return SkipVbaseDtorsBB;
1184void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1204 unsigned AS = getThisAddress(CGF).getAddressSpace();
1205 llvm::Value *Int8This =
nullptr;
1208 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1209 auto I = VBaseMap.find(VBase);
1210 assert(I != VBaseMap.end());
1211 if (!I->second.hasVtorDisp())
1214 llvm::Value *VBaseOffset =
1215 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1216 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1219 llvm::Value *VtorDispValue = Builder.CreateSub(
1220 VBaseOffset, llvm::ConstantInt::get(CGM.
PtrDiffTy, ConstantVBaseOffset),
1222 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1225 Int8This = Builder.CreateBitCast(getThisValue(CGF),
1226 CGF.
Int8Ty->getPointerTo(AS));
1227 llvm::Value *VtorDispPtr =
1228 Builder.CreateInBoundsGEP(CGF.
Int8Ty, Int8This, VBaseOffset);
1230 VtorDispPtr = Builder.CreateConstGEP1_32(CGF.
Int8Ty, VtorDispPtr, -4);
1231 VtorDispPtr = Builder.CreateBitCast(
1232 VtorDispPtr, CGF.
Int32Ty->getPointerTo(AS),
"vtordisp.ptr");
1234 Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1245 return ExpectedCallingConv == ActualCallingConv;
1260 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1273 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1274 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1275 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1276 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1281 if (VBT->getVBaseWithVPtr())
1284 llvm::Value *GVPtr =
1287 "vbptr." + VBT->ObjectWithVPtr->getName());
1293MicrosoftCXXABI::buildStructorSignature(
GlobalDecl GD,
1295 AddedStructorArgCounts Added;
1297 if (isa<CXXDestructorDecl>(GD.
getDecl()) &&
1300 ArgTys.push_back(getContext().IntTy);
1303 auto *CD = dyn_cast<CXXConstructorDecl>(GD.
getDecl());
1312 if (
Class->getNumVBases()) {
1314 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1317 ArgTys.push_back(getContext().IntTy);
1325void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1331 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1338llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1343 return llvm::GlobalValue::InternalLinkage;
1355 if (Dtor->
hasAttr<DLLExportAttr>())
1356 return llvm::GlobalValue::WeakODRLinkage;
1357 if (Dtor->
hasAttr<DLLImportAttr>())
1358 return llvm::GlobalValue::AvailableExternallyLinkage;
1359 return llvm::GlobalValue::LinkOnceODRLinkage;
1364 return llvm::GlobalValue::LinkOnceODRLinkage;
1366 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1368 llvm_unreachable(
"invalid dtor type");
1385MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1407 if (isa<CXXDestructorDecl>(MD))
1412 getContext().getASTRecordLayout(MD->
getParent());
1419Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1425 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1464 llvm::Value *VBaseOffset =
1465 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1466 llvm::Value *VBasePtr = CGF.
Builder.CreateInBoundsGEP(
1467 Result.getElementType(), Result.getPointer(), VBaseOffset);
1472 if (!StaticOffset.
isZero()) {
1493 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1503 Params.insert(Params.begin() + 1, IsMostDerived);
1505 Params.push_back(IsMostDerived);
1506 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1512 Params.push_back(ShouldDelete);
1513 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1517void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1534 llvm::Value *
This = loadIncomingCXXThis(CGF);
1537 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1538 if (!Adjustment.
isZero()) {
1539 unsigned AS = cast<llvm::PointerType>(
This->getType())->getAddressSpace();
1540 llvm::Type *charPtrTy = CGF.
Int8Ty->getPointerTo(AS),
1541 *thisTy =
This->getType();
1542 This = CGF.
Builder.CreateBitCast(This, charPtrTy);
1546 This = CGF.
Builder.CreateBitCast(This, thisTy,
"this.adjusted");
1549 setCXXABIThisValue(CGF, This);
1559 if (HasThisReturn(CGF.
CurGD))
1561 else if (hasMostDerivedReturn(CGF.
CurGD))
1566 assert(getStructorImplicitParamDecl(CGF) &&
1567 "no implicit parameter for a constructor with virtual bases?");
1568 getStructorImplicitParamValue(CGF)
1575 assert(getStructorImplicitParamDecl(CGF) &&
1576 "no implicit parameter for a deleting destructor?");
1577 getStructorImplicitParamValue(CGF)
1580 "should_call_delete");
1586 bool ForVirtualBase,
bool Delegating) {
1591 return AddedStructorArgs{};
1595 llvm::Value *MostDerivedArg;
1597 MostDerivedArg = getStructorImplicitParamValue(CGF);
1602 return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1604 return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1607llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
1609 bool ForVirtualBase,
bool Delegating) {
1616 bool Delegating,
Address This,
1628 assert(
Type != CXXDtorType::Dtor_Deleting &&
1629 "The deleting destructor should only be called via a virtual call");
1634 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1635 if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1636 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1645 if (BaseDtorEndBB) {
1647 CGF.
Builder.CreateBr(BaseDtorEndBB);
1652void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1654 llvm::GlobalVariable *VTable) {
1662 llvm::GlobalObject::VCallVisibility TypeVis =
1664 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1665 VTable->setVCallVisibilityMetadata(TypeVis);
1672 getContext().getLangOpts().RTTIData
1673 ? getContext().toCharUnitsFromBits(
1674 getContext().getTargetInfo().getPointerWidth(LangAS::Default))
1693 getContext().getASTRecordLayout(DerivedRD);
1699 Offset = VBI->second.VBaseOffset;
1715 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1716 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1717 if (VTable->hasInitializer())
1723 llvm::Constant *RTTI =
nullptr;
1726 RTTI = getMSCompleteObjectLocator(RD, *Info);
1729 auto components = builder.beginStruct();
1731 VTable->hasLocalLinkage());
1732 components.finishAndSetAsInitializer(VTable);
1734 emitVTableTypeMetadata(*Info, RD, VTable);
1738bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1740 return Vptr.NearestVBase !=
nullptr;
1743llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1746 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(
Base, VTableClass);
1747 if (!VTableAddressPoint) {
1748 assert(
Base.getBase()->getNumVBases() &&
1749 !getContext().getASTRecordLayout(
Base.getBase()).hasOwnVFPtr());
1751 return VTableAddressPoint;
1757 llvm::raw_svector_ostream Out(Name);
1764 (void)getAddrOfVTable(VTableClass,
Base.getBaseOffset());
1765 VFTableIdTy
ID(VTableClass,
Base.getBaseOffset());
1766 return VFTablesMap[
ID];
1769llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1771 llvm::Constant *VFTable = getVTableAddressPoint(
Base, VTableClass);
1772 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1776llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1782 VFTableIdTy
ID(RD, VPtrOffset);
1783 VTablesMapTy::iterator I;
1785 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID,
nullptr));
1789 llvm::GlobalVariable *&VTable = I->second;
1794 if (DeferredVFTables.insert(RD).second) {
1802 llvm::StringSet<> ObservedMangledNames;
1803 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1806 if (!ObservedMangledNames.insert(Name.str()).second)
1807 llvm_unreachable(
"Already saw this mangling before?");
1812 const std::unique_ptr<VPtrInfo> *VFPtrI =
1813 llvm::find_if(VFPtrs, [&](
const std::unique_ptr<VPtrInfo> &VPI) {
1814 return VPI->FullOffsetInMDC == VPtrOffset;
1816 if (VFPtrI == VFPtrs.end()) {
1817 VFTablesMap[
ID] =
nullptr;
1820 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1832 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1833 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1835 bool VFTableComesFromAnotherTU =
1836 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1837 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1838 bool VTableAliasIsRequred =
1839 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1841 if (llvm::GlobalValue *VFTable =
1842 CGM.
getModule().getNamedGlobal(VFTableName)) {
1843 VFTablesMap[
ID] = VFTable;
1844 VTable = VTableAliasIsRequred
1845 ? cast<llvm::GlobalVariable>(
1846 cast<llvm::GlobalAlias>(VFTable)->getAliaseeObject())
1847 :
cast<
llvm::GlobalVariable>(VFTable);
1853 llvm::GlobalValue::LinkageTypes VTableLinkage =
1854 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1856 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1862 llvm::GlobalValue *VFTable;
1863 VTable =
new llvm::GlobalVariable(CGM.
getModule(), VTableType,
1864 true, VTableLinkage,
1865 nullptr, VTableName);
1866 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1868 llvm::Comdat *
C =
nullptr;
1869 if (!VFTableComesFromAnotherTU &&
1870 (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1871 (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1872 VTableAliasIsRequred)))
1873 C = CGM.
getModule().getOrInsertComdat(VFTableName.str());
1878 if (VTableAliasIsRequred) {
1879 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1880 llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1881 llvm::ConstantInt::get(CGM.
Int32Ty, 1)};
1884 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1885 VTable->getValueType(), VTable, GEPIndices);
1886 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1887 VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1889 C->setSelectionKind(llvm::Comdat::Largest);
1891 VFTable = llvm::GlobalAlias::create(CGM.
Int8PtrTy,
1893 VFTableName.str(), VTableGEP,
1895 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1904 VTable->setComdat(
C);
1906 if (RD->
hasAttr<DLLExportAttr>())
1907 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1909 VFTablesMap[
ID] = VFTable;
1920 Ty = Ty->getPointerTo();
1922 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1924 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1925 llvm::Value *VTable = CGF.
GetVTablePtr(VPtr, Ty->getPointerTo(),
1926 MethodDecl->getParent());
1933 auto getObjectWithVPtr = [&] {
1936 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1937 return Info->FullOffsetInMDC == ML.VFPtrOffset;
1946 getObjectWithVPtr(), VTable, Ty,
1954 llvm::Value *VFuncPtr =
1955 Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.
Index,
"vfn");
1956 VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.
getPointerAlign());
1963llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1965 Address This, DeleteOrMemberCallExpr E) {
1968 assert((CE !=
nullptr) ^ (D !=
nullptr));
1969 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
1981 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1987 ThisTy = CE->getObjectType();
1989 ThisTy = D->getDestroyedType();
1992 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1994 ImplicitParam, Context.
IntTy, CE);
1998const VBTableGlobals &
1999MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
2002 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
2004 std::tie(Entry, Added) =
2005 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
2006 VBTableGlobals &VBGlobals = Entry->second;
2011 VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2016 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2017 E = VBGlobals.VBTables->end();
2019 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,
Linkage));
2026MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2028 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
2029 "can't form pointers to ctors or virtual dtors");
2033 llvm::raw_svector_ostream Out(ThunkName);
2034 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2037 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
2038 return cast<llvm::Function>(GV);
2044 llvm::Function *ThunkFn =
2045 llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
2047 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2050 ? llvm::GlobalValue::LinkOnceODRLinkage
2051 : llvm::GlobalValue::InternalLinkage);
2053 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
2062 ThunkFn->addFnAttr(
"thunk");
2065 ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
2075 buildThisParam(CGF, FunctionArgs);
2082 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2086 llvm::Type *ThunkPtrTy = ThunkTy->getPointerTo();
2088 getThisAddress(CGF), ThunkPtrTy->getPointerTo(), MD->
getParent());
2090 llvm::Value *VFuncPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2091 ThunkPtrTy, VTable, ML.
Index,
"vfn");
2100void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2101 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2102 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2103 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2104 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2105 if (GV->isDeclaration())
2106 emitVBTableDefinition(*VBT, RD, GV);
2110llvm::GlobalVariable *
2112 llvm::GlobalVariable::LinkageTypes
Linkage) {
2114 llvm::raw_svector_ostream Out(OutName);
2115 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2116 StringRef Name = OutName.str();
2118 llvm::ArrayType *VBTableType =
2121 assert(!CGM.
getModule().getNamedGlobal(Name) &&
2122 "vbtable with this name already exists: mangling bug?");
2127 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2129 if (RD->
hasAttr<DLLImportAttr>())
2130 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2131 else if (RD->
hasAttr<DLLExportAttr>())
2132 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2134 if (!GV->hasExternalLinkage())
2135 emitVBTableDefinition(VBT, RD, GV);
2140void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2142 llvm::GlobalVariable *GV)
const {
2146 "should only emit vbtables for classes with vbtables");
2150 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2157 Offsets[0] = llvm::ConstantInt::get(CGM.
IntTy, -VBPtrOffset.
getQuantity());
2160 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2161 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2163 assert(!
Offset.isNegative());
2168 CompleteVBPtrOffset +=
2170 Offset -= CompleteVBPtrOffset;
2172 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2173 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2174 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.
IntTy,
Offset.getQuantity());
2177 assert(Offsets.size() ==
2178 cast<llvm::ArrayType>(GV->getValueType())->getNumElements());
2179 llvm::ArrayType *VBTableType =
2180 llvm::ArrayType::get(CGM.
IntTy, Offsets.size());
2181 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
2182 GV->setInitializer(Init);
2184 if (RD->
hasAttr<DLLImportAttr>())
2185 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2188llvm::Value *MicrosoftCXXABI::performThisAdjustment(
CodeGenFunction &CGF,
2192 return This.getPointer();
2198 V =
This.getPointer();
2208 CGF.
Builder.CreateNeg(VtorDisp));
2221 llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2225 V = CGF.
Builder.CreateInBoundsGEP(CGF.
Int8Ty, VBPtr, VBaseOffset);
2244 return Ret.getPointer();
2246 auto OrigTy =
Ret.getType();
2249 llvm::Value *
V =
Ret.getPointer();
2254 llvm::Value *VBaseOffset =
2257 V = CGF.
Builder.CreateInBoundsGEP(CGF.
Int8Ty, VBPtr, VBaseOffset);
2264 return CGF.
Builder.CreateBitCast(
V, OrigTy);
2274bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *
expr) {
2277 return expr->getAllocatedType().isDestructedType();
2288llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(
CodeGenFunction &CGF,
2298 llvm::Value *numElements,
2301 assert(requiresArrayCookie(
expr));
2304 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2320 llvm::FunctionCallee Dtor,
2321 llvm::Constant *Addr) {
2326 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2327 CGF.
IntTy, DtorStub->getType(),
false);
2330 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2331 if (llvm::Function *TLRegDtorFn =
2332 dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2333 TLRegDtorFn->setDoesNotThrow();
2339 llvm::FunctionCallee Dtor,
2340 llvm::Constant *Addr) {
2355void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2359 if (CXXThreadLocalInits.empty())
2364 ?
"/include:___dyn_tls_init@12"
2365 :
"/include:__dyn_tls_init");
2370 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2371 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2372 CGM.
getModule(), InitFunc->getType(),
true,
2373 llvm::GlobalVariable::InternalLinkage, InitFunc,
2374 Twine(InitFunc->getName(),
"$initializer$"));
2375 InitFuncPtr->setSection(
".CRT$XDU");
2382 std::vector<llvm::Function *> NonComdatInits;
2383 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2384 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2386 llvm::Function *F = CXXThreadLocalInits[I];
2389 if (llvm::Comdat *
C = GV->getComdat())
2390 AddToXDU(F)->setComdat(
C);
2392 NonComdatInits.push_back(F);
2395 if (!NonComdatInits.empty()) {
2396 llvm::FunctionType *FTy =
2397 llvm::FunctionType::get(CGM.
VoidTy,
false);
2413 llvm::Constant *TlsGuardConstant =
2415 llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant);
2417 TlsGuard->setThreadLocal(
true);
2425 llvm::FunctionType *FTy =
2426 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()), {},
2429 FTy,
"__dyn_tls_on_demand_init",
2431 llvm::AttributeList::FunctionIndex,
2432 llvm::Attribute::NoUnwind),
2437 llvm::BasicBlock *DynInitBB,
2438 llvm::BasicBlock *ContinueBB) {
2439 llvm::LoadInst *TlsGuardValue =
2441 llvm::Value *CmpResult =
2443 CGF.
Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2447 llvm::GlobalValue *TlsGuard,
2448 llvm::BasicBlock *ContinueBB) {
2450 llvm::Function *InitializerFunction =
2452 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(InitializerFunction);
2453 CallVal->setCallingConv(InitializerFunction->getCallingConv());
2455 CGF.
Builder.CreateBr(ContinueBB);
2459 llvm::BasicBlock *DynInitBB =
2461 llvm::BasicBlock *ContinueBB =
2467 CGF.
Builder.SetInsertPoint(DynInitBB);
2469 CGF.
Builder.SetInsertPoint(ContinueBB);
2487 unsigned AS = cast<llvm::PointerType>(
V->getType())->getAddressSpace();
2488 V = CGF.
Builder.CreateBitCast(
V, RealVarTy->getPointerTo(AS));
2491 Address Addr(
V, RealVarTy, Alignment);
2495 AlignmentSource::Decl)
2501 StringRef VarName(
"_Init_thread_epoch");
2503 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2505 auto *GV =
new llvm::GlobalVariable(
2507 false, llvm::GlobalVariable::ExternalLinkage,
2509 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2515 llvm::FunctionType *FTy =
2516 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2517 CGM.
IntTy->getPointerTo(),
false);
2519 FTy,
"_Init_thread_header",
2521 llvm::AttributeList::FunctionIndex,
2522 llvm::Attribute::NoUnwind),
2527 llvm::FunctionType *FTy =
2528 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2529 CGM.
IntTy->getPointerTo(),
false);
2531 FTy,
"_Init_thread_footer",
2533 llvm::AttributeList::FunctionIndex,
2534 llvm::Attribute::NoUnwind),
2539 llvm::FunctionType *FTy =
2540 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2541 CGM.
IntTy->getPointerTo(),
false);
2543 FTy,
"_Init_thread_abort",
2545 llvm::AttributeList::FunctionIndex,
2546 llvm::Attribute::NoUnwind),
2554 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2555 : Guard(Guard), GuardNum(GuardNum) {}
2561 llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2562 llvm::ConstantInt *Mask =
2563 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2564 Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2570 CallInitThreadAbort(
Address Guard) : Guard(Guard.getPointer()) {}
2580 llvm::GlobalVariable *GV,
2584 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2586 llvm::Function *F = CGF.
CurFn;
2587 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2588 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2594 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2598 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2601 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2602 llvm::ConstantInt *
Zero = llvm::ConstantInt::get(GuardTy, 0);
2606 GuardInfo *GI =
nullptr;
2607 if (ThreadlocalStatic)
2609 else if (!ThreadsafeStatic)
2612 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2617 GuardNum = getContext().getStaticLocalNumber(&D);
2618 assert(GuardNum > 0);
2620 }
else if (HasPerVariableGuard) {
2624 GuardNum = GI->BitIndex++;
2627 if (!HasPerVariableGuard && GuardNum >= 32) {
2629 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2638 llvm::raw_svector_ostream Out(GuardName);
2639 if (HasPerVariableGuard)
2640 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2643 getMangleContext().mangleStaticGuardVariable(&D, Out);
2649 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2650 GV->getLinkage(), Zero, GuardName.str());
2651 GuardVar->setVisibility(GV->getVisibility());
2652 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2653 GuardVar->setAlignment(GuardAlign.
getAsAlign());
2654 if (GuardVar->isWeakForLinker())
2655 GuardVar->setComdat(
2656 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2659 if (GI && !HasPerVariableGuard)
2660 GI->Guard = GuardVar;
2665 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2666 "static local from the same function had different linkage");
2668 if (!HasPerVariableGuard) {
2676 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2677 llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2678 llvm::Value *NeedsInit =
2679 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
2683 CodeGenFunction::GuardKind::VariableGuard, &D);
2688 Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2692 Builder.CreateBr(EndBlock);
2710 llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2711 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2712 llvm::LoadInst *InitThreadEpoch =
2714 llvm::Value *IsUninitialized =
2715 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2719 CodeGenFunction::GuardKind::VariableGuard, &D);
2725 GuardAddr.getPointer());
2726 llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2727 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2728 llvm::Value *ShouldDoInit =
2729 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2731 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2739 GuardAddr.getPointer());
2740 Builder.CreateBr(EndBlock);
2769 fields.push_back(CGM.
IntTy);
2773 fields.push_back(CGM.
IntTy);
2775 fields.push_back(CGM.
IntTy);
2777 fields.push_back(CGM.
IntTy);
2779 if (fields.size() == 1)
2784void MicrosoftCXXABI::
2787 assert(fields.empty());
2792 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2795 fields.push_back(getZeroInt());
2797 fields.push_back(getAllOnesInt());
2802 fields.push_back(getZeroInt());
2804 fields.push_back(getZeroInt());
2806 fields.push_back(getAllOnesInt());
2812 GetNullMemberPointerFields(MPT, fields);
2813 if (fields.size() == 1)
2815 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2816 assert(Res->getType() == ConvertMemberPointerType(MPT));
2821MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2822 bool IsMemberFunction,
2825 unsigned VBTableIndex) {
2834 fields.push_back(FirstField);
2837 fields.push_back(llvm::ConstantInt::get(
2843 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2849 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2851 return llvm::ConstantStruct::getAnon(fields);
2860llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl *RD,
2863 MSInheritanceModel::Virtual)
2864 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2865 llvm::Constant *FirstField =
2867 return EmitFullMemberPointer(FirstField,
false, RD,
2871llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2876 return EmitNullMemberPointer(DstTy);
2882 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2883 C = EmitMemberFunctionPointer(MD);
2890 const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2892 FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
2895 C = EmitMemberDataPointer(RD, FieldOffset);
2898 if (!MemberPointerPath.empty()) {
2899 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2911 if (DerivedMember) {
2919 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2920 Base->getCanonicalDecl())
2921 DerivedToBasePath.push_back(&BS);
2924 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2926 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2927 : CK_BaseToDerivedMemberPointer;
2928 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2929 DerivedToBasePath.end(),
C);
2935MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2936 assert(MD->
isInstance() &&
"Member function must not be static!");
2942 unsigned VBTableIndex = 0;
2943 llvm::Constant *FirstField;
2948 if (Types.isFuncTypeConvertible(FPT)) {
2950 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
2960 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2964 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2967 if (VBTableIndex == 0 &&
2969 MSInheritanceModel::Virtual)
2970 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2973 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2974 return EmitFullMemberPointer(FirstField,
true, RD,
2975 NonVirtualBaseAdjustment, VBTableIndex);
2990 llvm::ICmpInst::Predicate
Eq;
2991 llvm::Instruction::BinaryOps
And, Or;
2993 Eq = llvm::ICmpInst::ICMP_NE;
2994 And = llvm::Instruction::Or;
2995 Or = llvm::Instruction::And;
2997 Eq = llvm::ICmpInst::ICMP_EQ;
2998 And = llvm::Instruction::And;
2999 Or = llvm::Instruction::Or;
3008 return Builder.CreateICmp(
Eq, L, R);
3011 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
3012 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
3013 llvm::Value *Cmp0 = Builder.CreateICmp(
Eq, L0, R0,
"memptr.cmp.first");
3016 llvm::Value *Res =
nullptr;
3017 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
3018 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3019 llvm::Value *LF = Builder.CreateExtractValue(L, I);
3020 llvm::Value *RF = Builder.CreateExtractValue(R, I);
3021 llvm::Value *Cmp = Builder.CreateICmp(
Eq, LF, RF,
"memptr.cmp.rest");
3023 Res = Builder.CreateBinOp(And, Res, Cmp);
3031 llvm::Value *
Zero = llvm::Constant::getNullValue(L0->getType());
3032 llvm::Value *IsZero = Builder.CreateICmp(
Eq, L0, Zero,
"memptr.cmp.iszero");
3033 Res = Builder.CreateBinOp(Or, Res, IsZero);
3038 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
3043 llvm::Value *MemPtr,
3049 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
3051 GetNullMemberPointerFields(MPT, fields);
3052 assert(!fields.empty());
3053 llvm::Value *FirstField = MemPtr;
3054 if (MemPtr->getType()->isStructTy())
3055 FirstField = Builder.CreateExtractValue(MemPtr, 0);
3056 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
3064 for (
int I = 1, E = fields.size(); I < E; ++I) {
3065 llvm::Value *
Field = Builder.CreateExtractValue(MemPtr, I);
3066 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
3067 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
3073 llvm::Constant *Val) {
3076 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3077 Val->getAggregateElement(0
U) : Val;
3078 return FirstField->isNullValue();
3083 if (isZeroInitializable(MPT) && Val->isNullValue())
3089 GetNullMemberPointerFields(MPT, Fields);
3090 if (Fields.size() == 1) {
3091 assert(Val->getType()->isIntegerTy());
3092 return Val == Fields[0];
3096 for (I = 0, E = Fields.size(); I != E; ++I) {
3097 if (Val->getAggregateElement(I) != Fields[I])
3106 llvm::Value *VBPtrOffset,
3107 llvm::Value *VBTableOffset,
3108 llvm::Value **VBPtrOut) {
3111 This = Builder.CreateElementBitCast(This, CGM.
Int8Ty);
3112 llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3113 This.getElementType(),
This.getPointer(), VBPtrOffset,
"vbptr");
3114 if (VBPtrOut) *VBPtrOut = VBPtr;
3115 VBPtr = Builder.CreateBitCast(VBPtr,
3116 CGM.
Int32Ty->getPointerTo(0)->getPointerTo(
This.getAddressSpace()));
3119 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3120 VBPtrAlign =
This.getAlignment().alignmentAtOffset(
3126 llvm::Value *VBTable = Builder.CreateAlignedLoad(
3127 CGM.
Int32Ty->getPointerTo(0), VBPtr, VBPtrAlign,
"vbtable");
3130 llvm::Value *VBTableIndex = Builder.CreateAShr(
3131 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3135 llvm::Value *VBaseOffs =
3136 Builder.CreateInBoundsGEP(CGM.
Int32Ty, VBTable, VBTableIndex);
3137 VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.
Int32Ty->getPointerTo(0));
3138 return Builder.CreateAlignedLoad(CGM.
Int32Ty, VBaseOffs,
3144llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3146 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3149 llvm::BasicBlock *OriginalBB =
nullptr;
3150 llvm::BasicBlock *SkipAdjustBB =
nullptr;
3151 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3158 OriginalBB = Builder.GetInsertBlock();
3161 llvm::Value *IsVirtual =
3162 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3164 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3176 "member pointer representation requires a "
3177 "complete class type for %0 to perform this expression");
3180 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3183 llvm::Value *VBPtr =
nullptr;
3184 llvm::Value *VBaseOffs =
3185 GetVBaseOffsetFromVBPtr(CGF,
Base, VBPtrOffset, VBTableOffset, &VBPtr);
3186 llvm::Value *AdjustedBase =
3187 Builder.CreateInBoundsGEP(CGM.
Int8Ty, VBPtr, VBaseOffs);
3190 if (VBaseAdjustBB) {
3191 Builder.CreateBr(SkipAdjustBB);
3193 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3194 Phi->addIncoming(
Base.getPointer(), OriginalBB);
3195 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3198 return AdjustedBase;
3201llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3205 unsigned AS =
Base.getAddressSpace();
3214 llvm::Value *FieldOffset = MemPtr;
3215 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3216 llvm::Value *VBPtrOffset =
nullptr;
3217 if (MemPtr->getType()->isStructTy()) {
3220 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3222 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3224 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3228 if (VirtualBaseAdjustmentOffset) {
3229 Addr = AdjustVirtualBase(CGF, E, RD,
Base, VirtualBaseAdjustmentOffset,
3232 Addr =
Base.getPointer();
3236 Addr = Builder.CreateBitCast(Addr, CGF.
Int8Ty->getPointerTo(AS));
3239 Addr = Builder.CreateInBoundsGEP(CGF.
Int8Ty, Addr, FieldOffset,
3244 return Builder.CreateBitCast(Addr, PType);
3251 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3252 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3256 if (isa<llvm::Constant>(Src))
3257 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3267 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3268 if (IsReinterpret && IsFunc)
3273 if (IsReinterpret &&
3280 llvm::Value *
IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3281 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3285 if (IsReinterpret) {
3288 assert(Src->getType() == DstNull->getType());
3289 return Builder.CreateSelect(
IsNotNull, Src, DstNull);
3292 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3295 Builder.CreateCondBr(
IsNotNull, ConvertBB, ContinueBB);
3298 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3302 Builder.CreateBr(ContinueBB);
3306 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3307 Phi->addIncoming(DstNull, OriginalBB);
3308 Phi->addIncoming(Dst, ConvertBB);
3312llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3322 bool IsConstant = isa<llvm::Constant>(Src);
3325 llvm::Value *FirstField = Src;
3326 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3327 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3328 llvm::Value *VBPtrOffset = getZeroInt();
3332 FirstField = Builder.CreateExtractValue(Src, I++);
3334 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3336 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3338 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3341 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3347 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3354 llvm::Value *SrcVBIndexEqZero =
3355 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3356 if (SrcInheritance == MSInheritanceModel::Virtual) {
3357 if (int64_t SrcOffsetToFirstVBase =
3358 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3359 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3361 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3363 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3374 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3379 llvm::Value *NVDisp;
3380 if (IsDerivedToBase)
3381 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3383 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3385 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3389 llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3392 if (llvm::GlobalVariable *VDispMap =
3393 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3394 llvm::Value *VBIndex = Builder.CreateExactUDiv(
3395 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3397 llvm::Constant *Mapping = VDispMap->getInitializer();
3398 VirtualBaseAdjustmentOffset =
3399 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3401 llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3402 VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3403 CGM.
IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3409 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3416 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3418 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3420 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3426 if (DstInheritance == MSInheritanceModel::Virtual) {
3427 if (int64_t DstOffsetToFirstVBase =
3428 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3429 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3431 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3433 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3442 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3444 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3446 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3448 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3450 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3456MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3457 llvm::Constant *Src) {
3464 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3468llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3472 assert(CK == CK_DerivedToBaseMemberPointer ||
3473 CK == CK_BaseToDerivedMemberPointer ||
3474 CK == CK_ReinterpretMemberPointer);
3477 if (MemberPointerConstantIsNull(SrcTy, Src))
3478 return EmitNullMemberPointer(DstTy);
3483 if (CK == CK_ReinterpretMemberPointer)
3487 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3488 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3493CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3495 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3509 llvm::Value *FunctionPointer = MemPtr;
3510 llvm::Value *NonVirtualBaseAdjustment =
nullptr;
3511 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3512 llvm::Value *VBPtrOffset =
nullptr;
3513 if (MemPtr->getType()->isStructTy()) {
3516 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3518 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3520 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3522 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3525 if (VirtualBaseAdjustmentOffset) {
3526 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD, This,
3527 VirtualBaseAdjustmentOffset, VBPtrOffset);
3529 ThisPtrForCall =
This.getPointer();
3532 if (NonVirtualBaseAdjustment) {
3534 llvm::Value *Ptr = Builder.CreateBitCast(ThisPtrForCall, CGF.
Int8PtrTy);
3535 Ptr = Builder.CreateInBoundsGEP(CGF.
Int8Ty, Ptr, NonVirtualBaseAdjustment);
3536 ThisPtrForCall = Builder.CreateBitCast(Ptr, ThisPtrForCall->getType(),
3541 Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo());
3547 return new MicrosoftCXXABI(CGM);
3581 StringRef MangledName(
"??_7type_info@@6B@");
3582 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3586 llvm::GlobalVariable::ExternalLinkage,
3587 nullptr, MangledName);
3600 IsPrivateOnPath = 1 | 8,
3604 HasHierarchyDescriptor = 64
3610 MSRTTIClass *getFirstChild() {
return this + 1; }
3611 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3612 return Child + 1 + Child->NumBases;
3616 uint32_t Flags, NumBases, OffsetInVBase;
3620uint32_t MSRTTIClass::initialize(
const MSRTTIClass *
Parent,
3622 Flags = HasHierarchyDescriptor;
3624 VirtualRoot =
nullptr;
3628 Flags |= IsPrivate | IsPrivateOnPath;
3634 if (
Parent->Flags & IsPrivateOnPath)
3635 Flags |= IsPrivateOnPath;
3636 VirtualRoot =
Parent->VirtualRoot;
3637 OffsetInVBase =
Parent->OffsetInVBase + RD->getASTContext()
3638 .getASTRecordLayout(
Parent->RD).getBaseClassOffset(RD).getQuantity();
3642 MSRTTIClass *Child = getFirstChild();
3644 NumBases += Child->initialize(
this, &
Base) + 1;
3645 Child = getNextChild(Child);
3650static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3655 return llvm::GlobalValue::InternalLinkage;
3661 return llvm::GlobalValue::LinkOnceODRLinkage;
3663 llvm_unreachable(
"Invalid linkage!");
3669struct MSRTTIBuilder {
3671 HasBranchingHierarchy = 1,
3672 HasVirtualBranchingHierarchy = 2,
3673 HasAmbiguousBases = 4
3676 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3677 : CGM(ABI.CGM), Context(CGM.getContext()),
3678 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3679 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3682 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3683 llvm::GlobalVariable *
3685 llvm::GlobalVariable *getClassHierarchyDescriptor();
3686 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3690 llvm::LLVMContext &VMContext;
3693 llvm::GlobalVariable::LinkageTypes
Linkage;
3694 MicrosoftCXXABI &ABI;
3703 Classes.push_back(MSRTTIClass(RD));
3714 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3715 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3716 !VirtualBases.insert(Class->RD).second) {
3717 Class = MSRTTIClass::getNextChild(Class);
3720 if (!UniqueBases.insert(Class->RD).second)
3721 AmbiguousBases.insert(Class->RD);
3724 if (AmbiguousBases.empty())
3726 for (MSRTTIClass &Class : Classes)
3727 if (AmbiguousBases.count(Class.RD))
3728 Class.Flags |= MSRTTIClass::IsAmbiguous;
3731llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3734 llvm::raw_svector_ostream Out(MangledName);
3735 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3739 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3745 Classes.front().initialize(
nullptr,
nullptr);
3748 for (
auto Class : Classes) {
3749 if (
Class.RD->getNumBases() > 1)
3750 Flags |= HasBranchingHierarchy;
3753 if (
Class.Flags & MSRTTIClass::IsAmbiguous)
3754 Flags |= HasAmbiguousBases;
3756 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3757 Flags |= HasVirtualBranchingHierarchy;
3760 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
IntTy, 0),
3761 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3764 auto Type = ABI.getClassHierarchyDescriptorType();
3768 if (CHD->isWeakForLinker())
3769 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3771 auto *Bases = getBaseClassArray(Classes);
3774 llvm::Constant *Fields[] = {
3775 llvm::ConstantInt::get(CGM.
IntTy, 0),
3776 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3777 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3778 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3779 Bases->getValueType(), Bases,
3782 CHD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3786llvm::GlobalVariable *
3790 llvm::raw_svector_ostream Out(MangledName);
3791 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3799 llvm::Type *PtrType = ABI.getImageRelativeType(
3800 ABI.getBaseClassDescriptorType()->getPointerTo());
3801 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3803 new llvm::GlobalVariable(
Module, ArrType,
3805 nullptr, MangledName);
3806 if (BCA->isWeakForLinker())
3807 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3811 for (MSRTTIClass &Class : Classes)
3812 BaseClassArrayData.push_back(
3813 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3814 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3815 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3819llvm::GlobalVariable *
3820MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3823 uint32_t OffsetInVBTable = 0;
3824 int32_t VBPtrOffset = -1;
3825 if (
Class.VirtualRoot) {
3833 llvm::raw_svector_ostream Out(MangledName);
3834 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3835 Class.RD,
Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3840 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3844 auto Type = ABI.getBaseClassDescriptorType();
3847 nullptr, MangledName);
3848 if (BCD->isWeakForLinker())
3849 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3852 llvm::Constant *Fields[] = {
3853 ABI.getImageRelativeConstant(
3855 llvm::ConstantInt::get(CGM.
IntTy,
Class.NumBases),
3856 llvm::ConstantInt::get(CGM.
IntTy,
Class.OffsetInVBase),
3857 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3858 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3859 llvm::ConstantInt::get(CGM.
IntTy,
Class.Flags),
3860 ABI.getImageRelativeConstant(
3861 MSRTTIBuilder(ABI,
Class.RD).getClassHierarchyDescriptor()),
3863 BCD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3867llvm::GlobalVariable *
3868MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3871 llvm::raw_svector_ostream Out(MangledName);
3872 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3876 if (
auto COL =
Module.getNamedGlobal(MangledName))
3881 int VFPtrOffset = 0;
3887 ->second.hasVtorDisp())
3891 llvm::StructType *
Type = ABI.getCompleteObjectLocatorType();
3893 nullptr, MangledName);
3896 llvm::Constant *Fields[] = {
3897 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3898 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3899 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3900 ABI.getImageRelativeConstant(
3902 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3903 ABI.getImageRelativeConstant(COL),
3906 if (!ABI.isImageRelative())
3907 FieldsRef = FieldsRef.drop_back();
3908 COL->setInitializer(llvm::ConstantStruct::get(
Type, FieldsRef));
3909 if (COL->isWeakForLinker())
3910 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3915 bool &IsConst,
bool &IsVolatile,
3916 bool &IsUnaligned) {
3926 IsUnaligned =
false;
3928 if (!PointeeType.
isNull()) {
3949MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3954 bool IsConst, IsVolatile, IsUnaligned;
3978llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3981 llvm::raw_svector_ostream Out(MangledName);
3982 getMangleContext().mangleCXXRTTI(
Type, Out);
3986 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3987 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3995 llvm::raw_svector_ostream Out(TypeInfoString);
3996 getMangleContext().mangleCXXRTTIName(
Type, Out);
4000 llvm::Constant *Fields[] = {
4002 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
4003 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
4004 llvm::StructType *TypeDescriptorType =
4005 getTypeDescriptorType(TypeInfoString);
4006 auto *Var =
new llvm::GlobalVariable(
4007 CGM.
getModule(), TypeDescriptorType,
false,
4008 getLinkageForRTTI(
Type),
4009 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
4011 if (Var->isWeakForLinker())
4012 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
4013 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
4017llvm::GlobalVariable *
4018MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
4020 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
4023void MicrosoftCXXABI::emitCXXStructor(
GlobalDecl GD) {
4024 if (
auto *ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
4026 llvm::Function *Fn =
4032 auto *dtor = cast<CXXDestructorDecl>(GD.
getDecl());
4038 dtor->getParent()->getNumVBases() == 0)
4049 if (Fn->isWeakForLinker())
4050 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
4060 llvm::raw_svector_ostream Out(ThunkName);
4061 getMangleContext().mangleName(
GlobalDecl(CD, CT), Out);
4064 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
4065 return cast<llvm::Function>(GV);
4071 QualType RecordTy = getContext().getRecordType(RD);
4072 llvm::Function *ThunkFn = llvm::Function::Create(
4073 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
4074 ThunkFn->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
4076 if (ThunkFn->isWeakForLinker())
4077 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
4088 buildThisParam(CGF, FunctionArgs);
4094 &getContext().Idents.get(
"src"),
4095 getContext().getLValueReferenceType(RecordTy,
4099 FunctionArgs.push_back(&SrcParam);
4106 &getContext().Idents.get(
"is_most_derived"),
4110 FunctionArgs.push_back(&IsMostDerived);
4118 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4119 llvm::Value *
This = getThisValue(CGF);
4121 llvm::Value *SrcVal =
4138 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
4139 ArgVec.push_back(PD->getDefaultArg());
4142 CodeGenFunction::RunCleanupsScope Cleanups(CGF);
4148 AddedStructorArgCounts ExtraArgs =
4153 llvm::Constant *CalleePtr =
4158 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4161 Cleanups.ForceCleanup();
4170llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
4172 int32_t VBPtrOffset,
4184 uint32_t
Size = getContext().getTypeSizeInChars(T).getQuantity();
4187 llvm::raw_svector_ostream Out(MangledName);
4188 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
4189 VBPtrOffset, VBIndex, Out);
4191 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4192 return getImageRelativeConstant(GV);
4196 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
4200 llvm::Constant *CopyCtor;
4207 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
4209 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4211 CopyCtor = getImageRelativeConstant(CopyCtor);
4213 bool IsScalar = !RD;
4214 bool HasVirtualBases =
false;
4215 bool IsStdBadAlloc =
false;
4230 if (HasVirtualBases)
4235 llvm::Constant *Fields[] = {
4236 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4238 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4239 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4240 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4241 llvm::ConstantInt::get(CGM.
IntTy, Size),
4244 llvm::StructType *CTType = getCatchableTypeType();
4245 auto *GV =
new llvm::GlobalVariable(
4246 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
4247 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4248 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4249 GV->setSection(
".xdata");
4250 if (GV->isWeakForLinker())
4251 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4252 return getImageRelativeConstant(GV);
4255llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4259 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
4284 if (MostDerivedClass) {
4291 Classes.front().initialize(
nullptr,
nullptr);
4293 for (
const MSRTTIClass &Class : Classes) {
4296 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4299 uint32_t OffsetInVBTable = 0;
4300 int32_t VBPtrOffset = -1;
4301 if (
Class.VirtualRoot) {
4312 CatchableTypes.insert(getCatchableType(RTTITy,
Class.OffsetInVBase,
4313 VBPtrOffset, OffsetInVBTable));
4321 CatchableTypes.insert(getCatchableType(T));
4334 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4345 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4347 uint32_t NumEntries = CatchableTypes.size();
4348 llvm::Type *CTType =
4349 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4350 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4351 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4352 llvm::Constant *Fields[] = {
4353 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4354 llvm::ConstantArray::get(
4356 CatchableTypes.end()))
4360 llvm::raw_svector_ostream Out(MangledName);
4361 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4363 CTA =
new llvm::GlobalVariable(
4364 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4365 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4366 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4367 CTA->setSection(
".xdata");
4368 if (CTA->isWeakForLinker())
4369 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4373llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4374 bool IsConst, IsVolatile, IsUnaligned;
4379 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4384 uint32_t NumEntries =
4385 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0
U))
4386 ->getLimitedValue();
4390 llvm::raw_svector_ostream Out(MangledName);
4391 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, IsUnaligned,
4397 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4413 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4416 if (!DtorD->isTrivial())
4417 CleanupFn = llvm::ConstantExpr::getBitCast(
4421 llvm::Constant *ForwardCompat =
4422 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4423 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4424 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4425 llvm::StructType *TIType = getThrowInfoType();
4426 llvm::Constant *Fields[] = {
4427 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4428 getImageRelativeConstant(CleanupFn),
4430 PointerToCatchableTypes
4432 auto *GV =
new llvm::GlobalVariable(
4433 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4434 llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4435 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4436 GV->setSection(
".xdata");
4437 if (GV->isWeakForLinker())
4438 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4444 assert(SubExpr &&
"SubExpr cannot be null");
4454 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4457 llvm::Value *Args[] = {
4464std::pair<llvm::Value *, const CXXRecordDecl *>
4467 std::tie(This, std::ignore, RD) =
4472bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4504 if (
const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4505 if (!isPermittedToBeHomogeneousAggregate(FRD))
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *DynInitBB, llvm::BasicBlock *ContinueBB)
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM)
static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM)
static llvm::GlobalValue * getTlsGuardVar(CodeGenModule &CGM)
static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile, bool &IsUnaligned)
static llvm::CallBase * emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
static bool isTrivialForMSVC(const CXXRecordDecl *RD)
static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM)
static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *ContinueBB)
static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)
Find ambiguity among base classes.
static void emitDynamicTlsInitialization(CodeGenFunction &CGF)
static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)
Recursively serializes a class hierarchy in pre-order depth first order.
static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM)
static bool isDeletingDtor(GlobalDecl GD)
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM)
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo &VFPtr, SmallString< 256 > &Name)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
const NestedNameSpecifier * Specifier
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
bool isMemberPointerToDerivedMember() const
const ValueDecl * getMemberPointerDecl() const
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
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 ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod, bool IsBuiltin=false) const
Retrieves the default calling convention for the current target.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const LangOptions & getLangOpts() const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getExceptionObjectType(QualType T) const
const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
Represents a base class of a C++ class.
CXXCatchStmt - This represents a C++ catch block.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
Represents a call to a member function that may be written either with member call syntax (e....
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++ struct/union/class.
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class....
bool hasPrivateFields() const
bool hasProtectedFields() const
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
CXXRecordDecl * getMostRecentNonInjectedDecl()
base_class_range vbases()
MSInheritanceModel getMSInheritanceModel() const
Returns the inheritance model used for this record.
bool nullFieldOffsetIsZero() const
In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...
bool hasDefinition() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
bool hasNonTrivialDefaultConstructor() const
Determine whether this class has a non-trivial default constructor (C++11 [class.ctor]p5).
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is virtually derived from the class Base.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
const CXXBaseSpecifier *const * path_const_iterator
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
void setSRetAfterThis(bool AfterThis)
llvm::Value * getPointer() const
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
Address CreateConstInBoundsGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name="")
Address 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...
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateGEP(Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual llvm::Value * EmitDynamicCastToVoid(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy)=0
llvm::Value *& getStructorImplicitParamValue(CodeGenFunction &CGF)
virtual void EmitCXXConstructors(const CXXConstructorDecl *D)=0
Emit constructor variants required by this ABI.
virtual llvm::Constant * getAddrOfRTTIDescriptor(QualType Ty)=0
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
virtual llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const ReturnAdjustment &RA)=0
virtual bool HasThisReturn(GlobalDecl GD) const
Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...
virtual llvm::Value * getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, const CXXRecordDecl *NearestVBase)=0
Get the address point of the vtable for the given base subobject while building a constructor or a de...
virtual void emitBeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *C)=0
virtual std::vector< CharUnits > getVBPtrOffsets(const CXXRecordDecl *RD)
Gets the offsets of all the virtual base pointers in a given class.
virtual void emitRethrow(CodeGenFunction &CGF, bool isNoReturn)=0
virtual void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, const CXXRecordDecl *RD)
Emit the code to initialize hidden members required to handle virtual inheritance,...
virtual bool isMemberPointerConvertible(const MemberPointerType *MPT) const
Return whether or not a member pointers type is convertible to an IR type.
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
virtual bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr)=0
Checks if ABI requires extra virtual offset for vtable field.
virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)=0
Emits the guarded initializer and destructor setup for the given variable, given that it couldn't be ...
virtual void EmitCXXDestructors(const CXXDestructorDecl *D)=0
Emit destructor variants required by this ABI.
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
virtual bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor, CXXDtorType DT) const =0
Returns true if the given destructor type should be emitted as a linkonce delegating thunk,...
virtual CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD)
Get the ABI-specific "this" parameter adjustment to apply in the prologue of a virtual function.
virtual void setCXXDestructorDLLStorage(llvm::GlobalValue *GV, const CXXDestructorDecl *Dtor, CXXDtorType DT) const
RecordArgABI
Specify how one should pass an argument of a record type.
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
virtual llvm::Constant * EmitNullMemberPointer(const MemberPointerType *MPT)
Create a null member pointer of the given type.
virtual StringRef GetPureVirtualCallName()=0
Gets the pure virtual member call function.
virtual CharUnits getArrayCookieSizeImpl(QualType elementType)
Returns the extra size required in order to store the array cookie for the given type.
virtual bool isSRetParameterAfterThis() const
Returns true if the implicit 'sret' parameter comes after the implicit 'this' parameter of C++ instan...
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const =0
Determine whether it's possible to emit a vtable for RD, even though we do not know that the vtable h...
virtual StringRef GetDeletedVirtualCallName()=0
Gets the deleted virtual member call name.
virtual llvm::Value * EmitMemberPointerIsNotNull(CodeGenFunction &CGF, llvm::Value *MemPtr, const MemberPointerType *MPT)
Determine if a member pointer is non-null. Returns an i1.
virtual const CXXRecordDecl * getThisArgumentTypeForMethod(const CXXMethodDecl *MD)
Get the type of the implicit "this" parameter used by a method.
virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType)=0
Emit a reference to a non-local thread_local variable (including triggering the initialization of all...
bool isEmittedWithConstantInitializer(const VarDecl *VD, bool InspectInitForWeakDef=false) const
Determine whether we will definitely emit this variable with a constant initializer,...
virtual llvm::Value * EmitMemberPointerComparison(CodeGenFunction &CGF, llvm::Value *L, llvm::Value *R, const MemberPointerType *MPT, bool Inequality)
Emit a comparison between two member pointers. Returns an i1.
virtual llvm::Constant * EmitMemberPointer(const APValue &MP, QualType MPT)
Create a member pointer for the given member pointer constant.
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
virtual llvm::Value * readArrayCookieImpl(CodeGenFunction &IGF, Address ptr, CharUnits cookieSize)
Reads the array cookie for an allocation which is known to have one.
virtual llvm::Value * EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, const MemberPointerType *MPT)
Calculate an l-value from an object and a data member pointer.
virtual llvm::Value * getCXXDestructorImplicitParam(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating)=0
Get the implicit (second) parameter that comes after the "this" pointer, or nullptr if there is isn't...
virtual bool requiresArrayCookie(const CXXDeleteExpr *E, QualType eltType)
virtual CatchTypeInfo getCatchAllTypeInfo()
virtual std::pair< llvm::Value *, const CXXRecordDecl * > LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD)=0
Load a vtable from This, an object of polymorphic type RD, or from one of its virtual bases if it doe...
virtual llvm::Constant * getVTableAddressPointForConstExpr(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject while building a constexpr.
virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD, bool ReturnAdjustment)=0
virtual Address adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD, Address This, bool VirtualCall)
Perform ABI-specific "this" argument adjustment required prior to a call of a virtual function.
virtual llvm::Value * EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E)=0
Emit the ABI-specific virtual destructor call.
bool mayNeedDestruction(const VarDecl *VD) const
virtual llvm::BasicBlock * EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD)
virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)=0
Checks if ABI requires to initialize vptrs for given dynamic class.
virtual llvm::Value * EmitDynamicCastCall(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd)=0
virtual void emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E)=0
virtual llvm::Value * GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl)=0
virtual bool isThisCompleteObject(GlobalDecl GD) const =0
Determine whether there's something special about the rules of the ABI tell us that 'this' is a compl...
virtual CGCallee getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD, Address This, llvm::Type *Ty, SourceLocation Loc)=0
Build a virtual function pointer in the ABI-specific way.
virtual bool classifyReturnType(CGFunctionInfo &FI) const =0
If the C++ ABI requires the given type be returned in a particular way, this method sets RetAI and re...
virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0
virtual CatchTypeInfo getAddrOfCXXCatchHandlerType(QualType Ty, QualType CatchHandlerType)=0
virtual void EmitThreadLocalInitFuncs(CodeGenModule &CGM, ArrayRef< const VarDecl * > CXXThreadLocals, ArrayRef< llvm::Function * > CXXThreadLocalInits, ArrayRef< const VarDecl * > CXXThreadLocalInitVars)=0
Emits ABI-required functions necessary to initialize thread_local variables in this translation unit.
virtual bool usesThreadWrapperFunction(const VarDecl *VD) const =0
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)=0
Emit the destructor call.
virtual llvm::GlobalVariable * getAddrOfVTable(const CXXRecordDecl *RD, CharUnits VPtrOffset)=0
Get the address of the vtable for the given record decl which should be used for the vptr at the give...
virtual bool EmitBadCastCall(CodeGenFunction &CGF)=0
virtual void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD, CallArgList &CallArgs)
virtual llvm::Constant * EmitMemberDataPointer(const MemberPointerType *MPT, CharUnits offset)
Create a member pointer for the given field.
virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0
virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD)=0
Emit any tables needed to implement virtual inheritance.
virtual void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD)=0
Emits the VTable definitions required for the given record type.
virtual CGCallee EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, Address This, llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr, const MemberPointerType *MPT)
Load a member function from an object and a member function pointer.
virtual bool isPermittedToBeHomogeneousAggregate(const CXXRecordDecl *RD) const
Returns true if the ABI permits the argument to be a homogeneous aggregate.
virtual void emitCXXStructor(GlobalDecl GD)=0
Emit a single constructor/destructor with the given type from a C++ constructor Decl.
virtual bool exportThunk()=0
virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0
virtual bool isZeroInitializable(const MemberPointerType *MPT)
Return true if the given member pointer can be zero-initialized (in the C++ sense) with an LLVM zeroi...
virtual bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy)=0
virtual llvm::Value * EmitMemberPointerConversion(CodeGenFunction &CGF, const CastExpr *E, llvm::Value *Src)
Perform a derived-to-base, base-to-derived, or bitcast member pointer conversion.
virtual llvm::Constant * EmitMemberFunctionPointer(const CXXMethodDecl *MD)
Create a member pointer for the given method.
virtual llvm::GlobalVariable * getThrowInfo(QualType T)
virtual llvm::GlobalValue::LinkageTypes getCXXDestructorLinkage(GVALinkage Linkage, const CXXDestructorDecl *Dtor, CXXDtorType DT) const
virtual Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType)
Initialize the array cookie for the given allocation.
ASTContext & getContext() const
virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, QualType SrcRecordTy)=0
virtual AddedStructorArgCounts buildStructorSignature(GlobalDecl GD, SmallVectorImpl< CanQualType > &ArgTys)=0
Build the signature of the given constructor or destructor variant by adding any required parameters.
virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const ThisAdjustment &TA)=0
MangleContext & getMangleContext()
Gets the mangle context.
virtual AddedStructorArgs getImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating)=0
All available information about a concrete callee.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool isInstanceMethod() const
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
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...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::Type * ConvertTypeForMem(QualType T)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
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.
llvm::Function * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() 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...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Type * ConvertType(QualType T)
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
CodeGenTypes & getTypes() const
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
LValue EmitLoadOfReferenceLValue(LValue RefLVal)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
llvm::Instruction * CurrentFuncletPad
llvm::LLVMContext & getLLVMContext()
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.
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object)
Add a destructor and object to add to the C++ global destructor function.
void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, const CXXRecordDecl *RD)
Create and attach type metadata for the given vtable.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::GlobalObject::VCallVisibility GetVCallVisibilityLevel(const CXXRecordDecl *RD, llvm::DenseSet< const CXXRecordDecl * > &Visited)
Returns the vcall visibility of the given type.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenVTables & getVTables()
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
DiagnosticsEngine & getDiags() const
llvm::Constant * getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the constructor/destructor of the given type.
llvm::GlobalValue::LinkageTypes getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage, bool IsConstantVariable)
Returns LLVM linkage for a declarator.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void EmitGlobal(GlobalDecl D)
Emit code for a single global function or var decl.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metad