30 #include "llvm/ADT/StringExtras.h"
31 #include "llvm/ADT/StringSet.h"
32 #include "llvm/IR/Intrinsics.h"
34 using namespace clang;
35 using namespace CodeGen;
40 struct VBTableGlobals {
45 class MicrosoftCXXABI :
public CGCXXABI {
48 :
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
49 ClassHierarchyDescriptorType(nullptr),
50 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
51 ThrowInfoType(nullptr) {
54 "visibility export mapping option unimplemented in this ABI");
57 bool HasThisReturn(
GlobalDecl GD)
const override;
58 bool hasMostDerivedReturn(
GlobalDecl GD)
const override;
64 bool isSRetParameterAfterThis()
const override {
return true; }
66 bool isThisCompleteObject(
GlobalDecl GD)
const override {
69 if (isa<CXXDestructorDecl>(GD.
getDecl())) {
78 case Dtor_Comdat: llvm_unreachable(
"emitting dtor comdat as function?");
80 llvm_unreachable(
"bad dtor kind");
89 assert(Args.size() >= 2 &&
90 "expected the arglist to have at least two args!");
99 std::vector<CharUnits> getVBPtrOffsets(
const CXXRecordDecl *RD)
override {
100 std::vector<CharUnits> VBPtrOffsets;
104 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
105 for (
const std::unique_ptr<VPtrInfo> &VBT : *VBGlobals.VBTables) {
110 if (VBT->getVBaseWithVPtr())
112 VBPtrOffsets.push_back(Offs);
114 llvm::array_pod_sort(VBPtrOffsets.begin(), VBPtrOffsets.end());
118 StringRef GetPureVirtualCallName()
override {
return "_purecall"; }
119 StringRef GetDeletedVirtualCallName()
override {
return "_purecall"; }
130 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
133 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
135 getAddrOfCXXCatchHandlerType(
QualType Ty,
QualType CatchHandlerType)
override;
141 if (getContext().getLangOpts().EHAsynch)
147 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
151 llvm::Type *StdTypeInfoPtrTy)
override;
153 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
156 bool shouldEmitExactDynamicCast(
QualType DestRecordTy)
override {
163 llvm::BasicBlock *CastSuccess,
164 llvm::BasicBlock *CastFail)
override {
165 llvm_unreachable(
"unsupported");
171 llvm::BasicBlock *CastEnd)
override;
177 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override {
230 AddedStructorArgCounts
240 void setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
244 llvm::GlobalValue::LinkageTypes
251 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
253 if (MD->isVirtual()) {
255 if (
const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
259 return MD->getParent();
277 return MD->getParent();
283 bool VirtualCall)
override;
294 bool Delegating)
override;
300 bool Delegating)
override;
308 llvm::GlobalVariable *VTable);
318 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *VTableClass)
override {
319 return !VTableClass->
hasAttr<MSNoVTableAttr>();
326 llvm::Value *getVTableAddressPointInStructor(
330 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
340 DeleteOrMemberCallExpr E)
override;
345 "Only deleting destructor thunks are available in this ABI");
350 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
352 llvm::GlobalVariable *
354 llvm::GlobalVariable::LinkageTypes
Linkage);
356 llvm::GlobalVariable *
360 llvm::raw_svector_ostream Out(OutName);
361 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
362 StringRef MangledName = OutName.str();
364 if (
auto *VDispMap = CGM.
getModule().getNamedGlobal(MangledName))
370 llvm::UndefValue::get(CGM.
IntTy));
371 Map[0] = llvm::ConstantInt::get(CGM.
IntTy, 0);
372 bool AnyDifferent =
false;
373 for (
const auto &I : SrcRD->
vbases()) {
374 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
380 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.
IntTy, DstVBIndex * 4);
381 AnyDifferent |= SrcVBIndex != DstVBIndex;
387 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.
IntTy, Map.size());
388 llvm::Constant *
Init = llvm::ConstantArray::get(VDispMapTy, Map);
389 llvm::GlobalValue::LinkageTypes
Linkage =
391 ? llvm::GlobalValue::LinkOnceODRLinkage
392 : llvm::GlobalValue::InternalLinkage;
393 auto *VDispMap =
new llvm::GlobalVariable(
400 llvm::GlobalVariable *GV)
const;
402 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
405 getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.
getDecl()));
408 Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
410 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
412 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
415 bool exportThunk()
override {
return false; }
423 void EmitThreadLocalInitFuncs(
428 bool usesThreadWrapperFunction(
const VarDecl *VD)
const override {
429 return getContext().getLangOpts().isCompatibleWithMSVC(
431 (!isEmittedWithConstantInitializer(VD) || mayNeedDestruction(VD));
437 llvm::GlobalVariable *DeclPtr,
438 bool PerformInit)
override;
440 llvm::FunctionCallee Dtor,
441 llvm::Constant *Addr)
override;
472 llvm::Value *NumElements,
479 friend struct MSRTTIBuilder;
481 bool isImageRelative()
const {
486 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
488 TDTypeName += llvm::utostr(TypeInfoString.size());
489 llvm::StructType *&TypeDescriptorType =
490 TypeDescriptorTypeMap[TypeInfoString.size()];
491 if (TypeDescriptorType)
492 return TypeDescriptorType;
493 llvm::Type *FieldTypes[] = {
496 llvm::ArrayType::get(CGM.
Int8Ty, TypeInfoString.size() + 1)};
499 return TypeDescriptorType;
502 llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
503 if (!isImageRelative())
508 llvm::StructType *getBaseClassDescriptorType() {
509 if (BaseClassDescriptorType)
510 return BaseClassDescriptorType;
511 llvm::Type *FieldTypes[] = {
518 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
522 return BaseClassDescriptorType;
525 llvm::StructType *getClassHierarchyDescriptorType() {
526 if (ClassHierarchyDescriptorType)
527 return ClassHierarchyDescriptorType;
531 llvm::Type *FieldTypes[] = {
535 getImageRelativeType(
536 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
538 ClassHierarchyDescriptorType->setBody(FieldTypes);
539 return ClassHierarchyDescriptorType;
542 llvm::StructType *getCompleteObjectLocatorType() {
543 if (CompleteObjectLocatorType)
544 return CompleteObjectLocatorType;
547 llvm::Type *FieldTypes[] = {
552 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
553 getImageRelativeType(CompleteObjectLocatorType),
556 if (!isImageRelative())
557 FieldTypesRef = FieldTypesRef.drop_back();
558 CompleteObjectLocatorType->setBody(FieldTypesRef);
559 return CompleteObjectLocatorType;
562 llvm::GlobalVariable *getImageBase() {
563 StringRef Name =
"__ImageBase";
564 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(Name))
569 llvm::GlobalValue::ExternalLinkage,
575 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
576 if (!isImageRelative())
579 if (PtrVal->isNullValue())
580 return llvm::Constant::getNullValue(CGM.
IntTy);
582 llvm::Constant *ImageBaseAsInt =
583 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.
IntPtrTy);
584 llvm::Constant *PtrValAsInt =
585 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.
IntPtrTy);
586 llvm::Constant *Diff =
587 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
589 return llvm::ConstantExpr::getTrunc(Diff, CGM.
IntTy);
597 llvm::Constant *getZeroInt() {
598 return llvm::ConstantInt::get(CGM.
IntTy, 0);
601 llvm::Constant *getAllOnesInt() {
602 return llvm::Constant::getAllOnesValue(CGM.
IntTy);
616 llvm::Value *VBPtrOffset,
617 llvm::Value *VBTableOffset,
618 llvm::Value **VBPtr =
nullptr);
623 int32_t VBTableOffset,
624 llvm::Value **VBPtr =
nullptr) {
625 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
626 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
627 *VBTOffset = llvm::ConstantInt::get(CGM.
IntTy, VBTableOffset);
628 return GetVBaseOffsetFromVBPtr(CGF,
Base, VBPOffset, VBTOffset, VBPtr);
631 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
639 llvm::Value *VirtualBaseAdjustmentOffset,
640 llvm::Value *VBPtrOffset );
644 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
645 bool IsMemberFunction,
648 unsigned VBTableIndex);
657 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
660 llvm::Function *EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
663 llvm::Constant *EmitMemberDataPointer(
const CXXRecordDecl *RD,
673 return RD->
hasAttr<MSInheritanceAttr>();
680 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
681 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
687 bool Inequality)
override;
698 llvm::Value *EmitNonNullMemberPointerConversion(
706 llvm::Value *Src)
override;
708 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
709 llvm::Constant *Src)
override;
711 llvm::Constant *EmitMemberPointerConversion(
724 llvm::StructType *getCatchableTypeType() {
725 if (CatchableTypeType)
726 return CatchableTypeType;
727 llvm::Type *FieldTypes[] = {
738 return CatchableTypeType;
741 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
742 llvm::StructType *&CatchableTypeArrayType =
743 CatchableTypeArrayTypeMap[NumEntries];
744 if (CatchableTypeArrayType)
745 return CatchableTypeArrayType;
748 CTATypeName += llvm::utostr(NumEntries);
750 getImageRelativeType(getCatchableTypeType()->getPointerTo());
751 llvm::Type *FieldTypes[] = {
753 llvm::ArrayType::get(CTType, NumEntries)
755 CatchableTypeArrayType =
757 return CatchableTypeArrayType;
760 llvm::StructType *getThrowInfoType() {
762 return ThrowInfoType;
763 llvm::Type *FieldTypes[] = {
771 return ThrowInfoType;
777 llvm::Type *Args[] = {CGM.
Int8PtrTy, getThrowInfoType()->getPointerTo()};
778 llvm::FunctionType *FTy =
779 llvm::FunctionType::get(CGM.
VoidTy, Args,
false);
780 llvm::FunctionCallee Throw =
784 if (
auto *Fn = dyn_cast<llvm::Function>(Throw.getCallee()))
785 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
793 llvm::Constant *getCatchableType(
QualType T,
794 uint32_t NVOffset = 0,
795 int32_t VBPtrOffset = -1,
796 uint32_t VBIndex = 0);
798 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
800 llvm::GlobalVariable *getThrowInfo(
QualType T)
override;
802 std::pair<llvm::Value *, const CXXRecordDecl *>
807 isPermittedToBeHomogeneousAggregate(
const CXXRecordDecl *RD)
const override;
810 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
811 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
812 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
814 VFTablesMapTy VFTablesMap;
815 VTablesMapTy VTablesMap;
822 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
827 GuardInfo() =
default;
828 llvm::GlobalVariable *Guard =
nullptr;
829 unsigned BitIndex = 0;
834 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
835 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
836 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
838 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
839 llvm::StructType *BaseClassDescriptorType;
840 llvm::StructType *ClassHierarchyDescriptorType;
841 llvm::StructType *CompleteObjectLocatorType;
843 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
845 llvm::StructType *CatchableTypeType;
846 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
847 llvm::StructType *ThrowInfoType;
865 case llvm::Triple::thumb:
871 case llvm::Triple::x86: {
882 return RAA_DirectInMemory;
885 case llvm::Triple::x86_64:
886 case llvm::Triple::aarch64:
890 llvm_unreachable(
"invalid enum");
902 llvm::Value *MDThis = EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr, DE);
907 void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
908 llvm::Value *Args[] = {
909 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
910 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
922 VarDecl *CatchParam = S->getExceptionDecl();
923 llvm::BasicBlock *CatchPadBB = CGF.
Builder.GetInsertBlock();
924 llvm::CatchPadInst *CPI =
925 cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
936 CPI->setArgOperand(2,
var.getObjectAddress(CGF).emitRawPointer(CGF));
944 std::tuple<Address, llvm::Value *, const CXXRecordDecl *>
955 return std::make_tuple(
Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0),
964 PolymorphicBase = BaseDecl;
968 assert(PolymorphicBase &&
"polymorphic class has no apparent vfptr?");
971 GetVirtualBaseClassOffset(CGF,
Value, SrcDecl, PolymorphicBase);
980 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
984 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
988 llvm::Value *Argument) {
989 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
990 llvm::FunctionType *FTy =
991 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
992 llvm::Value *Args[] = {Argument};
998 llvm::CallBase *
Call =
1000 Call->setDoesNotReturn();
1001 CGF.
Builder.CreateUnreachable();
1007 llvm::Type *StdTypeInfoPtrTy) {
1008 std::tie(ThisPtr, std::ignore, std::ignore) =
1009 performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
1011 return CGF.
Builder.CreateBitCast(Typeid, StdTypeInfoPtrTy);
1014 bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
1018 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
1021 llvm::Value *MicrosoftCXXABI::emitDynamicCastCall(
1023 QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
1025 llvm::Value *SrcRTTI =
1027 llvm::Value *DestRTTI =
1032 performBaseAdjustment(CGF,
This, SrcRecordTy);
1033 llvm::Value *ThisPtr =
This.emitRawPointer(CGF);
1045 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1047 llvm::Value *Args[] = {
1048 ThisPtr,
Offset, SrcRTTI, DestRTTI,
1053 llvm::Value *MicrosoftCXXABI::emitDynamicCastToVoid(
CodeGenFunction &CGF,
1056 std::tie(
Value, std::ignore, std::ignore) =
1057 performBaseAdjustment(CGF,
Value, SrcRecordTy);
1061 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
1063 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1065 llvm::Value *Args[] = {
Value.emitRawPointer(CGF)};
1073 llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1079 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.
PtrDiffTy, VBPtrChars);
1084 llvm::Value *VBTableOffset =
1087 llvm::Value *VBPtrToNewBase =
1088 GetVBaseOffsetFromVBPtr(CGF,
This, VBPtrOffset, VBTableOffset);
1091 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1094 bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1095 return isa<CXXConstructorDecl>(GD.
getDecl());
1099 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1103 bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1116 isa<VectorType>(
Base)) {
1153 if (
auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
1154 if (Ctor->isUserProvided())
1156 }
else if (
auto *Template = dyn_cast<FunctionTemplateDecl>(D)) {
1157 if (isa<CXXConstructorDecl>(Template->getTemplatedDecl()))
1159 }
else if (
auto *MethodDecl = dyn_cast<CXXMethodDecl>(D)) {
1160 if (MethodDecl->isCopyAssignmentOperator() && MethodDecl->isDeleted())
1180 if (isIndirectReturn) {
1201 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1202 assert(IsMostDerivedClass &&
1203 "ctor for a class with virtual bases must have an implicit parameter");
1204 llvm::Value *IsCompleteObject =
1205 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1207 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1208 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1209 CGF.
Builder.CreateCondBr(IsCompleteObject,
1210 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1215 EmitVBPtrStores(CGF, RD);
1219 return SkipVbaseCtorsBB;
1223 MicrosoftCXXABI::EmitDtorCompleteObjectHandler(
CodeGenFunction &CGF) {
1224 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1225 assert(IsMostDerivedClass &&
1226 "ctor for a class with virtual bases must have an implicit parameter");
1227 llvm::Value *IsCompleteObject =
1228 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1230 llvm::BasicBlock *CallVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.dtor_vbases");
1231 llvm::BasicBlock *SkipVbaseDtorsBB = CGF.
createBasicBlock(
"Dtor.skip_vbases");
1232 CGF.
Builder.CreateCondBr(IsCompleteObject,
1233 CallVbaseDtorsBB, SkipVbaseDtorsBB);
1238 return SkipVbaseDtorsBB;
1241 void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1261 llvm::Value *Int8This =
nullptr;
1264 const CXXRecordDecl *VBase = S.getType()->getAsCXXRecordDecl();
1265 auto I = VBaseMap.find(VBase);
1266 assert(I != VBaseMap.end());
1267 if (!I->second.hasVtorDisp())
1270 llvm::Value *VBaseOffset =
1271 GetVirtualBaseClassOffset(CGF, getThisAddress(CGF), RD, VBase);
1272 uint64_t ConstantVBaseOffset = I->second.VBaseOffset.getQuantity();
1275 llvm::Value *VtorDispValue = Builder.CreateSub(
1276 VBaseOffset, llvm::ConstantInt::get(CGM.
PtrDiffTy, ConstantVBaseOffset),
1278 VtorDispValue = Builder.CreateTruncOrBitCast(VtorDispValue, CGF.
Int32Ty);
1281 Int8This = getThisValue(CGF);
1283 llvm::Value *VtorDispPtr =
1284 Builder.CreateInBoundsGEP(CGF.
Int8Ty, Int8This, VBaseOffset);
1286 VtorDispPtr = Builder.CreateConstGEP1_32(CGF.
Int8Ty, VtorDispPtr, -4);
1288 Builder.CreateAlignedStore(VtorDispValue, VtorDispPtr,
1299 return ExpectedCallingConv == ActualCallingConv;
1314 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1327 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1328 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1329 const std::unique_ptr<VPtrInfo> &VBT = (*VBGlobals.VBTables)[I];
1330 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1335 if (VBT->getVBaseWithVPtr())
1338 llvm::Value *GVPtr =
1346 MicrosoftCXXABI::buildStructorSignature(
GlobalDecl GD,
1348 AddedStructorArgCounts Added;
1350 if (isa<CXXDestructorDecl>(GD.
getDecl()) &&
1353 ArgTys.push_back(getContext().IntTy);
1356 auto *CD = dyn_cast<CXXConstructorDecl>(GD.
getDecl());
1365 if (
Class->getNumVBases()) {
1367 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1370 ArgTys.push_back(getContext().IntTy);
1378 void MicrosoftCXXABI::setCXXDestructorDLLStorage(llvm::GlobalValue *GV,
1384 GV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1391 llvm::GlobalValue::LinkageTypes MicrosoftCXXABI::getCXXDestructorLinkage(
1396 return llvm::GlobalValue::InternalLinkage;
1407 if (Dtor->
hasAttr<DLLExportAttr>())
1408 return llvm::GlobalValue::WeakODRLinkage;
1409 if (Dtor->
hasAttr<DLLImportAttr>())
1410 return llvm::GlobalValue::AvailableExternallyLinkage;
1411 return llvm::GlobalValue::LinkOnceODRLinkage;
1416 return llvm::GlobalValue::LinkOnceODRLinkage;
1418 llvm_unreachable(
"MS C++ ABI does not support comdat dtors");
1420 llvm_unreachable(
"invalid dtor type");
1437 MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1459 if (isa<CXXDestructorDecl>(MD))
1464 getContext().getASTRecordLayout(MD->
getParent());
1471 Address MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1477 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1512 Result = Result.withElementType(CGF.
Int8Ty);
1516 llvm::Value *VBaseOffset =
1517 GetVirtualBaseClassOffset(CGF, Result, Derived, VBase);
1519 Result.getElementType(), Result.emitRawPointer(CGF), VBaseOffset);
1524 if (!StaticOffset.
isZero()) {
1526 Result = Result.withElementType(CGF.
Int8Ty);
1545 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1555 Params.insert(Params.begin() + 1, IsMostDerived);
1557 Params.push_back(IsMostDerived);
1558 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1564 Params.push_back(ShouldDelete);
1565 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1569 void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1586 llvm::Value *
This = loadIncomingCXXThis(CGF);
1589 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(CGF.
CurGD);
1590 if (!Adjustment.
isZero()) {
1596 setCXXABIThisValue(CGF,
This);
1606 if (HasThisReturn(CGF.
CurGD) || hasMostDerivedReturn(CGF.
CurGD))
1610 assert(getStructorImplicitParamDecl(CGF) &&
1611 "no implicit parameter for a constructor with virtual bases?");
1612 getStructorImplicitParamValue(CGF)
1619 assert(getStructorImplicitParamDecl(CGF) &&
1620 "no implicit parameter for a deleting destructor?");
1621 getStructorImplicitParamValue(CGF)
1624 "should_call_delete");
1630 bool ForVirtualBase,
bool Delegating) {
1635 return AddedStructorArgs{};
1639 llvm::Value *MostDerivedArg;
1641 MostDerivedArg = getStructorImplicitParamValue(CGF);
1646 return AddedStructorArgs::prefix({{MostDerivedArg, getContext().IntTy}});
1648 return AddedStructorArgs::suffix({{MostDerivedArg, getContext().IntTy}});
1653 bool ForVirtualBase,
bool Delegating) {
1673 "The deleting destructor should only be called via a virtual call");
1678 llvm::BasicBlock *BaseDtorEndBB =
nullptr;
1679 if (ForVirtualBase && isa<CXXConstructorDecl>(CGF.
CurCodeDecl)) {
1680 BaseDtorEndBB = EmitDtorCompleteObjectHandler(CGF);
1690 if (BaseDtorEndBB) {
1692 CGF.
Builder.CreateBr(BaseDtorEndBB);
1697 void MicrosoftCXXABI::emitVTableTypeMetadata(
const VPtrInfo &Info,
1699 llvm::GlobalVariable *VTable) {
1711 llvm::GlobalObject::VCallVisibility TypeVis =
1713 if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
1714 VTable->setVCallVisibilityMetadata(TypeVis);
1721 getContext().getLangOpts().RTTIData
1722 ? getContext().toCharUnitsFromBits(
1742 getContext().getASTRecordLayout(DerivedRD);
1748 Offset = VBI->second.VBaseOffset;
1759 void MicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables &CGVT,
1764 for (
const std::unique_ptr<VPtrInfo>& Info : VFPtrs) {
1765 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1766 if (VTable->hasInitializer())
1772 llvm::Constant *RTTI =
nullptr;
1775 RTTI = getMSCompleteObjectLocator(RD, *Info);
1778 auto components = builder.beginStruct();
1780 VTable->hasLocalLinkage());
1781 components.finishAndSetAsInitializer(VTable);
1783 emitVTableTypeMetadata(*Info, RD, VTable);
1787 bool MicrosoftCXXABI::isVirtualOffsetNeededForVTableField(
1792 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1795 llvm::Constant *VTableAddressPoint = getVTableAddressPoint(
Base, VTableClass);
1796 if (!VTableAddressPoint) {
1797 assert(
Base.getBase()->getNumVBases() &&
1798 !getContext().getASTRecordLayout(
Base.getBase()).hasOwnVFPtr());
1800 return VTableAddressPoint;
1806 llvm::raw_svector_ostream Out(Name);
1813 (void)getAddrOfVTable(VTableClass,
Base.getBaseOffset());
1814 VFTableIdTy
ID(VTableClass,
Base.getBaseOffset());
1815 return VFTablesMap[
ID];
1818 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1824 VFTableIdTy
ID(RD, VPtrOffset);
1825 VTablesMapTy::iterator I;
1827 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(
ID,
nullptr));
1831 llvm::GlobalVariable *&VTable = I->second;
1836 if (DeferredVFTables.insert(RD).second) {
1844 llvm::StringSet<> ObservedMangledNames;
1845 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1848 if (!ObservedMangledNames.insert(Name.str()).second)
1849 llvm_unreachable(
"Already saw this mangling before?");
1854 const std::unique_ptr<VPtrInfo> *VFPtrI =
1855 llvm::find_if(VFPtrs, [&](
const std::unique_ptr<VPtrInfo> &VPI) {
1856 return VPI->FullOffsetInMDC == VPtrOffset;
1858 if (VFPtrI == VFPtrs.end()) {
1859 VFTablesMap[
ID] =
nullptr;
1862 const std::unique_ptr<VPtrInfo> &VFPtr = *VFPtrI;
1874 llvm::GlobalValue::LinkageTypes VFTableLinkage =
1875 RD->
hasAttr<DLLImportAttr>() ? llvm::GlobalValue::LinkOnceODRLinkage
1877 bool VFTableComesFromAnotherTU =
1878 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1879 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1880 bool VTableAliasIsRequred =
1881 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1883 if (llvm::GlobalValue *VFTable =
1884 CGM.
getModule().getNamedGlobal(VFTableName)) {
1885 VFTablesMap[
ID] = VFTable;
1886 VTable = VTableAliasIsRequred
1887 ? cast<llvm::GlobalVariable>(
1888 cast<llvm::GlobalAlias>(VFTable)->getAliaseeObject())
1889 :
cast<
llvm::GlobalVariable>(VFTable);
1895 llvm::GlobalValue::LinkageTypes VTableLinkage =
1896 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1898 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1904 llvm::GlobalValue *VFTable;
1905 VTable =
new llvm::GlobalVariable(CGM.
getModule(), VTableType,
1906 true, VTableLinkage,
1907 nullptr, VTableName);
1908 VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1910 llvm::Comdat *
C =
nullptr;
1911 if (!VFTableComesFromAnotherTU &&
1912 llvm::GlobalValue::isWeakForLinker(VFTableLinkage))
1913 C = CGM.
getModule().getOrInsertComdat(VFTableName.str());
1918 if (VTableAliasIsRequred) {
1919 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1920 llvm::ConstantInt::get(CGM.
Int32Ty, 0),
1921 llvm::ConstantInt::get(CGM.
Int32Ty, 1)};
1924 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1925 VTable->getValueType(), VTable, GEPIndices);
1926 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1927 VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
1929 C->setSelectionKind(llvm::Comdat::Largest);
1933 VFTableName.str(), VTableGEP,
1935 VFTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
1944 VTable->setComdat(C);
1946 if (RD->
hasAttr<DLLExportAttr>())
1947 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1949 VFTablesMap[
ID] = VFTable;
1960 Ty = Ty->getPointerTo();
1962 adjustThisArgumentForVirtualFunctionCall(CGF, GD,
This,
true);
1964 auto *MethodDecl = cast<CXXMethodDecl>(GD.
getDecl());
1965 llvm::Value *VTable = CGF.
GetVTablePtr(VPtr, Ty->getPointerTo(),
1966 MethodDecl->getParent());
1973 auto getObjectWithVPtr = [&] {
1976 [&](
const std::unique_ptr<VPtrInfo> &Info) {
1977 return Info->FullOffsetInMDC == ML.VFPtrOffset;
1986 getObjectWithVPtr(), VTable, Ty,
1994 llvm::Value *VFuncPtr =
1995 Builder.CreateConstInBoundsGEP1_64(Ty, VTable, ML.
Index,
"vfn");
1996 VFunc = Builder.CreateAlignedLoad(Ty, VFuncPtr, CGF.
getPointerAlign());
2003 llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
2008 assert((CE !=
nullptr) ^ (D !=
nullptr));
2009 assert(CE ==
nullptr || CE->arg_begin() == CE->arg_end());
2021 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
2027 ThisTy = CE->getObjectType();
2029 ThisTy = D->getDestroyedType();
2032 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD,
This,
true);
2035 ImplicitParam, Context.
IntTy, CE);
2039 const VBTableGlobals &
2040 MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
2043 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
2045 std::tie(Entry, Added) =
2046 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
2047 VBTableGlobals &VBGlobals = Entry->second;
2052 VBGlobals.VBTables = &Context.enumerateVBTables(RD);
2057 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
2058 E = VBGlobals.VBTables->end();
2060 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD,
Linkage));
2067 MicrosoftCXXABI::EmitVirtualMemPtrThunk(
const CXXMethodDecl *MD,
2069 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
2070 "can't form pointers to ctors or virtual dtors");
2074 llvm::raw_svector_ostream Out(ThunkName);
2075 getMangleContext().mangleVirtualMemPtrThunk(MD, ML, Out);
2078 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
2079 return cast<llvm::Function>(GV);
2085 llvm::Function *ThunkFn =
2086 llvm::Function::Create(ThunkTy, llvm::Function::ExternalLinkage,
2088 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
2091 ? llvm::GlobalValue::LinkOnceODRLinkage
2092 : llvm::GlobalValue::InternalLinkage);
2094 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
2103 ThunkFn->addFnAttr(
"thunk");
2116 buildThisParam(CGF, FunctionArgs);
2123 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
2127 llvm::Type *ThunkPtrTy = ThunkTy->getPointerTo();
2129 getThisAddress(CGF), ThunkPtrTy->getPointerTo(), MD->
getParent());
2131 llvm::Value *VFuncPtr = CGF.
Builder.CreateConstInBoundsGEP1_64(
2132 ThunkPtrTy, VTable, ML.
Index,
"vfn");
2141 void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
2142 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
2143 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
2144 const std::unique_ptr<VPtrInfo>& VBT = (*VBGlobals.VBTables)[I];
2145 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
2146 if (GV->isDeclaration())
2147 emitVBTableDefinition(*VBT, RD, GV);
2151 llvm::GlobalVariable *
2153 llvm::GlobalVariable::LinkageTypes
Linkage) {
2155 llvm::raw_svector_ostream Out(OutName);
2156 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
2157 StringRef Name = OutName.str();
2159 llvm::ArrayType *VBTableType =
2162 assert(!CGM.
getModule().getNamedGlobal(Name) &&
2163 "vbtable with this name already exists: mangling bug?");
2168 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
2170 if (RD->
hasAttr<DLLImportAttr>())
2171 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
2172 else if (RD->
hasAttr<DLLExportAttr>())
2173 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
2175 if (!GV->hasExternalLinkage())
2176 emitVBTableDefinition(VBT, RD, GV);
2181 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
2183 llvm::GlobalVariable *GV)
const {
2187 "should only emit vbtables for classes with vbtables");
2191 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
2198 Offsets[0] = llvm::ConstantInt::get(CGM.
IntTy, -VBPtrOffset.
getQuantity());
2201 for (
const auto &I : ObjectWithVPtr->
vbases()) {
2202 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
2204 assert(!
Offset.isNegative());
2209 CompleteVBPtrOffset +=
2211 Offset -= CompleteVBPtrOffset;
2213 unsigned VBIndex = Context.getVBTableIndex(ObjectWithVPtr, VBase);
2214 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
2215 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.
IntTy,
Offset.getQuantity());
2218 assert(Offsets.size() ==
2219 cast<llvm::ArrayType>(GV->getValueType())->getNumElements());
2220 llvm::ArrayType *VBTableType =
2221 llvm::ArrayType::get(CGM.
IntTy, Offsets.size());
2222 llvm::Constant *
Init = llvm::ConstantArray::get(VBTableType, Offsets);
2223 GV->setInitializer(Init);
2225 if (RD->
hasAttr<DLLImportAttr>())
2226 GV->setLinkage(llvm::GlobalVariable::AvailableExternallyLinkage);
2229 llvm::Value *MicrosoftCXXABI::performThisAdjustment(
CodeGenFunction &CGF,
2233 return This.emitRawPointer(CGF);
2239 V =
This.emitRawPointer(CGF);
2249 CGF.
Builder.CreateNeg(VtorDisp));
2262 llvm::Value *VBaseOffset = GetVBaseOffsetFromVBPtr(
2285 return Ret.emitRawPointer(CGF);
2289 llvm::Value *
V =
Ret.emitRawPointer(CGF);
2294 llvm::Value *VBaseOffset =
2313 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *
expr) {
2316 return expr->getAllocatedType().isDestructedType();
2327 llvm::Value *MicrosoftCXXABI::readArrayCookieImpl(
CodeGenFunction &CGF,
2336 llvm::Value *numElements,
2339 assert(requiresArrayCookie(
expr));
2342 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2357 llvm::FunctionCallee Dtor,
2358 llvm::Constant *Addr) {
2363 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2364 CGF.
IntTy, DtorStub->getType(),
false);
2367 TLRegDtorTy,
"__tlregdtor", llvm::AttributeList(),
true);
2368 if (llvm::Function *TLRegDtorFn =
2369 dyn_cast<llvm::Function>(TLRegDtor.getCallee()))
2370 TLRegDtorFn->setDoesNotThrow();
2376 llvm::FunctionCallee Dtor,
2377 llvm::Constant *Addr) {
2392 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2396 if (CXXThreadLocalInits.empty())
2401 ?
"/include:___dyn_tls_init@12"
2402 :
"/include:__dyn_tls_init");
2407 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2408 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2409 CGM.
getModule(), InitFunc->getType(),
true,
2410 llvm::GlobalVariable::InternalLinkage, InitFunc,
2411 Twine(InitFunc->getName(),
"$initializer$"));
2412 InitFuncPtr->setSection(
".CRT$XDU");
2419 std::vector<llvm::Function *> NonComdatInits;
2420 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2421 llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(
2423 llvm::Function *F = CXXThreadLocalInits[I];
2426 if (llvm::Comdat *C = GV->getComdat())
2427 AddToXDU(F)->setComdat(C);
2429 NonComdatInits.push_back(F);
2432 if (!NonComdatInits.empty()) {
2433 llvm::FunctionType *FTy =
2434 llvm::FunctionType::get(CGM.
VoidTy,
false);
2450 llvm::Constant *TlsGuardConstant =
2452 llvm::GlobalValue *TlsGuard = cast<llvm::GlobalValue>(TlsGuardConstant);
2454 TlsGuard->setThreadLocal(
true);
2462 llvm::FunctionType *FTy =
2463 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()), {},
2466 FTy,
"__dyn_tls_on_demand_init",
2468 llvm::AttributeList::FunctionIndex,
2469 llvm::Attribute::NoUnwind),
2474 llvm::BasicBlock *DynInitBB,
2475 llvm::BasicBlock *ContinueBB) {
2476 llvm::LoadInst *TlsGuardValue =
2478 llvm::Value *CmpResult =
2480 CGF.
Builder.CreateCondBr(CmpResult, DynInitBB, ContinueBB);
2484 llvm::GlobalValue *TlsGuard,
2485 llvm::BasicBlock *ContinueBB) {
2487 llvm::Function *InitializerFunction =
2489 llvm::CallInst *CallVal = CGF.
Builder.CreateCall(InitializerFunction);
2490 CallVal->setCallingConv(InitializerFunction->getCallingConv());
2492 CGF.
Builder.CreateBr(ContinueBB);
2496 llvm::BasicBlock *DynInitBB =
2498 llvm::BasicBlock *ContinueBB =
2504 CGF.
Builder.SetInsertPoint(DynInitBB);
2506 CGF.
Builder.SetInsertPoint(ContinueBB);
2525 Address Addr(
V, RealVarTy, Alignment);
2535 StringRef VarName(
"_Init_thread_epoch");
2537 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2539 auto *GV =
new llvm::GlobalVariable(
2541 false, llvm::GlobalVariable::ExternalLinkage,
2543 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2549 llvm::FunctionType *FTy =
2550 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2551 CGM.
IntTy->getPointerTo(),
false);
2553 FTy,
"_Init_thread_header",
2555 llvm::AttributeList::FunctionIndex,
2556 llvm::Attribute::NoUnwind),
2561 llvm::FunctionType *FTy =
2562 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2563 CGM.
IntTy->getPointerTo(),
false);
2565 FTy,
"_Init_thread_footer",
2567 llvm::AttributeList::FunctionIndex,
2568 llvm::Attribute::NoUnwind),
2573 llvm::FunctionType *FTy =
2574 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2575 CGM.
IntTy->getPointerTo(),
false);
2577 FTy,
"_Init_thread_abort",
2579 llvm::AttributeList::FunctionIndex,
2580 llvm::Attribute::NoUnwind),
2588 ResetGuardBit(
Address Guard,
unsigned GuardNum)
2589 : Guard(Guard), GuardNum(GuardNum) {}
2595 llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2596 llvm::ConstantInt *Mask =
2597 llvm::ConstantInt::get(CGF.
IntTy, ~(1ULL << GuardNum));
2598 Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2604 CallInitThreadAbort(
RawAddress Guard) : Guard(Guard.getPointer()) {}
2614 llvm::GlobalVariable *GV,
2618 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2620 llvm::Function *F = CGF.
CurFn;
2621 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2622 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2628 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2632 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2635 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2636 llvm::ConstantInt *
Zero = llvm::ConstantInt::get(GuardTy, 0);
2640 GuardInfo *GI =
nullptr;
2641 if (ThreadlocalStatic)
2643 else if (!ThreadsafeStatic)
2646 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2651 GuardNum = getContext().getStaticLocalNumber(&D);
2652 assert(GuardNum > 0);
2654 }
else if (HasPerVariableGuard) {
2658 GuardNum = GI->BitIndex++;
2661 if (!HasPerVariableGuard && GuardNum >= 32) {
2663 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2672 llvm::raw_svector_ostream Out(GuardName);
2673 if (HasPerVariableGuard)
2674 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2677 getMangleContext().mangleStaticGuardVariable(&D, Out);
2683 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2684 GV->getLinkage(), Zero, GuardName.str());
2685 GuardVar->setVisibility(GV->getVisibility());
2686 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2687 GuardVar->setAlignment(GuardAlign.
getAsAlign());
2688 if (GuardVar->isWeakForLinker())
2689 GuardVar->setComdat(
2690 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2693 if (GI && !HasPerVariableGuard)
2694 GI->Guard = GuardVar;
2699 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2700 "static local from the same function had different linkage");
2702 if (!HasPerVariableGuard) {
2710 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1ULL << GuardNum);
2711 llvm::LoadInst *LI = Builder.CreateLoad(GuardAddr);
2712 llvm::Value *NeedsInit =
2713 Builder.CreateICmpEQ(Builder.CreateAnd(LI, Bit), Zero);
2722 Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardAddr);
2726 Builder.CreateBr(EndBlock);
2744 llvm::LoadInst *FirstGuardLoad = Builder.CreateLoad(GuardAddr);
2745 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2746 llvm::LoadInst *InitThreadEpoch =
2748 llvm::Value *IsUninitialized =
2749 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2759 GuardAddr.getPointer());
2760 llvm::LoadInst *SecondGuardLoad = Builder.CreateLoad(GuardAddr);
2761 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2762 llvm::Value *ShouldDoInit =
2763 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2765 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2773 GuardAddr.getPointer());
2774 Builder.CreateBr(EndBlock);
2803 fields.push_back(CGM.
IntTy);
2807 fields.push_back(CGM.
IntTy);
2809 fields.push_back(CGM.
IntTy);
2811 fields.push_back(CGM.
IntTy);
2813 if (fields.size() == 1)
2818 void MicrosoftCXXABI::
2821 assert(fields.empty());
2826 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2829 fields.push_back(getZeroInt());
2831 fields.push_back(getAllOnesInt());
2836 fields.push_back(getZeroInt());
2838 fields.push_back(getZeroInt());
2840 fields.push_back(getAllOnesInt());
2846 GetNullMemberPointerFields(MPT, fields);
2847 if (fields.size() == 1)
2849 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2850 assert(Res->getType() == ConvertMemberPointerType(MPT));
2855 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2856 bool IsMemberFunction,
2859 unsigned VBTableIndex) {
2868 fields.push_back(FirstField);
2871 fields.push_back(llvm::ConstantInt::get(
2877 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2883 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2885 return llvm::ConstantStruct::getAnon(fields);
2894 llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(
const CXXRecordDecl *RD,
2898 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2899 llvm::Constant *FirstField =
2901 return EmitFullMemberPointer(FirstField,
false, RD,
2905 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2910 return EmitNullMemberPointer(DstTy);
2916 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2917 C = EmitMemberFunctionPointer(MD);
2924 const FieldDecl *FD = dyn_cast<FieldDecl>(MPD);
2926 FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
2929 C = EmitMemberDataPointer(RD, FieldOffset);
2932 if (!MemberPointerPath.empty()) {
2933 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2945 if (DerivedMember) {
2953 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2954 Base->getCanonicalDecl())
2955 DerivedToBasePath.push_back(&BS);
2958 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2960 CastKind CK = DerivedMember ? CK_DerivedToBaseMemberPointer
2961 : CK_BaseToDerivedMemberPointer;
2962 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2963 DerivedToBasePath.end(), C);
2969 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2970 assert(MD->
isInstance() &&
"Member function must not be static!");
2976 unsigned VBTableIndex = 0;
2977 llvm::Constant *FirstField;
2982 if (Types.isFuncTypeConvertible(FPT)) {
2984 Ty = Types.GetFunctionType(Types.arrangeCXXMethodDeclaration(MD));
2994 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2998 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
3001 if (VBTableIndex == 0 &&
3004 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
3007 return EmitFullMemberPointer(FirstField,
true, RD,
3008 NonVirtualBaseAdjustment, VBTableIndex);
3023 llvm::ICmpInst::Predicate
Eq;
3024 llvm::Instruction::BinaryOps
And,
Or;
3026 Eq = llvm::ICmpInst::ICMP_NE;
3027 And = llvm::Instruction::Or;
3030 Eq = llvm::ICmpInst::ICMP_EQ;
3032 Or = llvm::Instruction::Or;
3041 return Builder.CreateICmp(Eq, L, R);
3044 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
3045 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
3046 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
3049 llvm::Value *Res =
nullptr;
3050 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
3051 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
3052 llvm::Value *LF = Builder.CreateExtractValue(L, I);
3053 llvm::Value *RF = Builder.CreateExtractValue(R, I);
3054 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
3056 Res = Builder.CreateBinOp(And, Res, Cmp);
3064 llvm::Value *
Zero = llvm::Constant::getNullValue(L0->getType());
3065 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero,
"memptr.cmp.iszero");
3066 Res = Builder.CreateBinOp(Or, Res, IsZero);
3071 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
3076 llvm::Value *MemPtr,
3082 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
3084 GetNullMemberPointerFields(MPT, fields);
3085 assert(!fields.empty());
3086 llvm::Value *FirstField = MemPtr;
3087 if (MemPtr->getType()->isStructTy())
3088 FirstField = Builder.CreateExtractValue(MemPtr, 0);
3089 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
3097 for (
int I = 1, E = fields.size(); I < E; ++I) {
3098 llvm::Value *
Field = Builder.CreateExtractValue(MemPtr, I);
3099 llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
3100 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
3106 llvm::Constant *Val) {
3109 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
3110 Val->getAggregateElement(0
U) : Val;
3111 return FirstField->isNullValue();
3116 if (isZeroInitializable(MPT) && Val->isNullValue())
3122 GetNullMemberPointerFields(MPT, Fields);
3123 if (Fields.size() == 1) {
3124 assert(Val->getType()->isIntegerTy());
3125 return Val == Fields[0];
3129 for (I = 0, E = Fields.size(); I != E; ++I) {
3130 if (Val->getAggregateElement(I) != Fields[I])
3139 llvm::Value *VBPtrOffset,
3140 llvm::Value *VBTableOffset,
3141 llvm::Value **VBPtrOut) {
3144 llvm::Value *VBPtr = Builder.CreateInBoundsGEP(
3145 CGM.
Int8Ty,
This.emitRawPointer(CGF), VBPtrOffset,
"vbptr");
3150 if (
auto CI = dyn_cast<llvm::ConstantInt>(VBPtrOffset)) {
3151 VBPtrAlign =
This.getAlignment().alignmentAtOffset(
3157 llvm::Value *VBTable = Builder.CreateAlignedLoad(
3158 CGM.
Int32Ty->getPointerTo(0), VBPtr, VBPtrAlign,
"vbtable");
3161 llvm::Value *VBTableIndex = Builder.CreateAShr(
3162 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
3166 llvm::Value *VBaseOffs =
3167 Builder.CreateInBoundsGEP(CGM.
Int32Ty, VBTable, VBTableIndex);
3168 return Builder.CreateAlignedLoad(CGM.
Int32Ty, VBaseOffs,
3174 llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
3176 Address Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
3179 llvm::BasicBlock *OriginalBB =
nullptr;
3180 llvm::BasicBlock *SkipAdjustBB =
nullptr;
3181 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
3188 OriginalBB = Builder.GetInsertBlock();
3191 llvm::Value *IsVirtual =
3192 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
3194 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
3206 "member pointer representation requires a "
3207 "complete class type for %0 to perform this expression");
3210 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
3213 llvm::Value *VBPtr =
nullptr;
3214 llvm::Value *VBaseOffs =
3215 GetVBaseOffsetFromVBPtr(CGF,
Base, VBPtrOffset, VBTableOffset, &VBPtr);
3216 llvm::Value *AdjustedBase =
3217 Builder.CreateInBoundsGEP(CGM.
Int8Ty, VBPtr, VBaseOffs);
3220 if (VBaseAdjustBB) {
3221 Builder.CreateBr(SkipAdjustBB);
3223 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
3224 Phi->addIncoming(
Base.emitRawPointer(CGF), OriginalBB);
3225 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
3228 return AdjustedBase;
3231 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
3241 llvm::Value *FieldOffset = MemPtr;
3242 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3243 llvm::Value *VBPtrOffset =
nullptr;
3244 if (MemPtr->getType()->isStructTy()) {
3247 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
3249 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3251 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3255 if (VirtualBaseAdjustmentOffset) {
3256 Addr = AdjustVirtualBase(CGF, E, RD,
Base, VirtualBaseAdjustmentOffset,
3259 Addr =
Base.emitRawPointer(CGF);
3263 return Builder.CreateInBoundsGEP(CGF.
Int8Ty, Addr, FieldOffset,
3271 assert(E->
getCastKind() == CK_DerivedToBaseMemberPointer ||
3272 E->
getCastKind() == CK_BaseToDerivedMemberPointer ||
3276 if (isa<llvm::Constant>(Src))
3277 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
3287 bool IsReinterpret = E->
getCastKind() == CK_ReinterpretMemberPointer;
3288 if (IsReinterpret && IsFunc)
3293 if (IsReinterpret &&
3300 llvm::Value *
IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
3301 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
3305 if (IsReinterpret) {
3308 assert(Src->getType() == DstNull->getType());
3309 return Builder.CreateSelect(IsNotNull, Src, DstNull);
3312 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
3315 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
3318 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
3322 Builder.CreateBr(ContinueBB);
3326 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
3327 Phi->addIncoming(DstNull, OriginalBB);
3328 Phi->addIncoming(Dst, ConvertBB);
3332 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
3342 bool IsConstant = isa<llvm::Constant>(Src);
3345 llvm::Value *FirstField = Src;
3346 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
3347 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
3348 llvm::Value *VBPtrOffset = getZeroInt();
3352 FirstField = Builder.CreateExtractValue(Src, I++);
3354 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
3356 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
3358 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
3361 bool IsDerivedToBase = (CK == CK_DerivedToBaseMemberPointer);
3367 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3374 llvm::Value *SrcVBIndexEqZero =
3375 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3377 if (
int64_t SrcOffsetToFirstVBase =
3378 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3379 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3381 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3383 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3394 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3399 llvm::Value *NVDisp;
3400 if (IsDerivedToBase)
3401 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3403 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3405 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3409 llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero;
3412 if (llvm::GlobalVariable *VDispMap =
3413 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3414 llvm::Value *VBIndex = Builder.CreateExactUDiv(
3415 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3417 llvm::Constant *Mapping = VDispMap->getInitializer();
3418 VirtualBaseAdjustmentOffset =
3419 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3421 llvm::Value *Idxs[] = {getZeroInt(), VBIndex};
3422 VirtualBaseAdjustmentOffset = Builder.CreateAlignedLoad(
3423 CGM.
IntTy, Builder.CreateInBoundsGEP(VDispMap->getValueType(),
3429 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3436 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3438 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3440 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3447 if (
int64_t DstOffsetToFirstVBase =
3448 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3449 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3451 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3453 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3462 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3464 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3466 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3468 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3470 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3476 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3477 llvm::Constant *Src) {
3484 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3488 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3492 assert(CK == CK_DerivedToBaseMemberPointer ||
3493 CK == CK_BaseToDerivedMemberPointer ||
3494 CK == CK_ReinterpretMemberPointer);
3497 if (MemberPointerConstantIsNull(SrcTy, Src))
3498 return EmitNullMemberPointer(DstTy);
3503 if (CK == CK_ReinterpretMemberPointer)
3507 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3508 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3513 CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3515 llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr,
3527 llvm::Value *FunctionPointer = MemPtr;
3528 llvm::Value *NonVirtualBaseAdjustment =
nullptr;
3529 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3530 llvm::Value *VBPtrOffset =
nullptr;
3531 if (MemPtr->getType()->isStructTy()) {
3534 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3536 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3538 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3540 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3543 if (VirtualBaseAdjustmentOffset) {
3544 ThisPtrForCall = AdjustVirtualBase(CGF, E, RD,
This,
3545 VirtualBaseAdjustmentOffset, VBPtrOffset);
3547 ThisPtrForCall =
This.emitRawPointer(CGF);
3550 if (NonVirtualBaseAdjustment)
3551 ThisPtrForCall = Builder.CreateInBoundsGEP(CGF.
Int8Ty, ThisPtrForCall,
3552 NonVirtualBaseAdjustment);
3559 return new MicrosoftCXXABI(CGM);
3593 StringRef MangledName(
"??_7type_info@@6B@");
3594 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3598 llvm::GlobalVariable::ExternalLinkage,
3599 nullptr, MangledName);
3610 struct MSRTTIClass {
3612 IsPrivateOnPath = 1 | 8,
3616 HasHierarchyDescriptor = 64
3622 MSRTTIClass *getFirstChild() {
return this + 1; }
3623 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3624 return Child + 1 + Child->NumBases;
3628 uint32_t Flags, NumBases, OffsetInVBase;
3634 Flags = HasHierarchyDescriptor;
3636 VirtualRoot =
nullptr;
3640 Flags |= IsPrivate | IsPrivateOnPath;
3646 if (
Parent->Flags & IsPrivateOnPath)
3647 Flags |= IsPrivateOnPath;
3648 VirtualRoot =
Parent->VirtualRoot;
3649 OffsetInVBase =
Parent->OffsetInVBase + RD->getASTContext()
3650 .getASTRecordLayout(
Parent->RD).getBaseClassOffset(RD).getQuantity();
3654 MSRTTIClass *Child = getFirstChild();
3656 NumBases += Child->initialize(
this, &
Base) + 1;
3657 Child = getNextChild(Child);
3662 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3665 llvm_unreachable(
"Linkage hasn't been computed!");
3670 return llvm::GlobalValue::InternalLinkage;
3675 return llvm::GlobalValue::LinkOnceODRLinkage;
3677 llvm_unreachable(
"Invalid linkage!");
3683 struct MSRTTIBuilder {
3685 HasBranchingHierarchy = 1,
3686 HasVirtualBranchingHierarchy = 2,
3687 HasAmbiguousBases = 4
3690 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3691 : CGM(ABI.CGM), Context(CGM.getContext()),
3692 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3693 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3696 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3697 llvm::GlobalVariable *
3699 llvm::GlobalVariable *getClassHierarchyDescriptor();
3700 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo &Info);
3704 llvm::LLVMContext &VMContext;
3707 llvm::GlobalVariable::LinkageTypes
Linkage;
3708 MicrosoftCXXABI &ABI;
3717 Classes.push_back(MSRTTIClass(RD));
3728 for (MSRTTIClass *
Class = &Classes.front();
Class <= &Classes.back();) {
3729 if ((
Class->Flags & MSRTTIClass::IsVirtual) &&
3730 !VirtualBases.insert(
Class->RD).second) {
3734 if (!UniqueBases.insert(
Class->RD).second)
3735 AmbiguousBases.insert(
Class->RD);
3738 if (AmbiguousBases.empty())
3740 for (MSRTTIClass &
Class : Classes)
3741 if (AmbiguousBases.count(
Class.RD))
3742 Class.Flags |= MSRTTIClass::IsAmbiguous;
3745 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3748 llvm::raw_svector_ostream Out(MangledName);
3749 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3753 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3759 Classes.front().initialize(
nullptr,
nullptr);
3762 for (
const MSRTTIClass &Class : Classes) {
3763 if (
Class.RD->getNumBases() > 1)
3764 Flags |= HasBranchingHierarchy;
3767 if (
Class.Flags & MSRTTIClass::IsAmbiguous)
3768 Flags |= HasAmbiguousBases;
3770 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3771 Flags |= HasVirtualBranchingHierarchy;
3774 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.
IntTy, 0),
3775 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3778 auto Type = ABI.getClassHierarchyDescriptorType();
3782 if (CHD->isWeakForLinker())
3783 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3785 auto *Bases = getBaseClassArray(Classes);
3788 llvm::Constant *Fields[] = {
3789 llvm::ConstantInt::get(CGM.
IntTy, 0),
3790 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3791 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3792 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3793 Bases->getValueType(), Bases,
3796 CHD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3800 llvm::GlobalVariable *
3804 llvm::raw_svector_ostream Out(MangledName);
3805 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3813 llvm::Type *PtrType = ABI.getImageRelativeType(
3814 ABI.getBaseClassDescriptorType()->getPointerTo());
3815 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3817 new llvm::GlobalVariable(
Module, ArrType,
3819 nullptr, MangledName);
3820 if (BCA->isWeakForLinker())
3821 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3825 for (MSRTTIClass &Class : Classes)
3826 BaseClassArrayData.push_back(
3827 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3828 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3829 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3833 llvm::GlobalVariable *
3834 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3837 uint32_t OffsetInVBTable = 0;
3838 int32_t VBPtrOffset = -1;
3839 if (
Class.VirtualRoot) {
3847 llvm::raw_svector_ostream Out(MangledName);
3848 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3849 Class.RD,
Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3854 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3858 auto Type = ABI.getBaseClassDescriptorType();
3861 nullptr, MangledName);
3862 if (BCD->isWeakForLinker())
3863 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3866 llvm::Constant *Fields[] = {
3867 ABI.getImageRelativeConstant(
3869 llvm::ConstantInt::get(CGM.
IntTy,
Class.NumBases),
3870 llvm::ConstantInt::get(CGM.
IntTy,
Class.OffsetInVBase),
3871 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3872 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3873 llvm::ConstantInt::get(CGM.
IntTy,
Class.Flags),
3874 ABI.getImageRelativeConstant(
3875 MSRTTIBuilder(ABI,
Class.RD).getClassHierarchyDescriptor()),
3877 BCD->setInitializer(llvm::ConstantStruct::get(
Type, Fields));
3881 llvm::GlobalVariable *
3882 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo &Info) {
3885 llvm::raw_svector_ostream Out(MangledName);
3886 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info.
MangledPath, Out);
3890 if (
auto COL =
Module.getNamedGlobal(MangledName))
3895 int VFPtrOffset = 0;
3901 ->second.hasVtorDisp())
3905 llvm::StructType *
Type = ABI.getCompleteObjectLocatorType();
3907 nullptr, MangledName);
3910 llvm::Constant *Fields[] = {
3911 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3912 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3913 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3914 ABI.getImageRelativeConstant(
3916 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3917 ABI.getImageRelativeConstant(COL),
3920 if (!ABI.isImageRelative())
3921 FieldsRef = FieldsRef.drop_back();
3922 COL->setInitializer(llvm::ConstantStruct::get(
Type, FieldsRef));
3923 if (COL->isWeakForLinker())
3924 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3929 bool &IsConst,
bool &IsVolatile,
3930 bool &IsUnaligned) {
3940 IsUnaligned =
false;
3942 if (!PointeeType.
isNull()) {
3963 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3968 bool IsConst, IsVolatile, IsUnaligned;
3992 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3995 llvm::raw_svector_ostream Out(MangledName);
3996 getMangleContext().mangleCXXRTTI(
Type, Out);
4000 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4009 llvm::raw_svector_ostream Out(TypeInfoString);
4010 getMangleContext().mangleCXXRTTIName(
Type, Out);
4014 llvm::Constant *Fields[] = {
4016 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
4017 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
4018 llvm::StructType *TypeDescriptorType =
4019 getTypeDescriptorType(TypeInfoString);
4020 auto *Var =
new llvm::GlobalVariable(
4021 CGM.
getModule(), TypeDescriptorType,
false,
4022 getLinkageForRTTI(
Type),
4023 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
4025 if (Var->isWeakForLinker())
4026 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
4031 llvm::GlobalVariable *
4032 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
4034 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
4037 void MicrosoftCXXABI::emitCXXStructor(
GlobalDecl GD) {
4038 if (
auto *ctor = dyn_cast<CXXConstructorDecl>(GD.
getDecl())) {
4040 llvm::Function *Fn =
4046 auto *dtor = cast<CXXDestructorDecl>(GD.
getDecl());
4052 dtor->getParent()->getNumVBases() == 0)
4063 if (Fn->isWeakForLinker())
4064 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
4074 llvm::raw_svector_ostream Out(ThunkName);
4075 getMangleContext().mangleName(
GlobalDecl(CD, CT), Out);
4078 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
4079 return cast<llvm::Function>(GV);
4085 QualType RecordTy = getContext().getRecordType(RD);
4086 llvm::Function *ThunkFn = llvm::Function::Create(
4087 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
4090 if (ThunkFn->isWeakForLinker())
4091 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
4102 buildThisParam(CGF, FunctionArgs);
4108 &getContext().Idents.get(
"src"),
4109 getContext().getLValueReferenceType(RecordTy,
4113 FunctionArgs.push_back(&SrcParam);
4120 &getContext().Idents.get(
"is_most_derived"),
4124 FunctionArgs.push_back(&IsMostDerived);
4132 setCXXABIThisValue(CGF, loadIncomingCXXThis(CGF));
4133 llvm::Value *
This = getThisValue(CGF);
4135 llvm::Value *SrcVal =
4152 assert(PD->hasDefaultArg() &&
"ctor closure lacks default args");
4153 ArgVec.push_back(PD->getDefaultArg());
4162 AddedStructorArgCounts ExtraArgs =
4167 llvm::Constant *CalleePtr =
4172 Args, CD,
Ctor_Complete, ExtraArgs.Prefix, ExtraArgs.Suffix);
4175 Cleanups.ForceCleanup();
4184 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
4186 int32_t VBPtrOffset,
4198 uint32_t
Size = getContext().getTypeSizeInChars(
T).getQuantity();
4201 llvm::raw_svector_ostream Out(MangledName);
4202 getMangleContext().mangleCXXCatchableType(
T, CD, CT, Size, NVOffset,
4203 VBPtrOffset, VBIndex, Out);
4205 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4206 return getImageRelativeConstant(GV);
4210 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(
T));
4214 llvm::Constant *CopyCtor;
4221 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4223 CopyCtor = getImageRelativeConstant(CopyCtor);
4225 bool IsScalar = !RD;
4226 bool HasVirtualBases =
false;
4227 bool IsStdBadAlloc =
false;
4242 if (HasVirtualBases)
4247 llvm::Constant *Fields[] = {
4248 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4250 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
4251 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
4252 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
4253 llvm::ConstantInt::get(CGM.
IntTy, Size),
4256 llvm::StructType *CTType = getCatchableTypeType();
4257 auto *GV =
new llvm::GlobalVariable(
4258 CGM.
getModule(), CTType,
true, getLinkageForRTTI(
T),
4259 llvm::ConstantStruct::get(CTType, Fields), MangledName);
4260 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4261 GV->setSection(
".xdata");
4262 if (GV->isWeakForLinker())
4263 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4264 return getImageRelativeConstant(GV);
4267 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
4271 llvm::GlobalVariable *&CTA = CatchableTypeArrays[
T];
4296 if (MostDerivedClass) {
4303 Classes.front().initialize(
nullptr,
nullptr);
4305 for (
const MSRTTIClass &Class : Classes) {
4308 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
4311 uint32_t OffsetInVBTable = 0;
4312 int32_t VBPtrOffset = -1;
4313 if (
Class.VirtualRoot) {
4324 CatchableTypes.insert(getCatchableType(RTTITy,
Class.OffsetInVBase,
4325 VBPtrOffset, OffsetInVBTable));
4333 CatchableTypes.insert(getCatchableType(
T));
4346 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4357 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4359 uint32_t NumEntries = CatchableTypes.size();
4360 llvm::Type *CTType =
4361 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4362 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4363 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4364 llvm::Constant *Fields[] = {
4365 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4366 llvm::ConstantArray::get(
4368 CatchableTypes.end()))
4372 llvm::raw_svector_ostream Out(MangledName);
4373 getMangleContext().mangleCXXCatchableTypeArray(
T, NumEntries, Out);
4375 CTA =
new llvm::GlobalVariable(
4376 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(
T),
4377 llvm::ConstantStruct::get(CTAType, Fields), MangledName);
4378 CTA->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4379 CTA->setSection(
".xdata");
4380 if (CTA->isWeakForLinker())
4381 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4385 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4386 bool IsConst, IsVolatile, IsUnaligned;
4391 llvm::GlobalVariable *CTA = getCatchableTypeArray(
T);
4396 uint32_t NumEntries =
4397 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0
U))
4398 ->getLimitedValue();
4402 llvm::raw_svector_ostream Out(MangledName);
4403 getMangleContext().mangleCXXThrowInfo(
T, IsConst, IsVolatile, IsUnaligned,
4409 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4425 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4428 if (!DtorD->isTrivial())
4431 llvm::Constant *ForwardCompat =
4432 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4433 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(CTA);
4434 llvm::StructType *TIType = getThrowInfoType();
4435 llvm::Constant *Fields[] = {
4436 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4437 getImageRelativeConstant(CleanupFn),
4439 PointerToCatchableTypes
4441 auto *GV =
new llvm::GlobalVariable(
4442 CGM.
getModule(), TIType,
true, getLinkageForRTTI(
T),
4443 llvm::ConstantStruct::get(TIType, Fields), MangledName.str());
4444 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4445 GV->setSection(
".xdata");
4446 if (GV->isWeakForLinker())
4447 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4453 assert(SubExpr &&
"SubExpr cannot be null");
4463 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
4470 std::pair<llvm::Value *, const CXXRecordDecl *>
4473 std::tie(
This, std::ignore, RD) =
4478 bool MicrosoftCXXABI::isPermittedToBeHomogeneousAggregate(
4510 if (
const CXXRecordDecl *FRD = B.getType()->getAsCXXRecordDecl()) {
4511 if (!isPermittedToBeHomogeneousAggregate(FRD))
static llvm::FunctionCallee getThrowFn(CodeGenModule &CGM)
static void emitTlsGuardCheck(CodeGenFunction &CGF, llvm::GlobalValue *TlsGuard, llvm::BasicBlock *DynInitBB, llvm::BasicBlock *ContinueBB)
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 QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile, bool &IsUnaligned)
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::CallBase * emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
static llvm::FunctionCallee getInitThreadFooterFn(CodeGenModule &CGM)
static bool isDeletingDtor(GlobalDecl GD)
static llvm::GlobalValue * getTlsGuardVar(CodeGenModule &CGM)
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
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
__DEVICE__ int max(int __a, int __b)
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.
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
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
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.
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
Represents a base class of a C++ class.
CXXCatchStmt - This represents a C++ catch block.
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
bool isGlobalDelete() const
Represents a C++ destructor within a class.
Represents a call to a member function that may be written either with member call syntax (e....
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Represents a C++ struct/union/class.
bool hasNonTrivialCopyAssignment() const
Determine whether this class has a non-trivial copy assignment operator (C++ [class....
bool hasPrivateFields() const
bool hasProtectedFields() const
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_range vbases()
CXXRecordDecl * getMostRecentNonInjectedDecl()
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]).
const Expr * getSubExpr() const
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
const CXXBaseSpecifier *const * path_const_iterator
CharUnits - This is an opaque type for sizes expressed in character units.
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
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.
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
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::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Implements C++ ABI-specific code generation functions.
RecordArgABI
Specify how one should pass an argument of a record type.
MangleContext & getMangleContext()
Gets the mangle context.
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
CanQualType getReturnType() const
unsigned getEffectiveCallingConvention() const
getEffectiveCallingConvention - Return the actual calling convention to use, which may depend on the ...
ABIArgInfo & getReturnInfo()
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Function * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
LValue EmitLoadOfReferenceLValue(LValue RefLVal)
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void EmitMustTailThunk(GlobalDecl GD, llvm::Value *AdjustedThisPtr, llvm::FunctionCallee Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
void EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
llvm::LLVMContext & getLLVMContext()
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
EmitAutoVarAlloca - Emit the alloca and debug information for a local variable.
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
ASTContext & getContext() const
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 GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
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.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
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...
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitAutoVarCleanups(const AutoVarEmission &emission)
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
CodeGenTypes & getTypes() const
llvm::Instruction * CurrentFuncletPad
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const
Set visibility, dllimport/dllexport and dso_local.
void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object)
Add a destructor and object to add to the C++ global destructor function.
void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, const CXXRecordDecl *RD)
Create and attach type metadata for the given vtable.
const TargetInfo & getTarget() const
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::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.
CodeGenTypes & getTypes()
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.
llvm::GlobalValue::LinkageTypes getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage)
Returns LLVM linkage for a declarator.
llvm::Module & getModule() const
CodeGenVTables & getVTables()
void EmitGlobal(GlobalDecl D)
Emit code for a single global function or var decl.
const LangOptions & getLangOpts() const
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.
llvm::LLVMContext & getLLVMContext()
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::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::Function * codegenCXXStructor(GlobalDecl GD)
DiagnosticsEngine & getDiags() const
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.
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.
StringRef getMangledName(GlobalDecl GD)
ASTContext & getContext() const
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::GlobalValue * GetGlobalValue(StringRef Ref)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const
const CodeGenOptions & getCodeGenOpts() 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)
MicrosoftVTableContext & getMicrosoftVTableContext()
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.
const ABIInfo & getABIInfo() const
const CGFunctionInfo & arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD)
Arrange a thunk that takes 'this' as the first parameter followed by varargs.
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
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()
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.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Represents a prototype with parameter type info, e.g.
bool isVariadic() const
Whether this function prototype is variadic.
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
GlobalDecl getWithDtorType(CXXDtorType Type)
const Decl * getDecl() const
CXXDtorType getDtorType() 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 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.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
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...
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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.
TLSKind getTLSKind() const
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed? If so, the variable need not have a usable destr...
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
@ NormalCleanup
Denotes a cleanup that should run when a scope is exited using normal control flow (falling off the e...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)
Creates a Microsoft-family ABI.
constexpr XRayInstrMask None
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 Call(InterpState &S, CodePtr OpPC, const Function *Func, uint32_t VarArgSize)
bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
bool Init(InterpState &S, CodePtr OpPC)
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
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.
@ VisibleNone
No linkage according to the standard, but is visible from other translation units because of types de...
@ None
No linkage, which means that the entity is unique and can only be referred to from within its scope.
@ UniqueExternal
External linkage within a unique namespace.
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
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.
@ Other
Other implicit parameter.
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,...
Struct with all information about dynamic [sub]class needed to set vptr.
const CXXRecordDecl * NearestVBase
llvm::PointerType * VoidPtrTy
llvm::PointerType * Int8PtrPtrTy
CharUnits getIntAlign() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getIntSize() const
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy
llvm::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.
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::@189 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.
struct clang::ThisAdjustment::VirtualAdjustment::@191 Microsoft
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...