;
35using namespaceCodeGen;
40structVBTableGlobals {
45classMicrosoftCXXABI :
public CGCXXABI{
48:
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
49ClassHierarchyDescriptorType(nullptr),
50CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
51ThrowInfoType(nullptr) {
54 "visibility export mapping option unimplemented in this ABI");
69 if(isa<CXXDestructorDecl>(GD.
getDecl())) {
78 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
80llvm_unreachable(
"bad dtor kind");
89assert(Args.size() >= 2 &&
90 "expected the arglist to have at least two args!");
100std::vector<CharUnits> VBPtrOffsets;
104 constVBTableGlobals &VBGlobals = enumerateVBTables(RD);
105 for(
conststd::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
110 if(VBT->getVBaseWithVPtr())
112VBPtrOffsets.push_back(Offs);
114llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
130llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl*RD,
151llvm::Type *StdTypeInfoPtrTy)
override;
163llvm::BasicBlock *CastSuccess,
164llvm::BasicBlock *CastFail)
override{
165llvm_unreachable(
"unsupported");
171llvm::BasicBlock *CastEnd)
override;
230AddedStructorArgCounts
244llvm::GlobalValue::LinkageTypes
251 auto*MD = cast<CXXMethodDecl>(GD.
getDecl());
253 if(MD->isVirtual()) {
255 if(
const auto*DD = dyn_cast<CXXDestructorDecl>(MD)) {
259 returnMD->getParent();
277 returnMD->getParent();
283 boolVirtualCall)
override;
308llvm::GlobalVariable *VTable);
314CodeGenFunction::VPtr Vptr)
override;
319 return!VTableClass->
hasAttr<MSNoVTableAttr>();
340DeleteOrMemberCallExpr
E,
341llvm::CallBase **CallOrInvoke)
override;
346 "Only deleting destructor thunks are available in this ABI");
353llvm::GlobalVariable *
355llvm::GlobalVariable::LinkageTypes
Linkage);
357llvm::GlobalVariable *
361llvm::raw_svector_ostream Out(OutName);
363StringRef MangledName = OutName.str();
365 if(
auto*VDispMap = CGM.
getModule().getNamedGlobal(MangledName))
371llvm::UndefValue::get(CGM.
IntTy));
372Map[0] = llvm::ConstantInt::get(CGM.
IntTy, 0);
373 boolAnyDifferent =
false;
374 for(
const auto&I : SrcRD->
vbases()) {
375 const CXXRecordDecl*VBase = I.getType()->getAsCXXRecordDecl();
381Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.
IntTy, DstVBIndex * 4);
382AnyDifferent |= SrcVBIndex != DstVBIndex;
388llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.
IntTy, Map.size());
389llvm::Constant *
Init= llvm::ConstantArray::get(VDispMapTy, Map);
390llvm::GlobalValue::LinkageTypes
Linkage=
392? llvm::GlobalValue::LinkOnceODRLinkage
393: llvm::GlobalValue::InternalLinkage;
394 auto*VDispMap =
newllvm::GlobalVariable(
401llvm::GlobalVariable *GV)
const;
409Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
411Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
413Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
433LangOptions::MSVC2019_5) &&
441llvm::GlobalVariable *DeclPtr,
442 boolPerformInit)
override;
444llvm::FunctionCallee Dtor,
445llvm::Constant *Addr)
override;
476llvm::Value *NumElements,
483 friend structMSRTTIBuilder;
485 boolisImageRelative()
const{
490llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
492TDTypeName += llvm::utostr(TypeInfoString.size());
493llvm::StructType *&TypeDescriptorType =
494TypeDescriptorTypeMap[TypeInfoString.size()];
495 if(TypeDescriptorType)
496 returnTypeDescriptorType;
497llvm::Type *FieldTypes[] = {
500llvm::ArrayType::get(CGM.
Int8Ty, TypeInfoString.size() + 1)};
502llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, TDTypeName);
503 returnTypeDescriptorType;
506llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
507 if(!isImageRelative())
512llvm::StructType *getBaseClassDescriptorType() {
513 if(BaseClassDescriptorType)
514 returnBaseClassDescriptorType;
515llvm::Type *FieldTypes[] = {
524BaseClassDescriptorType = llvm::StructType::create(
526 returnBaseClassDescriptorType;
529llvm::StructType *getClassHierarchyDescriptorType() {
530 if(ClassHierarchyDescriptorType)
531 returnClassHierarchyDescriptorType;
535ClassHierarchyDescriptorType =
536llvm::StructType::create(FieldTypes,
"rtti.ClassHierarchyDescriptor");
537 returnClassHierarchyDescriptorType;
540llvm::StructType *getCompleteObjectLocatorType() {
541 if(CompleteObjectLocatorType)
542 returnCompleteObjectLocatorType;
543llvm::Type *FieldTypes[] = {
549getImageRelativeType(CGM.
VoidTy),
552 if(!isImageRelative())
553FieldTypesRef = FieldTypesRef.drop_back();
554CompleteObjectLocatorType =
555llvm::StructType::create(FieldTypesRef,
"rtti.CompleteObjectLocator");
556 returnCompleteObjectLocatorType;
559llvm::GlobalVariable *getImageBase() {
560StringRef Name =
"__ImageBase";
561 if(llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name))
566llvm::GlobalValue::ExternalLinkage,
572llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
573 if(!isImageRelative())
576 if(PtrVal->isNullValue())
577 returnllvm::Constant::getNullValue(CGM.
IntTy);
579llvm::Constant *ImageBaseAsInt =
580llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.
IntPtrTy);
581llvm::Constant *PtrValAsInt =
582llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.
IntPtrTy);
583llvm::Constant *Diff =
584llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
586 returnllvm::ConstantExpr::getTrunc(Diff, CGM.
IntTy);
594llvm::Constant *getZeroInt() {
595 returnllvm::ConstantInt::get(CGM.
IntTy, 0);
598llvm::Constant *getAllOnesInt() {
599 returnllvm::Constant::getAllOnesValue(CGM.
IntTy);
613llvm::Value *VBPtrOffset,
614llvm::Value *VBTableOffset,
615llvm::Value **VBPtr =
nullptr);
620int32_t VBTableOffset,
621llvm::Value **VBPtr =
nullptr) {
622assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
623llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
624*VBTOffset = llvm::ConstantInt::get(CGM.
IntTy, VBTableOffset);
625 returnGetVBaseOffsetFromVBPtr(CGF,
Base, VBPOffset, VBTOffset, VBPtr);
628std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
636llvm::Value *VirtualBaseAdjustmentOffset,
637llvm::Value *VBPtrOffset
);
641llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
642 boolIsMemberFunction,
645 unsignedVBTableIndex);
654 constVBTableGlobals &enumerateVBTables(
const CXXRecordDecl*RD);
657llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl*MD,
670 returnRD->
hasAttr<MSInheritanceAttr>();
684 boolInequality)
override;
695llvm::Value *EmitNonNullMemberPointerConversion(
703llvm::Value *Src)
override;
706llvm::Constant *Src)
override;
715 AddressThis, llvm::Value *&ThisPtrForCall,
721llvm::StructType *getCatchableTypeType() {
722 if(CatchableTypeType)
723 returnCatchableTypeType;
724llvm::Type *FieldTypes[] = {
733CatchableTypeType = llvm::StructType::create(
735 returnCatchableTypeType;
738llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
739llvm::StructType *&CatchableTypeArrayType =
740CatchableTypeArrayTypeMap[NumEntries];
741 if(CatchableTypeArrayType)
742 returnCatchableTypeArrayType;
745CTATypeName += llvm::utostr(NumEntries);
746llvm::Type *CTType = getImageRelativeType(CGM.
UnqualPtrTy);
747llvm::Type *FieldTypes[] = {
749llvm::ArrayType::get(CTType, NumEntries)
751CatchableTypeArrayType =
752llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes, CTATypeName);
753 returnCatchableTypeArrayType;
756llvm::StructType *getThrowInfoType() {
758 returnThrowInfoType;
759llvm::Type *FieldTypes[] = {
765ThrowInfoType = llvm::StructType::create(CGM.
getLLVMContext(), FieldTypes,
767 returnThrowInfoType;
774llvm::FunctionType *FTy =
775llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
776llvm::FunctionCallee Throw =
780 if(
auto*Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
781 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
789llvm::Constant *getCatchableType(
QualType T,
790uint32_t NVOffset = 0,
791int32_t VBPtrOffset = -1,
792uint32_t VBIndex = 0);
794llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
798std::pair<llvm::Value *, const CXXRecordDecl *>
806 typedefstd::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
807 typedefllvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
808 typedefllvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
810VFTablesMapTy VFTablesMap;
811VTablesMapTy VTablesMap;
818llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
823GuardInfo() =
default;
824llvm::GlobalVariable *Guard =
nullptr;
825 unsignedBitIndex = 0;
830llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
831llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
832llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
834llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
835llvm::StructType *BaseClassDescriptorType;
836llvm::StructType *ClassHierarchyDescriptorType;
837llvm::StructType *CompleteObjectLocatorType;
839llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
841llvm::StructType *CatchableTypeType;
842llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
843llvm::StructType *ThrowInfoType;
849MicrosoftCXXABI::getRecordArgABI(
const CXXRecordDecl*RD)
const{
861 casellvm::Triple::thumb:
867 casellvm::Triple::x86: {
878 returnRAA_DirectInMemory;
881 casellvm::Triple::x86_64:
882 casellvm::Triple::aarch64:
886llvm_unreachable(
"invalid enum");
898llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE,
904voidMicrosoftCXXABI::emitRethrow(
CodeGenFunction&CGF,
boolisNoReturn) {
905llvm::Value *Args[] = {llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
906llvm::ConstantPointerNull::get(CGM.
UnqualPtrTy)};
918 VarDecl*CatchParam = S->getExceptionDecl();
919llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
920llvm::CatchPadInst *CPI =
921cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHIIt());
932CPI->setArgOperand(2,
var.getObjectAddress(CGF).emitRawPointer(CGF));
940std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
951 returnstd::make_tuple(
Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
960PolymorphicBase = BaseDecl;
964assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
966llvm::Value *Offset =
967GetVirtualBaseClassOffset(CGF,
Value, SrcDecl, PolymorphicBase);
969 Value.getElementType(),
Value.emitRawPointer(CGF), Offset);
972 returnstd::make_tuple(
Address(Ptr, CGF.
Int8Ty, VBaseAlign), Offset,
976boolMicrosoftCXXABI::shouldTypeidBeNullChecked(
QualTypeSrcRecordTy) {
978 return!getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
982llvm::Value *Argument) {
983llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
984llvm::FunctionType *FTy =
985llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
986llvm::Value *Args[] = {Argument};
992llvm::CallBase *
Call=
994 Call->setDoesNotReturn();
995CGF.
Builder.CreateUnreachable();
1001llvm::Type *StdTypeInfoPtrTy) {
1002std::tie(ThisPtr, std::ignore, std::ignore) =
1003performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
1005 returnCGF.
Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
1008boolMicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
boolSrcIsPtr,
1012!getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1015llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
1017 QualTypeDestRecordTy, llvm::BasicBlock *CastEnd) {
1018llvm::Value *SrcRTTI =
1020llvm::Value *DestRTTI =
1023llvm::Value *Offset;
1024std::tie(This, Offset, std::ignore) =
1025performBaseAdjustment(CGF, This, SrcRecordTy);
1026llvm::Value *ThisPtr =
This.emitRawPointer(CGF);
1038llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1039 "__RTDynamicCast");
1040llvm::Value *Args[] = {
1041ThisPtr, Offset, SrcRTTI, DestRTTI,
1046llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(
CodeGenFunction&CGF,
1049std::tie(
Value, std::ignore, std::ignore) =
1050performBaseAdjustment(CGF,
Value, SrcRecordTy);
1054llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1056llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1058llvm::Value *Args[] = {
Value.emitRawPointer(CGF)};
1066llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1072llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.
PtrDiffTy, VBPtrChars);
1077llvm::Value *VBTableOffset =
1080llvm::Value *VBPtrToNewBase =
1081GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1084 returnCGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1087boolMicrosoftCXXABI::HasThisReturn(
GlobalDeclGD)
const{
1088 returnisa<CXXConstructorDecl>(GD.
getDecl());
1092 returnisa<CXXDestructorDecl>(GD.
getDecl()) &&
1096boolMicrosoftCXXABI::hasMostDerivedReturn(
GlobalDeclGD)
const{
1106uint64_t NumElts = 0;
1109isa<VectorType>(
Base)) {
1146 if(
auto*Ctor = dyn_cast<CXXConstructorDecl>(
D)) {
1147 if(Ctor->isUserProvided())
1149}
else if(
auto*Template = dyn_cast<FunctionTemplateDecl>(
D)) {
1150 if(isa<CXXConstructorDecl>(Template->getTemplatedDecl()))
1152}
else if(
auto*MethodDecl = dyn_cast<CXXMethodDecl>(
D)) {
1153 if(MethodDecl->isCopyAssignmentOperator() && MethodDecl->isDeleted())
1162boolMicrosoftCXXABI::classifyReturnType(
CGFunctionInfo&FI)
const{
1173 if(isIndirectReturn) {
1194llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1195assert(IsMostDerivedClass &&
1196 "ctor for a class with virtual bases must have an implicit parameter");
1197llvm::Value *IsCompleteObject =
1198CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1200llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1201llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1202CGF.
Builder.CreateCondBr(IsCompleteObject,
1203CallVbaseCtorsBB, SkipVbaseCtorsBB);
1208EmitVBPtrStores(CGF, RD);
1212 returnSkipVbaseCtorsBB;
1216MicrosoftCXXABI::EmitDtorCompleteObjectHandler(
CodeGenFunction&CGF) {
1217llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1218assert(IsMostDerivedClass &&
1219 "ctor for a class with virtual bases must have an implicit parameter");
1220llvm::Value *IsCompleteObject =
1221CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1223llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1224llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1225CGF.
Builder.CreateCondBr(IsCompleteObject,
1226CallVbaseDtorsBB, SkipVbaseDtorsBB);
1231 returnSkipVbaseDtorsBB;
1234voidMicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1254llvm::Value *Int8This =
nullptr;
1257 const CXXRecordDecl*VBase = S.getType()->getAsCXXRecordDecl();
1258 autoI = VBaseMap.find(VBase);
1259assert(I != VBaseMap.end());
1260 if(!I->second.hasVtorDisp())
1263llvm::Value *VBaseOffset =
1264GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1265 uint64_tConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1268llvm::Value *VtorDispValue = Builder.CreateSub(
1269VBaseOffset, llvm::ConstantInt::get(CGM.
PtrDiffTy, ConstantVBaseOffset),
1271VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1274Int8This = getThisValue(CGF);
1276llvm::Value *VtorDispPtr =
1277Builder.CreateInBoundsGEP(CGF.
Int8Ty, Int8This, VBaseOffset);
1279VtorDispPtr = Builder.CreateConstGEP1_32(CGF.
Int8Ty, VtorDispPtr, -4);
1281Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1292 returnExpectedCallingConv == ActualCallingConv;
1303 if(
D->
hasAttr<DLLExportAttr>() &&
D->isDefaultConstructor() &&
1307 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1320 constVBTableGlobals &VBGlobals = enumerateVBTables(RD);
1321 for(
unsignedI = 0,
E= VBGlobals.VBTables->size(); I !=
E; ++I) {
1322 conststd::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1323llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1328 if(VBT->getVBaseWithVPtr())
1331llvm::Value *GVPtr =
1339MicrosoftCXXABI::buildStructorSignature(
GlobalDeclGD,
1341AddedStructorArgCounts Added;
1343 if(isa<CXXDestructorDecl>(GD.
getDecl()) &&
1346ArgTys.push_back(getContext().IntTy);
1349 auto*CD = dyn_cast<CXXConstructorDecl>(GD.
getDecl());
1358 if(
Class->getNumVBases()) {
1360ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1363ArgTys.push_back(getContext().IntTy);
1371voidMicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1377GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1384llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1389 returnllvm::GlobalValue::InternalLinkage;
1400 if(Dtor->
hasAttr<DLLExportAttr>())
1401 returnllvm::GlobalValue::WeakODRLinkage;
1402 if(Dtor->
hasAttr<DLLImportAttr>())
1403 returnllvm::GlobalValue::AvailableExternallyLinkage;
1404 returnllvm::GlobalValue::LinkOnceODRLinkage;
1409 returnllvm::GlobalValue::LinkOnceODRLinkage;
1411llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1413llvm_unreachable(
"invalid dtor type");
1425 if(
D->getParent()->getNumVBases() > 0 &&
D->
hasAttr<DLLExportAttr>())
1430MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDeclGD) {
1452 if(isa<CXXDestructorDecl>(MD))
1457getContext().getASTRecordLayout(MD->
getParent());
1464AddressMicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1470 CharUnitsAdjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1471 if(Adjustment.
isZero())
1505Result = Result.withElementType(CGF.
Int8Ty);
1509llvm::Value *VBaseOffset =
1510GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1512Result.getElementType(), Result.emitRawPointer(CGF), VBaseOffset);
1517 if(!StaticOffset.
isZero()) {
1519Result = Result.withElementType(CGF.
Int8Ty);
1538assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1543ImplicitParamKind::Other);
1548Params.insert(Params.begin() + 1, IsMostDerived);
1550Params.push_back(IsMostDerived);
1551getStructorImplicitParamDecl(CGF) = IsMostDerived;
1555&Context.
Idents.
get(
"should_call_delete"), Context.
IntTy,
1556ImplicitParamKind::Other);
1557Params.push_back(ShouldDelete);
1558getStructorImplicitParamDecl(CGF) = ShouldDelete;
1562voidMicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction&CGF) {
1579llvm::Value *
This= loadIncomingCXXThis(CGF);
1582 CharUnitsAdjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1583 if(!Adjustment.
isZero()) {
1589setCXXABIThisValue(CGF, This);
1599 if(HasThisReturn(CGF.
CurGD) || hasMostDerivedReturn(CGF.
CurGD))
1603assert(getStructorImplicitParamDecl(CGF) &&
1604 "no implicit parameter for a constructor with virtual bases?");
1605getStructorImplicitParamValue(CGF)
1608 "is_most_derived");
1612assert(getStructorImplicitParamDecl(CGF) &&
1613 "no implicit parameter for a deleting destructor?");
1614getStructorImplicitParamValue(CGF)
1617 "should_call_delete");
1627 if(!
D->getParent()->getNumVBases())
1628 returnAddedStructorArgs{};
1632llvm::Value *MostDerivedArg;
1634MostDerivedArg = getStructorImplicitParamValue(CGF);
1639 returnAddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1641 returnAddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1644llvm::Value *MicrosoftCXXABI::getCXXDestructorImplicitParam(
1665assert(
Type!= CXXDtorType::Dtor_Deleting &&
1666 "The deleting destructor should only be called via a virtual call");
1671llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1672 if(ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1673BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1683 if(BaseDtorEndBB) {
1685CGF.
Builder.CreateBr(BaseDtorEndBB);
1690voidMicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo&Info,
1692llvm::GlobalVariable *VTable) {
1703llvm::DenseSet<const CXXRecordDecl *>
Visited;
1704llvm::GlobalObject::VCallVisibility TypeVis =
1706 if(TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1707VTable->setVCallVisibilityMetadata(TypeVis);
1714getContext().getLangOpts().RTTIData
1715? getContext().toCharUnitsFromBits(
1716getContext().getTargetInfo().getPointerWidth(LangAS::Default))
1735getContext().getASTRecordLayout(DerivedRD);
1741Offset = VBI->second.VBaseOffset;
1742 if(!Offset.isZero())
1752voidMicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables&CGVT,
1757 for(
conststd::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1758llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1759 if(VTable->hasInitializer())
1765llvm::Constant *RTTI =
nullptr;
1768RTTI = getMSCompleteObjectLocator(RD, *Info);
1771 autocomponents = builder.beginStruct();
1773VTable->hasLocalLinkage());
1774components.finishAndSetAsInitializer(VTable);
1776emitVTableTypeMetadata(*Info, RD, VTable);
1780boolMicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1782 returnVptr.NearestVBase !=
nullptr;
1785llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1788llvm::Constant *VTableAddressPoint = getVTableAddressPoint(
Base, VTableClass);
1789 if(!VTableAddressPoint) {
1790assert(
Base.getBase()->getNumVBases() &&
1791!getContext().getASTRecordLayout(
Base.getBase()).hasOwnVFPtr());
1793 returnVTableAddressPoint;
1799llvm::raw_svector_ostream Out(Name);
1806(void)getAddrOfVTable(VTableClass,
Base.getBaseOffset());
1807VFTableIdTy
ID(VTableClass,
Base.getBaseOffset());
1808 returnVFTablesMap[
ID];
1811llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl*RD,
1817VFTableIdTy
ID(RD, VPtrOffset);
1818VTablesMapTy::iterator I;
1820std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID,
nullptr));
1824llvm::GlobalVariable *&VTable = I->second;
1829 if(DeferredVFTables.insert(RD).second) {
1837llvm::StringSet<> ObservedMangledNames;
1838 for(
size_tJ = 0, F = VFPtrs.size(); J != F; ++J) {
1841 if(!ObservedMangledNames.insert(Name.str()).second)
1842llvm_unreachable(
"Already saw this mangling before?");
1847 conststd::unique_ptr<VPtrInfo> *VFPtrI =
1848llvm::find_if(VFPtrs, [&](
conststd::unique_ptr<VPtrInfo> &VPI) {
1849 returnVPI->FullOffsetInMDC == VPtrOffset;
1851 if(VFPtrI == VFPtrs.end()) {
1852VFTablesMap[
ID] =
nullptr;
1855 conststd::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1867llvm::GlobalValue::LinkageTypes VFTableLinkage =
1868RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1870 boolVFTableComesFromAnotherTU =
1871llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1872llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1873 boolVTableAliasIsRequred =
1874!VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1876 if(llvm::GlobalValue *VFTable =
1877CGM.
getModule().getNamedGlobal(VFTableName)) {
1878VFTablesMap[
ID] = VFTable;
1879VTable = VTableAliasIsRequred
1880? cast<llvm::GlobalVariable>(
1881cast<llvm::GlobalAlias>(VFTable)->getAliaseeObject())
1882:
cast<
llvm::GlobalVariable>(VFTable);
1888llvm::GlobalValue::LinkageTypes VTableLinkage =
1889VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1891StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1897llvm::GlobalValue *VFTable;
1898VTable =
newllvm::GlobalVariable(CGM.
getModule(), VTableType,
1899 true, VTableLinkage,
1900 nullptr, VTableName);
1901VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1903llvm::Comdat *
C=
nullptr;
1904 if(!VFTableComesFromAnotherTU &&
1905llvm::GlobalValue::isWeakForLinker(VFTableLinkage))
1906 C= CGM.
getModule().getOrInsertComdat(VFTableName.str());
1911 if(VTableAliasIsRequred) {
1912llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1913llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1914llvm::ConstantInt::get(CGM.
Int32Ty, 1)};
1917llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1918VTable->getValueType(), VTable, GEPIndices);
1919 if(llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1920VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1922 C->setSelectionKind(llvm::Comdat::Largest);
1924VFTable = llvm::GlobalAlias::create(CGM.
Int8PtrTy,
1926VFTableName.str(), VTableGEP,
1928VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1937VTable->setComdat(
C);
1939 if(RD->
hasAttr<DLLExportAttr>())
1940VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1942VFTablesMap[
ID] = VFTable;
1955adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1957 auto*MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1958llvm::Value *VTable =
1966 autogetObjectWithVPtr = [&] {
1969[&](
conststd::unique_ptr<VPtrInfo> &Info) {
1970return Info->FullOffsetInMDC == ML.VFPtrOffset;
1979getObjectWithVPtr(), VTable, Ty,
1987llvm::Value *VFuncPtr =
1988Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.
Index,
"vfn");
1989VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.
getPointerAlign());
1996llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1998 AddressThis, DeleteOrMemberCallExpr
E, llvm::CallBase **CallOrInvoke) {
1999 auto*CE = dyn_cast<const CXXMemberCallExpr *>(
E);
2000 auto*
D= dyn_cast<const CXXDeleteExpr *>(
E);
2001assert((CE !=
nullptr) ^ (
D!=
nullptr));
2002assert(CE ==
nullptr|| CE->arg_begin() == CE->arg_end());
2014llvm::Value *ImplicitParam = llvm::ConstantInt::get(
2020ThisTy = CE->getObjectType();
2022ThisTy =
D->getDestroyedType();
2025 This= adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
2028ImplicitParam, Context.
IntTy, CE, CallOrInvoke);
2032constVBTableGlobals &
2033MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl*RD) {
2036llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
2038std::tie(Entry, Added) =
2039VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
2040VBTableGlobals &VBGlobals = Entry->second;
2045VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2050 for(VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2051 E= VBGlobals.VBTables->end();
2053VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,
Linkage));
2060MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl*MD,
2062assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
2063 "can't form pointers to ctors or virtual dtors");
2067llvm::raw_svector_ostream Out(ThunkName);
2068getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2071 if(llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
2072 returncast<llvm::Function>(GV);
2078llvm::Function *ThunkFn =
2079llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
2081assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2084? llvm::GlobalValue::LinkOnceODRLinkage
2085: llvm::GlobalValue::InternalLinkage);
2087ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
2096ThunkFn->addFnAttr(
"thunk");
2099ThunkFn->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
2109buildThisParam(CGF, FunctionArgs);
2116setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2121llvm::Value *VTable =
2124llvm::Value *VFuncPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2125ThunkPtrTy, VTable, ML.
Index,
"vfn");
2134voidMicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl*RD) {
2135 constVBTableGlobals &VBGlobals = enumerateVBTables(RD);
2136 for(
unsignedI = 0,
E= VBGlobals.VBTables->size(); I !=
E; ++I) {
2137 conststd::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2138llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2139 if(GV->isDeclaration())
2140emitVBTableDefinition(*VBT, RD, GV);
2144llvm::GlobalVariable *
2146llvm::GlobalVariable::LinkageTypes
Linkage) {
2148llvm::raw_svector_ostream Out(OutName);
2149getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2150StringRef Name = OutName.str();
2152llvm::ArrayType *VBTableType =
2155assert(!CGM.
getModule().getNamedGlobal(Name) &&
2156 "vbtable with this name already exists: mangling bug?");
2161GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2163 if(RD->
hasAttr<DLLImportAttr>())
2164GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2165 else if(RD->
hasAttr<DLLExportAttr>())
2166GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2168 if(!GV->hasExternalLinkage())
2169emitVBTableDefinition(VBT, RD, GV);
2174voidMicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo&VBT,
2176llvm::GlobalVariable *GV)
const{
2180 "should only emit vbtables for classes with vbtables");
2184 const ASTRecordLayout&DerivedLayout = getContext().getASTRecordLayout(RD);
2191Offsets[0] = llvm::ConstantInt::get(CGM.
IntTy, -VBPtrOffset.
getQuantity());
2194 for(
const auto&I : ObjectWithVPtr->
vbases()) {
2195 const CXXRecordDecl*VBase = I.getType()->getAsCXXRecordDecl();
2197assert(!Offset.isNegative());
2202CompleteVBPtrOffset +=
2204Offset -= CompleteVBPtrOffset;
2206 unsignedVBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2207assert(Offsets[VBIndex] ==
nullptr&&
"The same vbindex seen twice?");
2208Offsets[VBIndex] = llvm::ConstantInt::get(CGM.
IntTy, Offset.getQuantity());
2211assert(Offsets.size() ==
2212cast<llvm::ArrayType>(GV->getValueType())->getNumElements());
2213llvm::ArrayType *VBTableType =
2214llvm::ArrayType::get(CGM.
IntTy, Offsets.size());
2215llvm::Constant *
Init= llvm::ConstantArray::get(VBTableType, Offsets);
2216GV->setInitializer(
Init);
2218 if(RD->
hasAttr<DLLImportAttr>())
2219GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2222llvm::Value *MicrosoftCXXABI::performThisAdjustment(
2227 return This.emitRawPointer(CGF);
2233 V=
This.emitRawPointer(CGF);
2243CGF.
Builder.CreateNeg(VtorDisp));
2256llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2275llvm::Value *MicrosoftCXXABI::performReturnAdjustment(
2280 return Ret.emitRawPointer(CGF);
2284llvm::Value *
V=
Ret.emitRawPointer(CGF);
2289llvm::Value *VBaseOffset =
2308boolMicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr*
expr) {
2311 return expr->getAllocatedType().isDestructedType();
2322llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(
CodeGenFunction&CGF,
2331llvm::Value *numElements,
2334assert(requiresArrayCookie(
expr));
2337 CharUnitscookieSize = getArrayCookieSizeImpl(elementType);
2352llvm::FunctionCallee Dtor,
2353llvm::Constant *Addr) {
2358llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2359CGF.
IntTy, DtorStub->getType(),
false);
2362TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2363 if(llvm::Function *TLRegDtorFn =
2364dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2365TLRegDtorFn->setDoesNotThrow();
2371llvm::FunctionCallee Dtor,
2372llvm::Constant *Addr) {
2376 if(
D.getTLSKind())
2387voidMicrosoftCXXABI::EmitThreadLocalInitFuncs(
2391 if(CXXThreadLocalInits.empty())
2396?
"/include:___dyn_tls_init@12" 2397:
"/include:__dyn_tls_init");
2402 autoAddToXDU = [&CGM](llvm::Function *InitFunc) {
2403llvm::GlobalVariable *InitFuncPtr =
newllvm::GlobalVariable(
2404CGM.
getModule(), InitFunc->getType(),
true,
2405llvm::GlobalVariable::InternalLinkage, InitFunc,
2406Twine(InitFunc->getName(),
"$initializer$"));
2407InitFuncPtr->setSection(
".CRT$XDU");
2414std::vector<llvm::Function *> NonComdatInits;
2415 for(
size_tI = 0,
E= CXXThreadLocalInitVars.size(); I !=
E; ++I) {
2416llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2418llvm::Function *F = CXXThreadLocalInits[I];
2421 if(llvm::Comdat *
C= GV->getComdat())
2422AddToXDU(F)->setComdat(
C);
2424NonComdatInits.push_back(F);
2427 if(!NonComdatInits.empty()) {
2428llvm::FunctionType *FTy =
2429llvm::FunctionType::get(CGM.
VoidTy,
false);
2445llvm::Constant *TlsGuardConstant =
2447llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant);
2449TlsGuard->setThreadLocal(
true);
2457llvm::FunctionType *FTy =
2458llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()), {},
2461FTy,
"__dyn_tls_on_demand_init",
2463llvm::AttributeList::FunctionIndex,
2464llvm::Attribute::NoUnwind),
2469llvm::BasicBlock *DynInitBB,
2470llvm::BasicBlock *ContinueBB) {
2471llvm::LoadInst *TlsGuardValue =
2473llvm::Value *CmpResult =
2474CGF.
Builder.CreateICmpEQ(TlsGuardValue, CGF.
Builder.getInt8(0));
2475CGF.
Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2479llvm::GlobalValue *TlsGuard,
2480llvm::BasicBlock *ContinueBB) {
2482llvm::Function *InitializerFunction =
2484llvm::CallInst *CallVal = CGF.
Builder.CreateCall(InitializerFunction);
2485CallVal->setCallingConv(InitializerFunction->getCallingConv());
2487CGF.
Builder.CreateBr(ContinueBB);
2491llvm::BasicBlock *DynInitBB =
2493llvm::BasicBlock *ContinueBB =
2499CGF.
Builder.SetInsertPoint(DynInitBB);
2501CGF.
Builder.SetInsertPoint(ContinueBB);
2520 AddressAddr(
V, RealVarTy, Alignment);
2524AlignmentSource::Decl)
2530StringRef VarName(
"_Init_thread_epoch");
2532 if(
auto*GV = CGM.
getModule().getNamedGlobal(VarName))
2534 auto*GV =
newllvm::GlobalVariable(
2536 false, llvm::GlobalVariable::ExternalLinkage,
2538 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2544llvm::FunctionType *FTy =
2545llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2548FTy,
"_Init_thread_header",
2550llvm::AttributeList::FunctionIndex,
2551llvm::Attribute::NoUnwind),
2556llvm::FunctionType *FTy =
2557llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2560FTy,
"_Init_thread_footer",
2562llvm::AttributeList::FunctionIndex,
2563llvm::Attribute::NoUnwind),
2568llvm::FunctionType *FTy =
2569llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2572FTy,
"_Init_thread_abort",
2574llvm::AttributeList::FunctionIndex,
2575llvm::Attribute::NoUnwind),
2583ResetGuardBit(
AddressGuard,
unsignedGuardNum)
2584: Guard(Guard), GuardNum(GuardNum) {}
2590llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2591llvm::ConstantInt *Mask =
2592llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2593Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2599CallInitThreadAbort(
RawAddressGuard) : Guard(Guard.getPointer()) {}
2609llvm::GlobalVariable *GV,
2612 if(!
D.isStaticLocal()) {
2613assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2615llvm::Function *F = CGF.
CurFn;
2616F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2617F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2622 boolThreadlocalStatic =
D.getTLSKind();
2623 boolThreadsafeStatic = getContext().
getLangOpts().ThreadsafeStatics;
2627 boolHasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2630llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2631llvm::ConstantInt *
Zero= llvm::ConstantInt::get(GuardTy, 0);
2635GuardInfo *GI =
nullptr;
2636 if(ThreadlocalStatic)
2638 else if(!ThreadsafeStatic)
2641llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2643 if(
D.isExternallyVisible()) {
2646GuardNum = getContext().getStaticLocalNumber(&
D);
2647assert(GuardNum > 0);
2649}
else if(HasPerVariableGuard) {
2653GuardNum = GI->BitIndex++;
2656 if(!HasPerVariableGuard && GuardNum >= 32) {
2657 if(
D.isExternallyVisible())
2658ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2660GuardVar =
nullptr;
2667llvm::raw_svector_ostream Out(GuardName);
2668 if(HasPerVariableGuard)
2669getMangleContext().mangleThreadSafeStaticGuardVariable(&
D, GuardNum,
2672getMangleContext().mangleStaticGuardVariable(&
D, Out);
2678 newllvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2679GV->getLinkage(), Zero, GuardName.str());
2680GuardVar->setVisibility(GV->getVisibility());
2681GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2682GuardVar->setAlignment(GuardAlign.
getAsAlign());
2683 if(GuardVar->isWeakForLinker())
2684GuardVar->setComdat(
2685CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2686 if(
D.getTLSKind())
2688 if(GI && !HasPerVariableGuard)
2689GI->Guard = GuardVar;
2694assert(GuardVar->getLinkage() == GV->getLinkage() &&
2695 "static local from the same function had different linkage");
2697 if(!HasPerVariableGuard) {
2705llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2706llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2707llvm::Value *NeedsInit =
2708Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
2712CodeGenFunction::GuardKind::VariableGuard, &
D);
2717Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2718CGF.
EHStack.pushCleanup<ResetGuardBit>(
EHCleanup, GuardAddr, GuardNum);
2721Builder.CreateBr(EndBlock);
2739llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2740FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2741llvm::LoadInst *InitThreadEpoch =
2743llvm::Value *IsUninitialized =
2744Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2745llvm::BasicBlock *AttemptInitBlock = CGF.
createBasicBlock(
"init.attempt");
2748CodeGenFunction::GuardKind::VariableGuard, &
D);
2754GuardAddr.getPointer());
2755llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2756SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2757llvm::Value *ShouldDoInit =
2758Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2760Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2768GuardAddr.getPointer());
2769Builder.CreateBr(EndBlock);
2798fields.push_back(CGM.
IntTy);
2802fields.push_back(CGM.
IntTy);
2804fields.push_back(CGM.
IntTy);
2806fields.push_back(CGM.
IntTy);
2808 if(fields.size() == 1)
2813voidMicrosoftCXXABI::
2816assert(fields.empty());
2821fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2824fields.push_back(getZeroInt());
2826fields.push_back(getAllOnesInt());
2831fields.push_back(getZeroInt());
2833fields.push_back(getZeroInt());
2835fields.push_back(getAllOnesInt());
2841GetNullMemberPointerFields(MPT, fields);
2842 if(fields.size() == 1)
2844llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2845assert(Res->getType() == ConvertMemberPointerType(MPT));
2850MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2851 boolIsMemberFunction,
2854 unsignedVBTableIndex) {
2863fields.push_back(FirstField);
2866fields.push_back(llvm::ConstantInt::get(
2872Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2873fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, Offs.
getQuantity()));
2878fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2880 returnllvm::ConstantStruct::getAnon(fields);
2889llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl*RD,
2892MSInheritanceModel::Virtual)
2893offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2894llvm::Constant *FirstField =
2896 returnEmitFullMemberPointer(FirstField,
false, RD,
2900llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue&MP,
2905 returnEmitNullMemberPointer(DstTy);
2910llvm::Constant *
C;
2911 if(
const CXXMethodDecl*MD = dyn_cast<CXXMethodDecl>(MPD)) {
2912 C= EmitMemberFunctionPointer(MD);
2919 const FieldDecl*FD = dyn_cast<FieldDecl>(MPD);
2921FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
2924 C= EmitMemberDataPointer(RD, FieldOffset);
2927 if(!MemberPointerPath.empty()) {
2928 const CXXRecordDecl*SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2940 if(DerivedMember) {
2948 if(BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2949 Base->getCanonicalDecl())
2950DerivedToBasePath.push_back(&BS);
2953assert(DerivedToBasePath.size() == MemberPointerPath.size());
2955 CastKindCK = DerivedMember ? CK_DerivedToBaseMemberPointer
2956: CK_BaseToDerivedMemberPointer;
2957 C= EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2958DerivedToBasePath.end(),
C);
2964MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl*MD) {
2965assert(MD->
isInstance() &&
"Member function must not be static!");
2971 unsignedVBTableIndex = 0;
2972llvm::Constant *FirstField;
2977 if(Types.isFuncTypeConvertible(FPT)) {
2979Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
2989FirstField = EmitVirtualMemPtrThunk(MD, ML);
2993VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2996 if(VBTableIndex == 0 &&
2998MSInheritanceModel::Virtual)
2999NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
3002 returnEmitFullMemberPointer(FirstField,
true, RD,
3003NonVirtualBaseAdjustment, VBTableIndex);
3018llvm::ICmpInst::Predicate
Eq;
3019llvm::Instruction::BinaryOps
And,
Or;
3021 Eq= llvm::ICmpInst::ICMP_NE;
3022 And= llvm::Instruction::Or;
3023 Or= llvm::Instruction::And;
3025 Eq= llvm::ICmpInst::ICMP_EQ;
3026 And= llvm::Instruction::And;
3027 Or= llvm::Instruction::Or;
3036 returnBuilder.CreateICmp(
Eq, L, R);
3039llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
3040llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
3041llvm::Value *Cmp0 = Builder.CreateICmp(
Eq, L0, R0,
"memptr.cmp.first");
3044llvm::Value *Res =
nullptr;
3045llvm::StructType *LType = cast<llvm::StructType>(L->getType());
3046 for(
unsignedI = 1,
E= LType->getNumElements(); I !=
E; ++I) {
3047llvm::Value *LF = Builder.CreateExtractValue(L, I);
3048llvm::Value *RF = Builder.CreateExtractValue(R, I);
3049llvm::Value *Cmp = Builder.CreateICmp(
Eq, LF, RF,
"memptr.cmp.rest");
3051Res = Builder.CreateBinOp(
And, Res, Cmp);
3059llvm::Value *
Zero= llvm::Constant::getNullValue(L0->getType());
3060llvm::Value *IsZero = Builder.CreateICmp(
Eq, L0, Zero,
"memptr.cmp.iszero");
3061Res = Builder.CreateBinOp(
Or, Res, IsZero);
3066 returnBuilder.CreateBinOp(
And, Res, Cmp0,
"memptr.cmp");
3071llvm::Value *MemPtr,
3077fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
3079GetNullMemberPointerFields(MPT, fields);
3080assert(!fields.empty());
3081llvm::Value *FirstField = MemPtr;
3082 if(MemPtr->getType()->isStructTy())
3083FirstField = Builder.CreateExtractValue(MemPtr, 0);
3084llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
3092 for(
intI = 1,
E= fields.size(); I <
E; ++I) {
3093llvm::Value *
Field= Builder.CreateExtractValue(MemPtr, I);
3094llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
3095Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
3101llvm::Constant *Val) {
3104llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3105Val->getAggregateElement(0
U) : Val;
3106 returnFirstField->isNullValue();
3111 if(isZeroInitializable(MPT) && Val->isNullValue())
3117GetNullMemberPointerFields(MPT, Fields);
3118 if(Fields.size() == 1) {
3119assert(Val->getType()->isIntegerTy());
3120 returnVal == Fields[0];
3124 for(I = 0,
E= Fields.size(); I !=
E; ++I) {
3125 if(Val->getAggregateElement(I) != Fields[I])
3134llvm::Value *VBPtrOffset,
3135llvm::Value *VBTableOffset,
3136llvm::Value **VBPtrOut) {
3139llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3140CGM.
Int8Ty,
This.emitRawPointer(CGF), VBPtrOffset,
"vbptr");
3145 if(
autoCI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3146VBPtrAlign =
This.getAlignment().alignmentAtOffset(
3152llvm::Value *VBTable =
3153Builder.CreateAlignedLoad(CGM.
UnqualPtrTy, VBPtr, VBPtrAlign,
"vbtable");
3156llvm::Value *VBTableIndex = Builder.CreateAShr(
3157VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3158 "vbtindex",
true);
3161llvm::Value *VBaseOffs =
3162Builder.CreateInBoundsGEP(CGM.
Int32Ty, VBTable, VBTableIndex);
3163 returnBuilder.CreateAlignedLoad(CGM.
Int32Ty, VBaseOffs,
3169llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3171 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3174llvm::BasicBlock *OriginalBB =
nullptr;
3175llvm::BasicBlock *SkipAdjustBB =
nullptr;
3176llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3183OriginalBB = Builder.GetInsertBlock();
3186llvm::Value *IsVirtual =
3187Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3188 "memptr.is_vbase");
3189Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3201 "member pointer representation requires a " 3202 "complete class type for %0 to perform this expression");
3205offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3208llvm::Value *VBPtr =
nullptr;
3209llvm::Value *VBaseOffs =
3210GetVBaseOffsetFromVBPtr(CGF,
Base, VBPtrOffset, VBTableOffset, &VBPtr);
3211llvm::Value *AdjustedBase =
3212Builder.CreateInBoundsGEP(CGM.
Int8Ty, VBPtr, VBaseOffs);
3215 if(VBaseAdjustBB) {
3216Builder.CreateBr(SkipAdjustBB);
3218llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3219Phi->addIncoming(
Base.emitRawPointer(CGF), OriginalBB);
3220Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3223 returnAdjustedBase;
3226llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3236llvm::Value *FieldOffset = MemPtr;
3237llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3238llvm::Value *VBPtrOffset =
nullptr;
3239 if(MemPtr->getType()->isStructTy()) {
3242FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3244VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3246VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3250 if(VirtualBaseAdjustmentOffset) {
3251Addr = AdjustVirtualBase(CGF,
E, RD,
Base, VirtualBaseAdjustmentOffset,
3254Addr =
Base.emitRawPointer(CGF);
3258 returnBuilder.CreateInBoundsGEP(CGF.
Int8Ty, Addr, FieldOffset,
3266assert(
E->getCastKind() == CK_DerivedToBaseMemberPointer ||
3267 E->getCastKind() == CK_BaseToDerivedMemberPointer ||
3268 E->getCastKind() == CK_ReinterpretMemberPointer);
3271 if(isa<llvm::Constant>(Src))
3272 returnEmitMemberPointerConversion(
E, cast<llvm::Constant>(Src));
3282 boolIsReinterpret =
E->getCastKind() == CK_ReinterpretMemberPointer;
3283 if(IsReinterpret && IsFunc)
3288 if(IsReinterpret &&
3295llvm::Value *
IsNotNull= EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3296llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3300 if(IsReinterpret) {
3303assert(Src->getType() == DstNull->getType());
3304 returnBuilder.CreateSelect(
IsNotNull, Src, DstNull);
3307llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3309llvm::BasicBlock *ContinueBB = CGF.
createBasicBlock(
"memptr.converted");
3310Builder.CreateCondBr(
IsNotNull, ConvertBB, ContinueBB);
3313llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3314SrcTy, DstTy,
E->getCastKind(),
E->path_begin(),
E->path_end(), Src,
3317Builder.CreateBr(ContinueBB);
3321llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3322Phi->addIncoming(DstNull, OriginalBB);
3323Phi->addIncoming(Dst, ConvertBB);
3327llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3337 boolIsConstant = isa<llvm::Constant>(Src);
3340llvm::Value *FirstField = Src;
3341llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3342llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3343llvm::Value *VBPtrOffset = getZeroInt();
3347FirstField = Builder.CreateExtractValue(Src, I++);
3349NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3351VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3353VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3356 boolIsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3362llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3369llvm::Value *SrcVBIndexEqZero =
3370Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3371 if(SrcInheritance == MSInheritanceModel::Virtual) {
3372 if(int64_t SrcOffsetToFirstVBase =
3373getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3374llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3376llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3378NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3389llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3394llvm::Value *NVDisp;
3395 if(IsDerivedToBase)
3396NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3398NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3400NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3404llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3407 if(llvm::GlobalVariable *VDispMap =
3408getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3409llvm::Value *VBIndex = Builder.CreateExactUDiv(
3410VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3412llvm::Constant *Mapping = VDispMap->getInitializer();
3413VirtualBaseAdjustmentOffset =
3414Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3416llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3417VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3418CGM.
IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3424Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3431llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3433getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3435Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3441 if(DstInheritance == MSInheritanceModel::Virtual) {
3442 if(int64_t DstOffsetToFirstVBase =
3443getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3444llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3446llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3448NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3457Dst = llvm::PoisonValue::get(ConvertMemberPointerType(DstTy));
3459Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3461Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3463Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3465Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3471MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr*
E,
3472llvm::Constant *Src) {
3479 returnEmitMemberPointerConversion(SrcTy, DstTy, CK,
E->path_begin(),
3480 E->path_end(), Src);
3483llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3487assert(CK == CK_DerivedToBaseMemberPointer ||
3488CK == CK_BaseToDerivedMemberPointer ||
3489CK == CK_ReinterpretMemberPointer);
3492 if(MemberPointerConstantIsNull(SrcTy, Src))
3493 returnEmitNullMemberPointer(DstTy);
3498 if(CK == CK_ReinterpretMemberPointer)
3502 auto*Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3503SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3508CGCalleeMicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3510llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3522llvm::Value *FunctionPointer = MemPtr;
3523llvm::Value *NonVirtualBaseAdjustment =
nullptr;
3524llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3525llvm::Value *VBPtrOffset =
nullptr;
3526 if(MemPtr->getType()->isStructTy()) {
3529FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3531NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3533VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3535VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3538 if(VirtualBaseAdjustmentOffset) {
3539ThisPtrForCall = AdjustVirtualBase(CGF,
E, RD, This,
3540VirtualBaseAdjustmentOffset, VBPtrOffset);
3542ThisPtrForCall =
This.emitRawPointer(CGF);
3545 if(NonVirtualBaseAdjustment)
3546ThisPtrForCall = Builder.CreateInBoundsGEP(CGF.
Int8Ty, ThisPtrForCall,
3547NonVirtualBaseAdjustment);
3554 return newMicrosoftCXXABI(CGM);
3588StringRef MangledName(
"??_7type_info@@6B@");
3589 if(
autoVTable = CGM.
getModule().getNamedGlobal(MangledName))
3593llvm::GlobalVariable::ExternalLinkage,
3594 nullptr, MangledName);
3607IsPrivateOnPath = 1 | 8,
3611HasHierarchyDescriptor = 64
3617MSRTTIClass *getFirstChild() {
return this+ 1; }
3618 staticMSRTTIClass *getNextChild(MSRTTIClass *Child) {
3619 returnChild + 1 + Child->NumBases;
3623 uint32_tFlags, NumBases, OffsetInVBase;
3629Flags = HasHierarchyDescriptor;
3631VirtualRoot =
nullptr;
3635Flags |= IsPrivate | IsPrivateOnPath;
3641 if(
Parent->Flags & IsPrivateOnPath)
3642Flags |= IsPrivateOnPath;
3643VirtualRoot =
Parent->VirtualRoot;
3644OffsetInVBase =
Parent->OffsetInVBase + RD->getASTContext()
3645.getASTRecordLayout(
Parent->RD).getBaseClassOffset(RD).getQuantity();
3649MSRTTIClass *Child = getFirstChild();
3651NumBases += Child->initialize(
this, &
Base) + 1;
3652Child = getNextChild(Child);
3657staticllvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualTypeTy) {
3659 caseLinkage::Invalid:
3660llvm_unreachable(
"Linkage hasn't been computed!");
3663 caseLinkage::Internal:
3664 caseLinkage::UniqueExternal:
3665 returnllvm::GlobalValue::InternalLinkage;
3667 caseLinkage::VisibleNone:
3668 caseLinkage::Module:
3669 caseLinkage::External:
3670 returnllvm::GlobalValue::LinkOnceODRLinkage;
3672llvm_unreachable(
"Invalid linkage!");
3678structMSRTTIBuilder {
3680HasBranchingHierarchy = 1,
3681HasVirtualBranchingHierarchy = 2,
3682HasAmbiguousBases = 4
3685MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl*RD)
3686: CGM(ABI.CGM), Context(CGM.getContext()),
3687VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3688 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3691llvm::GlobalVariable *getBaseClassDescriptor(
constMSRTTIClass &Classes);
3692llvm::GlobalVariable *
3694llvm::GlobalVariable *getClassHierarchyDescriptor();
3695llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo&Info);
3699llvm::LLVMContext &VMContext;
3702llvm::GlobalVariable::LinkageTypes
Linkage;
3703MicrosoftCXXABI &ABI;
3712Classes.push_back(MSRTTIClass(RD));
3723 for(MSRTTIClass *
Class= &Classes.front();
Class<= &Classes.back();) {
3724 if((
Class->Flags & MSRTTIClass::IsVirtual) &&
3725!VirtualBases.insert(
Class->RD).second) {
3729 if(!UniqueBases.insert(
Class->RD).second)
3730AmbiguousBases.insert(
Class->RD);
3733 if(AmbiguousBases.empty())
3735 for(MSRTTIClass &
Class: Classes)
3736 if(AmbiguousBases.count(
Class.RD))
3737 Class.Flags |= MSRTTIClass::IsAmbiguous;
3740llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3743llvm::raw_svector_ostream Out(MangledName);
3744ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3748 if(
autoCHD =
Module.getNamedGlobal(MangledName))
3754Classes.front().initialize(
nullptr,
nullptr);
3757 for(
constMSRTTIClass &Class : Classes) {
3758 if(
Class.RD->getNumBases() > 1)
3759Flags |= HasBranchingHierarchy;
3762 if(
Class.Flags & MSRTTIClass::IsAmbiguous)
3763Flags |= HasAmbiguousBases;
3765 if((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3766Flags |= HasVirtualBranchingHierarchy;
3769llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
IntTy, 0),
3770llvm::ConstantInt::get(CGM.
IntTy, 0)};
3773 auto Type= ABI.getClassHierarchyDescriptorType();
3777 if(CHD->isWeakForLinker())
3778CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3780 auto*Bases = getBaseClassArray(Classes);
3783llvm::Constant *Fields[] = {
3784llvm::ConstantInt::get(CGM.
IntTy, 0),
3785llvm::ConstantInt::get(CGM.
IntTy, Flags),
3786llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3787ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3788Bases->getValueType(), Bases,
3791CHD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3795llvm::GlobalVariable *
3799llvm::raw_svector_ostream Out(MangledName);
3800ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3808llvm::Type *PtrType = ABI.getImageRelativeType(CGM.
UnqualPtrTy);
3809 auto*ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3811 newllvm::GlobalVariable(
Module, ArrType,
3813 nullptr, MangledName);
3814 if(BCA->isWeakForLinker())
3815BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3819 for(MSRTTIClass &Class : Classes)
3820BaseClassArrayData.push_back(
3821ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3822BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3823BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3827llvm::GlobalVariable *
3828MSRTTIBuilder::getBaseClassDescriptor(
constMSRTTIClass &Class) {
3833 if(
Class.VirtualRoot) {
3841llvm::raw_svector_ostream Out(MangledName);
3842ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3843 Class.RD,
Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3848 if(
autoBCD =
Module.getNamedGlobal(MangledName))
3852 auto Type= ABI.getBaseClassDescriptorType();
3855 nullptr, MangledName);
3856 if(BCD->isWeakForLinker())
3857BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3860llvm::Constant *Fields[] = {
3861ABI.getImageRelativeConstant(
3863llvm::ConstantInt::get(CGM.
IntTy,
Class.NumBases),
3864llvm::ConstantInt::get(CGM.
IntTy,
Class.OffsetInVBase),
3865llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3866llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3867llvm::ConstantInt::get(CGM.
IntTy,
Class.Flags),
3868ABI.getImageRelativeConstant(
3869MSRTTIBuilder(ABI,
Class.RD).getClassHierarchyDescriptor()),
3871BCD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3875llvm::GlobalVariable *
3876MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo&Info) {
3879llvm::raw_svector_ostream Out(MangledName);
3880ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3884 if(
autoCOL =
Module.getNamedGlobal(MangledName))
3889 intVFPtrOffset = 0;
3895->second.hasVtorDisp())
3899llvm::StructType *
Type= ABI.getCompleteObjectLocatorType();
3901 nullptr, MangledName);
3904llvm::Constant *Fields[] = {
3905llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3906llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3907llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3908ABI.getImageRelativeConstant(
3910ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3911ABI.getImageRelativeConstant(COL),
3914 if(!ABI.isImageRelative())
3915FieldsRef = FieldsRef.drop_back();
3916COL->setInitializer(llvm::ConstantStruct::get(
Type, FieldsRef));
3917 if(COL->isWeakForLinker())
3918COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3923 bool&IsConst,
bool&IsVolatile,
3924 bool&IsUnaligned) {
3933IsVolatile =
false;
3934IsUnaligned =
false;
3936 if(!PointeeType.
isNull()) {
3957MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3962 boolIsConst, IsVolatile, IsUnaligned;
3986llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3989llvm::raw_svector_ostream Out(MangledName);
3990getMangleContext().mangleCXXRTTI(
Type, Out);
3994 if(llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4003llvm::raw_svector_ostream Out(TypeInfoString);
4004getMangleContext().mangleCXXRTTIName(
Type, Out);
4008llvm::Constant *Fields[] = {
4010llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
4011llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
4012llvm::StructType *TypeDescriptorType =
4013getTypeDescriptorType(TypeInfoString);
4014 auto*Var =
newllvm::GlobalVariable(
4015CGM.
getModule(), TypeDescriptorType,
false,
4016getLinkageForRTTI(
Type),
4017llvm::ConstantStruct::get(TypeDescriptorType, Fields),
4019 if(Var->isWeakForLinker())
4020Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
4025llvm::GlobalVariable *
4026MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl*RD,
4028 returnMSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
4031voidMicrosoftCXXABI::emitCXXStructor(
GlobalDeclGD) {
4032 if(
auto*ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
4034llvm::Function *
Fn=
4040 auto*dtor = cast<CXXDestructorDecl>(GD.
getDecl());
4046dtor->getParent()->getNumVBases() == 0)
4057 if(
Fn->isWeakForLinker())
4058 Fn->setComdat(CGM.
getModule().getOrInsertComdat(
Fn->getName()));
4068llvm::raw_svector_ostream Out(ThunkName);
4069getMangleContext().mangleName(
GlobalDecl(CD, CT), Out);
4072 if(llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
4073 returncast<llvm::Function>(GV);
4079 QualTypeRecordTy = getContext().getRecordType(RD);
4080llvm::Function *ThunkFn = llvm::Function::Create(
4081ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
4082ThunkFn->setCallingConv(
static_cast<llvm::CallingConv::ID
>(
4084 if(ThunkFn->isWeakForLinker())
4085ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
4096buildThisParam(CGF, FunctionArgs);
4102&getContext().Idents.get(
"src"),
4103getContext().getLValueReferenceType(RecordTy,
4105ImplicitParamKind::Other);
4107FunctionArgs.push_back(&SrcParam);
4114&getContext().Idents.get(
"is_most_derived"),
4115getContext().IntTy, ImplicitParamKind::Other);
4118FunctionArgs.push_back(&IsMostDerived);
4126setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4127llvm::Value *
This= getThisValue(CGF);
4129llvm::Value *SrcVal =
4146assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
4147ArgVec.push_back(PD->getDefaultArg());
4150CodeGenFunction::RunCleanupsScope Cleanups(CGF);
4156AddedStructorArgCounts ExtraArgs =
4161llvm::Constant *CalleePtr =
4166Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4169Cleanups.ForceCleanup();
4178llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
4180int32_t VBPtrOffset,
4192 uint32_t Size= getContext().getTypeSizeInChars(
T).getQuantity();
4195llvm::raw_svector_ostream Out(MangledName);
4196getMangleContext().mangleCXXCatchableType(
T, CD, CT, Size, NVOffset,
4197VBPtrOffset, VBIndex, Out);
4199 if(llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4200 returngetImageRelativeConstant(GV);
4204llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(
T));
4208llvm::Constant *CopyCtor;
4215CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4217CopyCtor = getImageRelativeConstant(CopyCtor);
4219 boolIsScalar = !RD;
4220 boolHasVirtualBases =
false;
4221 boolIsStdBadAlloc =
false;
4236 if(HasVirtualBases)
4241llvm::Constant *Fields[] = {
4242llvm::ConstantInt::get(CGM.
IntTy, Flags),
4244llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4245llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4246llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4247llvm::ConstantInt::get(CGM.
IntTy, Size),
4250llvm::StructType *CTType = getCatchableTypeType();
4251 auto*GV =
newllvm::GlobalVariable(
4252CGM.
getModule(), CTType,
true, getLinkageForRTTI(
T),
4253llvm::ConstantStruct::get(CTType, Fields), MangledName);
4254GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4255GV->setSection(
".xdata");
4256 if(GV->isWeakForLinker())
4257GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4258 returngetImageRelativeConstant(GV);
4261llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4265llvm::GlobalVariable *&CTA = CatchableTypeArrays[
T];
4290 if(MostDerivedClass) {
4297Classes.front().initialize(
nullptr,
nullptr);
4299 for(
constMSRTTIClass &Class : Classes) {
4302(MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4307 if(
Class.VirtualRoot) {
4318CatchableTypes.insert(getCatchableType(RTTITy,
Class.OffsetInVBase,
4319VBPtrOffset, OffsetInVBTable));
4327CatchableTypes.insert(getCatchableType(
T));
4340CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4351CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4353 uint32_tNumEntries = CatchableTypes.size();
4354llvm::Type *CTType = getImageRelativeType(CGM.
UnqualPtrTy);
4355llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4356llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4357llvm::Constant *Fields[] = {
4358llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4359llvm::ConstantArray::get(
4361CatchableTypes.end()))
4365llvm::raw_svector_ostream Out(MangledName);
4366getMangleContext().mangleCXXCatchableTypeArray(
T, NumEntries, Out);
4368CTA =
newllvm::GlobalVariable(
4369CGM.
getModule(), CTAType,
true, getLinkageForRTTI(
T),
4370llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4371CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4372CTA->setSection(
".xdata");
4373 if(CTA->isWeakForLinker())
4374CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4378llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4379 boolIsConst, IsVolatile, IsUnaligned;
4384llvm::GlobalVariable *CTA = getCatchableTypeArray(
T);
4390cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0
U))
4391->getLimitedValue();
4395llvm::raw_svector_ostream Out(MangledName);
4396getMangleContext().mangleCXXThrowInfo(
T, IsConst, IsVolatile, IsUnaligned,
4402 if(llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4418llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4421 if(!DtorD->isTrivial())
4424llvm::Constant *ForwardCompat =
4425getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4426llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(CTA);
4427llvm::StructType *TIType = getThrowInfoType();
4428llvm::Constant *Fields[] = {
4429llvm::ConstantInt::get(CGM.
IntTy, Flags),
4430getImageRelativeConstant(CleanupFn),
4432PointerToCatchableTypes
4434 auto*GV =
newllvm::GlobalVariable(
4435CGM.
getModule(), TIType,
true, getLinkageForRTTI(
T),
4436llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4437GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4438GV->setSection(
".xdata");
4439 if(GV->isWeakForLinker())
4440GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4445 const Expr*SubExpr =
E->getSubExpr();
4446assert(SubExpr &&
"SubExpr cannot be null");
4456llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4463std::pair<llvm::Value *, const CXXRecordDecl *>
4466std::tie(This, std::ignore, RD) =
4471boolMicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4503 if(
const CXXRecordDecl*FRD = B.getType()->getAsCXXRecordDecl()) {
4504 if(!isPermittedToBeHomogeneousAggregate(FRD))
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *DynInitBB, llvm::BasicBlock *ContinueBB)
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty, CodeGenModule &CGM)
static llvm::FunctionCallee getInitThreadAbortFn(CodeGenModule &CGM)
static llvm::FunctionCallee getInitThreadHeaderFn(CodeGenModule &CGM)
static llvm::GlobalValue * getTlsGuardVar(CodeGenModule &CGM)
static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile, bool &IsUnaligned)
static llvm::CallBase * emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
static llvm::FunctionCallee getDynTlsOnDemandInitFn(CodeGenModule &CGM)
static void emitDynamicTlsInitializationCall(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *ContinueBB)
static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)
Find ambiguity among base classes.
static void emitDynamicTlsInitialization(CodeGenFunction &CGF)
static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)
Recursively serializes a class hierarchy in pre-order depth first order.
static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM)
static bool isDeletingDtor(GlobalDecl GD)
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
static ConstantAddress getInitThreadEpochPtr(CodeGenModule &CGM)
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo &VFPtr, SmallString< 256 > &Name)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
llvm::DenseSet< const void * > Visited
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.
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 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.
bool needsImplicitCopyAssignment() const
Determine whether this class needs an implicit copy assignment operator to be lazily declared.
bool hasSimpleCopyAssignment() const
true if we know for sure that this class has a single, accessible, unambiguous copy assignment operat...
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
A C++ throw-expression (C++ [except.throw]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
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.
bool hasProfileIRInstr() const
Check if IR level profile instrumentation is on.
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
void setSRetAfterThis(bool AfterThis)
bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const
isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous aggregate.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
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 CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
Implements C++ ABI-specific code generation functions.
virtual bool shouldEmitExactDynamicCast(QualType DestRecordTy)=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 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 bool shouldTypeidBeNullChecked(QualType SrcRecordTy)=0
virtual llvm::Type * ConvertMemberPointerType(const MemberPointerType *MPT)
Find the LLVM type used to represent the given member pointer type.
virtual llvm::Value * performThisAdjustment(CodeGenFunction &CGF, Address This, const CXXRecordDecl *UnadjustedClass, const ThunkInfo &TI)=0
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 llvm::Value * performReturnAdjustment(CodeGenFunction &CGF, Address Ret, const CXXRecordDecl *UnadjustedClass, const ReturnAdjustment &RA)=0
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 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.
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 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 llvm::Value * emitExactDynamicCast(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastSuccess, llvm::BasicBlock *CastFail)=0
Emit a dynamic_cast from SrcRecordTy to DestRecordTy.
virtual const CXXRecordDecl * getThisArgumentTypeForMethod(GlobalDecl GD)
Get the type of the implicit "this" parameter used by a method.
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 llvm::Value * EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke)=0
Emit the ABI-specific virtual destructor call.
virtual bool exportThunk()=0
virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0
virtual llvm::Value * emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy)=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 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::Value * emitDynamicCastCall(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd)=0
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.
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.
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass, VTableAuthMode AuthMode=VTableAuthMode::Authenticate)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
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)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
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...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void 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.
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.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
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="")
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="")
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::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.
const ABIInfo & getABIInfo()
DiagnosticsEngine & getDiags() const
llvm::Constant * getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the constructor/destructor of the given type.
llvm::GlobalValue::LinkageTypes getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage)
Returns LLVM linkage for a declarator.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void EmitGlobal(GlobalDecl D)
Emit code for a single global function or var decl.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
void AppendLinkerOptions(StringRef Opts)
Appends Opts to the "llvm.linker.options" metadata value.
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Try to emit a base destructor as an alias to its primary base-class destructor.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
llvm::Function * codegenCXXStructor(GlobalDecl GD)
llvm::Constant * CreateRuntimeVariable(llvm::Type *Ty, StringRef Name)
Create a new runtime global variable with the specified type and name.
void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const
Set the TLS mode for the given LLVM GlobalValue for the thread-local variable declaration D.
ASTContext & getContext() const
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
MicrosoftVTableContext & getMicrosoftVTableContext()
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, llvm::Align Alignment)
Will return a global variable of the given type.
llvm::LLVMContext & getLLVMContext()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const
llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void addDeferredVTable(const CXXRecordDecl *RD)
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Function * CreateGlobalInitOrCleanUpFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false, llvm::GlobalVariable::LinkageTypes Linkage=llvm::GlobalVariable::InternalLinkage)
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)
Arrange a thunk that takes 'this' as the first parameter followed by varargs.
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
const CGFunctionInfo & arrangeCXXStructorDeclaration(GlobalDecl GD)
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
void createVTableInitializer(ConstantStructBuilder &builder, const VTableLayout &layout, llvm::Constant *rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
llvm::Type * getVTableType(const VTableLayout &layout)
Returns the type of a vtable with the given layout.
A specialization of Address that requires the address to be an LLVM Constant.
The standard implementation of ConstantInitBuilder used in Clang.
Information for lazily generating a cleanup.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
An abstract representation of an aligned address.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
const LangOptions & getLangOpts() const LLVM_READONLY
Helper to get the language options from the ASTContext.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
ArrayRef< ParmVarDecl * > parameters() const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
bool isVariadic() const
Whether this function prototype is variadic.
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
GlobalDecl getWithDtorType(CXXDtorType Type)
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const
bool isExplicitDefaultVisibilityExportMapping() const
bool isAllDefaultVisibilityExportMapping() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
QualType getPointeeType() const
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
bool isMemberDataPointer() const
Returns true if the member type (i.e.
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived.
MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
Describes a module or submodule.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
bool isExternallyVisible() const
Represents a parameter to a function.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstQualified() const
Determine whether this type is const-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool hasUnaligned() const
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
Encodes a location in the source.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
const Type * getTypeForDecl() const
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isObjectType() const
Determine whether this type is an object type.
Linkage getLinkage() const
Determine the linkage of this type.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
Represents a single component in a vtable.
ArrayRef< VTableComponent > vtable_components() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)
Creates a Microsoft-family ABI.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
constexpr Variable var(Literal L)
Returns the variable of L.
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool Ret(InterpState &S, CodePtr &PC)
The JSON file list parser is used to communicate input to InstallAPI.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_DefaultClosure
Default closure variant of a ctor.
@ Ctor_CopyingClosure
Copying closure variant of a ctor.
@ Ctor_Complete
Complete object ctor.
GVALinkage
A more specific kind of linkage than enum Linkage.
void initialize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)
bool inheritanceModelHasOnlyOneField(bool IsMemberFunction, MSInheritanceModel Inheritance)
bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)
bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
CXXDtorType
C++ destructor types.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
CastKind
CastKind - The kind of operation required for a conversion.
const FunctionProtoType * T
MSInheritanceModel
Assigned inheritance model for a class in the MS C++ ABI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Implicit
An implicit conversion.
Diagnostic wrappers for TextAPI types for error reporting.
Similar to AddedStructorArgs, but only notes the number of additional arguments.
Additional implicit arguments to add to the beginning (Prefix) and end (Suffix) of a constructor / de...
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler,...
llvm::PointerType * VoidPtrTy
llvm::PointerType * Int8PtrPtrTy
CharUnits getIntAlign() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getIntSize() const
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy
llvm::PointerType * UnqualPtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
const CXXRecordDecl * VBase
If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.
CharUnits VFPtrOffset
This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...
uint64_t Index
Method's index in the vftable.
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
A this pointer adjustment.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
The this pointer adjustment as well as an optional return adjustment for a thunk.
ThisAdjustment This
The this pointer adjustment.
Holds information about the inheritance path to a virtual base or function table pointer.
CharUnits NonVirtualOffset
IntroducingObject is at this offset from its containing complete object or virtual base.
CharUnits FullOffsetInMDC
Static offset from the top of the most derived class to this vfptr, including any virtual base offset...
const CXXRecordDecl * getVBaseWithVPtr() const
The vptr is stored inside the non-virtual component of this virtual base.
const CXXRecordDecl * IntroducingObject
This is the class that introduced the vptr by declaring new virtual methods or virtual bases.
BasePath MangledPath
The bases from the inheritance path that got used to mangle the vbtable name.
BasePath PathToIntroducingObject
This holds the base classes path from the complete type to the first base with the given vfptr offset...
const CXXRecordDecl * ObjectWithVPtr
This is the most derived class that has this vptr at offset zero.
struct clang::ReturnAdjustment::VirtualAdjustment::@193 Microsoft
uint32_t VBPtrOffset
The offset (in bytes) of the vbptr, relative to the beginning of the derived class.
uint32_t VBIndex
Index of the virtual base in the vbtable.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...
struct clang::ThisAdjustment::VirtualAdjustment::@195 Microsoft
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4