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,
85 const CXXCatchStmt *catchStmt)
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 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
123 QualType ty)
override;
125 getAddrOfCXXCatchHandlerType(mlir::Location loc, QualType ty,
126 QualType catchHandlerType)
override {
127 auto rtti = dyn_cast<cir::GlobalViewAttr>(getAddrOfRTTIDescriptor(loc, ty));
128 assert(rtti &&
"expected GlobalViewAttr");
129 return CatchTypeInfo{rtti, 0};
132 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *vtableClass)
override {
136 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
137 FunctionArgList &args)
const override {
138 assert(!args.empty() &&
"expected the arglist to not be empty!");
139 return args.size() - 1;
142 void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)
override;
145 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
146 Address thisAddr,
const CXXRecordDecl *classDecl,
147 const CXXRecordDecl *baseClassDecl)
override;
154 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
155 QualType srcRecordTy, QualType destRecordTy,
156 cir::PointerType destCIRTy,
bool isRefCast,
157 Address src)
override;
159 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
160 mlir::Value numElements,
const CXXNewExpr *e,
161 QualType elementType)
override;
164 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
169 virtual bool shouldRTTIBeUnique()
const {
return true; }
173 enum RTTIUniquenessKind {
191 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
196void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
201 "emitInstanceFunctionProlog: Naked");
206 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
209 if (getStructorImplicitParamDecl(cgf)) {
213 setStructorImplicitParamValue(cgf, val);
224 if (hasThisReturn(cgf.
curGD)) {
226 "emitInstanceFunctionProlog: hasThisReturn");
230CIRGenCXXABI::AddedStructorArgCounts
231CIRGenItaniumCXXABI::buildStructorSignature(
232 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
243 argTys.insert(argTys.begin() + 1,
246 return AddedStructorArgCounts::withPrefix(1);
249 return AddedStructorArgCounts{};
254enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
260 return StructorCIRGen::Emit;
265 return StructorCIRGen::Emit;
268 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
278 return StructorCIRGen::RAUW;
282 return StructorCIRGen::RAUW;
288 return StructorCIRGen::COMDAT;
289 return StructorCIRGen::Emit;
292 return StructorCIRGen::Alias;
302 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
304 if (globalValue && !globalValue.isDeclaration())
307 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
316void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
319 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
323 GlobalDecl baseDecl =
327 if (cirGenType == StructorCIRGen::Alias ||
328 cirGenType == StructorCIRGen::COMDAT) {
333 if (cirGenType == StructorCIRGen::RAUW) {
346void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
348 FunctionArgList ¶ms) {
353 if (needsVTTParameter(cgf.
curGD)) {
360 astContext,
nullptr, md->getLocation(),
361 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
362 params.insert(params.begin() + 1, vttDecl);
363 getStructorImplicitParamDecl(cgf) = vttDecl;
367void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
383void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
399CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
401 bool forVirtualBase,
bool delegating) {
402 if (!needsVTTParameter(GlobalDecl(d,
type)))
403 return AddedStructorArgs{};
413 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
419bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
423 if (!md->getParent()->getNumVBases())
437void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
438 const CXXRecordDecl *rd) {
439 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
440 if (vtable.hasInitializer())
446 mlir::Attribute rtti =
457 vtable.setLinkage(linkage);
460 vtable.setComdat(
true);
475 "emitVTableDefinitions: __fundamental_type_info");
478 [[maybe_unused]]
auto vtableAsGlobalValue =
479 dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
480 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
490 "emitVTableDefinitions: WholeProgramVTables");
499mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
500 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
501 Address thisAddr, DeleteOrMemberCallExpr
expr) {
502 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
503 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
504 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
508 GlobalDecl globalDecl(dtor, dtorType);
509 const CIRGenFunctionInfo *fnInfo =
518 thisTy,
nullptr, QualType(),
nullptr);
522void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
523 const CXXRecordDecl *rd) {
530class CIRGenItaniumRTTIBuilder {
532 const CIRGenItaniumCXXABI &cxxABI;
535 SmallVector<mlir::Attribute, 16> fields;
538 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
539 cir::GlobalLinkageKind linkage);
542 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
546 void buildVTablePointer(mlir::Location loc,
const Type *ty);
550 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
555 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
558 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
559 : cgm(cgm), cxxABI(abi) {}
563 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
566 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
567 cir::GlobalLinkageKind linkage,
568 mlir::SymbolTable::Visibility visibility);
587 PTI_Incomplete = 0x8,
591 PTI_ContainingClassIncomplete = 0x10,
603 VMI_NonDiamondRepeat = 0x1,
606 VMI_DiamondShaped = 0x2
621static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
637 case BuiltinType::WasmExternRef:
638 case BuiltinType::HLSLResource:
639 llvm_unreachable(
"NYI");
640 case BuiltinType::Void:
641 case BuiltinType::NullPtr:
642 case BuiltinType::Bool:
643 case BuiltinType::WChar_S:
644 case BuiltinType::WChar_U:
645 case BuiltinType::Char_U:
646 case BuiltinType::Char_S:
647 case BuiltinType::UChar:
648 case BuiltinType::SChar:
649 case BuiltinType::Short:
650 case BuiltinType::UShort:
651 case BuiltinType::Int:
652 case BuiltinType::UInt:
653 case BuiltinType::Long:
654 case BuiltinType::ULong:
655 case BuiltinType::LongLong:
656 case BuiltinType::ULongLong:
657 case BuiltinType::Half:
658 case BuiltinType::Float:
659 case BuiltinType::Double:
660 case BuiltinType::LongDouble:
661 case BuiltinType::Float16:
662 case BuiltinType::Float128:
663 case BuiltinType::Ibm128:
664 case BuiltinType::Char8:
665 case BuiltinType::Char16:
666 case BuiltinType::Char32:
667 case BuiltinType::Int128:
668 case BuiltinType::UInt128:
671#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
672 case BuiltinType::Id:
673#include "clang/Basic/OpenCLImageTypes.def"
674#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
675#include "clang/Basic/OpenCLExtensionTypes.def"
676 case BuiltinType::OCLSampler:
677 case BuiltinType::OCLEvent:
678 case BuiltinType::OCLClkEvent:
679 case BuiltinType::OCLQueue:
680 case BuiltinType::OCLReserveID:
681#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
682#include "clang/Basic/AArch64ACLETypes.def"
683#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
684#include "clang/Basic/PPCTypes.def"
685#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
686#include "clang/Basic/RISCVVTypes.def"
687#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
688#include "clang/Basic/AMDGPUTypes.def"
689 case BuiltinType::ShortAccum:
690 case BuiltinType::Accum:
691 case BuiltinType::LongAccum:
692 case BuiltinType::UShortAccum:
693 case BuiltinType::UAccum:
694 case BuiltinType::ULongAccum:
695 case BuiltinType::ShortFract:
696 case BuiltinType::Fract:
697 case BuiltinType::LongFract:
698 case BuiltinType::UShortFract:
699 case BuiltinType::UFract:
700 case BuiltinType::ULongFract:
701 case BuiltinType::SatShortAccum:
702 case BuiltinType::SatAccum:
703 case BuiltinType::SatLongAccum:
704 case BuiltinType::SatUShortAccum:
705 case BuiltinType::SatUAccum:
706 case BuiltinType::SatULongAccum:
707 case BuiltinType::SatShortFract:
708 case BuiltinType::SatFract:
709 case BuiltinType::SatLongFract:
710 case BuiltinType::SatUShortFract:
711 case BuiltinType::SatUFract:
712 case BuiltinType::SatULongFract:
713 case BuiltinType::BFloat16:
716 case BuiltinType::Dependent:
717#define BUILTIN_TYPE(Id, SingletonId)
718#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
719#include "clang/AST/BuiltinTypes.def"
720 llvm_unreachable(
"asking for RRTI for a placeholder type!");
722 case BuiltinType::ObjCId:
723 case BuiltinType::ObjCClass:
724 case BuiltinType::ObjCSel:
725 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
728 llvm_unreachable(
"Invalid BuiltinType Kind!");
731static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
733 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
744 return typeInfoIsInStandardLibrary(builtinTy);
749static bool isStandardLibraryRttiDescriptor(QualType ty) {
751 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
752 return typeInfoIsInStandardLibrary(builtinTy);
756 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
757 return typeInfoIsInStandardLibrary(pointerTy);
766static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
774 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
787 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
797 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
810 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
811 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
816static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
824 if (!bases.virtualBases.insert(baseDecl).second) {
827 flags |= VMI_DiamondShaped;
829 if (bases.nonVirtualBases.count(baseDecl))
830 flags |= VMI_NonDiamondRepeat;
834 if (!bases.nonVirtualBases.insert(baseDecl).second) {
837 flags |= VMI_NonDiamondRepeat;
839 if (bases.virtualBases.count(baseDecl))
840 flags |= VMI_NonDiamondRepeat;
845 for (
const auto &bs : baseDecl->bases())
846 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
851static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
856 for (
const auto &bs : rd->
bases())
857 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
866static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
884 return baseDecl->isEmpty() ||
889static bool isIncompleteClassType(
const RecordType *recordTy) {
890 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
904static bool containsIncompleteClassType(QualType ty) {
905 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
906 if (isIncompleteClassType(recordTy))
910 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
913 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
915 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
918 return containsIncompleteClassType(memberPointerTy->getPointeeType());
924const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
926 static const char *
const classTypeInfo =
927 "_ZTVN10__cxxabiv117__class_type_infoE";
929 static const char *
const siClassTypeInfo =
930 "_ZTVN10__cxxabiv120__si_class_type_infoE";
932 static const char *
const vmiClassTypeInfo =
933 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
936#define TYPE(Class, Base)
937#define ABSTRACT_TYPE(Class, Base)
938#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
939#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
940#define DEPENDENT_TYPE(Class, Base) case Type::Class:
941#include "clang/AST/TypeNodes.inc"
942 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
944 case Type::LValueReference:
945 case Type::RValueReference:
946 llvm_unreachable(
"References shouldn't get here");
949 case Type::DeducedTemplateSpecialization:
950 llvm_unreachable(
"Undeduced type shouldn't get here");
953 llvm_unreachable(
"Pipe types shouldn't get here");
955 case Type::ArrayParameter:
956 llvm_unreachable(
"Array Parameter types should not get here.");
962 case Type::ExtVector:
963 case Type::ConstantMatrix:
967 case Type::BlockPointer:
968 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
969 case Type::ConstantArray:
970 case Type::IncompleteArray:
971 case Type::VariableArray:
972 cgm.
errorNYI(
"VTableClassNameForType: __array_type_info");
975 case Type::FunctionNoProto:
976 case Type::FunctionProto:
977 cgm.
errorNYI(
"VTableClassNameForType: __function_type_info");
981 return "_ZTVN10__cxxabiv116__enum_type_infoE";
985 ->getDefinitionOrSelf();
988 return classTypeInfo;
991 if (canUseSingleInheritance(rd)) {
992 return siClassTypeInfo;
995 return vmiClassTypeInfo;
998 case Type::ObjCObject:
999 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
1002 case Type::ObjCInterface:
1003 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
1006 case Type::ObjCObjectPointer:
1008 cgm.
errorNYI(
"VTableClassNameForType: __pointer_type_info");
1011 case Type::MemberPointer:
1012 cgm.
errorNYI(
"VTableClassNameForType: __pointer_to_member_type_info");
1015 case Type::HLSLAttributedResource:
1016 case Type::HLSLInlineSpirv:
1017 llvm_unreachable(
"HLSL doesn't support virtual functions");
1036 if (containsIncompleteClassType(ty))
1037 return cir::GlobalLinkageKind::InternalLinkage;
1041 llvm_unreachable(
"Linkage hasn't been computed!");
1046 return cir::GlobalLinkageKind::InternalLinkage;
1054 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1056 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1060 return cir::GlobalLinkageKind::WeakODRLinkage;
1062 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1063 if (rd->
hasAttr<DLLImportAttr>() &&
1064 shouldUseExternalRttiDescriptor(cgm, ty))
1065 return cir::GlobalLinkageKind::ExternalLinkage;
1071 .isWindowsGNUEnvironment())
1075 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1078 llvm_unreachable(
"Invalid linkage!");
1082CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1083 cir::GlobalLinkageKind linkage) {
1085 SmallString<256>
name;
1086 llvm::raw_svector_ostream
out(name);
1092 mlir::Attribute init = builder.
getString(
1105 loc, name, initStr.getType(), linkage, align);
1111CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1114 SmallString<256>
name;
1115 llvm::raw_svector_ostream
out(name);
1120 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(
1121 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1136 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1143void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1146 const char *vTableName = vTableClassNameForType(cgm, ty);
1150 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1157 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1161 mlir::Attribute field{};
1163 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1165 SmallVector<mlir::Attribute, 4> offsets{
1167 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1172 assert(field &&
"expected attribute");
1173 fields.push_back(field);
1178void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1179 const CXXRecordDecl *rd) {
1183 mlir::Attribute baseTypeInfo =
1184 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1186 fields.push_back(baseTypeInfo);
1192void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1193 const CXXRecordDecl *rd) {
1194 mlir::Type unsignedIntLTy =
1201 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1202 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1207 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1240 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1242 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1244 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1245 .buildTypeInfo(loc, base.
getType()));
1259 const ASTRecordLayout &layout =
1268 offsetFlags |= BCTI_Virtual;
1270 offsetFlags |= BCTI_Public;
1272 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1276mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1282 SmallString<256>
name;
1283 llvm::raw_svector_ostream
out(name);
1286 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1287 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1289 if (oldGV && !oldGV.isDeclaration()) {
1290 assert(!oldGV.hasAvailableExternallyLinkage() &&
1291 "available_externally typeinfos not yet implemented");
1297 if (isStandardLibraryRttiDescriptor(ty) ||
1298 shouldUseExternalRttiDescriptor(cgm, ty))
1299 return getAddrOfExternalRTTIDescriptor(loc, ty);
1309 mlir::SymbolTable::Visibility symVisibility;
1312 symVisibility = mlir::SymbolTable::Visibility::Public;
1313 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1314 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1316 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1321 return buildTypeInfo(loc, ty, linkage, symVisibility);
1324mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1325 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1326 mlir::SymbolTable::Visibility visibility) {
1335 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1336 mlir::Attribute typeNameField;
1340 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1341 cxxABI.classifyRTTIUniqueness(ty, linkage);
1342 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1346 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1352 fields.push_back(typeNameField);
1355#define TYPE(Class, Base)
1356#define ABSTRACT_TYPE(Class, Base)
1357#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1358#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1359#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1360#include "clang/AST/TypeNodes.inc"
1361 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1366 case Type::ExtVector:
1367 case Type::ConstantMatrix:
1369 case Type::BlockPointer:
1374 case Type::LValueReference:
1375 case Type::RValueReference:
1376 llvm_unreachable(
"References shouldn't get here");
1379 case Type::DeducedTemplateSpecialization:
1380 llvm_unreachable(
"Undeduced type shouldn't get here");
1388 case Type::ConstantArray:
1389 case Type::IncompleteArray:
1390 case Type::VariableArray:
1391 case Type::ArrayParameter:
1396 case Type::FunctionNoProto:
1397 case Type::FunctionProto:
1407 case Type::Record: {
1409 ->getDefinitionOrSelf();
1415 if (canUseSingleInheritance(rd)) {
1416 buildSIClassTypeInfo(loc, rd);
1418 buildVMIClassTypeInfo(loc, rd);
1424 case Type::ObjCObject:
1425 case Type::ObjCInterface:
1426 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1429 case Type::ObjCObjectPointer:
1430 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1434 cgm.
errorNYI(
"buildTypeInfo: Pointer");
1437 case Type::MemberPointer:
1438 cgm.
errorNYI(
"buildTypeInfo: MemberPointer");
1445 case Type::HLSLAttributedResource:
1446 case Type::HLSLInlineSpirv:
1447 llvm_unreachable(
"HLSL doesn't support RTTI");
1451 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1453 SmallString<256>
name;
1454 llvm::raw_svector_ostream
out(name);
1458 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1459 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1468 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1475 gv.setName(oldGV.getName());
1476 if (!oldGV->use_empty()) {
1477 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1485 cgm.
errorNYI(
"buildTypeInfo: supportsCOMDAT & isWeakForLinker");
1491 gv.setAlignmentAttr(cgm.
getSize(align));
1508 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1513 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1522mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1524 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1529CIRGenItaniumCXXABI::RTTIUniquenessKind
1530CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1531 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1532 if (shouldRTTIBeUnique())
1536 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1537 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1545 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1546 return RUK_NonUniqueHidden;
1551 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1552 return RUK_NonUniqueVisible;
1555void CIRGenItaniumCXXABI::emitDestructorCall(
1557 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1558 GlobalDecl gd(dd,
type);
1564 CIRGenCallee callee =
1571void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1592mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1594 bool forVirtualBase,
bool delegating) {
1595 GlobalDecl gd(dd,
type);
1603 mlir::Value exceptionPtr = {},
1604 mlir::FlatSymbolRefAttr typeInfo = {},
1605 mlir::FlatSymbolRefAttr dtor = {}) {
1606 mlir::Block *currentBlock = builder.getInsertionBlock();
1607 mlir::Region *region = currentBlock->getParent();
1609 if (currentBlock->empty()) {
1610 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1611 cir::UnreachableOp::create(builder, loc);
1613 mlir::Block *throwBlock = builder.createBlock(region);
1615 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1616 cir::UnreachableOp::create(builder, loc);
1618 builder.setInsertionPointToEnd(currentBlock);
1619 cir::BrOp::create(builder, loc, throwBlock);
1622 (void)builder.createBlock(region);
1625void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1629 assert(cgf.
currSrcLoc &&
"expected source location");
1633 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1637void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1638 const CXXThrowExpr *e) {
1646 cir::PointerType throwTy =
1653 mlir::TypedValue<cir::PointerType> exceptionPtr =
1654 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1655 builder.getI64IntegerAttr(typeSize))
1663 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1666 assert(!typeInfo.getIndices() &&
"expected no indirection");
1675 if (
const RecordType *recordTy = clangThrowType->
getAs<RecordType>()) {
1678 if (!rec->hasTrivialDestructor()) {
1679 cgm.
errorNYI(
"emitThrow: non-trivial destructor");
1691 case TargetCXXABI::GenericItanium:
1692 case TargetCXXABI::GenericAArch64:
1693 return new CIRGenItaniumCXXABI(cgm);
1695 case TargetCXXABI::AppleARM64:
1699 return new CIRGenItaniumCXXABI(cgm);
1702 llvm_unreachable(
"bad or NYI ABI kind");
1706cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1708 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1709 cir::GlobalOp &vtable = vtables[rd];
1717 llvm::raw_svector_ostream
out(name);
1718 getMangleContext().mangleCXXVTable(rd,
out);
1733 cir::GlobalLinkageKind::ExternalLinkage,
1747 "getAddrOfVTable: PS4 DLL import/export");
1753CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1757 mlir::Location loc = cgf.
getLoc(srcLoc);
1760 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1763 mlir::Value vfunc{};
1765 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1769 mlir::Value vfuncLoad;
1772 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1774 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1775 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1788 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: strictVTablePointers");
1793 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1797mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1798 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1799 const CXXRecordDecl *nearestVBase) {
1801 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
1812 virtualPointerIndex);
1814 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
1820CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
1821 const CXXRecordDecl *vtableClass) {
1822 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1826 VTableLayout::AddressPointLocation addressPoint =
1832 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
1834 return cir::VTableAddrPointOp::create(
1836 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
1837 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
1842mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
1843 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
1844 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
1847 needsVTTParameter(cgf.
curGD)) {
1848 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
1851 return getVTableAddressPoint(base, vtableClass);
1854bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1855 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
1858 return needsVTTParameter(cgf.
curGD);
1861mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
1862 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
1863 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
1865 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
1867 CharUnits vbaseOffsetOffset =
1870 mlir::Value offsetVal =
1872 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
1873 vtableBytePtr, offsetVal);
1875 mlir::Value vbaseOffset;
1878 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
1894 cir::FuncType fnTy =
1904 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1908void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
1909 mlir::Location loc) {
1922 if (!dst->isDerivedFrom(src, paths))
1925 unsigned numPublicPaths = 0;
1938 if (pathElement.Base->isVirtual())
1941 if (numPublicPaths > 1)
1948 pathElement.Base->getType()->getAsCXXRecordDecl());
1953 if (numPublicPaths == 0)
1957 if (numPublicPaths > 1)
1985 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
1991 bool vtableUsesRelativeLayout =
1994 loc, src.
getPointer(), vtableUsesRelativeLayout);
2002 cir::PointerType destCIRTy,
2003 bool isRefCast,
Address src) {
2013 std::optional<CharUnits> offset;
2023 pathElement.Base->getType()->getAsCXXRecordDecl();
2024 if (pathElement.Base->isVirtual()) {
2038 offset = pathOffset;
2039 }
else if (offset != pathOffset) {
2055 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2057 mlir::Region *currentRegion = builder.getBlock()->getParent();
2062 builder.createBlock(currentRegion, currentRegion->end());
2065 return nullPtrValue;
2073 mlir::Value expectedVPtr =
2074 abi.getVTableAddressPoint(
BaseSubobject(srcDecl, *offset), destDecl);
2078 mlir::Type vptrTy = expectedVPtr.getType();
2082 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
2087 mlir::Value success =
2088 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2090 auto emitCastResult = [&] {
2091 if (offset->isZero())
2098 mlir::Value strideToApply =
2101 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2102 srcU8Ptr, strideToApply);
2107 mlir::Value failed = builder.
createNot(success);
2108 cir::IfOp::create(builder, loc, failed,
false,
2109 [&](mlir::OpBuilder &, mlir::Location) {
2112 return emitCastResult();
2115 return cir::TernaryOp::create(
2116 builder, loc, success,
2117 [&](mlir::OpBuilder &, mlir::Location) {
2118 auto result = emitCastResult();
2121 [&](mlir::OpBuilder &, mlir::Location) {
2122 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2132 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
2134 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
2139 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2140 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2147 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2149 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2150 badCastFuncRef, offsetHintAttr);
2153mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2155 QualType srcRecordTy,
2156 QualType destRecordTy,
2157 cir::PointerType destCIRTy,
2158 bool isRefCast, Address src) {
2159 bool isCastToVoid = destRecordTy.
isNull();
2160 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2173 return cir::TernaryOp::create(
2174 builder, loc, srcPtrIsNull,
2175 [&](mlir::OpBuilder, mlir::Location) {
2177 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2179 [&](mlir::OpBuilder &, mlir::Location) {
2181 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2189 destCIRTy, isRefCast, src);
2192 cir::DynamicCastInfoAttr castInfo =
2195 isRefCast, castInfo);
2200void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2201 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2202 QualType elementType,
const CXXDestructorDecl *dtor) {
2204 if (useGlobalDelete) {
2206 "emitVirtualObjectDelete: global delete");
2210 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2215CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2223Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2225 mlir::Value numElements,
2226 const CXXNewExpr *e,
2227 QualType elementType) {
2228 assert(requiresArrayCookie(e));
2240 CharUnits cookieSize =
2242 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2245 mlir::Value baseBytePtr =
2249 CharUnits cookieOffset = cookieSize - sizeSize;
2250 mlir::Value cookiePtrValue = baseBytePtr;
2251 if (!cookieOffset.
isZero()) {
2260 Address cookiePtr(cookiePtrValue, u8PtrTy, cookiePtrAlignment);
2263 Address numElementsPtr =
2269 mlir::Value dataOffset =
2272 mlir::Value dataPtr =
2274 mlir::Value finalPtr =
2277 return Address(finalPtr, newPtr.
getElementType(), finalAlignment);
2294struct CallEndCatch final : EHScopeStack::Cleanup {
2295 CallEndCatch(
bool mightThrow) : mightThrow(mightThrow) {}
2298 void emit(CIRGenFunction &cgf, Flags flags)
override {
2312 if (!cgf.
getBuilder().getBlock()->mightHaveTerminator())
2319 bool endMightThrow) {
2320 auto catchParam = cir::CatchParamOp::create(
2323 cgf.
ehStack.pushCleanup<CallEndCatch>(
2325 endMightThrow && !cgf.
cgm.
getLangOpts().AssumeNothrowExceptionDtor);
2327 return catchParam.getParam();
2339 cgf.
cgm.
errorNYI(loc,
"initCatchParam: ReferenceType");
2349 if (catchType->hasPointerRepresentation()) {
2350 cgf.
cgm.
errorNYI(loc,
"initCatchParam: hasPointerRepresentation");
2355 mlir::Value catchParam =
2361 cgf.
cgm.
errorNYI(loc,
"initCatchParam: cir::TEK_Complex");
2370 llvm_unreachable(
"evaluation kind filtered out!");
2374 llvm_unreachable(
"bad evaluation kind");
2377 cgf.
cgm.
errorNYI(loc,
"initCatchParam: cir::TEK_Aggregate");
2382void CIRGenItaniumCXXABI::emitBeginCatch(CIRGenFunction &cgf,
2383 const CXXCatchStmt *catchStmt) {
2414 auto getCatchParamAllocaIP = [&]() {
2415 cir::CIRBaseBuilderTy::InsertPoint currIns =
2417 mlir::Operation *currParent = currIns.getBlock()->getParentOp();
2419 mlir::Block *insertBlock =
nullptr;
2420 if (
auto scopeOp = currParent->getParentOfType<cir::ScopeOp>()) {
2421 insertBlock = &scopeOp.getScopeRegion().getBlocks().back();
2422 }
else if (
auto fnOp = currParent->getParentOfType<cir::FuncOp>()) {
2423 insertBlock = &fnOp.getRegion().getBlocks().back();
2425 llvm_unreachable(
"unknown outermost scope-like parent");
2434 CIRGenFunction::AutoVarEmission
var =
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 initCatchParam(CIRGenFunction &cgf, const VarDecl &catchParam, Address paramAddr, SourceLocation loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
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::Type paramTy, 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 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 cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm, const CXXMethodDecl *md)
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
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::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)
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.
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 emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
mlir::Value emitRuntimeCall(mlir::Location loc, cir::FuncOp callee, llvm::ArrayRef< mlir::Value > args={})
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)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::ArrayAttr={}, bool isLocal=false, bool assumeConvergent=false)
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.
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::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)
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
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>'.
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.
unsigned AddressPointIndex