28#include "llvm/Support/ErrorHandling.h"
38 llvm::DenseMap<const CXXRecordDecl *, cir::GlobalOp> vtables;
41 CIRGenItaniumCXXABI(CIRGenModule &cgm) : CIRGenCXXABI(cgm) {
46 AddedStructorArgs getImplicitConstructorArgs(CIRGenFunction &cgf,
47 const CXXConstructorDecl *d,
50 bool delegating)
override;
52 bool needsVTTParameter(clang::GlobalDecl gd)
override;
54 AddedStructorArgCounts
55 buildStructorSignature(GlobalDecl gd,
56 llvm::SmallVectorImpl<CanQualType> &argTys)
override;
58 void emitInstanceFunctionProlog(SourceLocation loc,
59 CIRGenFunction &cgf)
override;
61 void addImplicitStructorParams(CIRGenFunction &cgf, QualType &resTy,
62 FunctionArgList ¶ms)
override;
64 const CXXDestructorDecl *dd,
67 bool delegating)
override;
68 void emitCXXConstructors(
const clang::CXXConstructorDecl *d)
override;
69 void emitCXXDestructors(
const clang::CXXDestructorDecl *d)
override;
70 void emitCXXStructor(clang::GlobalDecl gd)
override;
72 void emitDestructorCall(CIRGenFunction &cgf,
const CXXDestructorDecl *dd,
74 bool delegating, Address thisAddr,
75 QualType thisTy)
override;
76 void registerGlobalDtor(
const VarDecl *vd, cir::FuncOp dtor,
77 mlir::Value addr)
override;
78 void emitVirtualObjectDelete(CIRGenFunction &cgf,
const CXXDeleteExpr *de,
79 Address ptr, QualType elementType,
80 const CXXDestructorDecl *dtor)
override;
82 void emitRethrow(CIRGenFunction &cgf,
bool isNoReturn)
override;
83 void emitThrow(CIRGenFunction &cgf,
const CXXThrowExpr *e)
override;
85 void emitBeginCatch(CIRGenFunction &cgf,
const CXXCatchStmt *catchStmt,
86 mlir::Value ehToken)
override;
88 bool useThunkForDtorVariant(
const CXXDestructorDecl *dtor,
96 bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
97 CIRGenFunction::VPtr vptr)
override;
99 cir::GlobalOp getAddrOfVTable(
const CXXRecordDecl *rd,
100 CharUnits vptrOffset)
override;
101 CIRGenCallee getVirtualFunctionPointer(CIRGenFunction &cgf,
102 clang::GlobalDecl gd, Address thisAddr,
104 SourceLocation loc)
override;
105 mlir::Value emitVirtualDestructorCall(CIRGenFunction &cgf,
106 const CXXDestructorDecl *dtor,
108 DeleteOrMemberCallExpr e)
override;
110 bool canSpeculativelyEmitVTable(
const CXXRecordDecl *RD)
const override;
111 bool canSpeculativelyEmitVTableAsBaseClass(
const CXXRecordDecl *RD)
const;
113 mlir::Value getVTableAddressPoint(BaseSubobject base,
114 const CXXRecordDecl *vtableClass)
override;
115 mlir::Value getVTableAddressPointInStructorWithVTT(
116 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
117 const CXXRecordDecl *nearestVBase);
119 mlir::Value getVTableAddressPointInStructor(
120 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
121 clang::BaseSubobject base,
122 const clang::CXXRecordDecl *nearestVBase)
override;
123 void emitVTableDefinitions(CIRGenVTables &cgvt,
124 const CXXRecordDecl *rd)
override;
125 void emitVirtualInheritanceTables(
const CXXRecordDecl *rd)
override;
127 void setThunkLinkage(cir::FuncOp thunk,
bool forVTable, GlobalDecl gd,
128 bool returnAdjustment)
override {
129 if (forVTable && !thunk.hasLocalLinkage())
130 thunk.setLinkage(cir::GlobalLinkageKind::AvailableExternallyLinkage);
135 bool exportThunk()
override {
return true; }
137 mlir::Value performThisAdjustment(CIRGenFunction &cgf, Address thisAddr,
138 const CXXRecordDecl *unadjustedClass,
139 const ThunkInfo &ti)
override;
142 const CXXRecordDecl *unadjustedClass,
143 const ReturnAdjustment &ra)
override;
145 bool shouldTypeidBeNullChecked(QualType srcTy)
override;
146 mlir::Value emitTypeid(CIRGenFunction &cgf, QualType SrcRecordTy,
147 Address thisPtr, mlir::Type StdTypeInfoPtrTy)
override;
148 void emitBadTypeidCall(CIRGenFunction &cgf, mlir::Location loc)
override;
150 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc,
151 QualType ty)
override;
153 StringRef getPureVirtualCallName()
override {
return "__cxa_pure_virtual"; }
154 StringRef getDeletedVirtualCallName()
override {
155 return "__cxa_deleted_virtual";
159 getAddrOfCXXCatchHandlerType(mlir::Location loc, QualType ty,
160 QualType catchHandlerType)
override {
161 auto rtti = dyn_cast<cir::GlobalViewAttr>(getAddrOfRTTIDescriptor(loc, ty));
162 assert(rtti &&
"expected GlobalViewAttr");
163 return CatchTypeInfo{rtti, 0};
166 bool doStructorsInitializeVPtrs(
const CXXRecordDecl *vtableClass)
override {
170 size_t getSrcArgforCopyCtor(
const CXXConstructorDecl *,
171 FunctionArgList &args)
const override {
172 assert(!args.empty() &&
"expected the arglist to not be empty!");
173 return args.size() - 1;
176 void emitBadCastCall(CIRGenFunction &cgf, mlir::Location loc)
override;
179 getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
180 Address thisAddr,
const CXXRecordDecl *classDecl,
181 const CXXRecordDecl *baseClassDecl)
override;
188 mlir::Value emitDynamicCast(CIRGenFunction &cgf, mlir::Location loc,
189 QualType srcRecordTy, QualType destRecordTy,
190 cir::PointerType destCIRTy,
bool isRefCast,
191 Address src)
override;
193 cir::MethodAttr buildVirtualMethodAttr(cir::MethodType methodTy,
194 const CXXMethodDecl *md)
override;
196 Address initializeArrayCookie(CIRGenFunction &cgf, Address newPtr,
197 mlir::Value numElements,
const CXXNewExpr *e,
198 QualType elementType)
override;
200 bool isZeroInitializable(
const MemberPointerType *MPT)
override;
203 CharUnits getArrayCookieSizeImpl(QualType elementType)
override;
208 virtual bool shouldRTTIBeUnique()
const {
return true; }
212 enum RTTIUniquenessKind {
230 classifyRTTIUniqueness(QualType canTy, cir::GlobalLinkageKind linkage)
const;
233 bool hasAnyUnusedVirtualInlineFunction(
const CXXRecordDecl *rd)
const;
234 bool isVTableHidden(
const CXXRecordDecl *rd)
const;
239void CIRGenItaniumCXXABI::emitInstanceFunctionProlog(
SourceLocation loc,
244 "emitInstanceFunctionProlog: Naked");
249 setCXXABIThisValue(cgf, loadIncomingCXXThis(cgf));
252 if (getStructorImplicitParamDecl(cgf)) {
256 setStructorImplicitParamValue(cgf, val);
267 if (hasThisReturn(cgf.
curGD)) {
269 "emitInstanceFunctionProlog: hasThisReturn");
273CIRGenCXXABI::AddedStructorArgCounts
274CIRGenItaniumCXXABI::buildStructorSignature(
275 GlobalDecl gd, llvm::SmallVectorImpl<CanQualType> &argTys) {
286 argTys.insert(argTys.begin() + 1,
289 return AddedStructorArgCounts::withPrefix(1);
292 return AddedStructorArgCounts{};
297enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
303 return StructorCIRGen::Emit;
308 return StructorCIRGen::Emit;
311 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(md)) {
321 return StructorCIRGen::RAUW;
325 return StructorCIRGen::RAUW;
331 return StructorCIRGen::COMDAT;
332 return StructorCIRGen::Emit;
335 return StructorCIRGen::Alias;
345 auto globalValue = dyn_cast_or_null<cir::CIRGlobalValueInterface>(
347 if (globalValue && !globalValue.isDeclaration())
350 auto entry = cast_or_null<cir::FuncOp>(cgm.
getGlobalValue(mangledName));
359void CIRGenItaniumCXXABI::emitCXXStructor(GlobalDecl gd) {
362 const auto *cd = dyn_cast<CXXConstructorDecl>(md);
366 GlobalDecl baseDecl =
370 if (cirGenType == StructorCIRGen::Alias ||
371 cirGenType == StructorCIRGen::COMDAT) {
376 if (cirGenType == StructorCIRGen::RAUW) {
389void CIRGenItaniumCXXABI::addImplicitStructorParams(CIRGenFunction &cgf,
391 FunctionArgList ¶ms) {
396 if (needsVTTParameter(cgf.
curGD)) {
403 astContext,
nullptr, md->getLocation(),
404 &astContext.
Idents.
get(
"vtt"), t, ImplicitParamKind::CXXVTT);
405 params.insert(params.begin() + 1, vttDecl);
406 getStructorImplicitParamDecl(cgf) = vttDecl;
410void CIRGenItaniumCXXABI::emitCXXConstructors(
const CXXConstructorDecl *d) {
426void CIRGenItaniumCXXABI::emitCXXDestructors(
const CXXDestructorDecl *d) {
442CIRGenCXXABI::AddedStructorArgs CIRGenItaniumCXXABI::getImplicitConstructorArgs(
444 bool forVirtualBase,
bool delegating) {
445 if (!needsVTTParameter(GlobalDecl(d,
type)))
446 return AddedStructorArgs{};
456 return AddedStructorArgs::withPrefix({{vtt, vttTy}});
462bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
466 if (!md->getParent()->getNumVBases())
480void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
481 const CXXRecordDecl *rd) {
482 cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
483 if (vtable.hasInitializer())
489 mlir::Attribute rtti =
500 vtable.setLinkage(linkage);
503 vtable.setComdat(
true);
518 "emitVTableDefinitions: __fundamental_type_info");
521 [[maybe_unused]]
auto vtableAsGlobalValue =
522 dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
523 assert(vtableAsGlobalValue &&
"VTable must support CIRGlobalValueInterface");
533 "emitVTableDefinitions: WholeProgramVTables");
542mlir::Value CIRGenItaniumCXXABI::emitVirtualDestructorCall(
543 CIRGenFunction &cgf,
const CXXDestructorDecl *dtor,
CXXDtorType dtorType,
544 Address thisAddr, DeleteOrMemberCallExpr
expr) {
545 auto *
callExpr = dyn_cast<const CXXMemberCallExpr *>(
expr);
546 auto *delExpr = dyn_cast<const CXXDeleteExpr *>(
expr);
547 assert((
callExpr !=
nullptr) ^ (delExpr !=
nullptr));
551 GlobalDecl globalDecl(dtor, dtorType);
552 const CIRGenFunctionInfo *fnInfo =
561 thisTy,
nullptr, QualType(),
nullptr);
565void CIRGenItaniumCXXABI::emitVirtualInheritanceTables(
566 const CXXRecordDecl *rd) {
573class CIRGenItaniumRTTIBuilder {
575 const CIRGenItaniumCXXABI &cxxABI;
578 SmallVector<mlir::Attribute, 16> fields;
581 cir::GlobalOp getAddrOfTypeName(mlir::Location loc, QualType ty,
582 cir::GlobalLinkageKind linkage);
585 mlir::Attribute getAddrOfExternalRTTIDescriptor(mlir::Location loc,
589 void buildVTablePointer(mlir::Location loc,
const Type *ty);
593 void buildSIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
598 void buildVMIClassTypeInfo(mlir::Location loc,
const CXXRecordDecl *rd);
602 void buildPointerTypeInfo(mlir::Location loc, QualType ty);
609 void buildPointerToMemberTypeInfo(mlir::Location loc,
610 const MemberPointerType *ty);
613 CIRGenItaniumRTTIBuilder(
const CIRGenItaniumCXXABI &abi, CIRGenModule &cgm)
614 : cgm(cgm), cxxABI(abi) {}
618 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty);
621 mlir::Attribute buildTypeInfo(mlir::Location loc, QualType ty,
622 cir::GlobalLinkageKind linkage,
623 mlir::SymbolTable::Visibility visibility);
642 PTI_Incomplete = 0x8,
646 PTI_ContainingClassIncomplete = 0x10,
658 VMI_NonDiamondRepeat = 0x1,
661 VMI_DiamondShaped = 0x2
676static bool typeInfoIsInStandardLibrary(
const BuiltinType *ty) {
692 case BuiltinType::WasmExternRef:
693 case BuiltinType::HLSLResource:
694 llvm_unreachable(
"NYI");
695 case BuiltinType::Void:
696 case BuiltinType::NullPtr:
697 case BuiltinType::Bool:
698 case BuiltinType::WChar_S:
699 case BuiltinType::WChar_U:
700 case BuiltinType::Char_U:
701 case BuiltinType::Char_S:
702 case BuiltinType::UChar:
703 case BuiltinType::SChar:
704 case BuiltinType::Short:
705 case BuiltinType::UShort:
706 case BuiltinType::Int:
707 case BuiltinType::UInt:
708 case BuiltinType::Long:
709 case BuiltinType::ULong:
710 case BuiltinType::LongLong:
711 case BuiltinType::ULongLong:
712 case BuiltinType::Half:
713 case BuiltinType::Float:
714 case BuiltinType::Double:
715 case BuiltinType::LongDouble:
716 case BuiltinType::Float16:
717 case BuiltinType::Float128:
718 case BuiltinType::Ibm128:
719 case BuiltinType::Char8:
720 case BuiltinType::Char16:
721 case BuiltinType::Char32:
722 case BuiltinType::Int128:
723 case BuiltinType::UInt128:
726#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
727 case BuiltinType::Id:
728#include "clang/Basic/OpenCLImageTypes.def"
729#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
730#include "clang/Basic/OpenCLExtensionTypes.def"
731 case BuiltinType::OCLSampler:
732 case BuiltinType::OCLEvent:
733 case BuiltinType::OCLClkEvent:
734 case BuiltinType::OCLQueue:
735 case BuiltinType::OCLReserveID:
736#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
737#include "clang/Basic/AArch64ACLETypes.def"
738#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
739#include "clang/Basic/PPCTypes.def"
740#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
741#include "clang/Basic/RISCVVTypes.def"
742#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
743#include "clang/Basic/AMDGPUTypes.def"
744 case BuiltinType::ShortAccum:
745 case BuiltinType::Accum:
746 case BuiltinType::LongAccum:
747 case BuiltinType::UShortAccum:
748 case BuiltinType::UAccum:
749 case BuiltinType::ULongAccum:
750 case BuiltinType::ShortFract:
751 case BuiltinType::Fract:
752 case BuiltinType::LongFract:
753 case BuiltinType::UShortFract:
754 case BuiltinType::UFract:
755 case BuiltinType::ULongFract:
756 case BuiltinType::SatShortAccum:
757 case BuiltinType::SatAccum:
758 case BuiltinType::SatLongAccum:
759 case BuiltinType::SatUShortAccum:
760 case BuiltinType::SatUAccum:
761 case BuiltinType::SatULongAccum:
762 case BuiltinType::SatShortFract:
763 case BuiltinType::SatFract:
764 case BuiltinType::SatLongFract:
765 case BuiltinType::SatUShortFract:
766 case BuiltinType::SatUFract:
767 case BuiltinType::SatULongFract:
768 case BuiltinType::BFloat16:
771 case BuiltinType::Dependent:
772#define BUILTIN_TYPE(Id, SingletonId)
773#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
774#include "clang/AST/BuiltinTypes.def"
775 llvm_unreachable(
"asking for RRTI for a placeholder type!");
777 case BuiltinType::ObjCId:
778 case BuiltinType::ObjCClass:
779 case BuiltinType::ObjCSel:
780 llvm_unreachable(
"FIXME: Objective-C types are unsupported!");
783 llvm_unreachable(
"Invalid BuiltinType Kind!");
786static bool typeInfoIsInStandardLibrary(
const PointerType *pointerTy) {
788 const auto *builtinTy = dyn_cast<BuiltinType>(pointeeTy);
799 return typeInfoIsInStandardLibrary(builtinTy);
804static bool isStandardLibraryRttiDescriptor(QualType ty) {
806 if (
const auto *builtinTy = dyn_cast<BuiltinType>(ty))
807 return typeInfoIsInStandardLibrary(builtinTy);
811 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
812 return typeInfoIsInStandardLibrary(pointerTy);
821static bool shouldUseExternalRttiDescriptor(CIRGenModule &cgm, QualType ty) {
829 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
842 bool isDLLImport = rd->
hasAttr<DLLImportAttr>();
852 return !isDLLImport || cgm.
getTriple().isWindowsItaniumEnvironment();
865 llvm::SmallPtrSet<const CXXRecordDecl *, 16> nonVirtualBases;
866 llvm::SmallPtrSet<const CXXRecordDecl *, 16> virtualBases;
871static unsigned computeVmiClassTypeInfoFlags(
const CXXBaseSpecifier *base,
879 if (!bases.virtualBases.insert(baseDecl).second) {
882 flags |= VMI_DiamondShaped;
884 if (bases.nonVirtualBases.count(baseDecl))
885 flags |= VMI_NonDiamondRepeat;
889 if (!bases.nonVirtualBases.insert(baseDecl).second) {
892 flags |= VMI_NonDiamondRepeat;
894 if (bases.virtualBases.count(baseDecl))
895 flags |= VMI_NonDiamondRepeat;
900 for (
const auto &bs : baseDecl->bases())
901 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
906static unsigned computeVmiClassTypeInfoFlags(
const CXXRecordDecl *rd) {
911 for (
const auto &bs : rd->
bases())
912 flags |= computeVmiClassTypeInfoFlags(&bs, bases);
921static bool canUseSingleInheritance(
const CXXRecordDecl *rd) {
939 return baseDecl->isEmpty() ||
944static bool isIncompleteClassType(
const RecordType *recordTy) {
945 return !recordTy->getDecl()->getDefinitionOrSelf()->isCompleteDefinition();
959static bool containsIncompleteClassType(QualType ty) {
960 if (
const auto *recordTy = dyn_cast<RecordType>(ty)) {
961 if (isIncompleteClassType(recordTy))
965 if (
const auto *pointerTy = dyn_cast<PointerType>(ty))
968 if (
const auto *memberPointerTy = dyn_cast<MemberPointerType>(ty)) {
970 if (!memberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
973 return containsIncompleteClassType(memberPointerTy->getPointeeType());
985 flags |= PTI_Volatile;
987 flags |= PTI_Restrict;
991 if (containsIncompleteClassType(ty))
992 flags |= PTI_Incomplete;
994 if (
const auto *proto = ty->
getAs<FunctionProtoType>()) {
995 if (proto->isNothrow()) {
996 flags |= PTI_Noexcept;
1004const char *vTableClassNameForType(
const CIRGenModule &cgm,
const Type *ty) {
1006 static const char *
const classTypeInfo =
1007 "_ZTVN10__cxxabiv117__class_type_infoE";
1009 static const char *
const siClassTypeInfo =
1010 "_ZTVN10__cxxabiv120__si_class_type_infoE";
1012 static const char *
const vmiClassTypeInfo =
1013 "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
1016#define TYPE(Class, Base)
1017#define ABSTRACT_TYPE(Class, Base)
1018#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1019#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1020#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1021#include "clang/AST/TypeNodes.inc"
1022 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1024 case Type::LValueReference:
1025 case Type::RValueReference:
1026 llvm_unreachable(
"References shouldn't get here");
1029 case Type::DeducedTemplateSpecialization:
1030 llvm_unreachable(
"Undeduced type shouldn't get here");
1033 llvm_unreachable(
"Pipe types shouldn't get here");
1035 case Type::ArrayParameter:
1036 llvm_unreachable(
"Array Parameter types should not get here.");
1040 case Type::OverflowBehavior:
1043 case Type::ExtVector:
1044 case Type::ConstantMatrix:
1048 case Type::BlockPointer:
1049 return "_ZTVN10__cxxabiv123__fundamental_type_infoE";
1050 case Type::ConstantArray:
1051 case Type::IncompleteArray:
1052 case Type::VariableArray:
1054 return "_ZTVN10__cxxabiv117__array_type_infoE";
1056 case Type::FunctionNoProto:
1057 case Type::FunctionProto:
1059 return "_ZTVN10__cxxabiv120__function_type_infoE";
1062 return "_ZTVN10__cxxabiv116__enum_type_infoE";
1064 case Type::Record: {
1066 ->getDefinitionOrSelf();
1069 return classTypeInfo;
1072 if (canUseSingleInheritance(rd)) {
1073 return siClassTypeInfo;
1076 return vmiClassTypeInfo;
1079 case Type::ObjCObject:
1080 cgm.
errorNYI(
"VTableClassNameForType: ObjCObject");
1083 case Type::ObjCInterface:
1084 cgm.
errorNYI(
"VTableClassNameForType: ObjCInterface");
1087 case Type::ObjCObjectPointer:
1090 return "_ZTVN10__cxxabiv119__pointer_type_infoE";
1092 case Type::MemberPointer:
1094 return "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
1096 case Type::HLSLAttributedResource:
1097 case Type::HLSLInlineSpirv:
1098 llvm_unreachable(
"HLSL doesn't support virtual functions");
1117 if (containsIncompleteClassType(ty))
1118 return cir::GlobalLinkageKind::InternalLinkage;
1122 llvm_unreachable(
"Linkage hasn't been computed!");
1127 return cir::GlobalLinkageKind::InternalLinkage;
1135 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1137 if (
const RecordType *record = dyn_cast<RecordType>(ty)) {
1141 return cir::GlobalLinkageKind::WeakODRLinkage;
1143 if (cgm.
getTriple().isWindowsItaniumEnvironment())
1144 if (rd->
hasAttr<DLLImportAttr>() &&
1145 shouldUseExternalRttiDescriptor(cgm, ty))
1146 return cir::GlobalLinkageKind::ExternalLinkage;
1152 .isWindowsGNUEnvironment())
1156 return cir::GlobalLinkageKind::LinkOnceODRLinkage;
1159 llvm_unreachable(
"Invalid linkage!");
1163CIRGenItaniumRTTIBuilder::getAddrOfTypeName(mlir::Location loc, QualType ty,
1164 cir::GlobalLinkageKind linkage) {
1166 SmallString<256>
name;
1167 llvm::raw_svector_ostream
out(name);
1173 mlir::Attribute init = builder.
getString(
1186 loc, name, initStr.getType(), linkage, align);
1192CIRGenItaniumRTTIBuilder::getAddrOfExternalRTTIDescriptor(mlir::Location loc,
1195 SmallString<256>
name;
1196 llvm::raw_svector_ostream
out(name);
1201 cir::GlobalOp gv = dyn_cast_or_null<cir::GlobalOp>(
1202 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1217 cgm.
errorNYI(
"getAddrOfExternalRTTIDescriptor: hasPS4DLLImportExport");
1224void CIRGenItaniumRTTIBuilder::buildVTablePointer(mlir::Location loc,
1227 const char *vTableName = vTableClassNameForType(cgm, ty);
1231 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1238 loc, vTableName, vtableGlobalTy, cir::GlobalLinkageKind::ExternalLinkage,
1242 mlir::Attribute field{};
1244 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1246 SmallVector<mlir::Attribute, 4> offsets{
1248 auto indices = mlir::ArrayAttr::get(builder.getContext(), offsets);
1253 assert(field &&
"expected attribute");
1254 fields.push_back(field);
1259void CIRGenItaniumRTTIBuilder::buildSIClassTypeInfo(mlir::Location loc,
1260 const CXXRecordDecl *rd) {
1264 mlir::Attribute baseTypeInfo =
1265 CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1267 fields.push_back(baseTypeInfo);
1273void CIRGenItaniumRTTIBuilder::buildVMIClassTypeInfo(mlir::Location loc,
1274 const CXXRecordDecl *rd) {
1275 mlir::Type unsignedIntLTy =
1282 unsigned flags = computeVmiClassTypeInfoFlags(rd);
1283 fields.push_back(cir::IntAttr::get(unsignedIntLTy, flags));
1288 fields.push_back(cir::IntAttr::get(unsignedIntLTy, rd->
getNumBases()));
1321 mlir::Type offsetFlagsLTy = cgm.
convertType(offsetFlagsTy);
1323 for (
const CXXBaseSpecifier &base : rd->
bases()) {
1325 fields.push_back(CIRGenItaniumRTTIBuilder(cxxABI, cgm)
1326 .buildTypeInfo(loc, base.
getType()));
1340 const ASTRecordLayout &layout =
1349 offsetFlags |= BCTI_Virtual;
1351 offsetFlags |= BCTI_Public;
1353 fields.push_back(cir::IntAttr::get(offsetFlagsLTy, offsetFlags));
1357void CIRGenItaniumRTTIBuilder::buildPointerTypeInfo(mlir::Location loc,
1381 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1382 fields.push_back(flagsAttr);
1384 mlir::Attribute pointeeTypeInfo =
1385 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, ty);
1386 fields.push_back(pointeeTypeInfo);
1389void CIRGenItaniumRTTIBuilder::buildPointerToMemberTypeInfo(
1390 mlir::Location loc,
const MemberPointerType *ty) {
1405 flags |= PTI_ContainingClassIncomplete;
1408 mlir::Attribute flagsAttr = cir::IntAttr::get(unsignedIntTy, flags);
1409 fields.push_back(flagsAttr);
1411 mlir::Attribute pointeeTypeInfo =
1412 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, pointeeTy);
1413 fields.push_back(pointeeTypeInfo);
1416 mlir::Attribute classTypeInfo =
1417 CIRGenItaniumRTTIBuilder(cxxABI, cgm).buildTypeInfo(loc, contextTy);
1418 fields.push_back(classTypeInfo);
1421mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(mlir::Location loc,
1427 SmallString<256>
name;
1428 llvm::raw_svector_ostream
out(name);
1431 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1432 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1434 if (oldGV && !oldGV.isDeclaration()) {
1435 assert(!oldGV.hasAvailableExternallyLinkage() &&
1436 "available_externally typeinfos not yet implemented");
1442 if (isStandardLibraryRttiDescriptor(ty) ||
1443 shouldUseExternalRttiDescriptor(cgm, ty))
1444 return getAddrOfExternalRTTIDescriptor(loc, ty);
1454 mlir::SymbolTable::Visibility symVisibility;
1457 symVisibility = mlir::SymbolTable::Visibility::Public;
1458 else if (cxxABI.classifyRTTIUniqueness(ty, linkage) ==
1459 CIRGenItaniumCXXABI::RUK_NonUniqueHidden) {
1461 "buildTypeInfo: classifyRTTIUniqueness == RUK_NonUniqueHidden");
1466 return buildTypeInfo(loc, ty, linkage, symVisibility);
1469mlir::Attribute CIRGenItaniumRTTIBuilder::buildTypeInfo(
1470 mlir::Location loc, QualType ty, cir::GlobalLinkageKind linkage,
1471 mlir::SymbolTable::Visibility visibility) {
1480 cir::GlobalOp typeName = getAddrOfTypeName(loc, ty, linkage);
1481 mlir::Attribute typeNameField;
1485 CIRGenItaniumCXXABI::RTTIUniquenessKind rttiUniqueness =
1486 cxxABI.classifyRTTIUniqueness(ty, linkage);
1487 if (rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique) {
1491 "buildTypeInfo: rttiUniqueness != CIRGenItaniumCXXABI::RUK_Unique");
1497 fields.push_back(typeNameField);
1500#define TYPE(Class, Base)
1501#define ABSTRACT_TYPE(Class, Base)
1502#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
1503#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
1504#define DEPENDENT_TYPE(Class, Base) case Type::Class:
1505#include "clang/AST/TypeNodes.inc"
1506 llvm_unreachable(
"Non-canonical and dependent types shouldn't get here");
1511 case Type::ExtVector:
1512 case Type::ConstantMatrix:
1514 case Type::BlockPointer:
1519 case Type::LValueReference:
1520 case Type::RValueReference:
1521 llvm_unreachable(
"References shouldn't get here");
1524 case Type::DeducedTemplateSpecialization:
1525 llvm_unreachable(
"Undeduced type shouldn't get here");
1533 case Type::OverflowBehavior:
1536 case Type::ConstantArray:
1537 case Type::IncompleteArray:
1538 case Type::VariableArray:
1539 case Type::ArrayParameter:
1544 case Type::FunctionNoProto:
1545 case Type::FunctionProto:
1555 case Type::Record: {
1557 ->getDefinitionOrSelf();
1563 if (canUseSingleInheritance(rd)) {
1564 buildSIClassTypeInfo(loc, rd);
1566 buildVMIClassTypeInfo(loc, rd);
1572 case Type::ObjCObject:
1573 case Type::ObjCInterface:
1574 cgm.
errorNYI(
"buildTypeInfo: ObjCObject & ObjCInterface");
1577 case Type::ObjCObjectPointer:
1578 cgm.
errorNYI(
"buildTypeInfo: ObjCObjectPointer");
1586 case Type::MemberPointer:
1594 case Type::HLSLAttributedResource:
1595 case Type::HLSLInlineSpirv:
1596 llvm_unreachable(
"HLSL doesn't support RTTI");
1600 cir::TypeInfoAttr init = builder.
getTypeInfo(builder.getArrayAttr(fields));
1602 SmallString<256>
name;
1603 llvm::raw_svector_ostream
out(name);
1607 auto oldGV = dyn_cast_or_null<cir::GlobalOp>(
1608 mlir::SymbolTable::lookupSymbolIn(cgm.
getModule(), name));
1617 cgm.
errorNYI(
"buildTypeInfo: target hasPS4DLLImportExport");
1624 gv.setName(oldGV.getName());
1625 if (!oldGV->use_empty()) {
1626 cgm.
errorNYI(
"buildTypeInfo: old GV !use_empty");
1634 cgm.
errorNYI(
"buildTypeInfo: supportsCOMDAT & isWeakForLinker");
1640 gv.setAlignmentAttr(cgm.
getSize(align));
1657 mlir::SymbolTable::setSymbolVisibility(typeName, visibility);
1662 mlir::SymbolTable::setSymbolVisibility(gv, visibility);
1671bool CIRGenItaniumCXXABI::shouldTypeidBeNullChecked(QualType srcTy) {
1675void CIRGenItaniumCXXABI::emitBadTypeidCall(CIRGenFunction &cgf,
1676 mlir::Location loc) {
1678 cir::FuncType fnTy =
1680 mlir::NamedAttrList attrs;
1681 attrs.set(cir::CIRDialect::getNoReturnAttrName(),
1687 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
1690mlir::Value CIRGenItaniumCXXABI::emitTypeid(CIRGenFunction &cgf, QualType srcTy,
1692 mlir::Type typeInfoPtrTy) {
1694 mlir::Location loc = cgm.
getLoc(classDecl->getSourceRange());
1695 mlir::Value vptr = cgf.
getVTablePtr(loc, thisPtr, classDecl);
1703 cgm.
errorNYI(
"buildVTablePointer: isRelativeLayout");
1705 vtbl = cir::VTableGetTypeInfoOp::create(
1713mlir::Attribute CIRGenItaniumCXXABI::getAddrOfRTTIDescriptor(mlir::Location loc,
1715 return CIRGenItaniumRTTIBuilder(*
this, cgm).buildTypeInfo(loc, ty);
1720CIRGenItaniumCXXABI::RTTIUniquenessKind
1721CIRGenItaniumCXXABI::classifyRTTIUniqueness(
1722 QualType canTy, cir::GlobalLinkageKind linkage)
const {
1723 if (shouldRTTIBeUnique())
1727 if (linkage != cir::GlobalLinkageKind::LinkOnceODRLinkage &&
1728 linkage != cir::GlobalLinkageKind::WeakODRLinkage)
1736 if (linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
1737 return RUK_NonUniqueHidden;
1742 assert(linkage == cir::GlobalLinkageKind::WeakODRLinkage);
1743 return RUK_NonUniqueVisible;
1746void CIRGenItaniumCXXABI::emitDestructorCall(
1748 bool forVirtualBase,
bool delegating, Address thisAddr, QualType thisTy) {
1749 GlobalDecl gd(dd,
type);
1755 CIRGenCallee callee =
1762void CIRGenItaniumCXXABI::registerGlobalDtor(
const VarDecl *vd,
1783mlir::Value CIRGenItaniumCXXABI::getCXXDestructorImplicitParam(
1785 bool forVirtualBase,
bool delegating) {
1786 GlobalDecl gd(dd,
type);
1794 mlir::Value exceptionPtr = {},
1795 mlir::FlatSymbolRefAttr typeInfo = {},
1796 mlir::FlatSymbolRefAttr dtor = {}) {
1797 mlir::Block *currentBlock = builder.getInsertionBlock();
1798 mlir::Region *region = currentBlock->getParent();
1800 if (currentBlock->empty()) {
1801 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1802 cir::UnreachableOp::create(builder, loc);
1804 mlir::Block *throwBlock = builder.createBlock(region);
1806 cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
1807 cir::UnreachableOp::create(builder, loc);
1809 builder.setInsertionPointToEnd(currentBlock);
1810 cir::BrOp::create(builder, loc, throwBlock);
1813 (void)builder.createBlock(region);
1816void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf,
bool isNoReturn) {
1820 assert(cgf.
currSrcLoc &&
"expected source location");
1824 cgm.
errorNYI(
"emitRethrow with isNoReturn false");
1828void CIRGenItaniumCXXABI::emitThrow(CIRGenFunction &cgf,
1829 const CXXThrowExpr *e) {
1837 cir::PointerType throwTy =
1844 mlir::TypedValue<cir::PointerType> exceptionPtr =
1845 cir::AllocExceptionOp::create(builder, subExprLoc, throwTy,
1846 builder.getI64IntegerAttr(typeSize))
1854 auto typeInfo = mlir::cast<cir::GlobalViewAttr>(
1857 assert(!typeInfo.getIndices() &&
"expected no indirection");
1867 mlir::FlatSymbolRefAttr dtor{};
1868 if (cxxrd && !cxxrd->hasTrivialDestructor()) {
1873 CXXDestructorDecl *dtorD = cxxrd->getDestructor();
1874 dtor = mlir::FlatSymbolRefAttr::get(
1886 case TargetCXXABI::GenericItanium:
1887 case TargetCXXABI::GenericAArch64:
1888 return new CIRGenItaniumCXXABI(cgm);
1890 case TargetCXXABI::AppleARM64:
1894 return new CIRGenItaniumCXXABI(cgm);
1897 llvm_unreachable(
"bad or NYI ABI kind");
1901cir::GlobalOp CIRGenItaniumCXXABI::getAddrOfVTable(
const CXXRecordDecl *rd,
1903 assert(vptrOffset.
isZero() &&
"Itanium ABI only supports zero vptr offsets");
1904 cir::GlobalOp &vtable = vtables[rd];
1912 llvm::raw_svector_ostream
out(name);
1913 getMangleContext().mangleCXXVTable(rd,
out);
1922 unsigned ptrAlign = cgm.
getLangOpts().RelativeCXXABIVTables
1928 cir::GlobalLinkageKind::ExternalLinkage,
1942 "getAddrOfVTable: PS4 DLL import/export");
1948CIRGenCallee CIRGenItaniumCXXABI::getVirtualFunctionPointer(
1952 mlir::Location loc = cgf.
getLoc(srcLoc);
1955 mlir::Value vtable = cgf.
getVTablePtr(loc, thisAddr, methodDecl->getParent());
1958 mlir::Value vfunc{};
1960 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: emitVTableTypeCheckedLoad");
1964 mlir::Value vfuncLoad;
1967 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: isRelativeLayout");
1969 auto vtableSlotPtr = cir::VTableGetVirtualFnAddrOp::create(
1970 builder, loc, builder.
getPointerTo(tyPtr), vtable, vtableIndex);
1983 cgm.
errorNYI(loc,
"getVirtualFunctionPointer: strictVTablePointers");
1988 CIRGenCallee callee(gd, vfunc.getDefiningOp());
1992mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
1993 CIRGenFunction &cgf,
const CXXRecordDecl *vtableClass, BaseSubobject base,
1994 const CXXRecordDecl *nearestVBase) {
1996 needsVTTParameter(cgf.
curGD) &&
"This class doesn't have VTT");
2007 virtualPointerIndex);
2009 auto vptrType = cir::VPtrType::get(cgf.
getBuilder().getContext());
2015CIRGenItaniumCXXABI::getVTableAddressPoint(BaseSubobject base,
2016 const CXXRecordDecl *vtableClass) {
2017 cir::GlobalOp vtable = getAddrOfVTable(vtableClass, CharUnits());
2021 VTableLayout::AddressPointLocation addressPoint =
2027 auto vtablePtrTy = cir::VPtrType::get(builder.getContext());
2029 return cir::VTableAddrPointOp::create(
2031 mlir::FlatSymbolRefAttr::get(vtable.getSymNameAttr()),
2032 cir::AddressPointAttr::get(cgm.
getBuilder().getContext(),
2037mlir::Value CIRGenItaniumCXXABI::getVTableAddressPointInStructor(
2038 CIRGenFunction &cgf,
const clang::CXXRecordDecl *vtableClass,
2039 clang::BaseSubobject base,
const clang::CXXRecordDecl *nearestVBase) {
2042 needsVTTParameter(cgf.
curGD)) {
2043 return getVTableAddressPointInStructorWithVTT(cgf, vtableClass, base,
2046 return getVTableAddressPoint(base, vtableClass);
2049bool CIRGenItaniumCXXABI::isVirtualOffsetNeededForVTableField(
2050 CIRGenFunction &cgf, CIRGenFunction::VPtr vptr) {
2053 return needsVTTParameter(cgf.
curGD);
2056mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset(
2057 mlir::Location loc, CIRGenFunction &cgf, Address thisAddr,
2058 const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) {
2060 mlir::Value vtablePtr = cgf.
getVTablePtr(loc, thisAddr, classDecl);
2062 CharUnits vbaseOffsetOffset =
2065 mlir::Value offsetVal =
2067 auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.
uInt8PtrTy,
2068 vtableBytePtr, offsetVal);
2070 mlir::Value vbaseOffset;
2073 cgm.
errorNYI(loc,
"getVirtualBaseClassOffset: relative layout");
2089 cir::FuncType fnTy =
2099 cir::UnreachableOp::create(cgf.
getBuilder(), loc);
2103void CIRGenItaniumCXXABI::emitBadCastCall(CIRGenFunction &cgf,
2104 mlir::Location loc) {
2120 unsigned numPublicPaths = 0;
2133 if (pathElement.Base->isVirtual())
2136 if (numPublicPaths > 1)
2143 pathElement.Base->getType()->getAsCXXRecordDecl());
2148 if (numPublicPaths == 0)
2152 if (numPublicPaths > 1)
2179 {voidPtrTy, rttiPtrTy, rttiPtrTy, ptrDiffTy}, voidPtrTy);
2181 fn->setAttr(cir::CIRDialect::getNoThrowAttrName(),
2182 mlir::UnitAttr::get(cgf.
getBuilder().getContext()));
2188 bool vtableUsesRelativeLayout = cgf.
cgm.
getLangOpts().RelativeCXXABIVTables;
2190 loc, src.
getPointer(), vtableUsesRelativeLayout);
2198 cir::PointerType destCIRTy,
2199 bool isRefCast,
Address src) {
2209 std::optional<CharUnits> offset;
2219 pathElement.Base->getType()->getAsCXXRecordDecl();
2220 if (pathElement.Base->isVirtual()) {
2234 offset = pathOffset;
2235 }
else if (offset != pathOffset) {
2251 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2253 mlir::Region *currentRegion = builder.getBlock()->getParent();
2258 builder.createBlock(currentRegion, currentRegion->end());
2261 return nullPtrValue;
2269 mlir::Value expectedVPtr =
2270 abi.getVTableAddressPoint(
BaseSubobject(srcDecl, *offset), destDecl);
2274 mlir::Type vptrTy = expectedVPtr.getType();
2278 mlir::Value srcVPtr = builder.
createLoad(loc, srcVPtrPtr);
2283 mlir::Value success =
2284 builder.
createCompare(loc, cir::CmpOpKind::eq, srcVPtr, expectedVPtr);
2286 auto emitCastResult = [&] {
2287 if (offset->isZero())
2294 mlir::Value strideToApply =
2297 mlir::Value resultU8Ptr = cir::PtrStrideOp::create(builder, loc, u8PtrTy,
2298 srcU8Ptr, strideToApply);
2303 mlir::Value failed = builder.
createNot(success);
2304 cir::IfOp::create(builder, loc, failed,
false,
2305 [&](mlir::OpBuilder &, mlir::Location) {
2308 return emitCastResult();
2311 return cir::TernaryOp::create(
2312 builder, loc, success,
2313 [&](mlir::OpBuilder &, mlir::Location) {
2314 auto result = emitCastResult();
2317 [&](mlir::OpBuilder &, mlir::Location) {
2318 mlir::Value nullPtrValue = builder.
getNullPtr(destCIRTy, loc);
2328 auto srcRtti = mlir::cast<cir::GlobalViewAttr>(
2330 auto destRtti = mlir::cast<cir::GlobalViewAttr>(
2335 auto runtimeFuncRef = mlir::FlatSymbolRefAttr::get(runtimeFuncOp);
2336 auto badCastFuncRef = mlir::FlatSymbolRefAttr::get(badCastFuncOp);
2343 auto offsetHintAttr = cir::IntAttr::get(ptrdiffTy, offsetHint.
getQuantity());
2345 return cir::DynamicCastInfoAttr::get(srcRtti, destRtti, runtimeFuncRef,
2346 badCastFuncRef, offsetHintAttr);
2349mlir::Value CIRGenItaniumCXXABI::emitDynamicCast(CIRGenFunction &cgf,
2351 QualType srcRecordTy,
2352 QualType destRecordTy,
2353 cir::PointerType destCIRTy,
2354 bool isRefCast, Address src) {
2355 bool isCastToVoid = destRecordTy.
isNull();
2356 assert((!isCastToVoid || !isRefCast) &&
"cannot cast to void reference");
2369 return cir::TernaryOp::create(
2370 builder, loc, srcPtrIsNull,
2371 [&](mlir::OpBuilder, mlir::Location) {
2373 loc, builder.
getNullPtr(destCIRTy, loc).getResult());
2375 [&](mlir::OpBuilder &, mlir::Location) {
2377 *
this, cgf, loc, srcRecordTy, destRecordTy, destCIRTy,
2385 destCIRTy, isRefCast, src);
2388 cir::DynamicCastInfoAttr castInfo =
2391 isRefCast, castInfo);
2395CIRGenItaniumCXXABI::buildVirtualMethodAttr(cir::MethodType methodTy,
2396 const CXXMethodDecl *md) {
2397 assert(md->
isVirtual() &&
"only deal with virtual member functions");
2403 vtableOffset = index * 4;
2408 vtableOffset = index * pointerWidth.
getQuantity();
2411 return cir::MethodAttr::get(methodTy, vtableOffset);
2415void CIRGenItaniumCXXABI::emitVirtualObjectDelete(
2416 CIRGenFunction &cgf,
const CXXDeleteExpr *delExpr, Address ptr,
2417 QualType elementType,
const CXXDestructorDecl *dtor) {
2419 if (useGlobalDelete) {
2421 "emitVirtualObjectDelete: global delete");
2425 emitVirtualDestructorCall(cgf, dtor, dtorType, ptr, delExpr);
2430CharUnits CIRGenItaniumCXXABI::getArrayCookieSizeImpl(QualType elementType) {
2438Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf,
2440 mlir::Value numElements,
2441 const CXXNewExpr *e,
2442 QualType elementType) {
2443 assert(requiresArrayCookie(e));
2455 CharUnits cookieSize =
2457 assert(cookieSize == getArrayCookieSizeImpl(elementType));
2460 mlir::Value baseBytePtr =
2464 CharUnits cookieOffset = cookieSize - sizeSize;
2465 mlir::Value cookiePtrValue = baseBytePtr;
2466 if (!cookieOffset.
isZero()) {
2475 Address cookiePtr(cookiePtrValue, u8PtrTy, cookiePtrAlignment);
2484 mlir::Value dataOffset =
2487 mlir::Value dataPtr =
2489 mlir::Value finalPtr =
2509struct CallEndCatch final : EHScopeStack::Cleanup {
2510 CallEndCatch(
bool mightThrow, mlir::Value catchToken)
2511 : mightThrow(mightThrow), catchToken(catchToken) {}
2513 mlir::Value catchToken;
2515 void emit(CIRGenFunction &cgf, Flags flags)
override {
2527 mlir::Type exnPtrTy,
bool endMightThrow) {
2528 auto catchTokenTy = cir::CatchTokenType::get(cgf.
getBuilder().getContext());
2529 auto beginCatch = cir::BeginCatchOp::create(cgf.
getBuilder(),
2531 catchTokenTy, exnPtrTy, ehToken);
2533 cgf.
ehStack.pushCleanup<CallEndCatch>(
2535 endMightThrow && !cgf.
cgm.
getLangOpts().AssumeNothrowExceptionDtor,
2536 beginCatch.getCatchToken());
2538 return beginCatch.getExnPtr();
2556 mlir::Value adjustedExn =
2562 if (
const PointerType *pt = dyn_cast<PointerType>(caughtType)) {
2568 "initCatchParam: catching a pointer of non-record");
2584 mlir::Value exnCast =
2596 if (catchType->hasPointerRepresentation()) {
2597 mlir::Value catchParam =
2602 "initCatchParam: PointerRepresentation OCL_Strong");
2607 cgf.
cgm.
errorNYI(loc,
"initCatchParam: PointerRepresentation "
2608 "OCL_ExplicitNone & OCL_Autoreleasing");
2616 cgf.
cgm.
errorNYI(loc,
"initCatchParam: PointerRepresentation OCL_Weak");
2620 llvm_unreachable(
"bad ownership qualifier!");
2625 mlir::Value catchParam =
2642 llvm_unreachable(
"evaluation kind filtered out!");
2645 llvm_unreachable(
"bad evaluation kind");
2649 auto *catchRD = catchType->getAsCXXRecordDecl();
2657 mlir::Value rawAdjustedExn =
2659 Address adjustedExn(rawAdjustedExn, cirCatchTy, caughtExnAlignment);
2666 cgf.
cgm.
errorNYI(loc,
"initCatchParam: cir::TEK_Aggregate non-trivial copy");
2671void CIRGenItaniumCXXABI::emitBeginCatch(CIRGenFunction &cgf,
2672 const CXXCatchStmt *catchStmt,
2673 mlir::Value ehToken) {
2704 auto getCatchParamAllocaIP = [&]() {
2705 cir::CIRBaseBuilderTy::InsertPoint currIns =
2707 mlir::Operation *currParent = currIns.getBlock()->getParentOp();
2709 mlir::Block *insertBlock =
nullptr;
2710 if (
auto scopeOp = currParent->getParentOfType<cir::ScopeOp>()) {
2711 insertBlock = &scopeOp.getScopeRegion().getBlocks().back();
2712 }
else if (
auto fnOp = currParent->getParentOfType<cir::FuncOp>()) {
2713 insertBlock = &fnOp.getRegion().getBlocks().back();
2715 llvm_unreachable(
"unknown outermost scope-like parent");
2724 CIRGenFunction::AutoVarEmission
var =
2731bool CIRGenItaniumCXXABI::hasAnyUnusedVirtualInlineFunction(
2732 const CXXRecordDecl *rd)
const {
2735 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2737 if (!vtableComponent.isUsedFunctionPointerKind())
2740 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2742 const bool isInlined =
2748 vtableComponent.getGlobalDecl(
false));
2749 auto entry = dyn_cast_or_null<cir::GlobalOp>(cgm.
getGlobalValue(name));
2755 if (!entry || entry.isDeclaration())
2761bool CIRGenItaniumCXXABI::isVTableHidden(
const CXXRecordDecl *rd)
const {
2764 for (
const auto &vtableComponent : vtableLayout.vtable_components()) {
2765 if (vtableComponent.isRTTIKind()) {
2766 const CXXRecordDecl *rttiDecl = vtableComponent.getRTTIDecl();
2767 if (rttiDecl->
getVisibility() == Visibility::HiddenVisibility)
2769 }
else if (vtableComponent.isUsedFunctionPointerKind()) {
2770 const CXXMethodDecl *method = vtableComponent.getFunctionDecl();
2771 if (method->
getVisibility() == Visibility::HiddenVisibility &&
2779bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTableAsBaseClass(
2780 const CXXRecordDecl *rd)
const {
2788 if (isVTableHidden(rd))
2808 if (hasAnyUnusedVirtualInlineFunction(rd))
2816 for (
const auto &
b : rd->
bases()) {
2817 auto *brd =
b.getType()->getAsCXXRecordDecl();
2818 assert(brd &&
"no class for base specifier");
2819 if (
b.isVirtual() || !brd->isDynamicClass())
2821 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2829bool CIRGenItaniumCXXABI::canSpeculativelyEmitVTable(
2830 const CXXRecordDecl *rd)
const {
2831 if (!canSpeculativelyEmitVTableAsBaseClass(rd))
2839 for (
const auto &
b : rd->
vbases()) {
2840 auto *brd =
b.getType()->getAsCXXRecordDecl();
2841 assert(brd &&
"no class for base specifier");
2842 if (!brd->isDynamicClass())
2844 if (!canSpeculativelyEmitVTableAsBaseClass(brd))
2854 int64_t nonVirtualAdjustment,
2855 int64_t virtualAdjustment,
2856 bool isReturnAdjustment) {
2857 if (!nonVirtualAdjustment && !virtualAdjustment)
2861 mlir::Location loc = builder.getUnknownLoc();
2866 if (nonVirtualAdjustment && !isReturnAdjustment) {
2867 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2868 v = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offsetConst);
2872 mlir::Value resultPtr;
2873 if (virtualAdjustment) {
2879 mlir::Value offsetPtr =
2880 cir::PtrStrideOp::create(builder, loc, i8PtrTy, vtablePtr,
2881 builder.
getSInt64(virtualAdjustment, loc));
2884 cgf.
cgm.
errorNYI(
"virtual adjustment for relative layout vtables");
2890 resultPtr = cir::PtrStrideOp::create(builder, loc, i8PtrTy, v, offset);
2897 if (nonVirtualAdjustment && isReturnAdjustment) {
2898 cir::ConstantOp offsetConst = builder.
getSInt64(nonVirtualAdjustment, loc);
2900 cir::PtrStrideOp::create(builder, loc, i8PtrTy, resultPtr, offsetConst);
2907mlir::Value CIRGenItaniumCXXABI::performThisAdjustment(
2908 CIRGenFunction &cgf, Address thisAddr,
const CXXRecordDecl *unadjustedClass,
2909 const ThunkInfo &ti) {
2916mlir::Value CIRGenItaniumCXXABI::performReturnAdjustment(
2917 CIRGenFunction &cgf, Address ret,
const CXXRecordDecl *unadjustedClass,
2918 const ReturnAdjustment &ra) {
2924bool CIRGenItaniumCXXABI::isZeroInitializable(
const MemberPointerType *mpt) {
static void emit(Program &P, llvm::SmallVectorImpl< std::byte > &Code, const T &Val, bool &Success)
Helper to write bytecode and bail out if 32-bit offsets become invalid.
static void emitConstructorDestructorAlias(CIRGenModule &cgm, GlobalDecl aliasDecl, GlobalDecl targetDecl)
static CharUnits computeOffsetHint(ASTContext &astContext, const CXXRecordDecl *src, const CXXRecordDecl *dst)
static void insertThrowAndSplit(mlir::OpBuilder &builder, mlir::Location loc, mlir::Value exceptionPtr={}, mlir::FlatSymbolRefAttr typeInfo={}, mlir::FlatSymbolRefAttr dtor={})
static mlir::Value callBeginCatch(CIRGenFunction &cgf, mlir::Value ehToken, mlir::Type exnPtrTy, bool endMightThrow)
static Address emitDynamicCastToVoid(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, Address src)
static cir::DynamicCastInfoAttr emitDynamicCastInfo(CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy)
static cir::GlobalLinkageKind getTypeInfoLinkage(CIRGenModule &cgm, QualType ty)
Return the linkage that the type info and type info name constants should have for the given type.
static mlir::Value performTypeAdjustment(CIRGenFunction &cgf, Address initialPtr, const CXXRecordDecl *unadjustedClass, int64_t nonVirtualAdjustment, int64_t virtualAdjustment, bool isReturnAdjustment)
static mlir::Value emitExactDynamicCast(CIRGenItaniumCXXABI &abi, CIRGenFunction &cgf, mlir::Location loc, QualType srcRecordTy, QualType destRecordTy, cir::PointerType destCIRTy, bool isRefCast, Address src)
static void emitCallToBadCast(CIRGenFunction &cgf, mlir::Location loc)
static void initCatchParam(CIRGenFunction &cgf, mlir::Value ehToken, const VarDecl &catchParam, Address paramAddr, SourceLocation loc)
A "special initializer" callback for initializing a catch parameter during catch initialization.
static cir::FuncOp getItaniumDynamicCastFn(CIRGenFunction &cgf)
static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm, const CXXMethodDecl *md)
static cir::FuncOp getBadCastFn(CIRGenFunction &cgf)
static RValue performReturnAdjustment(CIRGenFunction &cgf, QualType resultType, RValue rv, const ThunkInfo &thunk)
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)
static OpBuilder::InsertPoint getBestAllocaInsertPoint(mlir::Block *block)
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
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 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::TypeInfoAttr getTypeInfo(mlir::ArrayAttr fieldsAttr)
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc)
cir::PointerType getUInt8PtrTy()
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={})
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)
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={})
cir::AllocaOp createTempAlloca(mlir::Type ty, mlir::Location loc, const Twine &name="tmp", mlir::Value arraySize=nullptr, bool insertIntoFnEntryBlock=false)
This creates an alloca and inserts it into the entry block if ArraySize is nullptr,...
const clang::Decl * curFuncDecl
Address getAddrOfLocalVar(const clang::VarDecl *vd)
Return the address of a local variable.
void emitAnyExprToExn(const Expr *e, Address addr)
void emitAggregateCopy(LValue dest, LValue src, QualType eltTy, AggValueSlot::Overlap_t mayOverlap, bool isVolatile=false)
Emit an aggregate copy.
LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty)
mlir::Value getVTTParameter(GlobalDecl gd, bool forVirtualBase, bool delegating)
Return the VTT parameter that should be passed to a base constructor/destructor with virtual bases.
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
EHScopeStack ehStack
Tracks function scope overall cleanup handling.
mlir::Type convertTypeForMem(QualType t)
mlir::Value emitLoadOfComplex(LValue src, SourceLocation loc)
Load a complex number from the specified l-value.
void emitStoreOfScalar(mlir::Value value, Address addr, bool isVolatile, clang::QualType ty, LValueBaseInfo baseInfo, bool isInit=false, bool isNontemporal=false)
mlir::Value loadCXXVTT()
Load the VTT parameter to base constructors/destructors have virtual bases.
mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr, const clang::CXXRecordDecl *vtableClass)
Return the Value of the vtable pointer member pointed to by thisAddr.
void emitStoreOfComplex(mlir::Location loc, mlir::Value v, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
bool shouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *rd)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
CIRGenBuilderTy & getBuilder()
mlir::Value emitRuntimeCall(mlir::Location loc, cir::FuncOp callee, llvm::ArrayRef< mlir::Value > args={}, mlir::NamedAttrList attrs={})
mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source=AlignmentSource::Type)
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
void emitAutoVarCleanups(const AutoVarEmission &emission)
This class organizes the cross-function state that is used while generating CIR code.
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
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.
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
const clang::TargetInfo & getTarget() const
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
const cir::CIRDataLayout getDataLayout() const
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
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)
mlir::ModuleOp getModule() const
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.
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.
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)
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 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.
This represents one expression.
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, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
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.
PointerType - C99 6.7.5.1 - Pointer Declarators.
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.
@ 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
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Visibility getVisibility() const
Determine the visibility of this type.
Linkage getLinkage() const
Determine the linkage of this type.
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
AddressPointLocation getAddressPoint(BaseSubobject Base) const
Represents a variable declaration or definition.
TLSKind getTLSKind() const
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
const Expr * getInit() const
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.
@ Address
A pointer to a ValueDecl.
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)
@ 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.