27#include "llvm/Support/ErrorHandling.h"
37 llvm::DenseMap<const CXXRecordDecl *, cir::GlobalOp> vtables;
40 CIRGenItaniumCXXABI(CIRGenModule &cgm) : CIRGenCXXABI(cgm) {
45 AddedStructorArgs getImplicitConstructorArgs(CIRGenFunction &cgf,
46 const CXXConstructorDecl *d,
49 bool delegating)
override;
51 bool needsVTTParameter(clang::GlobalDecl gd)
override;
53 AddedStructorArgCounts
54 buildStructorSignature(GlobalDecl gd,
55 llvm::SmallVectorImpl<CanQualType> &argTys)
override;
57 void emitInstanceFunctionProlog(SourceLocation loc,
58 CIRGenFunction &cgf)
override;
60 void addImplicitStructorParams(CIRGenFunction &cgf, QualType &resTy,
61 FunctionArgList ¶ms)
override;
63 const CXXDestructorDecl *dd,
66 bool delegating)
override;
67 void emitCXXConstructors(
const clang::CXXConstructorDecl *d)
override;
68 void emitCXXDestructors(
const clang::CXXDestructorDecl *d)
override;
69 void emitCXXStructor(clang::GlobalDecl gd)
override;
71 void emitDestructorCall(CIRGenFunction &cgf,
const CXXDestructorDecl *dd,
73 bool delegating, Address thisAddr,
74 QualType thisTy)
override;
75 void registerGlobalDtor(
const VarDecl *vd, cir::FuncOp dtor,
76 mlir::Value addr)
override;
77 void emitVirtualObjectDelete(CIRGenFunction &cgf,
const CXXDeleteExpr *de,
78 Address ptr, QualType elementType,
79 const CXXDestructorDecl *dtor)
override;
81 void emitRethrow(CIRGenFunction &cgf,
bool isNoReturn)
override;
82 void emitThrow(CIRGenFunction &cgf,
const CXXThrowExpr *e)
override;
84 void emitBeginCatch(CIRGenFunction &cgf,
const CXXCatchStmt *catchStmt,
85 mlir::Value ehToken)
override;
87 bool useThunkForDtorVariant(
const CXXDestructorDecl *dtor,
95 bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
96 CIRGenFunction::VPtr vptr)
override;
98 cir::GlobalOp getAddrOfVTable(
const CXXRecordDecl *rd,
99 CharUnits vptrOffset)
override;
100 CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf,
101 clang::GlobalDecl gd, Address thisAddr,
103 SourceLocation loc)
override;
104 mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
105 const CXXDestructorDecl *dtor,
107 DeleteOrMemberCallExpr e)
override;
108 mlir::Value getVTableAddressPoint(BaseSubobject base,
109 const CXXRecordDecl *vtableClass)
override;
110 mlir::Value getVTableAddressPointInStructorWithVTT(
111 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
112 const CXXRecordDecl *nearestVBase);
114 mlir::Value getVTableAddressPointInStructor(
115 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
116 clang::BaseSubobject base,
117 const clang::CXXRecordDecl *nearestVBase)
override;
118 void emitVTableDefinitions(CIRGenVTables &cgvt,
119 const CXXRecordDecl *rd)
override;
120 void emitVirtualInheritanceTables(
const CXXRecordDecl *rd)
override;
122 void setThunkLinkage(cir::FuncOp thunk,
bool forVTable, GlobalDecl gd,
123 bool returnAdjustment)
override {
124 if (forVTable && !thunk.hasLocalLinkage())
125 thunk.setLinkage(cir::GlobalLinkageKind::AvailableExternallyLinkage);
130 bool exportThunk()
override {
return true; }
132 mlir::Value performThisAdjustment(CIRGenFunction &cgf, Address thisAddr,
133 const CXXRecordDecl *unadjustedClass,
134 const ThunkInfo &ti)
override;
137 const CXXRecordDecl *unadjustedClass,
138 const ReturnAdjustment &ra)
override;
140 bool shouldTypeidBeNullChecked(QualType srcTy)
override;
141 mlir::Value emitTypeid(CIRGenFunction &cgf, QualType SrcRecordTy,
142 Address thisPtr, mlir::Type StdTypeInfoPtrTy)
override;
143 void emitBadTypeidCall(CIRGenFunction &cgf, mlir::Location loc)
override;
145 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
146 QualType ty)
override;
148 StringRef getPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
149 StringRef getDeletedVirtualCallName()
override {
150 return "__cxa_deleted_virtual";
154 getAddrOfCXXCatchHandlerType(mlir::Location loc, QualType ty,
155 QualType catchHandlerType)
override {
156 auto rtti = dyn_cast<cir::GlobalViewAttr>(getAddrOfRTTIDescriptor(loc, ty));
157 assert(rtti &&
"expected GlobalViewAttr");
158 return CatchTypeInfo{rtti, 0};
161 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *vtableClass)
override {
165 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
166 FunctionArgList &args)
const override {
167 assert(!args.empty() &&
"expected the arglist to not be empty!");
168 return args.size() - 1;
171 void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)
override;
174 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
175 Address thisAddr,
const CXXRecordDecl *classDecl,
176 const CXXRecordDecl *baseClassDecl)
override;
183 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
184 QualType srcRecordTy, QualType destRecordTy,
185 cir::PointerType destCIRTy,
bool isRefCast,
186 Address src)
override;
188 cir::MethodAttr buildVirtualMethodAttr(cir::MethodType methodTy,
189 const CXXMethodDecl *md)
override;
191 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
192 mlir::Value numElements,
const CXXNewExpr *e,
193 QualType elementType)
override;
196 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
201 virtual bool shouldRTTIBeUnique()
const {
return true; }
205 enum RTTIUniquenessKind {
223 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
228void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
233 "emitInstanceFunctionProlog: Naked");
238 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
241 if (getStructorImplicitParamDecl(cgf)) {
245 setStructorImplicitParamValue(cgf, val);
256 if (hasThisReturn(cgf.
curGD)) {
258 "emitInstanceFunctionProlog: hasThisReturn");
262CIRGenCXXABI::AddedStructorArgCounts
263CIRGenItaniumCXXABI::buildStructorSignature(
264 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
275 argTys.insert(argTys.begin() + 1,
278 return AddedStructorArgCounts::withPrefix(1);
281 return AddedStructorArgCounts{};
286enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
292 return StructorCIRGen::Emit;
297 return StructorCIRGen::Emit;
300 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
310 return StructorCIRGen::RAUW;
314 return StructorCIRGen::RAUW;
320 return StructorCIRGen::COMDAT;
321 return StructorCIRGen::Emit;
324 return StructorCIRGen::Alias;
334 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
336 if (globalValue && !globalValue.isDeclaration())
339 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
348void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
351 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
355 GlobalDecl baseDecl =
359 if (cirGenType == StructorCIRGen::Alias ||
360 cirGenType == StructorCIRGen::COMDAT) {
365 if (cirGenType == StructorCIRGen::RAUW) {
378void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
380 FunctionArgList ¶ms) {
385 if (needsVTTParameter(cgf.
curGD)) {
392 astContext,
nullptr, md->getLocation(),
393 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
394 params.insert(params.begin() + 1, vttDecl);
395 getStructorImplicitParamDecl(cgf) = vttDecl;
399void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
415void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
431CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
433 bool forVirtualBase,
bool delegating) {
434 if (!needsVTTParameter(GlobalDecl(d,
type)))
435 return AddedStructorArgs{};
445 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
451bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
455 if (!md->getParent()->getNumVBases())
469void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
470 const CXXRecordDecl *rd) {
471 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
472 if (vtable.hasInitializer())
478 mlir::Attribute rtti =
489 vtable.setLinkage(linkage);
492 vtable.setComdat(
true);
507 "emitVTableDefinitions: __fundamental_type_info");
510 [[maybe_unused]]
auto vtableAsGlobalValue =
511 dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
512 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
522 "emitVTableDefinitions: WholeProgramVTables");
531mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
532 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
533 Address thisAddr, DeleteOrMemberCallExpr
expr) {
534 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
535 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
536 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
540 GlobalDecl globalDecl(dtor, dtorType);
541 const CIRGenFunctionInfo *fnInfo =
550 thisTy,
nullptr, QualType(),
nullptr);
554void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
555 const CXXRecordDecl *rd) {
562class CIRGenItaniumRTTIBuilder {
564 const CIRGenItaniumCXXABI &cxxABI;
567 SmallVector<mlir::Attribute, 16> fields;
570 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
571 cir::GlobalLinkageKind linkage);
574 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
578 void buildVTablePointer(mlir::Location loc,
const Type *ty);
582 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
587 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
590 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
591 : cgm(cgm), cxxABI(abi) {}
595 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
598 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
599 cir::GlobalLinkageKind linkage,
600 mlir::SymbolTable::Visibility visibility);
619 PTI_Incomplete = 0x8,
623 PTI_ContainingClassIncomplete = 0x10,
635 VMI_NonDiamondRepeat = 0x1,
638 VMI_DiamondShaped = 0x2
653static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
669 case BuiltinType::WasmExternRef:
670 case BuiltinType::HLSLResource:
671 llvm_unreachable(
"NYI");
672 case BuiltinType::Void:
673 case BuiltinType::NullPtr:
674 case BuiltinType::Bool:
675 case BuiltinType::WChar_S:
676 case BuiltinType::WChar_U:
677 case BuiltinType::Char_U:
678 case BuiltinType::Char_S:
679 case BuiltinType::UChar:
680 case BuiltinType::SChar:
681 case BuiltinType::Short:
682 case BuiltinType::UShort:
683 case BuiltinType::Int:
684 case BuiltinType::UInt:
685 case BuiltinType::Long:
686 case BuiltinType::ULong:
687 case BuiltinType::LongLong:
688 case BuiltinType::ULongLong:
689 case BuiltinType::Half:
690 case BuiltinType::Float:
691 case BuiltinType::Double:
692 case BuiltinType::LongDouble:
693 case BuiltinType::Float16:
694 case BuiltinType::Float128:
695 case BuiltinType::Ibm128:
696 case BuiltinType::Char8:
697 case BuiltinType::Char16:
698 case BuiltinType::Char32:
699 case BuiltinType::Int128:
700 case BuiltinType::UInt128:
703#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
704 case BuiltinType::Id:
705#include "clang/Basic/OpenCLImageTypes.def"
706#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
707#include "clang/Basic/OpenCLExtensionTypes.def"
708 case BuiltinType::OCLSampler:
709 case BuiltinType::OCLEvent:
710 case BuiltinType::OCLClkEvent:
711 case BuiltinType::OCLQueue:
712 case BuiltinType::OCLReserveID:
713#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
714#include "clang/Basic/AArch64ACLETypes.def"
715#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
716#include "clang/Basic/PPCTypes.def"
717#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
718#include "clang/Basic/RISCVVTypes.def"
719#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
720#include "clang/Basic/AMDGPUTypes.def"
721 case BuiltinType::ShortAccum:
722 case BuiltinType::Accum:
723 case BuiltinType::LongAccum:
724 case BuiltinType::UShortAccum:
725 case BuiltinType::UAccum:
726 case BuiltinType::ULongAccum:
727 case BuiltinType::ShortFract:
728 case BuiltinType::Fract:
729 case BuiltinType::LongFract:
730 case BuiltinType::UShortFract:
731 case BuiltinType::UFract:
732 case BuiltinType::ULongFract:
733 case BuiltinType::SatShortAccum:
734 case BuiltinType::SatAccum:
735 case BuiltinType::SatLongAccum:
736 case BuiltinType::SatUShortAccum:
737 case BuiltinType::SatUAccum:
738 case BuiltinType::SatULongAccum:
739 case BuiltinType::SatShortFract:
740 case BuiltinType::SatFract:
741 case BuiltinType::SatLongFract:
742 case BuiltinType::SatUShortFract:
743 case BuiltinType::SatUFract:
744 case BuiltinType::SatULongFract:
745 case BuiltinType::BFloat16:
748 case BuiltinType::Dependent:
749#define BUILTIN_TYPE(Id, SingletonId)
750#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
751#include "clang/AST/BuiltinTypes.def"
752 llvm_unreachable(
"asking for RRTI for a placeholder type!");
754 case BuiltinType::ObjCId:
755 case BuiltinType::ObjCClass:
756 case BuiltinType::ObjCSel:
757 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
760 llvm_unreachable(
"Invalid BuiltinType Kind!");
763static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
765 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
776 return typeInfoIsInStandardLibrary(builtinTy);
781static bool isStandardLibraryRttiDescriptor(QualType ty) {
783 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
784 return typeInfoIsInStandardLibrary(builtinTy);
788 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
789 return typeInfoIsInStandardLibrary(pointerTy);
798static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
806 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
819 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
829 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
842 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
843 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
848static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
856 if (!bases.virtualBases.insert(baseDecl).second) {
859 flags |= VMI_DiamondShaped;
861 if (bases.nonVirtualBases.count(baseDecl))
862 flags |= VMI_NonDiamondRepeat;
866 if (!bases.nonVirtualBases.insert(baseDecl).second) {
869 flags |= VMI_NonDiamondRepeat;
871 if (bases.virtualBases.count(baseDecl))
872 flags |= VMI_NonDiamondRepeat;
877 for (
const auto &bs : baseDecl->bases())
878 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
883static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
888 for (
const auto &bs : rd->
bases())
889 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
898static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
916 return baseDecl->isEmpty() ||
921static bool isIncompleteClassType(
const RecordType *recordTy) {
922 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
936static bool containsIncompleteClassType(QualType ty) {
937 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
938 if (isIncompleteClassType(recordTy))
942 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
945 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
947 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
950 return containsIncompleteClassType(memberPointerTy->getPointeeType());
956const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
958 static const char *
const classTypeInfo =
959 "_ZTVN10__cxxabiv117__class_type_infoE";
961 static const char *
const siClassTypeInfo =
962 "_ZTVN10__cxxabiv120__si_class_type_infoE";
964 static const char *
const vmiClassTypeInfo =
965 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
968#define TYPE(Class, Base)
969#define ABSTRACT_TYPE(Class, Base)
970#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
971#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
972#define DEPENDENT_TYPE(Class, Base) case Type::Class:
973#include "clang/AST/TypeNodes.inc"
974 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
976 case Type::LValueReference:
977 case Type::RValueReference:
978 llvm_unreachable(
"References shouldn't get here");
981 case Type::DeducedTemplateSpecialization:
982 llvm_unreachable(
"Undeduced type shouldn't get here");
985 llvm_unreachable(
"Pipe types shouldn't get here");
987 case Type::ArrayParameter:
988 llvm_unreachable(
"Array Parameter types should not get here.");
992 case Type::OverflowBehavior:
995 case Type::ExtVector:
996 case Type::ConstantMatrix:
1000 case Type::BlockPointer:
1001 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
1002 case Type::ConstantArray:
1003 case Type::IncompleteArray:
1004 case Type::VariableArray:
1006 return "_ZTVN10__cxxabiv117__array_type_infoE";
1008 case Type::FunctionNoProto:
1009 case Type::FunctionProto:
1011 return "_ZTVN10__cxxabiv120__function_type_infoE";
1014 return "_ZTVN10__cxxabiv116__enum_type_infoE";
1016 case Type::Record: {
1018 ->getDefinitionOrSelf();
1021 return classTypeInfo;
1024 if (canUseSingleInheritance(rd)) {
1025 return siClassTypeInfo;
1028 return vmiClassTypeInfo;
1031 case Type::ObjCObject:
1032 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
1035 case Type::ObjCInterface:
1036 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
1039 case Type::ObjCObjectPointer:
1042 return "_ZTVN10__cxxabiv119__pointer_type_infoE";
1044 case Type::MemberPointer:
1046 return "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
1048 case Type::HLSLAttributedResource:
1049 case Type::HLSLInlineSpirv:
1050 llvm_unreachable(
"HLSL doesn't support virtual functions");
1069 if (containsIncompleteClassType(ty))
1070 return cir::GlobalLinkageKind::InternalLinkage;
1074 llvm_unreachable(
"Linkage hasn't been computed!");
1079 return cir::GlobalLinkageKind::InternalLinkage;
1087 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1089 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1093 return cir::GlobalLinkageKind::WeakODRLinkage;
1095 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1096 if (rd->
hasAttr<DLLImportAttr>() &&
1097 shouldUseExternalRttiDescriptor(cgm, ty))
1098 return cir::GlobalLinkageKind::ExternalLinkage;
1104 .isWindowsGNUEnvironment())
1108 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1111 llvm_unreachable(
"Invalid linkage!");
1115CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1116 cir::GlobalLinkageKind linkage) {
1118 SmallString<256>
name;
1119 llvm::raw_svector_ostream
out(name);
1125 mlir::Attribute init = builder.
getString(
1138 loc, name, initStr.getType(), linkage, align);
1144CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1147 SmallString<256>
name;
1148 llvm::raw_svector_ostream
out(name);
1153 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(
1154 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1169 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1176void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1179 const char *vTableName = vTableClassNameForType(cgm, ty);
1183 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1190 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1194 mlir::Attribute field{};
1196 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1198 SmallVector<mlir::Attribute, 4> offsets{
1200 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1205 assert(field &&
"expected attribute");
1206 fields.push_back(field);
1211void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1212 const CXXRecordDecl *rd) {
1216 mlir::Attribute baseTypeInfo =
1217 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1219 fields.push_back(baseTypeInfo);
1225void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1226 const CXXRecordDecl *rd) {
1227 mlir::Type unsignedIntLTy =
1234 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1235 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1240 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1273 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1275 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1277 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1278 .buildTypeInfo(loc, base.
getType()));
1292 const ASTRecordLayout &layout =
1301 offsetFlags |= BCTI_Virtual;
1303 offsetFlags |= BCTI_Public;
1305 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1309mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1315 SmallString<256>
name;
1316 llvm::raw_svector_ostream
out(name);
1319 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1320 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1322 if (oldGV && !oldGV.isDeclaration()) {
1323 assert(!oldGV.hasAvailableExternallyLinkage() &&
1324 "available_externally typeinfos not yet implemented");
1330 if (isStandardLibraryRttiDescriptor(ty) ||
1331 shouldUseExternalRttiDescriptor(cgm, ty))
1332 return getAddrOfExternalRTTIDescriptor(loc, ty);
1342 mlir::SymbolTable::Visibility symVisibility;
1345 symVisibility = mlir::SymbolTable::Visibility::Public;
1346 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1347 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1349 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1354 return buildTypeInfo(loc, ty, linkage, symVisibility);
1357mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1358 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1359 mlir::SymbolTable::Visibility visibility) {
1368 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1369 mlir::Attribute typeNameField;
1373 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1374 cxxABI.classifyRTTIUniqueness(ty, linkage);
1375 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1379 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1385 fields.push_back(typeNameField);
1388#define TYPE(Class, Base)
1389#define ABSTRACT_TYPE(Class, Base)
1390#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1391#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1392#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1393#include "clang/AST/TypeNodes.inc"
1394 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1399 case Type::ExtVector:
1400 case Type::ConstantMatrix:
1402 case Type::BlockPointer:
1407 case Type::LValueReference:
1408 case Type::RValueReference:
1409 llvm_unreachable(
"References shouldn't get here");
1412 case Type::DeducedTemplateSpecialization:
1413 llvm_unreachable(
"Undeduced type shouldn't get here");
1421 case Type::OverflowBehavior:
1424 case Type::ConstantArray:
1425 case Type::IncompleteArray:
1426 case Type::VariableArray:
1427 case Type::ArrayParameter:
1432 case Type::FunctionNoProto:
1433 case Type::FunctionProto:
1443 case Type::Record: {
1445 ->getDefinitionOrSelf();
1451 if (canUseSingleInheritance(rd)) {
1452 buildSIClassTypeInfo(loc, rd);
1454 buildVMIClassTypeInfo(loc, rd);
1460 case Type::ObjCObject:
1461 case Type::ObjCInterface:
1462 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1465 case Type::ObjCObjectPointer:
1466 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1470 cgm.
errorNYI(
"buildTypeInfo: Pointer");
1473 case Type::MemberPointer:
1474 cgm.
errorNYI(
"buildTypeInfo: MemberPointer");
1481 case Type::HLSLAttributedResource:
1482 case Type::HLSLInlineSpirv:
1483 llvm_unreachable(
"HLSL doesn't support RTTI");
1487 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1489 SmallString<256>
name;
1490 llvm::raw_svector_ostream
out(name);
1494 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1495 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1504 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1511 gv.setName(oldGV.getName());
1512 if (!oldGV->use_empty()) {
1513 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1521 cgm.
errorNYI(
"buildTypeInfo: supportsCOMDAT & isWeakForLinker");
1527 gv.setAlignmentAttr(cgm.
getSize(align));
1544 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1549 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1558bool CIRGenItaniumCXXABI::shouldTypeidBeNullChecked(QualType srcTy) {
1562void CIRGenItaniumCXXABI::emitBadTypeidCall(CIRGenFunction &cgf,
1563 mlir::Location loc) {
1565 cir::FuncType fnTy =
1567 mlir::NamedAttrList attrs;
1568 attrs.set(cir::CIRDialect::getNoReturnAttrName(),
1574 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1577mlir::Value CIRGenItaniumCXXABI::emitTypeid(CIRGenFunction &cgf, QualType srcTy,
1579 mlir::Type typeInfoPtrTy) {
1581 mlir::Location loc = cgm.
getLoc(classDecl->getSourceRange());
1582 mlir::Value vptr = cgf.
getVTablePtr(loc, thisPtr, classDecl);
1590 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1592 vtbl = cir::VTableGetTypeInfoOp::create(
1600mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1602 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1607CIRGenItaniumCXXABI::RTTIUniquenessKind
1608CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1609 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1610 if (shouldRTTIBeUnique())
1614 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1615 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1623 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1624 return RUK_NonUniqueHidden;
1629 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1630 return RUK_NonUniqueVisible;
1633void CIRGenItaniumCXXABI::emitDestructorCall(
1635 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1636 GlobalDecl gd(dd,
type);
1642 CIRGenCallee callee =
1649void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1670mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1672 bool forVirtualBase,
bool delegating) {
1673 GlobalDecl gd(dd,
type);
1681 mlir::Value exceptionPtr = {},
1682 mlir::FlatSymbolRefAttr typeInfo = {},
1683 mlir::FlatSymbolRefAttr dtor = {}) {
1684 mlir::Block *currentBlock = builder.getInsertionBlock();
1685 mlir::Region *region = currentBlock->getParent();
1687 if (currentBlock->empty()) {
1688 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1689 cir::UnreachableOp::create(builder, loc);
1691 mlir::Block *throwBlock = builder.createBlock(region);
1693 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1694 cir::UnreachableOp::create(builder, loc);
1696 builder.setInsertionPointToEnd(currentBlock);
1697 cir::BrOp::create(builder, loc, throwBlock);
1700 (void)builder.createBlock(region);
1703void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1707 assert(cgf.
currSrcLoc &&
"expected source location");
1711 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1715void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1716 const CXXThrowExpr *e) {
1724 cir::PointerType throwTy =
1731 mlir::TypedValue<cir::PointerType> exceptionPtr =
1732 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1733 builder.getI64IntegerAttr(typeSize))
1741 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1744 assert(!typeInfo.getIndices() &&
"expected no indirection");
1753 if (
const RecordType *recordTy = clangThrowType->
getAs<RecordType>()) {
1756 if (!rec->hasTrivialDestructor()) {
1757 cgm.
errorNYI(
"emitThrow: non-trivial destructor");
1769 case TargetCXXABI::GenericItanium:
1770 case TargetCXXABI::GenericAArch64:
1771 return new CIRGenItaniumCXXABI(cgm);
1773 case TargetCXXABI::AppleARM64:
1777 return new CIRGenItaniumCXXABI(cgm);
1780 llvm_unreachable(
"bad or NYI ABI kind");
1784cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1786 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1787 cir::GlobalOp &vtable = vtables[rd];
1795 llvm::raw_svector_ostream
out(name);
1796 getMangleContext().mangleCXXVTable(rd,
out);
1811 cir::GlobalLinkageKind::ExternalLinkage,
1825 "getAddrOfVTable: PS4 DLL import/export");
1831CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1835 mlir::Location loc = cgf.
getLoc(srcLoc);
1838 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1841 mlir::Value vfunc{};
1843 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1847 mlir::Value vfuncLoad;
1850 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1852 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1853 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1866 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: strictVTablePointers");
1871 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1875mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1876 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1877 const CXXRecordDecl *nearestVBase) {
1879 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
1890 virtualPointerIndex);
1892 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
1898CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
1899 const CXXRecordDecl *vtableClass) {
1900 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1904 VTableLayout::AddressPointLocation addressPoint =
1910 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
1912 return cir::VTableAddrPointOp::create(
1914 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
1915 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
1920mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
1921 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
1922 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
1925 needsVTTParameter(cgf.
curGD)) {
1926 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
1929 return getVTableAddressPoint(base, vtableClass);
1932bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1933 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
1936 return needsVTTParameter(cgf.
curGD);
1939mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
1940 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
1941 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
1943 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
1945 CharUnits vbaseOffsetOffset =
1948 mlir::Value offsetVal =
1950 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
1951 vtableBytePtr, offsetVal);
1953 mlir::Value vbaseOffset;
1956 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
1972 cir::FuncType fnTy =
1982 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1986void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
1987 mlir::Location loc) {
2000 if (!dst->isDerivedFrom(src, paths))
2003 unsigned numPublicPaths = 0;
2016 if (pathElement.Base->isVirtual())
2019 if (numPublicPaths > 1)
2026 pathElement.Base->getType()->getAsCXXRecordDecl());
2031 if (numPublicPaths == 0)
2035 if (numPublicPaths > 1)
2063 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
2069 bool vtableUsesRelativeLayout =
2072 loc, src.
getPointer(), vtableUsesRelativeLayout);
2080 cir::PointerType destCIRTy,
2081 bool isRefCast,
Address src) {
2091 std::optional<CharUnits> offset;
2101 pathElement.Base->getType()->getAsCXXRecordDecl();
2102 if (pathElement.Base->isVirtual()) {
2116 offset = pathOffset;
2117 }
else if (offset != pathOffset) {
2133 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2135 mlir::Region *currentRegion = builder.getBlock()->getParent();
2140 builder.createBlock(currentRegion, currentRegion->end());
2143 return nullPtrValue;
2151 mlir::Value expectedVPtr =
2152 abi.getVTableAddressPoint(
BaseSubobject(srcDecl, *offset), destDecl);
2156 mlir::Type vptrTy = expectedVPtr.getType();
2160 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
2165 mlir::Value success =
2166 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2168 auto emitCastResult = [&] {
2169 if (offset->isZero())
2176 mlir::Value strideToApply =
2179 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2180 srcU8Ptr, strideToApply);
2185 mlir::Value failed = builder.
createNot(success);
2186 cir::IfOp::create(builder, loc, failed,
false,
2187 [&](mlir::OpBuilder &, mlir::Location) {
2190 return emitCastResult();
2193 return cir::TernaryOp::create(
2194 builder, loc, success,
2195 [&](mlir::OpBuilder &, mlir::Location) {
2196 auto result = emitCastResult();
2199 [&](mlir::OpBuilder &, mlir::Location) {
2200 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2210 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
2212 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
2217 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2218 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2225 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2227 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2228 badCastFuncRef, offsetHintAttr);
2231mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2233 QualType srcRecordTy,
2234 QualType destRecordTy,
2235 cir::PointerType destCIRTy,
2236 bool isRefCast, Address src) {
2237 bool isCastToVoid = destRecordTy.
isNull();
2238 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2251 return cir::TernaryOp::create(
2252 builder, loc, srcPtrIsNull,
2253 [&](mlir::OpBuilder, mlir::Location) {
2255 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2257 [&](mlir::OpBuilder &, mlir::Location) {
2259 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2267 destCIRTy, isRefCast, src);
2270 cir::DynamicCastInfoAttr castInfo =
2273 isRefCast, castInfo);
2277CIRGenItaniumCXXABI::buildVirtualMethodAttr(cir::MethodType methodTy,
2278 const CXXMethodDecl *md) {
2279 assert(md->
isVirtual() &&
"only deal with virtual member functions");
2285 vtableOffset = index * 4;
2290 vtableOffset = index * pointerWidth.
getQuantity();
2293 return cir::MethodAttr::get(methodTy, vtableOffset);
2297void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2298 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2299 QualType elementType,
const CXXDestructorDecl *dtor) {
2301 if (useGlobalDelete) {
2303 "emitVirtualObjectDelete: global delete");
2307 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2312CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2320Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2322 mlir::Value numElements,
2323 const CXXNewExpr *e,
2324 QualType elementType) {
2325 assert(requiresArrayCookie(e));
2337 CharUnits cookieSize =
2339 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2342 mlir::Value baseBytePtr =
2346 CharUnits cookieOffset = cookieSize - sizeSize;
2347 mlir::Value cookiePtrValue = baseBytePtr;
2348 if (!cookieOffset.
isZero()) {
2357 Address cookiePtr(cookiePtrValue, u8PtrTy, cookiePtrAlignment);
2360 Address numElementsPtr =
2366 mlir::Value dataOffset =
2369 mlir::Value dataPtr =
2371 mlir::Value finalPtr =
2374 return Address(finalPtr, newPtr.
getElementType(), finalAlignment);
2391struct CallEndCatch final : EHScopeStack::Cleanup {
2392 CallEndCatch(
bool mightThrow, mlir::Value catchToken)
2393 : mightThrow(mightThrow), catchToken(catchToken) {}
2395 mlir::Value catchToken;
2397 void emit(CIRGenFunction &cgf, Flags flags)
override {
2409 mlir::Type exnPtrTy,
bool endMightThrow) {
2410 auto catchTokenTy = cir::CatchTokenType::get(cgf.
getBuilder().getContext());
2411 auto beginCatch = cir::BeginCatchOp::create(cgf.
getBuilder(),
2413 catchTokenTy, exnPtrTy, ehToken);
2415 cgf.
ehStack.pushCleanup<CallEndCatch>(
2417 endMightThrow && !cgf.
cgm.
getLangOpts().AssumeNothrowExceptionDtor,
2418 beginCatch.getCatchToken());
2420 return beginCatch.getExnPtr();
2438 mlir::Value adjustedExn =
2445 cgf.
cgm.
errorNYI(loc,
"initCatchParam: catching a pointer");
2449 mlir::Value exnCast =
2461 if (catchType->hasPointerRepresentation()) {
2462 mlir::Value catchParam =
2467 "initCatchParam: PointerRepresentation OCL_Strong");
2472 cgf.
cgm.
errorNYI(loc,
"initCatchParam: PointerRepresentation "
2473 "OCL_ExplicitNone & OCL_Autoreleasing");
2481 cgf.
cgm.
errorNYI(loc,
"initCatchParam: PointerRepresentation OCL_Weak");
2485 llvm_unreachable(
"bad ownership qualifier!");
2490 mlir::Value catchParam =
2507 llvm_unreachable(
"evaluation kind filtered out!");
2510 llvm_unreachable(
"bad evaluation kind");
2513 cgf.
cgm.
errorNYI(loc,
"initCatchParam: cir::TEK_Aggregate");
2518void CIRGenItaniumCXXABI::emitBeginCatch(CIRGenFunction &cgf,
2519 const CXXCatchStmt *catchStmt,
2520 mlir::Value ehToken) {
2551 auto getCatchParamAllocaIP = [&]() {
2552 cir::CIRBaseBuilderTy::InsertPoint currIns =
2554 mlir::Operation *currParent = currIns.getBlock()->getParentOp();
2556 mlir::Block *insertBlock =
nullptr;
2557 if (
auto scopeOp = currParent->getParentOfType<cir::ScopeOp>()) {
2558 insertBlock = &scopeOp.getScopeRegion().getBlocks().back();
2559 }
else if (
auto fnOp = currParent->getParentOfType<cir::FuncOp>()) {
2560 insertBlock = &fnOp.getRegion().getBlocks().back();
2562 llvm_unreachable(
"unknown outermost scope-like parent");
2571 CIRGenFunction::AutoVarEmission
var =
2581 int64_t nonVirtualAdjustment,
2582 int64_t virtualAdjustment,
2583 bool isReturnAdjustment) {
2584 if (!nonVirtualAdjustment && !virtualAdjustment)
2588 mlir::Location loc = builder.getUnknownLoc();
2593 if (nonVirtualAdjustment && !isReturnAdjustment) {
2594 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2595 v = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offsetConst);
2599 mlir::Value resultPtr;
2600 if (virtualAdjustment) {
2609 if (nonVirtualAdjustment && isReturnAdjustment) {
2610 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2612 cir::PtrStrideOp::create(builder, loc, i8PtrTy, resultPtr, offsetConst);
2619mlir::Value CIRGenItaniumCXXABI::performThisAdjustment(
2620 CIRGenFunction &cgf, Address thisAddr,
const CXXRecordDecl *unadjustedClass,
2621 const ThunkInfo &ti) {
2628mlir::Value CIRGenItaniumCXXABI::performReturnAdjustment(
2629 CIRGenFunction &cgf, Address ret,
const CXXRecordDecl *unadjustedClass,
2630 const ReturnAdjustment &ra) {
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static CharUnits computeOffsetHint(ASTContext &astContext, const CXXRecordDecl *src, const CXXRecordDecl *dst)
static void insertThrowAndSplit(mlir::OpBuilder &builder, mlir::Location loc, mlir::Value exceptionPtr={}, mlir::FlatSymbolRefAttr typeInfo={}, mlir::FlatSymbolRefAttr dtor={})
static mlir::Value callBeginCatch(CIRGenFunction &cgf, mlir::Value ehToken, mlir::Type exnPtrTy, bool endMightThrow)
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
static cir::DynamicCastInfoAttr emitDynamicCastInfo(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy)
static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, QualType ty)
Return the linkage that the type info and type info name constants should have for the given type.
static mlir::Value performTypeAdjustment(CIRGenFunction &cgf, Address initialPtr, const CXXRecordDecl *unadjustedClass, int64_t nonVirtualAdjustment, int64_t virtualAdjustment, bool isReturnAdjustment)
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
static void emitCallToBadCast(CIRGenFunction &cgf, mlir::Location loc)
static void initCatchParam(CIRGenFunction &cgf, mlir::Value ehToken, const VarDecl &catchParam, Address paramAddr, SourceLocation loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm, const CXXMethodDecl *md)
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
static RValue performReturnAdjustment(CIRGenFunction &cgf, QualType resultType, RValue rv, const ThunkInfo &thunk)
Defines the clang::Expr interface and subclasses for C++ expressions.
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
mlir::Value createPtrIsNull(mlir::Value ptr)
cir::PtrStrideOp createPtrStride(mlir::Location loc, mlir::Value base, mlir::Value stride)
static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block)
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createNot(mlir::Value value)
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc)
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
mlir::Value getSignedInt(mlir::Location loc, int64_t val, unsigned numBits)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
cir::YieldOp createYield(mlir::Location loc, mlir::ValueRange value={})
Create a yield operation.
llvm::Align getABITypeAlign(mlir::Type ty) 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.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
mlir::Value getPointer() const
mlir::Type getElementType() const
clang::CharUnits getAlignment() const
mlir::Type getType() const
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
cir::IntType getUInt64Ty()
cir::TypeInfoAttr getTypeInfo(mlir::ArrayAttr fieldsAttr)
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc)
cir::PointerType getUInt8PtrTy()
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size)
Get a cir::ConstArrayAttr for a string literal.
cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr, llvm::MaybeAlign align)
cir::FuncType getFuncType(llvm::ArrayRef< mlir::Type > params, mlir::Type retTy, bool isVarArg=false)
mlir::Value createDynCastToVoid(mlir::Location loc, mlir::Value src, bool vtableUseRelativeLayout)
mlir::Value createDynCast(mlir::Location loc, mlir::Value src, cir::PointerType destType, bool isRefCast, cir::DynamicCastInfoAttr info)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy, mlir::Value addr, uint64_t offset)
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
Implements C++ ABI-specific code generation functions.
clang::MangleContext & getMangleContext()
Gets the mangle context.
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
static CIRGenCallee forVirtual(const clang::CallExpr *ce, clang::GlobalDecl md, Address addr, cir::FuncType fTy)
mlir::Type convertType(clang::QualType t)
static cir::TypeEvaluationKind getEvaluationKind(clang::QualType type)
Return the cir::TypeEvaluationKind of QualType type.
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
AutoVarEmission emitAutoVarAlloca(const clang::VarDecl &d, mlir::OpBuilder::InsertPoint ip={})
const clang::Decl * curFuncDecl
Address getAddrOfLocalVar(const clang::VarDecl *vd)
Return the address of a local variable.
void emitAnyExprToExn(const Expr *e, Address addr)
LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty)
mlir::Value getVTTParameter(GlobalDecl gd, bool forVirtualBase, bool delegating)
Return the VTT parameter that should be passed to a base constructor/destructor with virtual bases.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
mlir::Type convertTypeForMem(QualType t)
mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc)
Load a complex number from the specified l-value.
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, LValueBaseInfo baseInfo, bool isInit=false, bool isNontemporal=false)
mlir::Value loadCXXVTT()
Load the VTT parameter to base constructors/destructors have virtual bases.
mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr, const clang::CXXRecordDecl *vtableClass)
Return the Value of the vtable pointer member pointed to by thisAddr.
void emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
bool shouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *rd)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
CIRGenBuilderTy & getBuilder()
mlir::Value emitRuntimeCall(mlir::Location loc, cir::FuncOp callee, llvm::ArrayRef< mlir::Value > args={}, mlir::NamedAttrList attrs={})
mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
void emitAutoVarCleanups(const AutoVarEmission &emission)
This class organizes the cross-function state that is used while generating CIR code.
llvm::StringRef getMangledName(clang::GlobalDecl gd)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
ItaniumVTableContext & getItaniumVTableContext()
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
const clang::TargetInfo & getTarget() const
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
const cir::CIRDataLayout getDataLayout() const
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
cir::FuncOp codegenCXXStructor(clang::GlobalDecl gd)
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
mlir::Operation * getGlobalValue(llvm::StringRef ref)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::Operation *insertPoint=nullptr)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
CIRGenVTables & getVTables()
cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
cir::RecordType getVTableType(const clang::VTableLayout &layout)
Returns the type of a vtable with the given layout.
void createVTableInitializer(cir::GlobalOp &vtable, const clang::VTableLayout &layout, mlir::Attribute rtti, bool vtableHasLocalLinkage)
Add vtable components for the given vtable layout to the given global initializer.
void emitVTTDefinition(cir::GlobalOp vttOp, cir::GlobalLinkageKind linkage, const CXXRecordDecl *rd)
Emit the definition of the given vtable.
cir::GlobalOp getAddrOfVTT(const CXXRecordDecl *rd)
Get the address of the VTT for the given record decl.
bool isVTableExternal(const clang::CXXRecordDecl *rd)
At this point in the translation unit, does it appear that can we rely on the vtable being defined el...
uint64_t getSecondaryVirtualPointerIndex(const CXXRecordDecl *rd, BaseSubobject base)
Return the index in the VTT where the virtual pointer for the given subobject is located.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
bool isGlobalDelete() const
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.
SourceRange getSourceRange() const
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
const CXXBaseSpecifier * base_class_const_iterator
Iterator that traverses the base classes of a class.
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
const Expr * getSubExpr() const
static CanQual< Type > CreateUnsafe(QualType Other)
Qualifiers getQualifiers() const
Retrieve all qualifiers.
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
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.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
GlobalDecl - represents a global declaration.
GlobalDecl getWithCtorType(CXXCtorType Type)
CXXCtorType getCtorType() const
GlobalDecl getWithDtorType(CXXDtorType Type)
CXXDtorType getDtorType() const
const Decl * getDecl() const
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
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.
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
bool isRelativeLayout() const
const VTableLayout & getVTableLayout(const CXXRecordDecl *RD)
CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD, const CXXRecordDecl *VBase)
Return the offset in chars (relative to the vtable address point) where the offset of the virtual bas...
virtual void mangleCXXRTTI(QualType T, raw_ostream &)=0
virtual void mangleCXXRTTIName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getCanonicalType() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
ObjCLifetime getObjCLifetime() const
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...
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool hasPS4DLLImportExport() const
uint64_t getPointerAlign(LangAS AddrSpace) const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
unsigned getLongWidth() const
getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...
SourceLocation getBeginLoc() const LLVM_READONLY
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
Visibility getVisibility() const
Determine the visibility of this type.
Linkage getLinkage() const
Determine the linkage of this type.
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
AddressPointLocation getAddressPoint(BaseSubobject Base) const
Represents a variable declaration or definition.
TLSKind getTLSKind() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
static bool isLocalLinkage(GlobalLinkageKind linkage)
static bool isValidLinkage(GlobalLinkageKind gl)
static bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
static bool isDiscardableIfUnused(GlobalLinkageKind linkage)
Whether the definition of this global may be discarded if it is not used in its compilation unit.
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
llvm::Value * getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, llvm::BasicBlock::iterator InsertPoint, const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating)
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
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.
constexpr size_t align(size_t Size)
Aligns a size to the pointer alignment.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
@ 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_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
@ Type
The name was classified as a type.
U cast(CodeGen::Address addr)
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
static bool addressSpace()
static bool opGlobalUnnamedAddr()
static bool vtableEmitMetadata()
static bool emitTypeMetadataCodeForVCall()
static bool opFuncReadOnly()
static bool setDLLStorageClass()
static bool hiddenVisibility()
static bool opFuncNoUnwind()
static bool cxxabiAppleARM64CXXABI()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool isTrivialCtorOrDtor()
static bool opFuncCallingConv()
static bool opFuncWillReturn()
static bool protectedVisibility()
static bool deferredVtables()
static bool cxxabiUseARMGuardVarABI()
static bool cxxabiUseARMMethodPtrABI()
static bool setDSOLocal()
static bool vtableRelativeLayout()
const clang::CXXRecordDecl * nearestVBase
clang::CharUnits getPointerAlign() const
clang::CharUnits getSizeSize() const
cir::PointerType uInt8PtrTy
Represents an element in a path from a derived class to a base class.
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@103031170252120233124322035264172076254313213024 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@106065375072164260365214033034320247050276346205 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.