30#include "llvm/ADT/SmallString.h"
31#include "llvm/Support/ErrorHandling.h"
32#include "llvm/Support/raw_ostream.h"
42 llvm::DenseMap<const CXXRecordDecl *, cir::GlobalOp> vtables;
45 CIRGenItaniumCXXABI(CIRGenModule &cgm) : CIRGenCXXABI(cgm) {
50 AddedStructorArgs getImplicitConstructorArgs(CIRGenFunction &cgf,
51 const CXXConstructorDecl *d,
54 bool delegating)
override;
56 bool needsVTTParameter(clang::GlobalDecl gd)
override;
58 AddedStructorArgCounts
59 buildStructorSignature(GlobalDecl gd,
60 llvm::SmallVectorImpl<CanQualType> &argTys)
override;
62 void emitInstanceFunctionProlog(SourceLocation loc,
63 CIRGenFunction &cgf)
override;
65 void addImplicitStructorParams(CIRGenFunction &cgf, QualType &resTy,
66 FunctionArgList ¶ms)
override;
68 const CXXDestructorDecl *dd,
71 bool delegating)
override;
72 void emitCXXConstructors(
const clang::CXXConstructorDecl *d)
override;
73 void emitCXXDestructors(
const clang::CXXDestructorDecl *d)
override;
74 void emitCXXStructor(clang::GlobalDecl gd)
override;
76 void emitDestructorCall(CIRGenFunction &cgf,
const CXXDestructorDecl *dd,
78 bool delegating, Address thisAddr,
79 QualType thisTy)
override;
80 void registerGlobalDtor(
const VarDecl *vd, cir::FuncOp dtor,
81 mlir::Value addr)
override;
82 void emitVirtualObjectDelete(CIRGenFunction &cgf,
const CXXDeleteExpr *de,
83 Address ptr, QualType elementType,
84 const CXXDestructorDecl *dtor)
override;
86 void emitRethrow(CIRGenFunction &cgf,
bool isNoReturn)
override;
87 void emitThrow(CIRGenFunction &cgf,
const CXXThrowExpr *e)
override;
89 bool useThunkForDtorVariant(
const CXXDestructorDecl *dtor,
97 bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
98 CIRGenFunction::VPtr vptr)
override;
100 cir::GlobalOp getAddrOfVTable(
const CXXRecordDecl *rd,
101 CharUnits vptrOffset)
override;
102 CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf,
103 clang::GlobalDecl gd, Address thisAddr,
105 SourceLocation loc)
override;
106 mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
107 const CXXDestructorDecl *dtor,
109 DeleteOrMemberCallExpr e)
override;
111 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
112 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
114 mlir::Value getVTableAddressPoint(BaseSubobject base,
115 const CXXRecordDecl *vtableClass)
override;
116 mlir::Value getVTableAddressPointInStructorWithVTT(
117 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
118 const CXXRecordDecl *nearestVBase);
120 mlir::Value getVTableAddressPointInStructor(
121 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
122 clang::BaseSubobject base,
123 const clang::CXXRecordDecl *nearestVBase)
override;
124 void emitVTableDefinitions(CIRGenVTables &cgvt,
125 const CXXRecordDecl *rd)
override;
126 void emitVirtualInheritanceTables(
const CXXRecordDecl *rd)
override;
128 void setThunkLinkage(cir::FuncOp thunk,
bool forVTable, GlobalDecl gd,
129 bool returnAdjustment)
override {
130 if (forVTable && !thunk.hasLocalLinkage())
131 thunk.setLinkage(cir::GlobalLinkageKind::AvailableExternallyLinkage);
136 bool exportThunk()
override {
return true; }
138 mlir::Value performThisAdjustment(CIRGenFunction &cgf, Address thisAddr,
139 const CXXRecordDecl *unadjustedClass,
140 const ThunkInfo &ti)
override;
143 const CXXRecordDecl *unadjustedClass,
144 const ReturnAdjustment &ra)
override;
146 bool shouldTypeidBeNullChecked(QualType srcTy)
override;
147 mlir::Value emitTypeid(CIRGenFunction &cgf, QualType SrcRecordTy,
148 Address thisPtr, mlir::Type StdTypeInfoPtrTy)
override;
149 void emitBadTypeidCall(CIRGenFunction &cgf, mlir::Location loc)
override;
151 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
152 QualType ty)
override;
154 StringRef getPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
155 StringRef getDeletedVirtualCallName()
override {
156 return "__cxa_deleted_virtual";
160 getAddrOfCXXCatchHandlerType(mlir::Location loc, QualType ty,
161 QualType catchHandlerType)
override {
162 auto rtti = dyn_cast<cir::GlobalViewAttr>(getAddrOfRTTIDescriptor(loc, ty));
163 assert(rtti &&
"expected GlobalViewAttr");
164 return CatchTypeInfo{rtti, 0};
167 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *vtableClass)
override {
171 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
172 FunctionArgList &args)
const override {
173 assert(!args.empty() &&
"expected the arglist to not be empty!");
174 return args.size() - 1;
177 void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)
override;
180 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
181 Address thisAddr,
const CXXRecordDecl *classDecl,
182 const CXXRecordDecl *baseClassDecl)
override;
189 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
190 QualType srcRecordTy, QualType destRecordTy,
191 cir::PointerType destCIRTy,
bool isRefCast,
192 Address src)
override;
194 cir::MethodAttr buildVirtualMethodAttr(cir::MethodType methodTy,
195 const CXXMethodDecl *md)
override;
197 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
198 mlir::Value numElements,
const CXXNewExpr *e,
199 QualType elementType)
override;
201 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
204 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
209 virtual bool shouldRTTIBeUnique()
const {
return true; }
213 enum RTTIUniquenessKind {
231 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
234 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *rd)
const;
235 bool isVTableHidden(
const CXXRecordDecl *rd)
const;
240void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
245 "emitInstanceFunctionProlog: Naked");
250 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
253 if (getStructorImplicitParamDecl(cgf)) {
257 setStructorImplicitParamValue(cgf, val);
268 if (hasThisReturn(cgf.
curGD)) {
270 "emitInstanceFunctionProlog: hasThisReturn");
274CIRGenCXXABI::AddedStructorArgCounts
275CIRGenItaniumCXXABI::buildStructorSignature(
276 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
287 argTys.insert(argTys.begin() + 1,
290 return AddedStructorArgCounts::withPrefix(1);
293 return AddedStructorArgCounts{};
298enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
304 return StructorCIRGen::Emit;
309 return StructorCIRGen::Emit;
312 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
322 return StructorCIRGen::RAUW;
326 return StructorCIRGen::RAUW;
332 return StructorCIRGen::COMDAT;
333 return StructorCIRGen::Emit;
336 return StructorCIRGen::Alias;
346 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
348 if (globalValue && !globalValue.isDeclaration())
351 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
360void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
363 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
368 GlobalDecl baseDecl =
372 if (cirGenType == StructorCIRGen::Alias ||
373 cirGenType == StructorCIRGen::COMDAT) {
378 if (cirGenType == StructorCIRGen::RAUW) {
388 if (cirGenType == StructorCIRGen::COMDAT) {
389 llvm::SmallString<256> comdatKey;
390 llvm::raw_svector_ostream
out(comdatKey);
391 ItaniumMangleContext &mangler =
397 fn.setComdat(llvm::StringRef(comdatKey));
403void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
405 FunctionArgList ¶ms) {
410 if (needsVTTParameter(cgf.
curGD)) {
417 astContext,
nullptr, md->getLocation(),
418 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
419 params.insert(params.begin() + 1, vttDecl);
420 getStructorImplicitParamDecl(cgf) = vttDecl;
424void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
440void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
456CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
458 bool forVirtualBase,
bool delegating) {
459 if (!needsVTTParameter(GlobalDecl(d,
type)))
460 return AddedStructorArgs{};
470 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
476bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
480 if (!md->getParent()->getNumVBases())
494void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
495 const CXXRecordDecl *rd) {
496 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
497 if (vtable.hasInitializer())
503 mlir::Attribute rtti =
514 vtable.setLinkage(linkage);
517 vtable.setComdat(
true);
532 "emitVTableDefinitions: __fundamental_type_info");
535 [[maybe_unused]]
auto vtableAsGlobalValue =
536 dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
537 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
547 "emitVTableDefinitions: WholeProgramVTables");
556mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
557 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
558 Address thisAddr, DeleteOrMemberCallExpr
expr) {
559 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
560 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
561 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
565 GlobalDecl globalDecl(dtor, dtorType);
566 const CIRGenFunctionInfo *fnInfo =
575 thisTy,
nullptr, QualType(),
nullptr);
579void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
580 const CXXRecordDecl *rd) {
587class CIRGenItaniumRTTIBuilder {
589 const CIRGenItaniumCXXABI &cxxABI;
592 SmallVector<mlir::Attribute, 16> fields;
595 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
596 cir::GlobalLinkageKind linkage);
599 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
603 void buildVTablePointer(mlir::Location loc,
const Type *ty);
607 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
612 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
616 void buildPointerTypeInfo(mlir::Location loc, QualType ty);
623 void buildPointerToMemberTypeInfo(mlir::Location loc,
624 const MemberPointerType *ty);
627 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
628 : cgm(cgm), cxxABI(abi) {}
632 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
635 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
636 cir::GlobalLinkageKind linkage,
637 mlir::SymbolTable::Visibility visibility);
656 PTI_Incomplete = 0x8,
660 PTI_ContainingClassIncomplete = 0x10,
672 VMI_NonDiamondRepeat = 0x1,
675 VMI_DiamondShaped = 0x2
690static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
706 case BuiltinType::WasmExternRef:
707 case BuiltinType::HLSLResource:
708 llvm_unreachable(
"NYI");
709 case BuiltinType::Void:
710 case BuiltinType::NullPtr:
711 case BuiltinType::Bool:
712 case BuiltinType::WChar_S:
713 case BuiltinType::WChar_U:
714 case BuiltinType::Char_U:
715 case BuiltinType::Char_S:
716 case BuiltinType::UChar:
717 case BuiltinType::SChar:
718 case BuiltinType::Short:
719 case BuiltinType::UShort:
720 case BuiltinType::Int:
721 case BuiltinType::UInt:
722 case BuiltinType::Long:
723 case BuiltinType::ULong:
724 case BuiltinType::LongLong:
725 case BuiltinType::ULongLong:
726 case BuiltinType::Half:
727 case BuiltinType::Float:
728 case BuiltinType::Double:
729 case BuiltinType::LongDouble:
730 case BuiltinType::Float16:
731 case BuiltinType::Float128:
732 case BuiltinType::Ibm128:
733 case BuiltinType::Char8:
734 case BuiltinType::Char16:
735 case BuiltinType::Char32:
736 case BuiltinType::Int128:
737 case BuiltinType::UInt128:
740#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
741 case BuiltinType::Id:
742#include "clang/Basic/OpenCLImageTypes.def"
743#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
744#include "clang/Basic/OpenCLExtensionTypes.def"
745 case BuiltinType::OCLSampler:
746 case BuiltinType::OCLEvent:
747 case BuiltinType::OCLClkEvent:
748 case BuiltinType::OCLQueue:
749 case BuiltinType::OCLReserveID:
750#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
751#include "clang/Basic/AArch64ACLETypes.def"
752#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
753#include "clang/Basic/PPCTypes.def"
754#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
755#include "clang/Basic/RISCVVTypes.def"
756#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
757#include "clang/Basic/AMDGPUTypes.def"
758#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
759#include "clang/Basic/SPIRVTypes.def"
760 case BuiltinType::ShortAccum:
761 case BuiltinType::Accum:
762 case BuiltinType::LongAccum:
763 case BuiltinType::UShortAccum:
764 case BuiltinType::UAccum:
765 case BuiltinType::ULongAccum:
766 case BuiltinType::ShortFract:
767 case BuiltinType::Fract:
768 case BuiltinType::LongFract:
769 case BuiltinType::UShortFract:
770 case BuiltinType::UFract:
771 case BuiltinType::ULongFract:
772 case BuiltinType::SatShortAccum:
773 case BuiltinType::SatAccum:
774 case BuiltinType::SatLongAccum:
775 case BuiltinType::SatUShortAccum:
776 case BuiltinType::SatUAccum:
777 case BuiltinType::SatULongAccum:
778 case BuiltinType::SatShortFract:
779 case BuiltinType::SatFract:
780 case BuiltinType::SatLongFract:
781 case BuiltinType::SatUShortFract:
782 case BuiltinType::SatUFract:
783 case BuiltinType::SatULongFract:
784 case BuiltinType::BFloat16:
787 case BuiltinType::Dependent:
788#define BUILTIN_TYPE(Id, SingletonId)
789#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
790#include "clang/AST/BuiltinTypes.def"
791 llvm_unreachable(
"asking for RRTI for a placeholder type!");
793 case BuiltinType::ObjCId:
794 case BuiltinType::ObjCClass:
795 case BuiltinType::ObjCSel:
796 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
799 llvm_unreachable(
"Invalid BuiltinType Kind!");
802static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
804 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
815 return typeInfoIsInStandardLibrary(builtinTy);
820static bool isStandardLibraryRttiDescriptor(QualType ty) {
822 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
823 return typeInfoIsInStandardLibrary(builtinTy);
827 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
828 return typeInfoIsInStandardLibrary(pointerTy);
837static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
845 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
858 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
868 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
881 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
882 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
887static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
895 if (!bases.virtualBases.insert(baseDecl).second) {
898 flags |= VMI_DiamondShaped;
900 if (bases.nonVirtualBases.count(baseDecl))
901 flags |= VMI_NonDiamondRepeat;
905 if (!bases.nonVirtualBases.insert(baseDecl).second) {
908 flags |= VMI_NonDiamondRepeat;
910 if (bases.virtualBases.count(baseDecl))
911 flags |= VMI_NonDiamondRepeat;
916 for (
const auto &bs : baseDecl->bases())
917 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
922static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
927 for (
const auto &bs : rd->
bases())
928 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
937static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
955 return baseDecl->isEmpty() ||
960static bool isIncompleteClassType(
const RecordType *recordTy) {
961 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
975static bool containsIncompleteClassType(QualType ty) {
976 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
977 if (isIncompleteClassType(recordTy))
981 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
984 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
986 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
989 return containsIncompleteClassType(memberPointerTy->getPointeeType());
1001 flags |= PTI_Volatile;
1003 flags |= PTI_Restrict;
1007 if (containsIncompleteClassType(ty))
1008 flags |= PTI_Incomplete;
1010 if (
const auto *proto = ty->
getAs<FunctionProtoType>()) {
1011 if (proto->isNothrow()) {
1012 flags |= PTI_Noexcept;
1020const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
1022 static const char *
const classTypeInfo =
1023 "_ZTVN10__cxxabiv117__class_type_infoE";
1025 static const char *
const siClassTypeInfo =
1026 "_ZTVN10__cxxabiv120__si_class_type_infoE";
1028 static const char *
const vmiClassTypeInfo =
1029 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
1032#define TYPE(Class, Base)
1033#define ABSTRACT_TYPE(Class, Base)
1034#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1035#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1036#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1037#include "clang/AST/TypeNodes.inc"
1038 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1040 case Type::LValueReference:
1041 case Type::RValueReference:
1042 llvm_unreachable(
"References shouldn't get here");
1045 case Type::DeducedTemplateSpecialization:
1046 llvm_unreachable(
"Undeduced type shouldn't get here");
1049 llvm_unreachable(
"Pipe types shouldn't get here");
1051 case Type::ArrayParameter:
1052 llvm_unreachable(
"Array Parameter types should not get here.");
1056 case Type::OverflowBehavior:
1059 case Type::ExtVector:
1060 case Type::ConstantMatrix:
1064 case Type::BlockPointer:
1065 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
1066 case Type::ConstantArray:
1067 case Type::IncompleteArray:
1068 case Type::VariableArray:
1070 return "_ZTVN10__cxxabiv117__array_type_infoE";
1072 case Type::FunctionNoProto:
1073 case Type::FunctionProto:
1075 return "_ZTVN10__cxxabiv120__function_type_infoE";
1078 return "_ZTVN10__cxxabiv116__enum_type_infoE";
1080 case Type::Record: {
1082 ->getDefinitionOrSelf();
1085 return classTypeInfo;
1088 if (canUseSingleInheritance(rd)) {
1089 return siClassTypeInfo;
1092 return vmiClassTypeInfo;
1095 case Type::ObjCObject:
1096 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
1099 case Type::ObjCInterface:
1100 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
1103 case Type::ObjCObjectPointer:
1106 return "_ZTVN10__cxxabiv119__pointer_type_infoE";
1108 case Type::MemberPointer:
1110 return "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
1112 case Type::HLSLAttributedResource:
1113 case Type::HLSLInlineSpirv:
1114 llvm_unreachable(
"HLSL doesn't support virtual functions");
1133 if (containsIncompleteClassType(ty))
1134 return cir::GlobalLinkageKind::InternalLinkage;
1138 llvm_unreachable(
"Linkage hasn't been computed!");
1143 return cir::GlobalLinkageKind::InternalLinkage;
1151 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1153 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1157 return cir::GlobalLinkageKind::WeakODRLinkage;
1159 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1160 if (rd->
hasAttr<DLLImportAttr>() &&
1161 shouldUseExternalRttiDescriptor(cgm, ty))
1162 return cir::GlobalLinkageKind::ExternalLinkage;
1168 .isWindowsGNUEnvironment())
1172 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1175 llvm_unreachable(
"Invalid linkage!");
1179CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1180 cir::GlobalLinkageKind linkage) {
1182 SmallString<256>
name;
1183 llvm::raw_svector_ostream
out(name);
1189 mlir::Attribute init = builder.
getString(
1202 loc, name, initStr.getType(), linkage, align);
1208CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1211 SmallString<256>
name;
1212 llvm::raw_svector_ostream
out(name);
1217 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1232 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1239void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1242 const char *vTableName = vTableClassNameForType(cgm, ty);
1246 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1253 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1259 vTable.setConstant(
false);
1262 mlir::Attribute field{};
1264 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1266 SmallVector<mlir::Attribute, 4> offsets{
1268 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1273 assert(field &&
"expected attribute");
1274 fields.push_back(field);
1279void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1280 const CXXRecordDecl *rd) {
1284 mlir::Attribute baseTypeInfo =
1285 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1287 fields.push_back(baseTypeInfo);
1293void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1294 const CXXRecordDecl *rd) {
1295 mlir::Type unsignedIntLTy =
1302 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1303 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1308 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1341 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1343 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1345 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1346 .buildTypeInfo(loc, base.
getType()));
1360 const ASTRecordLayout &layout =
1369 offsetFlags |= BCTI_Virtual;
1371 offsetFlags |= BCTI_Public;
1373 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1377void CIRGenItaniumRTTIBuilder::buildPointerTypeInfo(mlir::Location loc,
1401 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1402 fields.push_back(flagsAttr);
1404 mlir::Attribute pointeeTypeInfo =
1405 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, ty);
1406 fields.push_back(pointeeTypeInfo);
1409void CIRGenItaniumRTTIBuilder::buildPointerToMemberTypeInfo(
1410 mlir::Location loc,
const MemberPointerType *ty) {
1425 flags |= PTI_ContainingClassIncomplete;
1428 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1429 fields.push_back(flagsAttr);
1431 mlir::Attribute pointeeTypeInfo =
1432 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, pointeeTy);
1433 fields.push_back(pointeeTypeInfo);
1436 mlir::Attribute classTypeInfo =
1437 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, contextTy);
1438 fields.push_back(classTypeInfo);
1441mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1447 SmallString<256>
name;
1448 llvm::raw_svector_ostream
out(name);
1451 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1453 if (oldGV && !oldGV.isDeclaration()) {
1454 assert(!oldGV.hasAvailableExternallyLinkage() &&
1455 "available_externally typeinfos not yet implemented");
1461 if (isStandardLibraryRttiDescriptor(ty) ||
1462 shouldUseExternalRttiDescriptor(cgm, ty))
1463 return getAddrOfExternalRTTIDescriptor(loc, ty);
1473 mlir::SymbolTable::Visibility symVisibility;
1476 symVisibility = mlir::SymbolTable::Visibility::Public;
1477 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1478 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1480 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1485 return buildTypeInfo(loc, ty, linkage, symVisibility);
1488mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1489 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1490 mlir::SymbolTable::Visibility visibility) {
1499 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1500 mlir::Attribute typeNameField;
1504 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1505 cxxABI.classifyRTTIUniqueness(ty, linkage);
1506 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1510 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1516 fields.push_back(typeNameField);
1519#define TYPE(Class, Base)
1520#define ABSTRACT_TYPE(Class, Base)
1521#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1522#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1523#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1524#include "clang/AST/TypeNodes.inc"
1525 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1530 case Type::ExtVector:
1531 case Type::ConstantMatrix:
1533 case Type::BlockPointer:
1538 case Type::LValueReference:
1539 case Type::RValueReference:
1540 llvm_unreachable(
"References shouldn't get here");
1543 case Type::DeducedTemplateSpecialization:
1544 llvm_unreachable(
"Undeduced type shouldn't get here");
1552 case Type::OverflowBehavior:
1555 case Type::ConstantArray:
1556 case Type::IncompleteArray:
1557 case Type::VariableArray:
1558 case Type::ArrayParameter:
1563 case Type::FunctionNoProto:
1564 case Type::FunctionProto:
1574 case Type::Record: {
1576 ->getDefinitionOrSelf();
1582 if (canUseSingleInheritance(rd)) {
1583 buildSIClassTypeInfo(loc, rd);
1585 buildVMIClassTypeInfo(loc, rd);
1591 case Type::ObjCObject:
1592 case Type::ObjCInterface:
1593 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1596 case Type::ObjCObjectPointer:
1597 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1605 case Type::MemberPointer:
1613 case Type::HLSLAttributedResource:
1614 case Type::HLSLInlineSpirv:
1615 llvm_unreachable(
"HLSL doesn't support RTTI");
1619 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1621 SmallString<256>
name;
1622 llvm::raw_svector_ostream
out(name);
1626 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
1630 gv.setLinkage(linkage);
1635 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1642 gv.setName(oldGV.getName());
1643 if (!oldGV->use_empty()) {
1644 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1656 gv.setAlignmentAttr(cgm.
getSize(align));
1673 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1678 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1687bool CIRGenItaniumCXXABI::shouldTypeidBeNullChecked(QualType srcTy) {
1691void CIRGenItaniumCXXABI::emitBadTypeidCall(CIRGenFunction &cgf,
1692 mlir::Location loc) {
1694 cir::FuncType fnTy =
1696 mlir::NamedAttrList attrs;
1697 attrs.set(cir::CIRDialect::getNoReturnAttrName(),
1703 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1706mlir::Value CIRGenItaniumCXXABI::emitTypeid(CIRGenFunction &cgf, QualType srcTy,
1708 mlir::Type typeInfoPtrTy) {
1710 mlir::Location loc = cgm.
getLoc(classDecl->getSourceRange());
1711 mlir::Value vptr = cgf.
getVTablePtr(loc, thisPtr, classDecl);
1719 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1721 vtbl = cir::VTableGetTypeInfoOp::create(
1729mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1731 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1736CIRGenItaniumCXXABI::RTTIUniquenessKind
1737CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1738 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1739 if (shouldRTTIBeUnique())
1743 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1744 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1752 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1753 return RUK_NonUniqueHidden;
1758 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1759 return RUK_NonUniqueVisible;
1762void CIRGenItaniumCXXABI::emitDestructorCall(
1764 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1765 GlobalDecl gd(dd,
type);
1771 CIRGenCallee callee =
1778void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1794mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1796 bool forVirtualBase,
bool delegating) {
1797 GlobalDecl gd(dd,
type);
1805 mlir::Value exceptionPtr = {},
1806 mlir::FlatSymbolRefAttr typeInfo = {},
1807 mlir::FlatSymbolRefAttr dtor = {}) {
1808 mlir::Block *currentBlock = builder.getInsertionBlock();
1809 mlir::Region *region = currentBlock->getParent();
1811 if (currentBlock->empty()) {
1812 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1813 cir::UnreachableOp::create(builder, loc);
1815 mlir::Block *throwBlock = builder.createBlock(region);
1817 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1818 cir::UnreachableOp::create(builder, loc);
1820 builder.setInsertionPointToEnd(currentBlock);
1821 cir::BrOp::create(builder, loc, throwBlock);
1824 (void)builder.createBlock(region);
1827void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1831 assert(cgf.
currSrcLoc &&
"expected source location");
1835 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1839void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1840 const CXXThrowExpr *e) {
1848 cir::PointerType throwTy =
1855 mlir::TypedValue<cir::PointerType> exceptionPtr =
1856 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1857 builder.getI64IntegerAttr(typeSize))
1865 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1868 assert(!typeInfo.getIndices() &&
"expected no indirection");
1878 mlir::FlatSymbolRefAttr dtor{};
1879 if (cxxrd && !cxxrd->hasTrivialDestructor()) {
1884 CXXDestructorDecl *dtorD = cxxrd->getDestructor();
1885 dtor = mlir::FlatSymbolRefAttr::get(
1897 case TargetCXXABI::GenericItanium:
1898 case TargetCXXABI::GenericAArch64:
1899 case TargetCXXABI::GenericARM:
1900 return new CIRGenItaniumCXXABI(cgm);
1902 case TargetCXXABI::AppleARM64:
1906 return new CIRGenItaniumCXXABI(cgm);
1909 llvm_unreachable(
"bad or NYI ABI kind");
1913cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1915 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1916 cir::GlobalOp &vtable = vtables[rd];
1924 llvm::raw_svector_ostream
out(name);
1925 getMangleContext().mangleCXXVTable(rd,
out);
1934 unsigned ptrAlign = cgm.
getLangOpts().RelativeCXXABIVTables
1940 cir::GlobalLinkageKind::ExternalLinkage,
1954 "getAddrOfVTable: PS4 DLL import/export");
1960CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1964 mlir::Location loc = cgf.
getLoc(srcLoc);
1967 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1970 mlir::Value vfunc{};
1972 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1976 mlir::Value vfuncLoad;
1979 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1981 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1982 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1995 if (
auto loadOp = vfuncLoad.getDefiningOp<cir::LoadOp>())
1996 loadOp.setInvariant(
true);
2001 CIRGenCallee callee(gd, vfunc.getDefiningOp());
2005mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
2006 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
2007 const CXXRecordDecl *nearestVBase) {
2009 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
2020 virtualPointerIndex);
2022 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
2028CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
2029 const CXXRecordDecl *vtableClass) {
2030 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
2034 VTableLayout::AddressPointLocation addressPoint =
2040 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
2042 return cir::VTableAddrPointOp::create(
2044 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
2045 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
2050mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
2051 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
2052 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
2055 needsVTTParameter(cgf.
curGD)) {
2056 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
2059 return getVTableAddressPoint(base, vtableClass);
2062bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2063 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
2066 return needsVTTParameter(cgf.
curGD);
2069mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
2070 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
2071 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
2073 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
2075 CharUnits vbaseOffsetOffset =
2078 mlir::Value offsetVal =
2080 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
2081 vtableBytePtr, offsetVal);
2083 mlir::Value vbaseOffset;
2086 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
2102 cir::FuncType fnTy =
2111 mlir::NamedAttrList attrs;
2112 attrs.set(cir::CIRDialect::getNoReturnAttrName(),
2116 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
2120void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
2121 mlir::Location loc) {
2144 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
2146 fn->setAttr(cir::CIRDialect::getNoThrowAttrName(),
2147 mlir::UnitAttr::get(cgf.
getBuilder().getContext()));
2153 bool vtableUsesRelativeLayout = cgf.
cgm.
getLangOpts().RelativeCXXABIVTables;
2155 loc, src.
getPointer(), vtableUsesRelativeLayout);
2163 cir::PointerType destCIRTy,
2164 bool isRefCast,
Address src) {
2174 std::optional<CharUnits> offset;
2184 pathElement.Base->getType()->getAsCXXRecordDecl();
2185 if (pathElement.Base->isVirtual()) {
2199 offset = pathOffset;
2200 }
else if (offset != pathOffset) {
2216 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2218 mlir::Region *currentRegion = builder.getBlock()->getParent();
2223 builder.createBlock(currentRegion, currentRegion->end());
2226 return nullPtrValue;
2234 mlir::Value expectedVPtr =
2239 mlir::Type vptrTy = expectedVPtr.getType();
2243 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
2248 mlir::Value success =
2249 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2251 auto emitCastResult = [&] {
2252 if (offset->isZero())
2259 mlir::Value strideToApply =
2262 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2263 srcU8Ptr, strideToApply);
2268 mlir::Value failed = builder.
createNot(success);
2269 cir::IfOp::create(builder, loc, failed,
false,
2270 [&](mlir::OpBuilder &, mlir::Location) {
2273 return emitCastResult();
2276 return cir::TernaryOp::create(
2277 builder, loc, success,
2278 [&](mlir::OpBuilder &, mlir::Location) {
2279 auto result = emitCastResult();
2282 [&](mlir::OpBuilder &, mlir::Location) {
2283 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2293 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
2295 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
2300 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2301 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2309 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2311 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2312 badCastFuncRef, offsetHintAttr);
2315mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2317 QualType srcRecordTy,
2318 QualType destRecordTy,
2319 cir::PointerType destCIRTy,
2320 bool isRefCast, Address src) {
2321 bool isCastToVoid = destRecordTy.
isNull();
2322 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2335 return cir::TernaryOp::create(
2336 builder, loc, srcPtrIsNull,
2337 [&](mlir::OpBuilder, mlir::Location) {
2339 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2341 [&](mlir::OpBuilder &, mlir::Location) {
2343 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2351 destCIRTy, isRefCast, src);
2354 cir::DynamicCastInfoAttr castInfo =
2357 isRefCast, castInfo);
2361CIRGenItaniumCXXABI::buildVirtualMethodAttr(cir::MethodType methodTy,
2362 const CXXMethodDecl *md) {
2363 assert(md->
isVirtual() &&
"only deal with virtual member functions");
2369 vtableOffset = index * 4;
2374 vtableOffset = index * pointerWidth.
getQuantity();
2377 return cir::MethodAttr::get(methodTy, vtableOffset);
2381void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2382 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2383 QualType elementType,
const CXXDestructorDecl *dtor) {
2385 if (useGlobalDelete) {
2387 "emitVirtualObjectDelete: global delete");
2391 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2396CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2404Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2406 mlir::Value numElements,
2407 const CXXNewExpr *e,
2408 QualType elementType) {
2409 assert(requiresArrayCookie(e));
2421 CharUnits cookieSize =
2423 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2427 mlir::Value baseBytePtr =
2431 CharUnits cookieOffset = cookieSize - sizeSize;
2432 mlir::Value cookiePtrValue = baseBytePtr;
2433 if (!cookieOffset.
isZero()) {
2442 Address cookiePtr(cookiePtrValue, u8Ty, cookiePtrAlignment);
2451 mlir::Value dataOffset =
2454 mlir::Value dataPtr =
2456 mlir::Value finalPtr =
2462bool CIRGenItaniumCXXABI::hasAnyUnusedVirtualInlineFunction(
2463 const CXXRecordDecl *rd)
const {
2466 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2468 if (!vtableComponent.isUsedFunctionPointerKind())
2471 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2473 const bool isInlined =
2479 vtableComponent.getGlobalDecl(
false));
2480 auto entry = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
2486 if (!entry || entry.isDeclaration())
2492bool CIRGenItaniumCXXABI::isVTableHidden(
const CXXRecordDecl *rd)
const {
2495 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2496 if (vtableComponent.isRTTIKind()) {
2497 const CXXRecordDecl *rttiDecl = vtableComponent.getRTTIDecl();
2498 if (rttiDecl->
getVisibility() == Visibility::HiddenVisibility)
2500 }
else if (vtableComponent.isUsedFunctionPointerKind()) {
2501 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2502 if (method->
getVisibility() == Visibility::HiddenVisibility &&
2510bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2511 const CXXRecordDecl *rd)
const {
2519 if (isVTableHidden(rd))
2539 if (hasAnyUnusedVirtualInlineFunction(rd))
2547 for (
const auto &b : rd->
bases()) {
2548 auto *brd = b.getType()->getAsCXXRecordDecl();
2549 assert(brd &&
"no class for base specifier");
2550 if (b.isVirtual() || !brd->isDynamicClass())
2552 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2560bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTable(
2561 const CXXRecordDecl *rd)
const {
2562 if (!canSpeculativelyEmitVTableAsBaseClass(rd))
2570 for (
const auto &b : rd->
vbases()) {
2571 auto *brd = b.getType()->getAsCXXRecordDecl();
2572 assert(brd &&
"no class for base specifier");
2573 if (!brd->isDynamicClass())
2575 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2585 int64_t nonVirtualAdjustment,
2586 int64_t virtualAdjustment,
2587 bool isReturnAdjustment) {
2588 if (!nonVirtualAdjustment && !virtualAdjustment)
2592 mlir::Location loc = builder.getUnknownLoc();
2597 if (nonVirtualAdjustment && !isReturnAdjustment) {
2598 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2599 v = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offsetConst);
2603 mlir::Value resultPtr;
2604 if (virtualAdjustment) {
2610 mlir::Value offsetPtr =
2611 cir::PtrStrideOp::create(builder, loc, i8PtrTy, vtablePtr,
2612 builder.
getSInt64(virtualAdjustment, loc));
2615 cgf.
cgm.
errorNYI(
"virtual adjustment for relative layout vtables");
2621 resultPtr = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offset);
2628 if (nonVirtualAdjustment && isReturnAdjustment) {
2629 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2631 cir::PtrStrideOp::create(builder, loc, i8PtrTy, resultPtr, offsetConst);
2638mlir::Value CIRGenItaniumCXXABI::performThisAdjustment(
2639 CIRGenFunction &cgf, Address thisAddr,
const CXXRecordDecl *unadjustedClass,
2640 const ThunkInfo &ti) {
2647mlir::Value CIRGenItaniumCXXABI::performReturnAdjustment(
2648 CIRGenFunction &cgf, Address ret,
const CXXRecordDecl *unadjustedClass,
2649 const ReturnAdjustment &ra) {
2655bool CIRGenItaniumCXXABI::isZeroInitializable(
const MemberPointerType *mpt) {
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static void insertThrowAndSplit(mlir::OpBuilder &builder, mlir::Location loc, mlir::Value exceptionPtr={}, mlir::FlatSymbolRefAttr typeInfo={}, mlir::FlatSymbolRefAttr dtor={})
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
static cir::DynamicCastInfoAttr emitDynamicCastInfo(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy)
static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, QualType ty)
Return the linkage that the type info and type info name constants should have for the given type.
static mlir::Value performTypeAdjustment(CIRGenFunction &cgf, Address initialPtr, const CXXRecordDecl *unadjustedClass, int64_t nonVirtualAdjustment, int64_t virtualAdjustment, bool isReturnAdjustment)
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
static void emitCallToBadCast(CIRGenFunction &cgf, mlir::Location loc)
static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm, const CXXMethodDecl *md)
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
static RValue performReturnAdjustment(CIRGenFunction &cgf, QualType resultType, RValue rv, const ThunkInfo &thunk)
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type)
Compute the flags for a __pbase_type_info, and remove the corresponding pieces from Type.
Defines the clang::Expr interface and subclasses for C++ expressions.
static QualType getPointeeType(const MemRegion *R)
C Language Family Type Representation.
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)
cir::PointerType getPointerTo(mlir::Type ty)
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)
mlir::Value createNot(mlir::Location loc, mlir::Value value)
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
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
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 getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CharUnits getExnObjectAlignment() const
Return the alignment (in bytes) of the thrown exception object.
CharUnits getPreferredTypeAlignInChars(QualType T) const
Return the PreferredAlignment of a (complete) type T, in characters.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
mlir::Value getPointer() const
mlir::Type getElementType() const
clang::CharUnits getAlignment() const
mlir::Type getType() const
mlir::Value emitRawPointer() const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
cir::IntType getUInt64Ty()
cir::IntType getUInt8Ty()
cir::TypeInfoAttr getTypeInfo(mlir::ArrayAttr fieldsAttr)
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc)
cir::PointerType getUInt8PtrTy()
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false, bool isNontemporal=false)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, bool isNontemporal=false, mlir::IntegerAttr align={}, cir::SyncScopeKindAttr scope={}, cir::MemOrderAttr order={})
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)
mlir::Attribute getString(llvm::StringRef str, mlir::Type eltTy, std::optional< size_t > size, bool ensureNullTerm=true)
Get a cir::ConstArrayAttr for a string literal.
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy, mlir::Value addr, uint64_t offset)
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)
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
const clang::Decl * curFuncDecl
Address getAddrOfLocalVar(const clang::VarDecl *vd)
Return the address of a local variable.
void emitAnyExprToExn(const Expr *e, Address addr)
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.
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 emitRuntimeCall(mlir::Location loc, cir::FuncOp callee, llvm::ArrayRef< mlir::Value > args={}, mlir::NamedAttrList attrs={})
std::optional< SourceRange > currSrcLoc
Use to track source locations across nested visitor traversals.
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
clang::ASTContext & getContext() const
This class organizes the cross-function state that is used while generating CIR code.
llvm::StringRef getMangledName(clang::GlobalDecl gd)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
clang::ASTContext & getASTContext() const
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
ItaniumVTableContext & getItaniumVTableContext()
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
const clang::TargetInfo & getTarget() const
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
const cir::CIRDataLayout getDataLayout() const
void eraseGlobalSymbol(mlir::Operation *op)
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::GlobalOp createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
void addDeferredVTable(const CXXRecordDecl *rd)
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)
bool supportsCOMDAT() const
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
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.
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.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
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.
base_class_range vbases()
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 One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
bool shouldEmitInExternalSource() const
Whether the definition of the declaration should be emitted in external sources.
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
FunctionDecl * getDefinition()
Get the definition for this declaration.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
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, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
virtual void mangleCXXCtorComdat(const CXXConstructorDecl *D, raw_ostream &)=0
virtual void mangleCXXDtorComdat(const CXXDestructorDecl *D, raw_ostream &)=0
uint64_t getMethodVTableIndex(GlobalDecl GD)
Locate a virtual function in the vtable.
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
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
bool isMemberFunctionPointer() const
Returns true if the member type (i.e.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Visibility getVisibility() const
Determines the visibility of this entity.
QualType getPointeeType() const
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isRestrictQualified() const
Determine whether this type is restrict-qualified.
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
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstQualified() const
Determine whether this type is const-qualified.
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
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.
CharUnits computeOffsetHint(ASTContext &Ctx, const CXXRecordDecl *Src, const CXXRecordDecl *Dst)
Compute the src2dst_offset hint as described in the Itanium C++ ABI [2.9.7].
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 size_t align(size_t Size)
Aligns a size to the pointer alignment.
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
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)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ 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)
@ EST_None
no exception specification
@ 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 cxxabiAppleARM64CXXABI()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool pointerAuthentication()
static bool opFuncCallingConv()
static bool opFuncWillReturn()
static bool protectedVisibility()
static bool cxxabiUseARMGuardVarABI()
static bool cxxabiUseARMMethodPtrABI()
static bool setDSOLocal()
static bool vtableRelativeLayout()
const clang::CXXRecordDecl * nearestVBase
clang::CharUnits getPointerAlign() const
clang::CharUnits getSizeSize() const
cir::PointerType uInt8PtrTy
Represents an element in a path from a derived class to a base class.
union clang::ReturnAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
union clang::ThisAdjustment::VirtualAdjustment Virtual
int64_t NonVirtual
The non-virtual adjustment from the derived object to its nearest virtual base.
ThisAdjustment This
The this pointer adjustment.
unsigned AddressPointIndex
struct clang::ReturnAdjustment::VirtualAdjustment::@103031170252120233124322035264172076254313213024 Itanium
int64_t VBaseOffsetOffset
The offset (in bytes), relative to the address point of the virtual base class offset.
struct clang::ThisAdjustment::VirtualAdjustment::@106065375072164260365214033034320247050276346205 Itanium
int64_t VCallOffsetOffset
The offset (in bytes), relative to the address point, of the virtual call offset.