26 #include "llvm/ADT/StringExtras.h"
27 #include "llvm/ADT/StringSet.h"
28 #include "llvm/IR/CallSite.h"
29 #include "llvm/IR/Intrinsics.h"
31 using namespace clang;
32 using namespace CodeGen;
37 struct VBTableGlobals {
42 class MicrosoftCXXABI :
public CGCXXABI {
45 :
CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
46 ClassHierarchyDescriptorType(nullptr),
47 CompleteObjectLocatorType(nullptr), CatchableTypeType(nullptr),
48 ThrowInfoType(nullptr), CatchHandlerTypeType(nullptr) {}
50 bool HasThisReturn(
GlobalDecl GD)
const override;
51 bool hasMostDerivedReturn(
GlobalDecl GD)
const override;
57 bool isSRetParameterAfterThis()
const override {
return true; }
61 assert(Args.size() >= 2 &&
62 "expected the arglist to have at least two args!");
71 StringRef GetPureVirtualCallName()
override {
return "_purecall"; }
72 StringRef GetDeletedVirtualCallName()
override {
return "_purecall"; }
83 llvm::GlobalVariable *getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
86 llvm::Constant *getAddrOfRTTIDescriptor(
QualType Ty)
override;
88 getAddrOfCXXCatchHandlerType(
QualType Ty,
QualType CatchHandlerType)
override;
90 bool shouldTypeidBeNullChecked(
bool IsDeref,
QualType SrcRecordTy)
override;
94 llvm::Type *StdTypeInfoPtrTy)
override;
96 bool shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
102 llvm::BasicBlock *CastEnd)
override;
168 getThisArgumentTypeForMethod(
const CXXMethodDecl *MD)
override {
170 if (MD->
isVirtual() && !isa<CXXDestructorDecl>(MD)) {
172 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(MD);
188 bool VirtualCall)
override;
193 llvm::Value *adjustThisParameterInVirtualFunctionPrologue(
209 llvm::GlobalVariable *VTable);
217 bool &NeedsVirtualOffset)
override;
223 llvm::GlobalVariable *getAddrOfVTable(
const CXXRecordDecl *RD,
239 "Only deleting destructor thunks are available in this ABI");
244 void emitVirtualInheritanceTables(
const CXXRecordDecl *RD)
override;
246 llvm::GlobalVariable *
248 llvm::GlobalVariable::LinkageTypes
Linkage);
250 llvm::GlobalVariable *
254 llvm::raw_svector_ostream Out(OutName);
255 getMangleContext().mangleCXXVirtualDisplacementMap(SrcRD, DstRD, Out);
257 StringRef MangledName = OutName.str();
259 if (
auto *VDispMap = CGM.getModule().getNamedGlobal(MangledName))
265 llvm::UndefValue::get(CGM.IntTy));
266 Map[0] = llvm::ConstantInt::get(CGM.IntTy, 0);
267 bool AnyDifferent =
false;
268 for (
const auto &I : SrcRD->
vbases()) {
269 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
275 Map[SrcVBIndex] = llvm::ConstantInt::get(CGM.IntTy, DstVBIndex * 4);
276 AnyDifferent |= SrcVBIndex != DstVBIndex;
282 llvm::ArrayType *VDispMapTy = llvm::ArrayType::get(CGM.IntTy,
Map.size());
283 llvm::Constant *Init = llvm::ConstantArray::get(VDispMapTy,
Map);
284 llvm::GlobalValue::LinkageTypes
Linkage =
286 ? llvm::GlobalValue::LinkOnceODRLinkage
288 auto *VDispMap =
new llvm::GlobalVariable(
289 CGM.getModule(), VDispMapTy,
true,
Linkage,
295 llvm::GlobalVariable *GV)
const;
297 void setThunkLinkage(llvm::Function *Thunk,
bool ForVTable,
300 Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
303 getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.
getDecl()));
307 else if (ReturnAdjustment)
308 Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
310 Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
317 const ReturnAdjustment &RA)
override;
319 void EmitThreadLocalInitFuncs(
321 ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *>>
326 bool usesThreadWrapperFunction()
const override {
return false; }
331 llvm::GlobalVariable *DeclPtr,
332 bool PerformInit)
override;
334 llvm::Constant *Dtor, llvm::Constant *Addr)
override;
372 friend struct MSRTTIBuilder;
374 bool isImageRelative()
const {
375 return CGM.getTarget().getPointerWidth(0) == 64;
379 llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
381 TDTypeName += llvm::utostr(TypeInfoString.size());
382 llvm::StructType *&TypeDescriptorType =
383 TypeDescriptorTypeMap[TypeInfoString.size()];
384 if (TypeDescriptorType)
385 return TypeDescriptorType;
386 llvm::Type *FieldTypes[] = {
389 llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
392 return TypeDescriptorType;
395 llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
396 if (!isImageRelative())
401 llvm::StructType *getBaseClassDescriptorType() {
402 if (BaseClassDescriptorType)
403 return BaseClassDescriptorType;
404 llvm::Type *FieldTypes[] = {
405 getImageRelativeType(CGM.Int8PtrTy),
411 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
414 CGM.getLLVMContext(), FieldTypes,
"rtti.BaseClassDescriptor");
415 return BaseClassDescriptorType;
418 llvm::StructType *getClassHierarchyDescriptorType() {
419 if (ClassHierarchyDescriptorType)
420 return ClassHierarchyDescriptorType;
423 CGM.getLLVMContext(),
"rtti.ClassHierarchyDescriptor");
424 llvm::Type *FieldTypes[] = {
428 getImageRelativeType(
429 getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
431 ClassHierarchyDescriptorType->setBody(FieldTypes);
432 return ClassHierarchyDescriptorType;
435 llvm::StructType *getCompleteObjectLocatorType() {
436 if (CompleteObjectLocatorType)
437 return CompleteObjectLocatorType;
439 CGM.getLLVMContext(),
"rtti.CompleteObjectLocator");
440 llvm::Type *FieldTypes[] = {
444 getImageRelativeType(CGM.Int8PtrTy),
445 getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
446 getImageRelativeType(CompleteObjectLocatorType),
449 if (!isImageRelative())
450 FieldTypesRef = FieldTypesRef.drop_back();
451 CompleteObjectLocatorType->setBody(FieldTypesRef);
452 return CompleteObjectLocatorType;
455 llvm::GlobalVariable *getImageBase() {
456 StringRef Name =
"__ImageBase";
457 if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
460 return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
466 llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
467 if (!isImageRelative())
470 if (PtrVal->isNullValue())
471 return llvm::Constant::getNullValue(CGM.IntTy);
473 llvm::Constant *ImageBaseAsInt =
474 llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
475 llvm::Constant *PtrValAsInt =
476 llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
477 llvm::Constant *Diff =
478 llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
480 return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
488 llvm::Constant *getZeroInt() {
489 return llvm::ConstantInt::get(CGM.IntTy, 0);
492 llvm::Constant *getAllOnesInt() {
493 return llvm::Constant::getAllOnesValue(CGM.IntTy);
496 llvm::Constant *getConstantOrZeroInt(llvm::Constant *
C) {
497 return C ? C : getZeroInt();
501 return C ? C : getZeroInt();
522 int32_t VBTableOffset,
524 assert(VBTableOffset % 4 == 0 &&
"should be byte offset into table of i32s");
525 llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
526 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
527 return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
530 std::pair<llvm::Value *, llvm::Value *>
543 llvm::Constant *EmitFullMemberPointer(llvm::Constant *FirstField,
544 bool IsMemberFunction,
547 unsigned VBTableIndex);
556 const VBTableGlobals &enumerateVBTables(
const CXXRecordDecl *RD);
559 llvm::Function *EmitVirtualMemPtrThunk(
570 return RD->
hasAttr<MSInheritanceAttr>();
573 bool isTypeInfoCalculable(
QualType Ty)
const override {
578 if (!RD->
hasAttr<MSInheritanceAttr>())
588 llvm::Constant *EmitMemberFunctionPointer(
const CXXMethodDecl *MD)
override;
589 llvm::Constant *EmitMemberPointer(
const APValue &MP,
QualType MPT)
override;
595 bool Inequality)
override;
616 llvm::Constant *EmitMemberPointerConversion(
const CastExpr *E,
617 llvm::Constant *Src)
override;
619 llvm::Constant *EmitMemberPointerConversion(
631 llvm::StructType *getCatchHandlerTypeType() {
632 if (!CatchHandlerTypeType) {
633 llvm::Type *FieldTypes[] = {
638 CGM.getLLVMContext(), FieldTypes,
"eh.CatchHandlerType");
640 return CatchHandlerTypeType;
643 llvm::StructType *getCatchableTypeType() {
644 if (CatchableTypeType)
645 return CatchableTypeType;
646 llvm::Type *FieldTypes[] = {
648 getImageRelativeType(CGM.Int8PtrTy),
653 getImageRelativeType(CGM.Int8PtrTy)
656 CGM.getLLVMContext(), FieldTypes,
"eh.CatchableType");
657 return CatchableTypeType;
660 llvm::StructType *getCatchableTypeArrayType(uint32_t NumEntries) {
661 llvm::StructType *&CatchableTypeArrayType =
662 CatchableTypeArrayTypeMap[NumEntries];
663 if (CatchableTypeArrayType)
664 return CatchableTypeArrayType;
667 CTATypeName += llvm::utostr(NumEntries);
669 getImageRelativeType(getCatchableTypeType()->getPointerTo());
670 llvm::Type *FieldTypes[] = {
672 llvm::ArrayType::get(CTType, NumEntries)
674 CatchableTypeArrayType =
676 return CatchableTypeArrayType;
679 llvm::StructType *getThrowInfoType() {
681 return ThrowInfoType;
682 llvm::Type *FieldTypes[] = {
684 getImageRelativeType(CGM.Int8PtrTy),
685 getImageRelativeType(CGM.Int8PtrTy),
686 getImageRelativeType(CGM.Int8PtrTy)
690 return ThrowInfoType;
696 llvm::Type *Args[] = {CGM.Int8PtrTy, getThrowInfoType()->getPointerTo()};
697 llvm::FunctionType *FTy =
698 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
699 auto *Fn = cast<llvm::Function>(
700 CGM.CreateRuntimeFunction(FTy,
"_CxxThrowException"));
702 if (CGM.getTarget().getTriple().getArch() == llvm::Triple::x86)
703 Fn->setCallingConv(llvm::CallingConv::X86_StdCall);
710 llvm::Constant *getCatchableType(
QualType T,
711 uint32_t NVOffset = 0,
712 int32_t VBPtrOffset = -1,
713 uint32_t VBIndex = 0);
715 llvm::GlobalVariable *getCatchableTypeArray(
QualType T);
717 llvm::GlobalVariable *getThrowInfo(
QualType T)
override;
720 typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
721 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
722 typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
724 VFTablesMapTy VFTablesMap;
725 VTablesMapTy VTablesMap;
728 llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
732 llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
737 GuardInfo() : Guard(nullptr), BitIndex(0) {}
738 llvm::GlobalVariable *Guard;
744 llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
745 llvm::DenseMap<const DeclContext *, GuardInfo> ThreadLocalGuardVariableMap;
746 llvm::DenseMap<const DeclContext *, unsigned> ThreadSafeGuardNumMap;
748 llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
749 llvm::StructType *BaseClassDescriptorType;
750 llvm::StructType *ClassHierarchyDescriptorType;
751 llvm::StructType *CompleteObjectLocatorType;
753 llvm::DenseMap<QualType, llvm::GlobalVariable *> CatchableTypeArrays;
755 llvm::StructType *CatchableTypeType;
756 llvm::DenseMap<uint32_t, llvm::StructType *> CatchableTypeArrayTypeMap;
757 llvm::StructType *ThrowInfoType;
758 llvm::StructType *CatchHandlerTypeType;
765 switch (CGM.getTarget().getTriple().getArch()) {
770 case llvm::Triple::x86:
777 if (!canCopyArgument(RD))
778 return RAA_DirectInMemory;
784 case llvm::Triple::x86_64:
802 bool CopyDeleted =
false;
821 llvm_unreachable(
"invalid enum");
834 EmitVirtualDestructorCall(CGF, Dtor, DtorType, Ptr,
nullptr);
839 void MicrosoftCXXABI::emitRethrow(
CodeGenFunction &CGF,
bool isNoReturn) {
841 llvm::ConstantPointerNull::get(CGM.Int8PtrTy),
842 llvm::ConstantPointerNull::get(getThrowInfoType()->getPointerTo())};
852 CallEndCatchMSVC() {}
866 llvm::Function *BeginCatch =
887 std::pair<llvm::Value *, llvm::Value *>
895 return std::make_pair(Value, llvm::ConstantInt::get(CGF.
Int32Ty, 0));
906 Value = CGF.
Builder.CreateInBoundsGEP(Value, Offset);
908 return std::make_pair(Value, Offset);
911 bool MicrosoftCXXABI::shouldTypeidBeNullChecked(
bool IsDeref,
915 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
920 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
921 llvm::FunctionType *FTy =
922 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false);
929 llvm::CallSite Call =
931 Call.setDoesNotReturn();
932 CGF.
Builder.CreateUnreachable();
938 llvm::Type *StdTypeInfoPtrTy) {
940 std::tie(ThisPtr, Offset) = performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
941 return CGF.
Builder.CreateBitCast(
945 bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(
bool SrcIsPtr,
949 !getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
963 std::tie(Value, Offset) = performBaseAdjustment(CGF, Value, SrcRecordTy);
974 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
980 return CGF.
Builder.CreateBitCast(Value, DestLTy);
988 std::tie(Value, Offset) = performBaseAdjustment(CGF, Value, SrcRecordTy);
992 llvm::Type *ArgTypes[] = {CGF.
Int8PtrTy};
994 llvm::FunctionType::get(CGF.
Int8PtrTy, ArgTypes,
false),
1004 llvm::Value *MicrosoftCXXABI::GetVirtualBaseClassOffset(
1008 int64_t VBPtrChars =
1010 llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
1014 CGM.getMicrosoftVTableContext().getVBTableIndex(ClassDecl, BaseClassDecl);
1016 llvm::ConstantInt::get(CGM.IntTy, VBTableChars.
getQuantity());
1019 GetVBaseOffsetFromVBPtr(CGF, This, VBPtrOffset, VBTableOffset);
1021 CGF.
Builder.CreateSExtOrBitCast(VBPtrToNewBase, CGM.PtrDiffTy);
1022 return CGF.
Builder.CreateNSWAdd(VBPtrOffset, VBPtrToNewBase);
1025 bool MicrosoftCXXABI::HasThisReturn(
GlobalDecl GD)
const {
1026 return isa<CXXConstructorDecl>(GD.
getDecl());
1030 return isa<CXXDestructorDecl>(GD.
getDecl()) &&
1034 bool MicrosoftCXXABI::hasMostDerivedReturn(
GlobalDecl GD)
const {
1038 bool MicrosoftCXXABI::classifyReturnType(
CGFunctionInfo &FI)
const {
1049 }
else if (!RD->
isPOD()) {
1062 llvm::Value *IsMostDerivedClass = getStructorImplicitParamValue(CGF);
1063 assert(IsMostDerivedClass &&
1064 "ctor for a class with virtual bases must have an implicit parameter");
1066 CGF.
Builder.CreateIsNotNull(IsMostDerivedClass,
"is_complete_object");
1068 llvm::BasicBlock *CallVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.init_vbases");
1069 llvm::BasicBlock *SkipVbaseCtorsBB = CGF.
createBasicBlock(
"ctor.skip_vbases");
1070 CGF.
Builder.CreateCondBr(IsCompleteObject,
1071 CallVbaseCtorsBB, SkipVbaseCtorsBB);
1076 EmitVBPtrStores(CGF, RD);
1080 return SkipVbaseCtorsBB;
1083 void MicrosoftCXXABI::initializeHiddenVirtualInheritanceMembers(
1104 cast<llvm::PointerType>(getThisValue(CGF)->getType())->getAddressSpace();
1107 for (VBOffsets::const_iterator I = VBaseMap.begin(), E = VBaseMap.end();
1109 if (!I->second.hasVtorDisp())
1113 GetVirtualBaseClassOffset(CGF, getThisValue(CGF), RD, I->first);
1116 VBaseOffset = Builder.CreateTruncOrBitCast(VBaseOffset, CGF.
Int32Ty);
1117 uint64_t ConstantVBaseOffset =
1122 VBaseOffset, llvm::ConstantInt::get(CGM.Int32Ty, ConstantVBaseOffset),
1126 Int8This = Builder.CreateBitCast(getThisValue(CGF),
1127 CGF.
Int8Ty->getPointerTo(AS));
1128 llvm::Value *VtorDispPtr = Builder.CreateInBoundsGEP(Int8This, VBaseOffset);
1130 VtorDispPtr = Builder.CreateConstGEP1_32(VtorDispPtr, -4);
1131 VtorDispPtr = Builder.CreateBitCast(
1132 VtorDispPtr, CGF.
Int32Ty->getPointerTo(AS),
"vtordisp.ptr");
1134 Builder.CreateStore(VtorDispValue, VtorDispPtr);
1144 return ExpectedCallingConv == ActualCallingConv;
1158 Fn->setLinkage(llvm::GlobalValue::WeakODRLinkage);
1159 Fn->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1166 CGF.
Builder.CreateBitCast(getThisValue(CGF), CGM.Int8PtrTy,
"this.int8");
1170 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1171 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1172 const VPtrInfo *VBT = (*VBGlobals.VBTables)[I];
1173 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1183 CGF.
Builder.CreateConstInBoundsGEP2_32(GV->getValueType(), GV, 0, 0);
1184 VBPtr = CGF.
Builder.CreateBitCast(VBPtr, GVPtr->getType()->getPointerTo(0),
1186 CGF.
Builder.CreateStore(GVPtr, VBPtr);
1196 ArgTys.push_back(getContext().IntTy);
1209 ArgTys.insert(ArgTys.begin() + 1, getContext().IntTy);
1211 ArgTys.push_back(getContext().IntTy);
1222 MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(
GlobalDecl GD) {
1239 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1246 if (isa<CXXDestructorDecl>(MD))
1251 getContext().getASTRecordLayout(MD->
getParent());
1258 llvm::Value *MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
1263 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1267 unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1268 llvm::Type *charPtrTy = CGF.
Int8Ty->getPointerTo(AS);
1269 This = CGF.
Builder.CreateBitCast(This, charPtrTy);
1289 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
1291 unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1292 llvm::Type *charPtrTy = CGF.
Int8Ty->getPointerTo(AS);
1302 This = CGF.
Builder.CreateBitCast(This, charPtrTy);
1305 This = CGF.
Builder.CreateInBoundsGEP(This, VBaseOffset);
1307 if (!StaticOffset.
isZero()) {
1309 This = CGF.
Builder.CreateBitCast(This, charPtrTy);
1317 This = CGF.
Builder.CreateConstInBoundsGEP1_32(CGF.
Int8Ty, This,
1329 assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
1339 if (FPT->isVariadic())
1340 Params.insert(Params.begin() + 1, IsMostDerived);
1342 Params.push_back(IsMostDerived);
1343 getStructorImplicitParamDecl(CGF) = IsMostDerived;
1348 &Context.
Idents.
get(
"should_call_delete"),
1350 Params.push_back(ShouldDelete);
1351 getStructorImplicitParamDecl(CGF) = ShouldDelete;
1355 llvm::Value *MicrosoftCXXABI::adjustThisParameterInVirtualFunctionPrologue(
1362 CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
1366 unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
1367 llvm::Type *charPtrTy = CGF.
Int8Ty->getPointerTo(AS),
1368 *thisTy = This->getType();
1370 This = CGF.
Builder.CreateBitCast(This, charPtrTy);
1372 This = CGF.
Builder.CreateConstInBoundsGEP1_32(CGF.
Int8Ty, This,
1374 return CGF.
Builder.CreateBitCast(This, thisTy);
1377 void MicrosoftCXXABI::EmitInstanceFunctionProlog(
CodeGenFunction &CGF) {
1388 if (HasThisReturn(CGF.
CurGD))
1390 else if (hasMostDerivedReturn(CGF.
CurGD))
1396 assert(getStructorImplicitParamDecl(CGF) &&
1397 "no implicit parameter for a constructor with virtual bases?");
1398 getStructorImplicitParamValue(CGF)
1405 assert(getStructorImplicitParamDecl(CGF) &&
1406 "no implicit parameter for a deleting destructor?");
1407 getStructorImplicitParamValue(CGF)
1410 "should_call_delete");
1414 unsigned MicrosoftCXXABI::addImplicitConstructorArgs(
1416 bool ForVirtualBase,
bool Delegating,
CallArgList &Args) {
1428 if (MostDerivedArg) {
1430 Args.insert(Args.begin() + 1,
1431 CallArg(RV, getContext().IntTy,
false));
1433 Args.
add(RV, getContext().IntTy);
1447 "The deleting destructor should only be called via a virtual call");
1448 This = adjustThisArgumentForVirtualFunctionCall(CGF,
GlobalDecl(DD, Type),
1458 void MicrosoftCXXABI::emitVTableBitSetEntries(
VPtrInfo *Info,
1460 llvm::GlobalVariable *VTable) {
1461 if (!getContext().getLangOpts().Sanitize.has(SanitizerKind::CFIVCall) &&
1462 !getContext().getLangOpts().Sanitize.has(SanitizerKind::CFINVCall) &&
1463 !getContext().getLangOpts().Sanitize.has(SanitizerKind::CFIDerivedCast) &&
1464 !getContext().getLangOpts().Sanitize.has(SanitizerKind::CFIUnrelatedCast))
1467 llvm::NamedMDNode *BitsetsMD =
1468 CGM.getModule().getOrInsertNamedMetadata(
"llvm.bitsets");
1474 getContext().getLangOpts().RTTIData
1475 ? getContext().toCharUnitsFromBits(
1476 getContext().getTargetInfo().getPointerWidth(0))
1480 if (!CGM.IsCFIBlacklistedRecord(RD))
1481 BitsetsMD->addOperand(
1482 CGM.CreateVTableBitSetEntry(VTable, AddressPoint, RD));
1488 BitsetsMD->addOperand(CGM.CreateVTableBitSetEntry(
1498 getContext().getASTRecordLayout(DerivedRD);
1504 Offset = VBI->second.VBaseOffset;
1507 if (!CGM.IsCFIBlacklistedRecord(DerivedRD))
1508 BitsetsMD->addOperand(
1509 CGM.CreateVTableBitSetEntry(VTable, AddressPoint, DerivedRD));
1514 BitsetsMD->addOperand(
1515 CGM.CreateVTableBitSetEntry(VTable, AddressPoint, RD));
1518 void MicrosoftCXXABI::emitVTableDefinitions(
CodeGenVTables &CGVT,
1524 llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->
FullOffsetInMDC);
1525 if (VTable->hasInitializer())
1528 llvm::Constant *RTTI = getContext().getLangOpts().RTTIData
1529 ? getMSCompleteObjectLocator(RD, Info)
1539 VTable->setInitializer(Init);
1541 emitVTableBitSetEntries(Info, RD, VTable);
1545 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
1547 const CXXRecordDecl *NearestVBase,
bool &NeedsVirtualOffset) {
1548 NeedsVirtualOffset = (NearestVBase !=
nullptr);
1552 llvm::GlobalValue *VTableAddressPoint = VFTablesMap[
ID];
1553 if (!VTableAddressPoint) {
1555 !getContext().getASTRecordLayout(Base.
getBase()).hasOwnVFPtr());
1557 return VTableAddressPoint;
1563 llvm::raw_svector_ostream Out(Name);
1567 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
1571 llvm::GlobalValue *VFTable = VFTablesMap[
ID];
1572 assert(VFTable &&
"Couldn't find a vftable for the given base?");
1576 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(
const CXXRecordDecl *RD,
1581 VFTableIdTy
ID(RD, VPtrOffset);
1582 VTablesMapTy::iterator I;
1584 std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(
ID,
nullptr));
1588 llvm::GlobalVariable *&VTable = I->second;
1593 if (DeferredVFTables.insert(RD).second) {
1596 CGM.addDeferredVTable(RD);
1601 llvm::StringSet<> ObservedMangledNames;
1602 for (
size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
1605 if (!ObservedMangledNames.insert(Name.str()).second)
1606 llvm_unreachable(
"Already saw this mangling before?");
1612 std::find_if(VFPtrs.begin(), VFPtrs.end(), [&](
VPtrInfo *VPI) {
1613 return VPI->FullOffsetInMDC == VPtrOffset;
1615 if (VFPtrI == VFPtrs.end()) {
1616 VFTablesMap[
ID] =
nullptr;
1624 llvm::GlobalValue::LinkageTypes VFTableLinkage = CGM.getVTableLinkage(RD);
1625 bool VFTableComesFromAnotherTU =
1626 llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage) ||
1627 llvm::GlobalValue::isExternalLinkage(VFTableLinkage);
1628 bool VTableAliasIsRequred =
1629 !VFTableComesFromAnotherTU && getContext().getLangOpts().RTTIData;
1631 if (llvm::GlobalValue *VFTable =
1632 CGM.getModule().getNamedGlobal(VFTableName)) {
1633 VFTablesMap[
ID] = VFTable;
1634 return VTableAliasIsRequred
1635 ? cast<llvm::GlobalVariable>(
1636 cast<llvm::GlobalAlias>(VFTable)->getBaseObject())
1637 : cast<llvm::GlobalVariable>(VFTable);
1640 uint64_t NumVTableSlots =
1643 llvm::GlobalValue::LinkageTypes VTableLinkage =
1644 VTableAliasIsRequred ? llvm::GlobalValue::PrivateLinkage : VFTableLinkage;
1646 StringRef VTableName = VTableAliasIsRequred ? StringRef() : VFTableName.str();
1648 llvm::ArrayType *VTableType =
1649 llvm::ArrayType::get(CGM.Int8PtrTy, NumVTableSlots);
1653 llvm::GlobalValue *VFTable;
1654 VTable =
new llvm::GlobalVariable(CGM.getModule(), VTableType,
1655 true, VTableLinkage,
1656 nullptr, VTableName);
1657 VTable->setUnnamedAddr(
true);
1659 llvm::Comdat *
C =
nullptr;
1660 if (!VFTableComesFromAnotherTU &&
1661 (llvm::GlobalValue::isWeakForLinker(VFTableLinkage) ||
1662 (llvm::GlobalValue::isLocalLinkage(VFTableLinkage) &&
1663 VTableAliasIsRequred)))
1664 C = CGM.getModule().getOrInsertComdat(VFTableName.str());
1669 if (VTableAliasIsRequred) {
1670 llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
1671 llvm::ConstantInt::get(CGM.IntTy, 1)};
1674 llvm::Constant *VTableGEP = llvm::ConstantExpr::getInBoundsGetElementPtr(
1675 VTable->getValueType(), VTable, GEPIndices);
1676 if (llvm::GlobalValue::isWeakForLinker(VFTableLinkage)) {
1679 C->setSelectionKind(llvm::Comdat::Largest);
1682 cast<llvm::PointerType>(VTableGEP->getType()), VFTableLinkage,
1683 VFTableName.str(), VTableGEP, &CGM.getModule());
1684 VFTable->setUnnamedAddr(
true);
1693 VTable->setComdat(C);
1695 if (RD->
hasAttr<DLLImportAttr>())
1696 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1697 else if (RD->
hasAttr<DLLExportAttr>())
1698 VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1700 VFTablesMap[
ID] = VFTable;
1715 for (
auto &&B : RD->
bases()) {
1716 const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
1718 if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) {
1720 MaxBaseOffset = BaseOffset;
1723 for (
auto &&B : RD->
vbases()) {
1724 const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
1726 if (BaseOffset <= Offset && BaseOffset >= MaxBaseOffset) {
1728 MaxBaseOffset = BaseOffset;
1742 RD = cast<CXXMethodDecl>(GD.
getDecl())->getParent();
1755 Ty = Ty->getPointerTo()->getPointerTo();
1757 adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1761 CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
1762 if (CGF.
SanOpts.
has(SanitizerKind::CFIVCall))
1767 Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1768 return Builder.CreateLoad(VFuncPtr);
1771 llvm::Value *MicrosoftCXXABI::EmitVirtualDestructorCall(
1780 const CGFunctionInfo *FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
1787 llvm::Value *ImplicitParam = llvm::ConstantInt::get(
1791 This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This,
true);
1793 ImplicitParam, Context.IntTy, CE,
1798 const VBTableGlobals &
1799 MicrosoftCXXABI::enumerateVBTables(
const CXXRecordDecl *RD) {
1802 llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
1804 std::tie(Entry, Added) =
1805 VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
1806 VBTableGlobals &VBGlobals = Entry->second;
1815 llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
1816 for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
1817 E = VBGlobals.VBTables->end();
1819 VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
1825 llvm::Function *MicrosoftCXXABI::EmitVirtualMemPtrThunk(
1828 assert(!isa<CXXConstructorDecl>(MD) && !isa<CXXDestructorDecl>(MD) &&
1829 "can't form pointers to ctors or virtual dtors");
1833 llvm::raw_svector_ostream Out(ThunkName);
1834 getMangleContext().mangleVirtualMemPtrThunk(MD, Out);
1838 if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
1839 return cast<llvm::Function>(GV);
1842 const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSMemberPointerThunk(MD);
1843 llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
1844 llvm::Function *ThunkFn =
1846 ThunkName.str(), &CGM.getModule());
1847 assert(ThunkFn->getName() == ThunkName &&
"name was uniqued!");
1850 ? llvm::GlobalValue::LinkOnceODRLinkage
1853 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));
1855 CGM.SetLLVMFunctionAttributes(MD, FnInfo, ThunkFn);
1856 CGM.SetLLVMFunctionAttributesForDefinition(MD, ThunkFn);
1862 ThunkFn->addFnAttr(
"thunk");
1865 ThunkFn->setUnnamedAddr(
false);
1875 buildThisParam(CGF, FunctionArgs);
1885 getThisValue(CGF), ThunkTy->getPointerTo()->getPointerTo());
1887 CGF.
Builder.CreateConstInBoundsGEP1_64(VTable, ML.
Index,
"vfn");
1895 void MicrosoftCXXABI::emitVirtualInheritanceTables(
const CXXRecordDecl *RD) {
1896 const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
1897 for (
unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
1898 const VPtrInfo *VBT = (*VBGlobals.VBTables)[I];
1899 llvm::GlobalVariable *GV = VBGlobals.Globals[I];
1900 if (GV->isDeclaration())
1901 emitVBTableDefinition(*VBT, RD, GV);
1905 llvm::GlobalVariable *
1907 llvm::GlobalVariable::LinkageTypes Linkage) {
1909 llvm::raw_svector_ostream Out(OutName);
1910 getMangleContext().mangleCXXVBTable(RD, VBT.
MangledPath, Out);
1912 StringRef Name = OutName.str();
1914 llvm::ArrayType *VBTableType =
1917 assert(!CGM.getModule().getNamedGlobal(Name) &&
1918 "vbtable with this name already exists: mangling bug?");
1919 llvm::GlobalVariable *GV =
1920 CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, Linkage);
1921 GV->setUnnamedAddr(
true);
1923 if (RD->
hasAttr<DLLImportAttr>())
1924 GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
1925 else if (RD->
hasAttr<DLLExportAttr>())
1926 GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
1928 if (!GV->hasExternalLinkage())
1929 emitVBTableDefinition(VBT, RD, GV);
1934 void MicrosoftCXXABI::emitVBTableDefinition(
const VPtrInfo &VBT,
1936 llvm::GlobalVariable *GV)
const {
1940 "should only emit vbtables for classes with vbtables");
1944 const ASTRecordLayout &DerivedLayout = getContext().getASTRecordLayout(RD);
1950 CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
1951 Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
1954 for (
const auto &I : ReusingBase->
vbases()) {
1955 const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
1962 CompleteVBPtrOffset +=
1964 Offset -= CompleteVBPtrOffset;
1966 unsigned VBIndex = Context.getVBTableIndex(ReusingBase, VBase);
1967 assert(Offsets[VBIndex] ==
nullptr &&
"The same vbindex seen twice?");
1968 Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.
getQuantity());
1971 assert(Offsets.size() ==
1972 cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
1974 llvm::ArrayType *VBTableType =
1975 llvm::ArrayType::get(CGM.IntTy, Offsets.size());
1976 llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
1977 GV->setInitializer(Init);
1994 CGF.
Builder.CreateBitCast(VtorDispPtr, CGF.
Int32Ty->getPointerTo());
2008 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2025 const ReturnAdjustment &RA) {
2039 V = CGF.
Builder.CreateInBoundsGEP(VBPtr, VBaseOffset);
2046 return CGF.
Builder.CreateBitCast(V, Ret->getType());
2056 bool MicrosoftCXXABI::requiresArrayCookie(
const CXXNewExpr *expr) {
2073 unsigned AS = allocPtr->getType()->getPointerAddressSpace();
2075 CGF.
Builder.CreateBitCast(allocPtr, CGF.
SizeTy->getPointerTo(AS));
2076 return CGF.
Builder.CreateLoad(numElementsPtr);
2084 assert(requiresArrayCookie(expr));
2087 CharUnits cookieSize = getArrayCookieSizeImpl(elementType);
2093 unsigned AS = newPtr->getType()->getPointerAddressSpace();
2095 = CGF.
Builder.CreateBitCast(cookiePtr, CGF.
SizeTy->getPointerTo(AS));
2096 CGF.
Builder.CreateStore(numElements, numElementsPtr);
2100 return CGF.
Builder.CreateConstInBoundsGEP1_64(newPtr,
2105 llvm::Constant *Dtor,
2106 llvm::Constant *Addr) {
2111 llvm::FunctionType *TLRegDtorTy = llvm::FunctionType::get(
2112 CGF.
IntTy, DtorStub->getType(),
false);
2114 llvm::Constant *TLRegDtor =
2116 if (llvm::Function *TLRegDtorFn = dyn_cast<llvm::Function>(TLRegDtor))
2117 TLRegDtorFn->setDoesNotThrow();
2123 llvm::Constant *Dtor,
2124 llvm::Constant *Addr) {
2132 void MicrosoftCXXABI::EmitThreadLocalInitFuncs(
2134 ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *>>
2141 auto AddToXDU = [&CGM](llvm::Function *InitFunc) {
2142 llvm::GlobalVariable *InitFuncPtr =
new llvm::GlobalVariable(
2143 CGM.
getModule(), InitFunc->getType(),
true,
2145 Twine(InitFunc->getName(),
"$initializer$"));
2146 InitFuncPtr->setSection(
".CRT$XDU");
2153 std::vector<llvm::Function *> NonComdatInits;
2154 for (
size_t I = 0, E = CXXThreadLocalInitVars.size(); I != E; ++I) {
2155 llvm::GlobalVariable *GV = CXXThreadLocalInitVars[I];
2156 llvm::Function *F = CXXThreadLocalInits[I];
2159 if (llvm::Comdat *C = GV->getComdat())
2160 AddToXDU(F)->setComdat(C);
2162 NonComdatInits.push_back(F);
2165 if (!NonComdatInits.empty()) {
2166 llvm::FunctionType *FTy =
2167 llvm::FunctionType::get(CGM.
VoidTy,
false);
2185 StringRef VarName(
"_Init_thread_epoch");
2186 if (
auto *GV = CGM.
getModule().getNamedGlobal(VarName))
2188 auto *GV =
new llvm::GlobalVariable(
2192 nullptr, llvm::GlobalVariable::GeneralDynamicTLSModel);
2198 llvm::FunctionType *FTy =
2199 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2200 CGM.
IntTy->getPointerTo(),
false);
2202 FTy,
"_Init_thread_header",
2204 llvm::AttributeSet::FunctionIndex,
2205 llvm::Attribute::NoUnwind));
2209 llvm::FunctionType *FTy =
2210 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2211 CGM.
IntTy->getPointerTo(),
false);
2213 FTy,
"_Init_thread_footer",
2215 llvm::AttributeSet::FunctionIndex,
2216 llvm::Attribute::NoUnwind));
2220 llvm::FunctionType *FTy =
2221 llvm::FunctionType::get(llvm::Type::getVoidTy(CGM.
getLLVMContext()),
2222 CGM.
IntTy->getPointerTo(),
false);
2224 FTy,
"_Init_thread_abort",
2226 llvm::AttributeSet::FunctionIndex,
2227 llvm::Attribute::NoUnwind));
2232 llvm::GlobalVariable *Guard;
2234 ResetGuardBit(llvm::GlobalVariable *Guard,
unsigned GuardNum)
2235 : Guard(Guard), GuardNum(GuardNum) {}
2241 llvm::LoadInst *LI = Builder.CreateLoad(Guard);
2242 llvm::ConstantInt *Mask =
2243 llvm::ConstantInt::get(CGF.
IntTy, ~(1U << GuardNum));
2244 Builder.CreateStore(Builder.CreateAnd(LI, Mask), Guard);
2249 llvm::GlobalVariable *Guard;
2250 CallInitThreadAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
2260 llvm::GlobalVariable *GV,
2264 assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
2266 llvm::Function *F = CGF.
CurFn;
2267 F->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
2268 F->setComdat(CGM.
getModule().getOrInsertComdat(F->getName()));
2274 bool ThreadsafeStatic = getContext().getLangOpts().ThreadsafeStatics;
2278 bool HasPerVariableGuard = ThreadsafeStatic && !ThreadlocalStatic;
2281 llvm::IntegerType *GuardTy = CGF.
Int32Ty;
2282 llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
2285 GuardInfo *GI =
nullptr;
2286 if (ThreadlocalStatic)
2288 else if (!ThreadsafeStatic)
2291 llvm::GlobalVariable *GuardVar = GI ? GI->Guard :
nullptr;
2296 GuardNum = getContext().getStaticLocalNumber(&D);
2297 assert(GuardNum > 0);
2299 }
else if (HasPerVariableGuard) {
2303 GuardNum = GI->BitIndex++;
2306 if (!HasPerVariableGuard && GuardNum >= 32) {
2308 ErrorUnsupportedABI(CGF,
"more than 32 guarded initializations");
2317 llvm::raw_svector_ostream Out(GuardName);
2318 if (HasPerVariableGuard)
2319 getMangleContext().mangleThreadSafeStaticGuardVariable(&D, GuardNum,
2322 getMangleContext().mangleStaticGuardVariable(&D, Out);
2329 new llvm::GlobalVariable(CGM.
getModule(), GuardTy,
false,
2330 GV->getLinkage(), Zero, GuardName.str());
2331 GuardVar->setVisibility(GV->getVisibility());
2332 GuardVar->setDLLStorageClass(GV->getDLLStorageClass());
2333 if (GuardVar->isWeakForLinker())
2334 GuardVar->setComdat(
2335 CGM.
getModule().getOrInsertComdat(GuardVar->getName()));
2337 GuardVar->setThreadLocal(
true);
2338 if (GI && !HasPerVariableGuard)
2339 GI->Guard = GuardVar;
2342 assert(GuardVar->getLinkage() == GV->getLinkage() &&
2343 "static local from the same function had different linkage");
2345 if (!HasPerVariableGuard) {
2353 llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1U << GuardNum);
2354 llvm::LoadInst *LI = Builder.CreateLoad(GuardVar);
2356 Builder.CreateICmpNE(Builder.CreateAnd(LI, Bit), Zero);
2359 Builder.CreateCondBr(IsInitialized, EndBlock, InitBlock);
2364 Builder.CreateStore(Builder.CreateOr(LI, Bit), GuardVar);
2368 Builder.CreateBr(EndBlock);
2388 llvm::LoadInst *FirstGuardLoad =
2389 Builder.CreateAlignedLoad(GuardVar, IntAlign);
2390 FirstGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2391 llvm::LoadInst *InitThreadEpoch =
2394 Builder.CreateICmpSGT(FirstGuardLoad, InitThreadEpoch);
2397 Builder.CreateCondBr(IsUninitialized, AttemptInitBlock, EndBlock);
2403 llvm::LoadInst *SecondGuardLoad =
2404 Builder.CreateAlignedLoad(GuardVar, IntAlign);
2405 SecondGuardLoad->setOrdering(llvm::AtomicOrdering::Unordered);
2407 Builder.CreateICmpEQ(SecondGuardLoad, getAllOnesInt());
2409 Builder.CreateCondBr(ShouldDoInit, InitBlock, EndBlock);
2417 Builder.CreateBr(EndBlock);
2434 return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) &&
2446 fields.push_back(CGM.
IntTy);
2450 fields.push_back(CGM.
IntTy);
2451 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2452 fields.push_back(CGM.
IntTy);
2453 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2454 fields.push_back(CGM.
IntTy);
2456 if (fields.size() == 1)
2461 void MicrosoftCXXABI::
2464 assert(fields.empty());
2469 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2471 if (RD->nullFieldOffsetIsZero())
2472 fields.push_back(getZeroInt());
2474 fields.push_back(getAllOnesInt());
2479 fields.push_back(getZeroInt());
2480 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2481 fields.push_back(getZeroInt());
2482 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2483 fields.push_back(getAllOnesInt());
2489 GetNullMemberPointerFields(MPT, fields);
2490 if (fields.size() == 1)
2492 llvm::Constant *Res = llvm::ConstantStruct::getAnon(fields);
2493 assert(Res->getType() == ConvertMemberPointerType(MPT));
2498 MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField,
2499 bool IsMemberFunction,
2502 unsigned VBTableIndex) {
2507 if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance))
2511 fields.push_back(FirstField);
2513 if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance))
2514 fields.push_back(llvm::ConstantInt::get(
2517 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) {
2520 Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2525 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2526 fields.push_back(llvm::ConstantInt::get(CGM.
IntTy, VBTableIndex));
2528 return llvm::ConstantStruct::getAnon(fields);
2536 MSInheritanceAttr::Keyword_virtual_inheritance)
2537 offset -= getContext().getOffsetOfBaseWithVBPtr(RD);
2538 llvm::Constant *FirstField =
2540 return EmitFullMemberPointer(FirstField,
false, RD,
2544 llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(
const APValue &MP,
2549 return EmitNullMemberPointer(DstTy);
2555 if (
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
2556 C = EmitMemberFunctionPointer(MD);
2559 C = EmitMemberDataPointer(DstTy, FieldOffset);
2562 if (!MemberPointerPath.empty()) {
2563 const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
2567 ->castAs<MemberPointerType>();
2575 if (DerivedMember) {
2583 if (BS.getType()->getAsCXXRecordDecl()->getCanonicalDecl() ==
2585 DerivedToBasePath.push_back(&BS);
2588 assert(DerivedToBasePath.size() == MemberPointerPath.size());
2592 C = EmitMemberPointerConversion(SrcTy, DstTy, CK, DerivedToBasePath.begin(),
2593 DerivedToBasePath.end(),
C);
2599 MicrosoftCXXABI::EmitMemberFunctionPointer(
const CXXMethodDecl *MD) {
2600 assert(MD->
isInstance() &&
"Member function must not be static!");
2607 unsigned VBTableIndex = 0;
2608 llvm::Constant *FirstField;
2610 if (!MD->isVirtual()) {
2625 VTableContext.getMethodVFTableLocation(MD);
2626 FirstField = EmitVirtualMemPtrThunk(MD, ML);
2630 VBTableIndex = VTableContext.getVBTableIndex(RD, ML.
VBase) * 4;
2633 if (VBTableIndex == 0 &&
2635 MSInheritanceAttr::Keyword_virtual_inheritance)
2636 NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD);
2639 FirstField = llvm::ConstantExpr::getBitCast(FirstField, CGM.
VoidPtrTy);
2640 return EmitFullMemberPointer(FirstField,
true, RD,
2641 NonVirtualBaseAdjustment, VBTableIndex);
2656 llvm::ICmpInst::Predicate Eq;
2657 llvm::Instruction::BinaryOps
And, Or;
2659 Eq = llvm::ICmpInst::ICMP_NE;
2660 And = llvm::Instruction::Or;
2663 Eq = llvm::ICmpInst::ICMP_EQ;
2665 Or = llvm::Instruction::Or;
2674 return Builder.CreateICmp(Eq, L, R);
2677 llvm::Value *L0 = Builder.CreateExtractValue(L, 0,
"lhs.0");
2678 llvm::Value *R0 = Builder.CreateExtractValue(R, 0,
"rhs.0");
2679 llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0,
"memptr.cmp.first");
2683 llvm::StructType *LType = cast<llvm::StructType>(L->getType());
2684 for (
unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
2685 llvm::Value *LF = Builder.CreateExtractValue(L, I);
2686 llvm::Value *RF = Builder.CreateExtractValue(R, I);
2687 llvm::Value *Cmp = Builder.CreateICmp(Eq, LF, RF,
"memptr.cmp.rest");
2689 Res = Builder.CreateBinOp(And, Res, Cmp);
2697 llvm::Value *Zero = llvm::Constant::getNullValue(L0->getType());
2698 llvm::Value *IsZero = Builder.CreateICmp(Eq, L0, Zero,
"memptr.cmp.iszero");
2699 Res = Builder.CreateBinOp(Or, Res, IsZero);
2704 return Builder.CreateBinOp(And, Res, Cmp0,
"memptr.cmp");
2715 fields.push_back(llvm::Constant::getNullValue(CGM.
VoidPtrTy));
2717 GetNullMemberPointerFields(MPT, fields);
2718 assert(!fields.empty());
2720 if (MemPtr->getType()->isStructTy())
2721 FirstField = Builder.CreateExtractValue(MemPtr, 0);
2722 llvm::Value *Res = Builder.CreateICmpNE(FirstField, fields[0],
"memptr.cmp0");
2730 for (
int I = 1, E = fields.size(); I < E; ++I) {
2731 llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
2732 llvm::Value *
Next = Builder.CreateICmpNE(Field, fields[I],
"memptr.cmp");
2733 Res = Builder.CreateOr(Res, Next,
"memptr.tobool");
2739 llvm::Constant *Val) {
2742 llvm::Constant *FirstField = Val->getType()->isStructTy() ?
2743 Val->getAggregateElement(0U) : Val;
2744 return FirstField->isNullValue();
2749 if (isZeroInitializable(MPT) && Val->isNullValue())
2755 GetNullMemberPointerFields(MPT, Fields);
2756 if (Fields.size() == 1) {
2757 assert(Val->getType()->isIntegerTy());
2758 return Val == Fields[0];
2762 for (I = 0, E = Fields.size(); I != E; ++I) {
2763 if (Val->getAggregateElement(I) != Fields[I])
2777 This = Builder.CreateBitCast(This, CGM.
Int8PtrTy);
2779 Builder.CreateInBoundsGEP(This, VBPtrOffset,
"vbptr");
2780 if (VBPtrOut) *VBPtrOut = VBPtr;
2781 VBPtr = Builder.CreateBitCast(VBPtr,
2782 CGM.
Int32Ty->getPointerTo(0)->getPointerTo(0));
2783 llvm::Value *VBTable = Builder.CreateLoad(VBPtr,
"vbtable");
2787 VBTableOffset, llvm::ConstantInt::get(VBTableOffset->getType(), 2),
2791 llvm::Value *VBaseOffs = Builder.CreateInBoundsGEP(VBTable, VBTableIndex);
2792 VBaseOffs = Builder.CreateBitCast(VBaseOffs, CGM.
Int32Ty->getPointerTo(0));
2793 return Builder.CreateLoad(VBaseOffs,
"vbase_offs");
2802 Base = Builder.CreateBitCast(Base, CGM.
Int8PtrTy);
2803 llvm::BasicBlock *OriginalBB =
nullptr;
2804 llvm::BasicBlock *SkipAdjustBB =
nullptr;
2805 llvm::BasicBlock *VBaseAdjustBB =
nullptr;
2812 OriginalBB = Builder.GetInsertBlock();
2816 Builder.CreateICmpNE(VBTableOffset, getZeroInt(),
2818 Builder.CreateCondBr(IsVirtual, VBaseAdjustBB, SkipAdjustBB);
2830 "member pointer representation requires a "
2831 "complete class type for %0 to perform this expression");
2834 offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
2839 GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
2840 llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
2843 if (VBaseAdjustBB) {
2844 Builder.CreateBr(SkipAdjustBB);
2846 llvm::PHINode *Phi = Builder.CreatePHI(CGM.
Int8PtrTy, 2,
"memptr.base");
2847 Phi->addIncoming(Base, OriginalBB);
2848 Phi->addIncoming(AdjustedBase, VBaseAdjustBB);
2851 return AdjustedBase;
2854 llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
2858 unsigned AS = Base->getType()->getPointerAddressSpace();
2868 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
2870 if (MemPtr->getType()->isStructTy()) {
2873 FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
2874 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
2875 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
2876 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
2877 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
2880 if (VirtualBaseAdjustmentOffset) {
2881 Base = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
2886 Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
2890 Builder.CreateInBoundsGEP(Base, FieldOffset,
"memptr.offset");
2894 return Builder.CreateBitCast(Addr, PType);
2906 if (isa<llvm::Constant>(Src))
2907 return EmitMemberPointerConversion(E, cast<llvm::Constant>(Src));
2918 if (IsReinterpret && IsFunc)
2923 if (IsReinterpret &&
2930 llvm::Value *IsNotNull = EmitMemberPointerIsNotNull(CGF, Src, SrcTy);
2931 llvm::Constant *DstNull = EmitNullMemberPointer(DstTy);
2935 if (IsReinterpret) {
2938 assert(Src->getType() == DstNull->getType());
2939 return Builder.CreateSelect(IsNotNull, Src, DstNull);
2942 llvm::BasicBlock *OriginalBB = Builder.GetInsertBlock();
2945 Builder.CreateCondBr(IsNotNull, ConvertBB, ContinueBB);
2948 llvm::Value *Dst = EmitNonNullMemberPointerConversion(
2952 Builder.CreateBr(ContinueBB);
2956 llvm::PHINode *Phi = Builder.CreatePHI(DstNull->getType(), 2,
"memptr.converted");
2957 Phi->addIncoming(DstNull, OriginalBB);
2958 Phi->addIncoming(Dst, ConvertBB);
2962 llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion(
2972 bool IsConstant = isa<llvm::Constant>(Src);
2976 llvm::Value *NonVirtualBaseAdjustment = getZeroInt();
2977 llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt();
2979 if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
2982 FirstField = Builder.CreateExtractValue(Src, I++);
2983 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
2984 NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
2985 if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
2986 VBPtrOffset = Builder.CreateExtractValue(Src, I++);
2987 if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
2988 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
2997 llvm::Value *&NVAdjustField = IsFunc ? NonVirtualBaseAdjustment : FirstField;
3005 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3006 if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3007 if (int64_t SrcOffsetToFirstVBase =
3008 getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) {
3009 llvm::Value *UndoSrcAdjustment = Builder.CreateSelect(
3011 llvm::ConstantInt::get(CGM.
IntTy, SrcOffsetToFirstVBase),
3013 NVAdjustField = Builder.CreateNSWAdd(NVAdjustField, UndoSrcAdjustment);
3024 llvm::Constant *BaseClassOffset = llvm::ConstantInt::get(
3030 if (IsDerivedToBase)
3031 NVDisp = Builder.CreateNSWSub(NVAdjustField, BaseClassOffset,
"adj");
3033 NVDisp = Builder.CreateNSWAdd(NVAdjustField, BaseClassOffset,
"adj");
3035 NVAdjustField = Builder.CreateSelect(SrcVBIndexEqZero, NVDisp, getZeroInt());
3040 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) &&
3041 MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) {
3042 if (llvm::GlobalVariable *VDispMap =
3043 getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) {
3045 VirtualBaseAdjustmentOffset, llvm::ConstantInt::get(CGM.
IntTy, 4));
3047 llvm::Constant *Mapping = VDispMap->getInitializer();
3048 VirtualBaseAdjustmentOffset =
3049 Mapping->getAggregateElement(cast<llvm::Constant>(VBIndex));
3052 VirtualBaseAdjustmentOffset =
3053 Builder.CreateLoad(Builder.CreateInBoundsGEP(VDispMap, Idxs));
3057 Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt());
3063 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) {
3064 llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get(
3066 getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity());
3068 Builder.CreateSelect(DstVBIndexEqZero, getZeroInt(), DstVBPtrOffset);
3074 if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) {
3075 if (int64_t DstOffsetToFirstVBase =
3076 getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) {
3077 llvm::Value *DoDstAdjustment = Builder.CreateSelect(
3079 llvm::ConstantInt::get(CGM.
IntTy, DstOffsetToFirstVBase),
3081 NVAdjustField = Builder.CreateNSWSub(NVAdjustField, DoDstAdjustment);
3087 if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) {
3090 Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy));
3092 Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
3093 if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
3094 Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++);
3095 if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
3096 Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++);
3097 if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
3098 Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++);
3104 MicrosoftCXXABI::EmitMemberPointerConversion(
const CastExpr *E,
3105 llvm::Constant *Src) {
3112 return EmitMemberPointerConversion(SrcTy, DstTy, CK, E->
path_begin(),
3116 llvm::Constant *MicrosoftCXXABI::EmitMemberPointerConversion(
3125 if (MemberPointerConstantIsNull(SrcTy, Src))
3126 return EmitNullMemberPointer(DstTy);
3135 auto *Dst = cast<llvm::Constant>(EmitNonNullMemberPointerConversion(
3136 SrcTy, DstTy, CK, PathBegin, PathEnd, Src, Builder));
3141 llvm::Value *MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
3148 llvm::FunctionType *FTy =
3153 MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
3159 llvm::Value *VirtualBaseAdjustmentOffset =
nullptr;
3161 if (MemPtr->getType()->isStructTy()) {
3164 FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
3165 if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance))
3166 NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
3167 if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
3168 VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
3169 if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
3170 VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
3173 if (VirtualBaseAdjustmentOffset) {
3174 This = AdjustVirtualBase(CGF, E, RD, This, VirtualBaseAdjustmentOffset,
3178 if (NonVirtualBaseAdjustment) {
3180 llvm::Value *Ptr = Builder.CreateBitCast(This, Builder.getInt8PtrTy());
3181 Ptr = Builder.CreateInBoundsGEP(Ptr, NonVirtualBaseAdjustment);
3182 This = Builder.CreateBitCast(Ptr, This->getType(),
"this.adjusted");
3185 return Builder.CreateBitCast(FunctionPointer, FTy->getPointerTo());
3189 return new MicrosoftCXXABI(CGM);
3223 StringRef MangledName(
"\01??_7type_info@@6B@");
3224 if (
auto VTable = CGM.
getModule().getNamedGlobal(MangledName))
3229 nullptr, MangledName);
3240 struct MSRTTIClass {
3242 IsPrivateOnPath = 1 | 8,
3246 HasHierarchyDescriptor = 64
3249 uint32_t initialize(
const MSRTTIClass *Parent,
3252 MSRTTIClass *getFirstChild() {
return this + 1; }
3253 static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
3254 return Child + 1 + Child->NumBases;
3258 uint32_t Flags, NumBases, OffsetInVBase;
3262 uint32_t MSRTTIClass::initialize(
const MSRTTIClass *Parent,
3264 Flags = HasHierarchyDescriptor;
3266 VirtualRoot =
nullptr;
3270 Flags |= IsPrivate | IsPrivateOnPath;
3276 if (Parent->Flags & IsPrivateOnPath)
3277 Flags |= IsPrivateOnPath;
3278 VirtualRoot = Parent->VirtualRoot;
3279 OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
3280 .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
3284 MSRTTIClass *Child = getFirstChild();
3286 NumBases += Child->initialize(
this, &Base) + 1;
3287 Child = getNextChild(Child);
3292 static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(
QualType Ty) {
3301 return llvm::GlobalValue::LinkOnceODRLinkage;
3303 llvm_unreachable(
"Invalid linkage!");
3309 struct MSRTTIBuilder {
3311 HasBranchingHierarchy = 1,
3312 HasVirtualBranchingHierarchy = 2,
3313 HasAmbiguousBases = 4
3316 MSRTTIBuilder(MicrosoftCXXABI &ABI,
const CXXRecordDecl *RD)
3317 : CGM(ABI.CGM), Context(CGM.getContext()),
3318 VMContext(CGM.getLLVMContext()),
Module(CGM.getModule()), RD(RD),
3319 Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
3322 llvm::GlobalVariable *getBaseClassDescriptor(
const MSRTTIClass &Classes);
3323 llvm::GlobalVariable *
3325 llvm::GlobalVariable *getClassHierarchyDescriptor();
3326 llvm::GlobalVariable *getCompleteObjectLocator(
const VPtrInfo *Info);
3330 llvm::LLVMContext &VMContext;
3333 llvm::GlobalVariable::LinkageTypes
Linkage;
3334 MicrosoftCXXABI &ABI;
3343 Classes.push_back(MSRTTIClass(RD));
3351 llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
3352 llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
3353 llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
3354 for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
3355 if ((Class->Flags & MSRTTIClass::IsVirtual) &&
3356 !VirtualBases.insert(Class->RD).second) {
3357 Class = MSRTTIClass::getNextChild(Class);
3360 if (!UniqueBases.insert(Class->RD).second)
3361 AmbiguousBases.insert(Class->RD);
3364 if (AmbiguousBases.empty())
3366 for (MSRTTIClass &Class : Classes)
3367 if (AmbiguousBases.count(Class.RD))
3368 Class.Flags |= MSRTTIClass::IsAmbiguous;
3371 llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
3374 llvm::raw_svector_ostream Out(MangledName);
3375 ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
3379 if (
auto CHD =
Module.getNamedGlobal(MangledName))
3385 Classes.front().initialize(
nullptr,
nullptr);
3388 for (
auto Class : Classes) {
3390 Flags |= HasBranchingHierarchy;
3393 if (Class.Flags & MSRTTIClass::IsAmbiguous)
3394 Flags |= HasAmbiguousBases;
3396 if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
3397 Flags |= HasVirtualBranchingHierarchy;
3401 llvm::ConstantInt::get(CGM.
IntTy, 0)};
3404 auto Type = ABI.getClassHierarchyDescriptorType();
3405 auto CHD =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3407 StringRef(MangledName));
3408 if (CHD->isWeakForLinker())
3409 CHD->setComdat(CGM.
getModule().getOrInsertComdat(CHD->getName()));
3411 auto *Bases = getBaseClassArray(Classes);
3414 llvm::Constant *Fields[] = {
3415 llvm::ConstantInt::get(CGM.
IntTy, 0),
3416 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3417 llvm::ConstantInt::get(CGM.
IntTy, Classes.size()),
3418 ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
3419 Bases->getValueType(), Bases,
3422 CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3426 llvm::GlobalVariable *
3430 llvm::raw_svector_ostream Out(MangledName);
3431 ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
3439 llvm::Type *PtrType = ABI.getImageRelativeType(
3440 ABI.getBaseClassDescriptorType()->getPointerTo());
3441 auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
3443 new llvm::GlobalVariable(
Module, ArrType,
3445 nullptr, StringRef(MangledName));
3446 if (BCA->isWeakForLinker())
3447 BCA->setComdat(CGM.
getModule().getOrInsertComdat(BCA->getName()));
3451 for (MSRTTIClass &Class : Classes)
3452 BaseClassArrayData.push_back(
3453 ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
3454 BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
3455 BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
3459 llvm::GlobalVariable *
3460 MSRTTIBuilder::getBaseClassDescriptor(
const MSRTTIClass &Class) {
3463 uint32_t OffsetInVBTable = 0;
3464 int32_t VBPtrOffset = -1;
3465 if (Class.VirtualRoot) {
3467 OffsetInVBTable = VTableContext.
getVBTableIndex(RD, Class.VirtualRoot) * 4;
3473 llvm::raw_svector_ostream Out(MangledName);
3474 ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
3475 Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
3480 if (
auto BCD =
Module.getNamedGlobal(MangledName))
3484 auto Type = ABI.getBaseClassDescriptorType();
3486 new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3487 nullptr, StringRef(MangledName));
3488 if (BCD->isWeakForLinker())
3489 BCD->setComdat(CGM.
getModule().getOrInsertComdat(BCD->getName()));
3492 llvm::Constant *Fields[] = {
3493 ABI.getImageRelativeConstant(
3495 llvm::ConstantInt::get(CGM.
IntTy, Class.NumBases),
3496 llvm::ConstantInt::get(CGM.
IntTy, Class.OffsetInVBase),
3497 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3498 llvm::ConstantInt::get(CGM.
IntTy, OffsetInVBTable),
3499 llvm::ConstantInt::get(CGM.
IntTy, Class.Flags),
3500 ABI.getImageRelativeConstant(
3501 MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
3503 BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
3507 llvm::GlobalVariable *
3508 MSRTTIBuilder::getCompleteObjectLocator(
const VPtrInfo *Info) {
3511 llvm::raw_svector_ostream Out(MangledName);
3512 ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info->
MangledPath, Out);
3516 if (
auto COL =
Module.getNamedGlobal(MangledName))
3521 int VFPtrOffset = 0;
3527 ->second.hasVtorDisp())
3531 llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
3532 auto COL =
new llvm::GlobalVariable(
Module, Type,
true, Linkage,
3533 nullptr, StringRef(MangledName));
3536 llvm::Constant *Fields[] = {
3537 llvm::ConstantInt::get(CGM.
IntTy, ABI.isImageRelative()),
3538 llvm::ConstantInt::get(CGM.
IntTy, OffsetToTop),
3539 llvm::ConstantInt::get(CGM.
IntTy, VFPtrOffset),
3540 ABI.getImageRelativeConstant(
3542 ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
3543 ABI.getImageRelativeConstant(COL),
3546 if (!ABI.isImageRelative())
3547 FieldsRef = FieldsRef.drop_back();
3548 COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
3549 if (COL->isWeakForLinker())
3550 COL->setComdat(CGM.
getModule().getOrInsertComdat(COL->getName()));
3555 bool &IsConst,
bool &IsVolatile) {
3566 if (!PointeeType.
isNull()) {
3586 MicrosoftCXXABI::getAddrOfCXXCatchHandlerType(
QualType Type,
3591 bool IsConst, IsVolatile;
3606 llvm::raw_svector_ostream Out(MangledName);
3607 getMangleContext().mangleCXXCatchHandlerType(Type, Flags, Out);
3610 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3611 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3613 llvm::Constant *Fields[] = {
3614 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3615 getAddrOfRTTIDescriptor(Type),
3617 llvm::StructType *CatchHandlerTypeType = getCatchHandlerTypeType();
3618 auto *Var =
new llvm::GlobalVariable(
3619 CGM.
getModule(), CatchHandlerTypeType,
true,
3620 llvm::GlobalValue::PrivateLinkage,
3621 llvm::ConstantStruct::get(CatchHandlerTypeType, Fields),
3622 StringRef(MangledName));
3623 Var->setUnnamedAddr(
true);
3624 Var->setSection(
"llvm.metadata");
3632 llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(
QualType Type) {
3635 llvm::raw_svector_ostream Out(MangledName);
3636 getMangleContext().mangleCXXRTTI(Type, Out);
3640 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3641 return llvm::ConstantExpr::getBitCast(GV, CGM.
Int8PtrTy);
3646 llvm::raw_svector_ostream Out(TypeInfoString);
3647 getMangleContext().mangleCXXRTTIName(Type, Out);
3651 llvm::Constant *Fields[] = {
3653 llvm::ConstantPointerNull::get(CGM.
Int8PtrTy),
3654 llvm::ConstantDataArray::getString(CGM.
getLLVMContext(), TypeInfoString)};
3655 llvm::StructType *TypeDescriptorType =
3656 getTypeDescriptorType(TypeInfoString);
3657 auto *Var =
new llvm::GlobalVariable(
3658 CGM.
getModule(), TypeDescriptorType,
false,
3659 getLinkageForRTTI(Type),
3660 llvm::ConstantStruct::get(TypeDescriptorType, Fields),
3661 StringRef(MangledName));
3662 if (Var->isWeakForLinker())
3663 Var->setComdat(CGM.
getModule().getOrInsertComdat(Var->getName()));
3664 return llvm::ConstantExpr::getBitCast(Var, CGM.
Int8PtrTy);
3668 llvm::GlobalVariable *
3669 MicrosoftCXXABI::getMSCompleteObjectLocator(
const CXXRecordDecl *RD,
3671 return MSRTTIBuilder(*
this, RD).getCompleteObjectLocator(Info);
3690 if (ProducedAlias) {
3706 if (Fn->isWeakForLinker())
3707 Fn->setComdat(CGM.
getModule().getOrInsertComdat(Fn->getName()));
3710 void MicrosoftCXXABI::emitCXXStructor(
const CXXMethodDecl *MD,
3712 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
3726 llvm::raw_svector_ostream Out(ThunkName);
3727 getMangleContext().mangleCXXCtor(CD, CT, Out);
3731 if (llvm::GlobalValue *GV = CGM.
getModule().getNamedValue(ThunkName))
3732 return cast<llvm::Function>(GV);
3738 QualType RecordTy = getContext().getRecordType(RD);
3740 ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.
getModule());
3741 ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
3743 if (ThunkFn->isWeakForLinker())
3744 ThunkFn->setComdat(CGM.
getModule().getOrInsertComdat(ThunkFn->getName()));
3755 buildThisParam(CGF, FunctionArgs);
3760 getContext(),
nullptr,
SourceLocation(), &getContext().Idents.get(
"src"),
3761 getContext().getLValueReferenceType(RecordTy,
3764 FunctionArgs.push_back(&SrcParam);
3770 &getContext().Idents.get(
"is_most_derived"),
3771 getContext().IntTy);
3774 FunctionArgs.push_back(&IsMostDerived);
3796 std::vector<Stmt *> ArgVec;
3797 for (
unsigned I = IsCopy ? 1 : 0, E = CD->
getNumParams(); I != E; ++I) {
3798 Stmt *DefaultArg = getContext().getDefaultArgExprForConstructor(CD, I);
3799 assert(DefaultArg &&
"sema forgot to instantiate default args");
3800 ArgVec.push_back(DefaultArg);
3807 ArgEnd(ArgVec.data() + ArgVec.size());
3808 CGF.
EmitCallArgs(Args, FPT, ArgBegin, ArgEnd, CD, IsCopy ? 1 : 0);
3811 unsigned ExtraArgs = addImplicitConstructorArgs(CGF, CD,
Ctor_Complete,
3821 Cleanups.ForceCleanup();
3830 llvm::Constant *MicrosoftCXXABI::getCatchableType(
QualType T,
3832 int32_t VBPtrOffset,
3844 uint32_t Size = getContext().getTypeSizeInChars(T).getQuantity();
3847 llvm::raw_svector_ostream Out(MangledName);
3848 getMangleContext().mangleCXXCatchableType(T, CD, CT, Size, NVOffset,
3849 VBPtrOffset, VBIndex, Out);
3851 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
3852 return getImageRelativeConstant(GV);
3856 llvm::Constant *TD = getImageRelativeConstant(getAddrOfRTTIDescriptor(T));
3860 llvm::Constant *CopyCtor;
3867 CopyCtor = llvm::ConstantExpr::getBitCast(CopyCtor, CGM.
Int8PtrTy);
3869 CopyCtor = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
3871 CopyCtor = getImageRelativeConstant(CopyCtor);
3873 bool IsScalar = !RD;
3874 bool HasVirtualBases =
false;
3875 bool IsStdBadAlloc =
false;
3880 HasVirtualBases = RD->getNumVBases() > 0;
3882 IsStdBadAlloc = II->isStr(
"bad_alloc") && RD->isInStdNamespace();
3890 if (HasVirtualBases)
3895 llvm::Constant *Fields[] = {
3896 llvm::ConstantInt::get(CGM.
IntTy, Flags),
3898 llvm::ConstantInt::get(CGM.
IntTy, NVOffset),
3899 llvm::ConstantInt::get(CGM.
IntTy, VBPtrOffset),
3900 llvm::ConstantInt::get(CGM.
IntTy, VBIndex),
3901 llvm::ConstantInt::get(CGM.
IntTy, Size),
3904 llvm::StructType *CTType = getCatchableTypeType();
3905 auto *GV =
new llvm::GlobalVariable(
3906 CGM.
getModule(), CTType,
true, getLinkageForRTTI(T),
3907 llvm::ConstantStruct::get(CTType, Fields), StringRef(MangledName));
3908 GV->setUnnamedAddr(
true);
3909 GV->setSection(
".xdata");
3910 if (GV->isWeakForLinker())
3911 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
3912 return getImageRelativeConstant(GV);
3915 llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(
QualType T) {
3919 llvm::GlobalVariable *&CTA = CatchableTypeArrays[T];
3944 if (MostDerivedClass) {
3951 Classes.front().initialize(
nullptr,
nullptr);
3953 for (
const MSRTTIClass &Class : Classes) {
3956 (MSRTTIClass::IsPrivateOnPath | MSRTTIClass::IsAmbiguous))
3959 uint32_t OffsetInVBTable = 0;
3960 int32_t VBPtrOffset = -1;
3961 if (Class.VirtualRoot) {
3972 CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
3973 VBPtrOffset, OffsetInVBTable));
3981 CatchableTypes.insert(getCatchableType(T));
3994 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4005 CatchableTypes.insert(getCatchableType(getContext().VoidPtrTy));
4007 uint32_t NumEntries = CatchableTypes.size();
4008 llvm::Type *CTType =
4009 getImageRelativeType(getCatchableTypeType()->getPointerTo());
4010 llvm::ArrayType *AT = llvm::ArrayType::get(CTType, NumEntries);
4011 llvm::StructType *CTAType = getCatchableTypeArrayType(NumEntries);
4012 llvm::Constant *Fields[] = {
4013 llvm::ConstantInt::get(CGM.
IntTy, NumEntries),
4014 llvm::ConstantArray::get(
4015 AT, llvm::makeArrayRef(CatchableTypes.begin(),
4016 CatchableTypes.end()))
4020 llvm::raw_svector_ostream Out(MangledName);
4021 getMangleContext().mangleCXXCatchableTypeArray(T, NumEntries, Out);
4023 CTA =
new llvm::GlobalVariable(
4024 CGM.
getModule(), CTAType,
true, getLinkageForRTTI(T),
4025 llvm::ConstantStruct::get(CTAType, Fields), StringRef(MangledName));
4026 CTA->setUnnamedAddr(
true);
4027 CTA->setSection(
".xdata");
4028 if (CTA->isWeakForLinker())
4029 CTA->setComdat(CGM.
getModule().getOrInsertComdat(CTA->getName()));
4033 llvm::GlobalVariable *MicrosoftCXXABI::getThrowInfo(
QualType T) {
4034 bool IsConst, IsVolatile;
4039 llvm::GlobalVariable *CTA = getCatchableTypeArray(T);
4044 uint32_t NumEntries =
4045 cast<llvm::ConstantInt>(CTA->getInitializer()->getAggregateElement(0U))
4046 ->getLimitedValue();
4050 llvm::raw_svector_ostream Out(MangledName);
4051 getMangleContext().mangleCXXThrowInfo(T, IsConst, IsVolatile, NumEntries,
4057 if (llvm::GlobalVariable *GV = CGM.
getModule().getNamedGlobal(MangledName))
4071 llvm::Constant *CleanupFn = llvm::Constant::getNullValue(CGM.
Int8PtrTy);
4074 if (!DtorD->isTrivial())
4075 CleanupFn = llvm::ConstantExpr::getBitCast(
4079 llvm::Constant *ForwardCompat =
4080 getImageRelativeConstant(llvm::Constant::getNullValue(CGM.
Int8PtrTy));
4081 llvm::Constant *PointerToCatchableTypes = getImageRelativeConstant(
4082 llvm::ConstantExpr::getBitCast(CTA, CGM.
Int8PtrTy));
4083 llvm::StructType *TIType = getThrowInfoType();
4084 llvm::Constant *Fields[] = {
4085 llvm::ConstantInt::get(CGM.
IntTy, Flags),
4086 getImageRelativeConstant(CleanupFn),
4088 PointerToCatchableTypes
4090 auto *GV =
new llvm::GlobalVariable(
4091 CGM.
getModule(), TIType,
true, getLinkageForRTTI(T),
4092 llvm::ConstantStruct::get(TIType, Fields), StringRef(MangledName));
4093 GV->setUnnamedAddr(
true);
4094 GV->setSection(
".xdata");
4095 if (GV->isWeakForLinker())
4096 GV->setComdat(CGM.
getModule().getOrInsertComdat(GV->getName()));
4111 llvm::GlobalVariable *TI = getThrowInfo(ThrowType);
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
CastKind getCastKind() const
llvm::IntegerType * IntTy
int
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
void setSRetAfterThis(bool AfterThis)
External linkage, which indicates that the entity can be referred to from other translation units...
bool isNullPtrType() const
StringRef getName() const
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
static llvm::Constant * getInitThreadFooterFn(CodeGenModule &CGM)
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
CodeGenTypes & getTypes()
llvm::Type * ConvertTypeForMem(QualType T)
CanQualType getReturnType() const
uint32_t VBPtrOffset
The offset (in bytes) of the vbptr, relative to the beginning of the derived class.
DestructionKind isDestructedType() const
QualType getType() const
Retrieves the type of the base class.
llvm::Module & getModule() const
llvm::LLVMContext & getLLVMContext()
static void detectAmbiguousBases(SmallVectorImpl< MSRTTIClass > &Classes)
Find ambiguity among base classes.
MSInheritanceAttr::Spelling getMSInheritanceModel() const
Returns the inheritance model used for this record.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
bool isGlobalDelete() const
No linkage, which means that the entity is unique and can only be referred to from within its scope...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool hasNonTrivialDestructor() const
Determine whether this class has a non-trivial destructor (C++ [class.dtor]p3)
static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
vtable_component_iterator vtable_component_begin() const
bool hasDefinition() const
QualType getPointeeType() const
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
bool isFuncTypeConvertible(const FunctionType *FT)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D)
Default closure variant of a ctor.
static llvm::GlobalVariable * getInitThreadEpochPtr(CodeGenModule &CGM)
const CXXBaseSpecifier *const * path_const_iterator
TLSKind getTLSKind() const
static llvm::Constant * getInitThreadHeaderFn(CodeGenModule &CGM)
A this pointer adjustment.
QualType getThisType(ASTContext &C) const
Returns the type of the this pointer.
llvm::Value * ReturnValue
A C++ throw-expression (C++ [except.throw]).
static llvm::Constant * getInitThreadAbortFn(CodeGenModule &CGM)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have...
static void mangleVFTableName(MicrosoftMangleContext &MangleContext, const CXXRecordDecl *RD, const VPtrInfo *VFPtr, SmallString< 256 > &Name)
GlobalDecl getCanonicalDecl() const
int32_t VBOffsetOffset
The offset (in bytes) of the vbase offset in the vbtable.
ArrayRef< const CXXRecordDecl * > getMemberPointerPath() const
const CXXRecordDecl * getVBaseWithVPtr() const
The vptr is stored inside the non-virtual component of this virtual base.
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, CallExpr::const_arg_iterator ArgBeg, CallExpr::const_arg_iterator ArgEnd, const FunctionDecl *CalleeDecl=nullptr, unsigned ParamsToSkip=0)
EmitCallArgs - Emit call arguments for a function.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
BasePath PathToBaseWithVPtr
bool hasNonTrivialCopyConstructor() const
Determine whether this class has a non-trivial copy constructor (C++ [class.copy]p6, C++11 [class.copy]p12)
bool isReferenceType() const
static const CXXRecordDecl * getClassAtVTableLocation(ASTContext &Ctx, const CXXRecordDecl *RD, CharUnits Offset)
uint64_t getNumVTableComponents() const
llvm::IntegerType * SizeTy
StructorType getFromDtorType(CXXDtorType T)
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
llvm::Function * codegenCXXStructor(const CXXMethodDecl *MD, StructorType Type)
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const Decl * getDecl() const
Describes a module or submodule.
unsigned getEffectiveCallingConvention() const
void EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args)
Emits a call or invoke to the given noreturn runtime function.
RValue EmitCall(const CGFunctionInfo &FnInfo, llvm::Value *Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, const Decl *TargetDecl=nullptr, llvm::Instruction **callOrInvoke=nullptr)
llvm::Value * GetVTablePtr(llvm::Value *This, llvm::Type *Ty)
virtual bool isTypeInfoCalculable(QualType Ty) const
const ValueDecl * getMemberPointerDecl() const
const CXXRecordDecl * getParent() const
path_iterator path_begin()
llvm::PointerType * VoidPtrTy
Concrete class used by the front-end to report problems and issues.
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, llvm::Constant *addr)
Register a global destructor using the C atexit runtime function.
const VPtrInfoVector & getVFPtrOffsets(const CXXRecordDecl *RD)
llvm::Value * getObjectAddress(CodeGenFunction &CGF) const
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
static bool hasDefaultCXXMethodCC(ASTContext &Context, const CXXMethodDecl *MD)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy)
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
bool isStaticLocal() const
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
bool isMemberFunctionPointer() const
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
llvm::GlobalValue * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false)
Return the address of the constructor/destructor of the given type.
llvm::CallSite EmitRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
FunctionDecl * getOperatorDelete() const
const CXXRecordDecl * VBase
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, llvm::GlobalVariable *Guard=nullptr)
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
const TargetInfo & getTarget() const
CastKind
CastKind - The kind of operation required for a conversion.
union clang::ReturnAdjustment::VirtualAdjustment Virtual
static void emitCXXConstructor(CodeGenModule &CGM, const CXXConstructorDecl *ctor, StructorType ctorType)
ID
Defines the set of possible language-specific address spaces.
QualType getPointeeType() const
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
CXXDtorType
C++ destructor types.
bool isDeleted() const
Whether this function has been deleted.
const Type * getTypeForDecl() const
CXXDtorType getDtorType() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
llvm::Value * GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
bool isMemberPointerToDerivedMember() const
Represents a C++ destructor within a class.
static llvm::CallSite emitRTtypeidCall(CodeGenFunction &CGF, llvm::Value *Argument)
DeclContext * getDeclContext()
ASTContext & getContext() const
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
base_class_iterator vbases_end()
MicrosoftVTableContext & getMicrosoftVTableContext()
void add(RValue rvalue, QualType type, bool needscopy=false)
llvm::Value * getExceptionFromSlot()
llvm::LLVMContext & getLLVMContext()
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
llvm::IntegerType * Int32Ty
QualType getAllocatedType() const
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isExternallyVisible() const
CharUnits getVBPtrOffset() const
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=None)
DeclarationName getDeclName() const
unsigned getNumBases() const
Retrieves the number of base classes of this class.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
unsigned getIntAlign() const
const CXXRecordDecl * ReusingBase
llvm::IRBuilder< PreserveNames, llvm::ConstantFolder, CGBuilderInserterTy > CGBuilderTy
CallingConv
CallingConv - Specifies the calling convention that a function uses.
bool isObjectType() const
Determine whether this type is an object type.
void EmitAnyExprToMem(const Expr *E, llvm::Value *Location, Qualifiers Quals, bool IsInitializer)
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
unsigned getVBTableIndex(const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the index of VBase in the vbtable of Derived. VBase must be a morally virtual base of Derived...
CXXRecordDecl * getMostRecentCXXRecordDecl() const
uint64_t getNumVTableThunks() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs=llvm::AttributeSet())
Create a new runtime function with the specified type and name.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
unsigned getNumParams() const
const Type * getTypePtr() const
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
struct clang::ReturnAdjustment::VirtualAdjustment::@114 Microsoft
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
Represents a static or instance method of a struct/union/class.
struct clang::ThisAdjustment::VirtualAdjustment::@116 Microsoft
const VTableLayout & getVFTableLayout(const CXXRecordDecl *RD, CharUnits VFPtrOffset)
bool hasExtendableVFPtr() const
SanitizerSet SanOpts
Sanitizers enabled for this function.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
const CXXRecordDecl * BaseWithVPtr
The vptr is stored inside this subobject.
bool isMemberDataPointer() 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.
llvm::AllocaInst * CreateMemTemp(QualType T, const Twine &Name="tmp")
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
MangleContext & getMangleContext()
Gets the mangle context.
CGCXXABI * CreateMicrosoftCXXABI(CodeGenModule &CGM)
Creates a Microsoft-family ABI.
bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is virtually derived from the class Base.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
virtual void mangleCXXVFTable(const CXXRecordDecl *Derived, ArrayRef< const CXXRecordDecl * > BasePath, raw_ostream &Out)=0
Mangle vftable symbols. Only a subset of the bases along the path to the vftable are included in the ...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
CXXCtorType
C++ constructor types.
SourceLocation getExprLoc() const LLVM_READONLY
const CGFunctionInfo & arrangeCXXMethodType(const CXXRecordDecl *RD, const FunctionProtoType *FTP)
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
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 ...
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const Expr * getSubExpr() const
static const Type * getElementType(const Expr *BaseExpr)
External linkage within a unique namespace.
static bool isDeletingDtor(GlobalDecl GD)
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=0, bool ForVTable=false, bool DontDefer=false)
Represents a delete expression for memory deallocation and destructor calls, e.g. "delete[] pArray"...
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
bool isZero() const
isZero - Test whether the quantity equals zero.
const VPtrInfoVector & enumerateVBTables(const CXXRecordDecl *RD)
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
bool isInstanceMethod() const
bool TryEmitDefinitionAsAlias(GlobalDecl Alias, GlobalDecl Target, bool InEveryTU)
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
QualType getExceptionObjectType(QualType T) const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CharUnits NonVirtualOffset
base_class_iterator vbases_begin()
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
void EmitThunks(GlobalDecl GD)
EmitThunks - Emit the associated thunks for the given global decl.
union clang::ThisAdjustment::VirtualAdjustment Virtual
vtable_thunk_iterator vtable_thunk_begin() const
void EmitAutoVarCleanups(const AutoVarEmission &emission)
static llvm::GlobalVariable * getTypeInfoVTable(CodeGenModule &CGM)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
Implements C++ ABI-specific code generation functions.
llvm::PointerType * Int8PtrTy
SourceLocation getLocStart() const LLVM_READONLY
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
ABIArgInfo & getReturnInfo()
Represents a base class of a C++ class.
RValue EmitCXXStructorCall(const CXXMethodDecl *MD, llvm::Value *Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E, StructorType Type)
Linkage getLinkage() const
Determine the linkage of this type.
bool isDefaultConstructor() const
static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
llvm::IntegerType * PtrDiffTy
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
DiagnosticsEngine & getDiags() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Represents a C++ struct/union/class.
BoundNodesTreeBuilder *const Builder
llvm::Type * ConvertType(QualType T)
static void emitCXXDestructor(CodeGenModule &CGM, const CXXDestructorDecl *dtor, StructorType dtorType)
CallingConv getDefaultCallingConvention(bool isVariadic, bool IsCXXMethod) const
Retrieves the default calling convention for the current target.
int32_t VtordispOffset
The offset of the vtordisp (in bytes), relative to the ECX.
No linkage according to the standard, but is visible from other translation units because of types de...
llvm::Constant * CreateVTableInitializer(const CXXRecordDecl *RD, const VTableComponent *Components, unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks, unsigned NumVTableThunks, llvm::Constant *RTTI)
Copying closure variant of a ctor.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CharUnits FullOffsetInMDC
uint64_t Index
Method's index in the vftable.
const CGFunctionInfo & arrangeMSCtorClosure(const CXXConstructorDecl *CD, CXXCtorType CT)
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, SourceLocation Loc=SourceLocation(), bool TLS=false)
VarDecl * getExceptionDecl() const
static RValue get(llvm::Value *V)
GVALinkage
A more specific kind of linkage than enum Linkage.
CodeGenVTables & getVTables()
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
uint32_t VBIndex
Index of the virtual base in the vbtable.
SourceLocation getLocation() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
const CXXConstructorDecl * getCopyConstructorForExceptionObject(CXXRecordDecl *RD)
bool isConstQualified() const
Determine whether this type is const-qualified.
RecordArgABI
Specify how one should pass an argument of a record type.
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
bool nullFieldOffsetIsZero() const
int32_t VBPtrOffset
The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
static void serializeClassHierarchy(SmallVectorImpl< MSRTTIClass > &Classes, const CXXRecordDecl *RD)
Recursively serializes a class hierarchy in pre-order depth first order.
base_class_range vbases()
static QualType decomposeTypeForEH(ASTContext &Context, QualType T, bool &IsConst, bool &IsVolatile)
void EmitMustTailThunk(const CXXMethodDecl *MD, llvm::Value *AdjustedThisPtr, llvm::Value *Callee)
Emit a musttail call for a thunk with a potentially adjusted this pointer.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
static llvm::Constant * getThrowFn(CodeGenModule &CGM)
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraArgs)
Arrange a call to a C++ method, passing the given arguments.
bool isPointerType() const
bool isPOD() const
Whether this class is a POD-type (C++ [class]p4)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.