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 cir::MethodAttr buildVirtualMethodAttr(cir::MethodType methodTy,
160 const CXXMethodDecl *md)
override;
162 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
163 mlir::Value numElements,
const CXXNewExpr *e,
164 QualType elementType)
override;
167 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
172 virtual bool shouldRTTIBeUnique()
const {
return true; }
176 enum RTTIUniquenessKind {
194 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
199void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
204 "emitInstanceFunctionProlog: Naked");
209 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
212 if (getStructorImplicitParamDecl(cgf)) {
216 setStructorImplicitParamValue(cgf, val);
227 if (hasThisReturn(cgf.
curGD)) {
229 "emitInstanceFunctionProlog: hasThisReturn");
233CIRGenCXXABI::AddedStructorArgCounts
234CIRGenItaniumCXXABI::buildStructorSignature(
235 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
246 argTys.insert(argTys.begin() + 1,
249 return AddedStructorArgCounts::withPrefix(1);
252 return AddedStructorArgCounts{};
257enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
263 return StructorCIRGen::Emit;
268 return StructorCIRGen::Emit;
271 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
281 return StructorCIRGen::RAUW;
285 return StructorCIRGen::RAUW;
291 return StructorCIRGen::COMDAT;
292 return StructorCIRGen::Emit;
295 return StructorCIRGen::Alias;
305 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
307 if (globalValue && !globalValue.isDeclaration())
310 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
319void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
322 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
326 GlobalDecl baseDecl =
330 if (cirGenType == StructorCIRGen::Alias ||
331 cirGenType == StructorCIRGen::COMDAT) {
336 if (cirGenType == StructorCIRGen::RAUW) {
349void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
351 FunctionArgList ¶ms) {
356 if (needsVTTParameter(cgf.
curGD)) {
363 astContext,
nullptr, md->getLocation(),
364 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
365 params.insert(params.begin() + 1, vttDecl);
366 getStructorImplicitParamDecl(cgf) = vttDecl;
370void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
386void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
402CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
404 bool forVirtualBase,
bool delegating) {
405 if (!needsVTTParameter(GlobalDecl(d,
type)))
406 return AddedStructorArgs{};
416 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
422bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
426 if (!md->getParent()->getNumVBases())
440void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
441 const CXXRecordDecl *rd) {
442 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
443 if (vtable.hasInitializer())
449 mlir::Attribute rtti =
460 vtable.setLinkage(linkage);
463 vtable.setComdat(
true);
478 "emitVTableDefinitions: __fundamental_type_info");
481 [[maybe_unused]]
auto vtableAsGlobalValue =
482 dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
483 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
493 "emitVTableDefinitions: WholeProgramVTables");
502mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
503 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
504 Address thisAddr, DeleteOrMemberCallExpr
expr) {
505 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
506 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
507 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
511 GlobalDecl globalDecl(dtor, dtorType);
512 const CIRGenFunctionInfo *fnInfo =
521 thisTy,
nullptr, QualType(),
nullptr);
525void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
526 const CXXRecordDecl *rd) {
533class CIRGenItaniumRTTIBuilder {
535 const CIRGenItaniumCXXABI &cxxABI;
538 SmallVector<mlir::Attribute, 16> fields;
541 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
542 cir::GlobalLinkageKind linkage);
545 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
549 void buildVTablePointer(mlir::Location loc,
const Type *ty);
553 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
558 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
561 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
562 : cgm(cgm), cxxABI(abi) {}
566 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
569 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
570 cir::GlobalLinkageKind linkage,
571 mlir::SymbolTable::Visibility visibility);
590 PTI_Incomplete = 0x8,
594 PTI_ContainingClassIncomplete = 0x10,
606 VMI_NonDiamondRepeat = 0x1,
609 VMI_DiamondShaped = 0x2
624static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
640 case BuiltinType::WasmExternRef:
641 case BuiltinType::HLSLResource:
642 llvm_unreachable(
"NYI");
643 case BuiltinType::Void:
644 case BuiltinType::NullPtr:
645 case BuiltinType::Bool:
646 case BuiltinType::WChar_S:
647 case BuiltinType::WChar_U:
648 case BuiltinType::Char_U:
649 case BuiltinType::Char_S:
650 case BuiltinType::UChar:
651 case BuiltinType::SChar:
652 case BuiltinType::Short:
653 case BuiltinType::UShort:
654 case BuiltinType::Int:
655 case BuiltinType::UInt:
656 case BuiltinType::Long:
657 case BuiltinType::ULong:
658 case BuiltinType::LongLong:
659 case BuiltinType::ULongLong:
660 case BuiltinType::Half:
661 case BuiltinType::Float:
662 case BuiltinType::Double:
663 case BuiltinType::LongDouble:
664 case BuiltinType::Float16:
665 case BuiltinType::Float128:
666 case BuiltinType::Ibm128:
667 case BuiltinType::Char8:
668 case BuiltinType::Char16:
669 case BuiltinType::Char32:
670 case BuiltinType::Int128:
671 case BuiltinType::UInt128:
674#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
675 case BuiltinType::Id:
676#include "clang/Basic/OpenCLImageTypes.def"
677#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
678#include "clang/Basic/OpenCLExtensionTypes.def"
679 case BuiltinType::OCLSampler:
680 case BuiltinType::OCLEvent:
681 case BuiltinType::OCLClkEvent:
682 case BuiltinType::OCLQueue:
683 case BuiltinType::OCLReserveID:
684#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
685#include "clang/Basic/AArch64ACLETypes.def"
686#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
687#include "clang/Basic/PPCTypes.def"
688#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
689#include "clang/Basic/RISCVVTypes.def"
690#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
691#include "clang/Basic/AMDGPUTypes.def"
692 case BuiltinType::ShortAccum:
693 case BuiltinType::Accum:
694 case BuiltinType::LongAccum:
695 case BuiltinType::UShortAccum:
696 case BuiltinType::UAccum:
697 case BuiltinType::ULongAccum:
698 case BuiltinType::ShortFract:
699 case BuiltinType::Fract:
700 case BuiltinType::LongFract:
701 case BuiltinType::UShortFract:
702 case BuiltinType::UFract:
703 case BuiltinType::ULongFract:
704 case BuiltinType::SatShortAccum:
705 case BuiltinType::SatAccum:
706 case BuiltinType::SatLongAccum:
707 case BuiltinType::SatUShortAccum:
708 case BuiltinType::SatUAccum:
709 case BuiltinType::SatULongAccum:
710 case BuiltinType::SatShortFract:
711 case BuiltinType::SatFract:
712 case BuiltinType::SatLongFract:
713 case BuiltinType::SatUShortFract:
714 case BuiltinType::SatUFract:
715 case BuiltinType::SatULongFract:
716 case BuiltinType::BFloat16:
719 case BuiltinType::Dependent:
720#define BUILTIN_TYPE(Id, SingletonId)
721#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
722#include "clang/AST/BuiltinTypes.def"
723 llvm_unreachable(
"asking for RRTI for a placeholder type!");
725 case BuiltinType::ObjCId:
726 case BuiltinType::ObjCClass:
727 case BuiltinType::ObjCSel:
728 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
731 llvm_unreachable(
"Invalid BuiltinType Kind!");
734static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
736 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
747 return typeInfoIsInStandardLibrary(builtinTy);
752static bool isStandardLibraryRttiDescriptor(QualType ty) {
754 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
755 return typeInfoIsInStandardLibrary(builtinTy);
759 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
760 return typeInfoIsInStandardLibrary(pointerTy);
769static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
777 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
790 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
800 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
813 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
814 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
819static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
827 if (!bases.virtualBases.insert(baseDecl).second) {
830 flags |= VMI_DiamondShaped;
832 if (bases.nonVirtualBases.count(baseDecl))
833 flags |= VMI_NonDiamondRepeat;
837 if (!bases.nonVirtualBases.insert(baseDecl).second) {
840 flags |= VMI_NonDiamondRepeat;
842 if (bases.virtualBases.count(baseDecl))
843 flags |= VMI_NonDiamondRepeat;
848 for (
const auto &bs : baseDecl->bases())
849 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
854static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
859 for (
const auto &bs : rd->
bases())
860 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
869static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
887 return baseDecl->isEmpty() ||
892static bool isIncompleteClassType(
const RecordType *recordTy) {
893 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
907static bool containsIncompleteClassType(QualType ty) {
908 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
909 if (isIncompleteClassType(recordTy))
913 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
916 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
918 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
921 return containsIncompleteClassType(memberPointerTy->getPointeeType());
927const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
929 static const char *
const classTypeInfo =
930 "_ZTVN10__cxxabiv117__class_type_infoE";
932 static const char *
const siClassTypeInfo =
933 "_ZTVN10__cxxabiv120__si_class_type_infoE";
935 static const char *
const vmiClassTypeInfo =
936 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
939#define TYPE(Class, Base)
940#define ABSTRACT_TYPE(Class, Base)
941#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
942#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
943#define DEPENDENT_TYPE(Class, Base) case Type::Class:
944#include "clang/AST/TypeNodes.inc"
945 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
947 case Type::LValueReference:
948 case Type::RValueReference:
949 llvm_unreachable(
"References shouldn't get here");
952 case Type::DeducedTemplateSpecialization:
953 llvm_unreachable(
"Undeduced type shouldn't get here");
956 llvm_unreachable(
"Pipe types shouldn't get here");
958 case Type::ArrayParameter:
959 llvm_unreachable(
"Array Parameter types should not get here.");
965 case Type::ExtVector:
966 case Type::ConstantMatrix:
970 case Type::BlockPointer:
971 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
972 case Type::ConstantArray:
973 case Type::IncompleteArray:
974 case Type::VariableArray:
975 cgm.
errorNYI(
"VTableClassNameForType: __array_type_info");
978 case Type::FunctionNoProto:
979 case Type::FunctionProto:
980 cgm.
errorNYI(
"VTableClassNameForType: __function_type_info");
984 return "_ZTVN10__cxxabiv116__enum_type_infoE";
988 ->getDefinitionOrSelf();
991 return classTypeInfo;
994 if (canUseSingleInheritance(rd)) {
995 return siClassTypeInfo;
998 return vmiClassTypeInfo;
1001 case Type::ObjCObject:
1002 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
1005 case Type::ObjCInterface:
1006 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
1009 case Type::ObjCObjectPointer:
1011 cgm.
errorNYI(
"VTableClassNameForType: __pointer_type_info");
1014 case Type::MemberPointer:
1015 cgm.
errorNYI(
"VTableClassNameForType: __pointer_to_member_type_info");
1018 case Type::HLSLAttributedResource:
1019 case Type::HLSLInlineSpirv:
1020 llvm_unreachable(
"HLSL doesn't support virtual functions");
1039 if (containsIncompleteClassType(ty))
1040 return cir::GlobalLinkageKind::InternalLinkage;
1044 llvm_unreachable(
"Linkage hasn't been computed!");
1049 return cir::GlobalLinkageKind::InternalLinkage;
1057 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1059 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1063 return cir::GlobalLinkageKind::WeakODRLinkage;
1065 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1066 if (rd->
hasAttr<DLLImportAttr>() &&
1067 shouldUseExternalRttiDescriptor(cgm, ty))
1068 return cir::GlobalLinkageKind::ExternalLinkage;
1074 .isWindowsGNUEnvironment())
1078 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1081 llvm_unreachable(
"Invalid linkage!");
1085CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1086 cir::GlobalLinkageKind linkage) {
1088 SmallString<256>
name;
1089 llvm::raw_svector_ostream
out(name);
1095 mlir::Attribute init = builder.
getString(
1108 loc, name, initStr.getType(), linkage, align);
1114CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1117 SmallString<256>
name;
1118 llvm::raw_svector_ostream
out(name);
1123 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(
1124 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1139 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1146void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1149 const char *vTableName = vTableClassNameForType(cgm, ty);
1153 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1160 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1164 mlir::Attribute field{};
1166 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1168 SmallVector<mlir::Attribute, 4> offsets{
1170 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1175 assert(field &&
"expected attribute");
1176 fields.push_back(field);
1181void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1182 const CXXRecordDecl *rd) {
1186 mlir::Attribute baseTypeInfo =
1187 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1189 fields.push_back(baseTypeInfo);
1195void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1196 const CXXRecordDecl *rd) {
1197 mlir::Type unsignedIntLTy =
1204 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1205 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1210 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1243 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1245 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1247 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1248 .buildTypeInfo(loc, base.
getType()));
1262 const ASTRecordLayout &layout =
1271 offsetFlags |= BCTI_Virtual;
1273 offsetFlags |= BCTI_Public;
1275 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1279mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1285 SmallString<256>
name;
1286 llvm::raw_svector_ostream
out(name);
1289 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1290 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1292 if (oldGV && !oldGV.isDeclaration()) {
1293 assert(!oldGV.hasAvailableExternallyLinkage() &&
1294 "available_externally typeinfos not yet implemented");
1300 if (isStandardLibraryRttiDescriptor(ty) ||
1301 shouldUseExternalRttiDescriptor(cgm, ty))
1302 return getAddrOfExternalRTTIDescriptor(loc, ty);
1312 mlir::SymbolTable::Visibility symVisibility;
1315 symVisibility = mlir::SymbolTable::Visibility::Public;
1316 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1317 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1319 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1324 return buildTypeInfo(loc, ty, linkage, symVisibility);
1327mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1328 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1329 mlir::SymbolTable::Visibility visibility) {
1338 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1339 mlir::Attribute typeNameField;
1343 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1344 cxxABI.classifyRTTIUniqueness(ty, linkage);
1345 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1349 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1355 fields.push_back(typeNameField);
1358#define TYPE(Class, Base)
1359#define ABSTRACT_TYPE(Class, Base)
1360#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1361#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1362#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1363#include "clang/AST/TypeNodes.inc"
1364 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1369 case Type::ExtVector:
1370 case Type::ConstantMatrix:
1372 case Type::BlockPointer:
1377 case Type::LValueReference:
1378 case Type::RValueReference:
1379 llvm_unreachable(
"References shouldn't get here");
1382 case Type::DeducedTemplateSpecialization:
1383 llvm_unreachable(
"Undeduced type shouldn't get here");
1391 case Type::ConstantArray:
1392 case Type::IncompleteArray:
1393 case Type::VariableArray:
1394 case Type::ArrayParameter:
1399 case Type::FunctionNoProto:
1400 case Type::FunctionProto:
1410 case Type::Record: {
1412 ->getDefinitionOrSelf();
1418 if (canUseSingleInheritance(rd)) {
1419 buildSIClassTypeInfo(loc, rd);
1421 buildVMIClassTypeInfo(loc, rd);
1427 case Type::ObjCObject:
1428 case Type::ObjCInterface:
1429 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1432 case Type::ObjCObjectPointer:
1433 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1437 cgm.
errorNYI(
"buildTypeInfo: Pointer");
1440 case Type::MemberPointer:
1441 cgm.
errorNYI(
"buildTypeInfo: MemberPointer");
1448 case Type::HLSLAttributedResource:
1449 case Type::HLSLInlineSpirv:
1450 llvm_unreachable(
"HLSL doesn't support RTTI");
1454 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1456 SmallString<256>
name;
1457 llvm::raw_svector_ostream
out(name);
1461 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1462 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1471 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1478 gv.setName(oldGV.getName());
1479 if (!oldGV->use_empty()) {
1480 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1488 cgm.
errorNYI(
"buildTypeInfo: supportsCOMDAT & isWeakForLinker");
1494 gv.setAlignmentAttr(cgm.
getSize(align));
1511 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1516 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1525mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1527 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1532CIRGenItaniumCXXABI::RTTIUniquenessKind
1533CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1534 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1535 if (shouldRTTIBeUnique())
1539 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1540 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1548 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1549 return RUK_NonUniqueHidden;
1554 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1555 return RUK_NonUniqueVisible;
1558void CIRGenItaniumCXXABI::emitDestructorCall(
1560 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1561 GlobalDecl gd(dd,
type);
1567 CIRGenCallee callee =
1574void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1595mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1597 bool forVirtualBase,
bool delegating) {
1598 GlobalDecl gd(dd,
type);
1606 mlir::Value exceptionPtr = {},
1607 mlir::FlatSymbolRefAttr typeInfo = {},
1608 mlir::FlatSymbolRefAttr dtor = {}) {
1609 mlir::Block *currentBlock = builder.getInsertionBlock();
1610 mlir::Region *region = currentBlock->getParent();
1612 if (currentBlock->empty()) {
1613 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1614 cir::UnreachableOp::create(builder, loc);
1616 mlir::Block *throwBlock = builder.createBlock(region);
1618 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1619 cir::UnreachableOp::create(builder, loc);
1621 builder.setInsertionPointToEnd(currentBlock);
1622 cir::BrOp::create(builder, loc, throwBlock);
1625 (void)builder.createBlock(region);
1628void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1632 assert(cgf.
currSrcLoc &&
"expected source location");
1636 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1640void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1641 const CXXThrowExpr *e) {
1649 cir::PointerType throwTy =
1656 mlir::TypedValue<cir::PointerType> exceptionPtr =
1657 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1658 builder.getI64IntegerAttr(typeSize))
1666 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1669 assert(!typeInfo.getIndices() &&
"expected no indirection");
1678 if (
const RecordType *recordTy = clangThrowType->
getAs<RecordType>()) {
1681 if (!rec->hasTrivialDestructor()) {
1682 cgm.
errorNYI(
"emitThrow: non-trivial destructor");
1694 case TargetCXXABI::GenericItanium:
1695 case TargetCXXABI::GenericAArch64:
1696 return new CIRGenItaniumCXXABI(cgm);
1698 case TargetCXXABI::AppleARM64:
1702 return new CIRGenItaniumCXXABI(cgm);
1705 llvm_unreachable(
"bad or NYI ABI kind");
1709cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1711 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1712 cir::GlobalOp &vtable = vtables[rd];
1720 llvm::raw_svector_ostream
out(name);
1721 getMangleContext().mangleCXXVTable(rd,
out);
1736 cir::GlobalLinkageKind::ExternalLinkage,
1750 "getAddrOfVTable: PS4 DLL import/export");
1756CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1760 mlir::Location loc = cgf.
getLoc(srcLoc);
1763 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1766 mlir::Value vfunc{};
1768 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1772 mlir::Value vfuncLoad;
1775 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1777 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1778 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1791 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: strictVTablePointers");
1796 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1800mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1801 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1802 const CXXRecordDecl *nearestVBase) {
1804 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
1815 virtualPointerIndex);
1817 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
1823CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
1824 const CXXRecordDecl *vtableClass) {
1825 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
1829 VTableLayout::AddressPointLocation addressPoint =
1835 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
1837 return cir::VTableAddrPointOp::create(
1839 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
1840 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
1845mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
1846 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
1847 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
1850 needsVTTParameter(cgf.
curGD)) {
1851 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
1854 return getVTableAddressPoint(base, vtableClass);
1857bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
1858 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
1861 return needsVTTParameter(cgf.
curGD);
1864mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
1865 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
1866 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
1868 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
1870 CharUnits vbaseOffsetOffset =
1873 mlir::Value offsetVal =
1875 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
1876 vtableBytePtr, offsetVal);
1878 mlir::Value vbaseOffset;
1881 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
1897 cir::FuncType fnTy =
1907 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1911void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
1912 mlir::Location loc) {
1925 if (!dst->isDerivedFrom(src, paths))
1928 unsigned numPublicPaths = 0;
1941 if (pathElement.Base->isVirtual())
1944 if (numPublicPaths > 1)
1951 pathElement.Base->getType()->getAsCXXRecordDecl());
1956 if (numPublicPaths == 0)
1960 if (numPublicPaths > 1)
1988 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
1994 bool vtableUsesRelativeLayout =
1997 loc, src.
getPointer(), vtableUsesRelativeLayout);
2005 cir::PointerType destCIRTy,
2006 bool isRefCast,
Address src) {
2016 std::optional<CharUnits> offset;
2026 pathElement.Base->getType()->getAsCXXRecordDecl();
2027 if (pathElement.Base->isVirtual()) {
2041 offset = pathOffset;
2042 }
else if (offset != pathOffset) {
2058 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2060 mlir::Region *currentRegion = builder.getBlock()->getParent();
2065 builder.createBlock(currentRegion, currentRegion->end());
2068 return nullPtrValue;
2076 mlir::Value expectedVPtr =
2077 abi.getVTableAddressPoint(
BaseSubobject(srcDecl, *offset), destDecl);
2081 mlir::Type vptrTy = expectedVPtr.getType();
2085 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
2090 mlir::Value success =
2091 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2093 auto emitCastResult = [&] {
2094 if (offset->isZero())
2101 mlir::Value strideToApply =
2104 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2105 srcU8Ptr, strideToApply);
2110 mlir::Value failed = builder.
createNot(success);
2111 cir::IfOp::create(builder, loc, failed,
false,
2112 [&](mlir::OpBuilder &, mlir::Location) {
2115 return emitCastResult();
2118 return cir::TernaryOp::create(
2119 builder, loc, success,
2120 [&](mlir::OpBuilder &, mlir::Location) {
2121 auto result = emitCastResult();
2124 [&](mlir::OpBuilder &, mlir::Location) {
2125 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2135 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
2137 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
2142 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2143 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2150 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2152 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2153 badCastFuncRef, offsetHintAttr);
2156mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2158 QualType srcRecordTy,
2159 QualType destRecordTy,
2160 cir::PointerType destCIRTy,
2161 bool isRefCast, Address src) {
2162 bool isCastToVoid = destRecordTy.
isNull();
2163 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2176 return cir::TernaryOp::create(
2177 builder, loc, srcPtrIsNull,
2178 [&](mlir::OpBuilder, mlir::Location) {
2180 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2182 [&](mlir::OpBuilder &, mlir::Location) {
2184 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2192 destCIRTy, isRefCast, src);
2195 cir::DynamicCastInfoAttr castInfo =
2198 isRefCast, castInfo);
2202CIRGenItaniumCXXABI::buildVirtualMethodAttr(cir::MethodType methodTy,
2203 const CXXMethodDecl *md) {
2204 assert(md->
isVirtual() &&
"only deal with virtual member functions");
2210 vtableOffset = index * 4;
2215 vtableOffset = index * pointerWidth.
getQuantity();
2218 return cir::MethodAttr::get(methodTy, vtableOffset);
2222void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2223 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2224 QualType elementType,
const CXXDestructorDecl *dtor) {
2226 if (useGlobalDelete) {
2228 "emitVirtualObjectDelete: global delete");
2232 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2237CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2245Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2247 mlir::Value numElements,
2248 const CXXNewExpr *e,
2249 QualType elementType) {
2250 assert(requiresArrayCookie(e));
2262 CharUnits cookieSize =
2264 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2267 mlir::Value baseBytePtr =
2271 CharUnits cookieOffset = cookieSize - sizeSize;
2272 mlir::Value cookiePtrValue = baseBytePtr;
2273 if (!cookieOffset.
isZero()) {
2282 Address cookiePtr(cookiePtrValue, u8PtrTy, cookiePtrAlignment);
2285 Address numElementsPtr =
2291 mlir::Value dataOffset =
2294 mlir::Value dataPtr =
2296 mlir::Value finalPtr =
2299 return Address(finalPtr, newPtr.
getElementType(), finalAlignment);
2316struct CallEndCatch final : EHScopeStack::Cleanup {
2317 CallEndCatch(
bool mightThrow) : mightThrow(mightThrow) {}
2320 void emit(CIRGenFunction &cgf, Flags flags)
override {
2334 if (!cgf.
getBuilder().getBlock()->mightHaveTerminator())
2341 bool endMightThrow) {
2342 auto catchParam = cir::CatchParamOp::create(
2345 cgf.
ehStack.pushCleanup<CallEndCatch>(
2347 endMightThrow && !cgf.
cgm.
getLangOpts().AssumeNothrowExceptionDtor);
2349 return catchParam.getParam();
2363 cgf.
cgm.
errorNYI(loc,
"initCatchParam: ReferenceType");
2373 if (catchType->hasPointerRepresentation()) {
2374 mlir::Value catchParam =
2379 "initCatchParam: PointerRepresentation OCL_Strong");
2384 cgf.
cgm.
errorNYI(loc,
"initCatchParam: PointerRepresentation "
2385 "OCL_ExplicitNone & OCL_Autoreleasing");
2393 cgf.
cgm.
errorNYI(loc,
"initCatchParam: PointerRepresentation OCL_Weak");
2397 llvm_unreachable(
"bad ownership qualifier!");
2402 mlir::Value catchParam =
2419 llvm_unreachable(
"evaluation kind filtered out!");
2422 llvm_unreachable(
"bad evaluation kind");
2425 cgf.
cgm.
errorNYI(loc,
"initCatchParam: cir::TEK_Aggregate");
2430void CIRGenItaniumCXXABI::emitBeginCatch(CIRGenFunction &cgf,
2431 const CXXCatchStmt *catchStmt) {
2462 auto getCatchParamAllocaIP = [&]() {
2463 cir::CIRBaseBuilderTy::InsertPoint currIns =
2465 mlir::Operation *currParent = currIns.getBlock()->getParentOp();
2467 mlir::Block *insertBlock =
nullptr;
2468 if (
auto scopeOp = currParent->getParentOfType<cir::ScopeOp>()) {
2469 insertBlock = &scopeOp.getScopeRegion().getBlocks().back();
2470 }
else if (
auto fnOp = currParent->getParentOfType<cir::FuncOp>()) {
2471 insertBlock = &fnOp.getRegion().getBlocks().back();
2473 llvm_unreachable(
"unknown outermost scope-like parent");
2482 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)
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 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)
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>'.
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