28#include "llvm/ABI/Types.h"
29#include "llvm/Support/Alignment.h"
30#include "llvm/Support/ErrorHandling.h"
31#include "llvm/Support/TypeSize.h"
41#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
42 case BuiltinType::Id: \
44#include "clang/Basic/AArch64ACLETypes.def"
54 return llvm::abi::VectorKind::SVEData;
56 return llvm::abi::VectorKind::SVEPredicate;
58 return llvm::abi::VectorKind::Generic;
79 auto It = TypeCache.find(QT);
80 if (It != TypeCache.end())
83 const llvm::abi::Type *
Result = convertTypeImpl(QT);
84 assert(
Result &&
"convertTypeImpl returned nullptr");
90const llvm::abi::Type *QualTypeMapper::convertTypeImpl(
QualType QT) {
94#define TYPE(Class, Base)
95#define ABSTRACT_TYPE(Class, Base)
96#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
97#define DEPENDENT_TYPE(Class, Base) case Type::Class:
98#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
99#include "clang/AST/TypeNodes.inc"
100 llvm::reportFatalInternalError(
101 "Non-canonical or dependent types should not reach ABI lowering");
107 case Type::LValueReference:
108 case Type::RValueReference:
109 return createPointerTypeForPointee(
111 case Type::ConstantArray:
112 case Type::ArrayParameter:
113 case Type::IncompleteArray:
114 case Type::VariableArray:
117 case Type::ExtVector:
127 return Builder.getAtomicType(
convertType(AT->getValueType()),
130 case Type::BlockPointer:
132 return createPointerTypeForPointee(ASTCtx.
VoidPtrTy);
133 case Type::ConstantMatrix: {
135 return Builder.getArrayType(
convertType(MT->getElementType()),
136 MT->getNumRows() * MT->getNumColumns(),
139 case Type::MemberPointer:
143 return Builder.getIntegerType(BIT->getNumBits(), getTypeAlign(QT),
147 case Type::ObjCObject:
148 case Type::ObjCInterface:
149 case Type::ObjCObjectPointer:
151 return Builder.getPointerType(
157 case Type::OverflowBehavior:
160 case Type::DeducedTemplateSpecialization:
161 case Type::FunctionProto:
162 case Type::FunctionNoProto:
163 case Type::HLSLAttributedResource:
164 case Type::HLSLInlineSpirv:
165 llvm::reportFatalInternalError(
"Type not supported in ABI lowering");
167 llvm_unreachable(
"unhandled type class in convertTypeImpl");
173const llvm::abi::Type *
174QualTypeMapper::convertBuiltinType(
const BuiltinType *BT) {
177 switch (BT->getKind()) {
178 case BuiltinType::Void:
179 return Builder.getVoidType();
181 case BuiltinType::NullPtr:
182 return createPointerTypeForPointee(QT);
184 case BuiltinType::Bool:
185 return Builder.getIntegerType(1, getTypeAlign(QT),
false,
188 case BuiltinType::MetaInfo:
189 llvm::reportFatalInternalError(
"std::meta::info is consteval-only type");
191 case BuiltinType::Char_S:
192 case BuiltinType::Char_U:
193 case BuiltinType::SChar:
194 case BuiltinType::UChar:
195 case BuiltinType::WChar_S:
196 case BuiltinType::WChar_U:
197 case BuiltinType::Char8:
198 case BuiltinType::Char16:
199 case BuiltinType::Char32:
200 case BuiltinType::Short:
201 case BuiltinType::UShort:
202 case BuiltinType::Int:
203 case BuiltinType::UInt:
204 case BuiltinType::Long:
205 case BuiltinType::ULong:
206 case BuiltinType::LongLong:
207 case BuiltinType::ULongLong:
208 case BuiltinType::Int128:
209 case BuiltinType::UInt128:
210 return Builder.getIntegerType(ASTCtx.getTypeSize(QT), getTypeAlign(QT),
211 BT->isSignedInteger(),
214 case BuiltinType::Half:
215 case BuiltinType::Float16:
216 case BuiltinType::BFloat16:
217 case BuiltinType::Float:
218 case BuiltinType::Double:
219 case BuiltinType::LongDouble:
220 case BuiltinType::Float128:
221 return Builder.getFloatType(ASTCtx.getFloatTypeSemantics(QT),
225 case BuiltinType::Ibm128:
226 llvm::reportFatalInternalError(
227 "IBM128 is not yet supported in the ABI lowering libary");
230 case BuiltinType::ShortAccum:
231 case BuiltinType::Accum:
232 case BuiltinType::LongAccum:
233 case BuiltinType::UShortAccum:
234 case BuiltinType::UAccum:
235 case BuiltinType::ULongAccum:
236 case BuiltinType::ShortFract:
237 case BuiltinType::Fract:
238 case BuiltinType::LongFract:
239 case BuiltinType::UShortFract:
240 case BuiltinType::UFract:
241 case BuiltinType::ULongFract:
242 case BuiltinType::SatShortAccum:
243 case BuiltinType::SatAccum:
244 case BuiltinType::SatLongAccum:
245 case BuiltinType::SatUShortAccum:
246 case BuiltinType::SatUAccum:
247 case BuiltinType::SatULongAccum:
248 case BuiltinType::SatShortFract:
249 case BuiltinType::SatFract:
250 case BuiltinType::SatLongFract:
251 case BuiltinType::SatUShortFract:
252 case BuiltinType::SatUFract:
253 case BuiltinType::SatULongFract:
254 llvm::reportFatalInternalError(
255 "Fixed Point types not yet implemented in the ABI lowering library");
258#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
259 case BuiltinType::Id:
260#include "clang/Basic/OpenCLImageTypes.def"
262#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) case BuiltinType::Id:
263#include "clang/Basic/OpenCLExtensionTypes.def"
264 case BuiltinType::OCLSampler:
265 case BuiltinType::OCLEvent:
266 case BuiltinType::OCLClkEvent:
267 case BuiltinType::OCLQueue:
268 case BuiltinType::OCLReserveID:
269 return createPointerTypeForPointee(QT);
272 case BuiltinType::ObjCId:
273 case BuiltinType::ObjCClass:
274 case BuiltinType::ObjCSel:
275 return createPointerTypeForPointee(QT);
278#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \
279 case BuiltinType::Id:
280#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
281 case BuiltinType::Id:
282#include "clang/Basic/AArch64ACLETypes.def"
283 return convertSVEBuiltinType(BT);
285 case BuiltinType::SveCount:
286 return Builder.getScalablePredicateOrCountVectorType(
287 getTypeAlign(QT), llvm::abi::VectorKind::SVECount);
294 case BuiltinType::MFloat8:
295 llvm::reportFatalInternalError(
296 "__mfp8 is not yet supported in the ABI lowering library");
299#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
300#include "clang/Basic/PPCTypes.def"
301 llvm::reportFatalInternalError(
302 "PPC MMA types not yet supported in ABI lowering library");
303#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
304#include "clang/Basic/RISCVVTypes.def"
305 llvm::reportFatalInternalError(
306 "RISC-V vector types not yet supported in ABI lowering library");
307#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
308#include "clang/Basic/WebAssemblyReferenceTypes.def"
309 llvm::reportFatalInternalError(
"WebAssembly reference types not yet "
310 "supported in ABI lowering library");
311#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
312#include "clang/Basic/AMDGPUTypes.def"
313 llvm::reportFatalInternalError(
314 "AMDGPU types not yet supported in ABI lowering library");
315#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
316#include "clang/Basic/HLSLIntangibleTypes.def"
317 llvm::reportFatalInternalError(
318 "HLSL intangible types not yet Supported in ABI lowering library");
319#define HLSL_PACKED_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
320#include "clang/Basic/HLSLPackedTypes.def"
321 llvm::reportFatalInternalError(
322 "HLSL packed types not yet Supported in ABI lowering library");
323#define SPIRV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
324#include "clang/Basic/SPIRVTypes.def"
325 llvm::reportFatalInternalError(
326 "SPIR-V types not yet supported in ABI lowering library");
329#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
330#define BUILTIN_TYPE(Id, SingletonId)
331#include "clang/AST/BuiltinTypes.def"
332 llvm::reportFatalInternalError(
333 "Placeholder type should not reach ABI lowering");
335 case BuiltinType::Dependent:
336 llvm::reportFatalInternalError(
337 "Dependent builtin type should not reach ABI lowering");
339 llvm_unreachable(
"unhandled builtin type kind in convertBuiltinType");
348const llvm::abi::Type *
349QualTypeMapper::convertArrayType(
const clang::ArrayType *AT) {
353 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
354 auto NumElements = CAT->getZExtSize();
355 return Builder.getArrayType(ElementType, NumElements, Size);
358 return Builder.getArrayType(ElementType, 0, 0);
359 if (
const auto *VAT = dyn_cast<VariableArrayType>(AT))
360 return createPointerTypeForPointee(VAT->getPointeeType());
361 llvm::reportFatalInternalError(
362 "unexpected array type in ABI lowering (dependent array types should be "
363 "resolved before reaching this point)");
366const llvm::abi::Type *QualTypeMapper::convertVectorType(
const VectorType *VT) {
367 const llvm::abi::Type *ElementType =
convertType(VT->getElementType());
368 QualType VectorQualType(VT, 0);
370 unsigned NElems = VT->getNumElements();
371 llvm::ElementCount NumElements = llvm::ElementCount::getFixed(NElems);
372 llvm::Align VectorAlign = getTypeAlign(VectorQualType);
378 return Builder.getVectorType(ElementType, NumElements, VectorAlign,
388const llvm::abi::Type *
389QualTypeMapper::convertSVEBuiltinType(
const BuiltinType *BT) {
390 ASTContext::BuiltinVectorTypeInfo Info = ASTCtx.getBuiltinVectorTypeInfo(BT);
392 "Expected 1, 2, 3 or 4 vectors!");
397 const llvm::abi::Type *ElementType =
399 ? Builder.getIntegerType(8, llvm::Align(1),
false)
403 ? llvm::abi::VectorKind::SVEPredicate
404 : llvm::abi::VectorKind::SVEData;
406 const llvm::abi::VectorType *VecTy = Builder.getVectorType(
407 ElementType, Info.
EC, getTypeAlign(QualType(BT, 0)), VecKind);
410 return Builder.getTupleType(VecTy, Info.
NumVectors);
419const llvm::abi::Type *
420QualTypeMapper::convertComplexType(
const ComplexType *CT) {
421 const llvm::abi::Type *ElementType =
convertType(CT->getElementType());
422 llvm::Align ComplexAlign = getTypeAlign(QualType(CT, 0));
424 return Builder.getComplexType(ElementType, ComplexAlign);
433const llvm::abi::Type *
434QualTypeMapper::convertMemberPointerType(
const clang::MemberPointerType *MPT) {
437 llvm::Align Align = getTypeAlign(QT);
441 return Builder.getMemberPointerType(IsFunctionPointer, Size, Align);
450const llvm::abi::Type *QualTypeMapper::convertRecordType(
const RecordType *RT) {
451 const RecordDecl *RD = RT->getDecl()->getDefinition();
453 return Builder.getRecordType({}, llvm::TypeSize::getFixed(0),
458 return convertUnionType(RD);
461 auto *CXXRd = dyn_cast<CXXRecordDecl>(RD);
462 if (CXXRd && (CXXRd->getNumBases() > 0 || CXXRd->getNumVBases() > 0))
463 return convertCXXRecordType(CXXRd);
464 return convertStructType(RD);
475const llvm::abi::RecordType *
476QualTypeMapper::convertCXXRecordType(
const CXXRecordDecl *RD) {
477 const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(RD);
478 SmallVector<llvm::abi::FieldInfo, 16> Fields;
479 SmallVector<llvm::abi::FieldInfo, 8> BaseClasses;
480 SmallVector<llvm::abi::FieldInfo, 8> VirtualBaseClasses;
483 if (RD->isPolymorphic()) {
484 const llvm::abi::Type *VtablePointer =
485 createPointerTypeForPointee(ASTCtx.VoidPtrTy);
486 Fields.emplace_back(VtablePointer, 0);
489 for (
const auto &Base : RD->bases()) {
490 if (
Base.isVirtual())
493 const RecordType *BaseRT =
Base.getType()->castAs<RecordType>();
496 Layout.getBaseClassOffset(BaseRT->getAsCXXRecordDecl()).getQuantity() *
498 BaseClasses.emplace_back(BaseType, BaseOffset);
501 for (
const auto &VBase : RD->vbases()) {
502 const RecordType *VBaseRT = VBase.getType()->castAs<RecordType>();
503 const llvm::abi::Type *VBaseType =
convertType(VBase.getType());
505 Layout.getVBaseClassOffset(VBaseRT->getAsCXXRecordDecl())
508 VirtualBaseClasses.emplace_back(VBaseType, VBaseOffset);
511 computeFieldInfo(RD, Fields, Layout);
514 [](
const llvm::abi::FieldInfo &A,
const llvm::abi::FieldInfo &B) {
515 return A.OffsetInBits < B.OffsetInBits;
518 llvm::TypeSize
Size =
519 llvm::TypeSize::getFixed(Layout.getSize().getQuantity() * 8);
520 llvm::Align Alignment = llvm::Align(Layout.getAlignment().getQuantity());
521 llvm::Align UnadjustedAlign =
522 llvm::Align(Layout.getUnadjustedAlignment().getQuantity());
524 llvm::abi::RecordFlags RecFlags = llvm::abi::RecordFlags::IsCXXRecord;
525 if (RD->isPolymorphic())
526 RecFlags |= llvm::abi::RecordFlags::IsPolymorphic;
527 if (RD->canPassInRegisters())
528 RecFlags |= llvm::abi::RecordFlags::CanPassInRegisters;
529 if (RD->hasFlexibleArrayMember())
530 RecFlags |= llvm::abi::RecordFlags::HasFlexibleArrayMember;
532 return Builder.getRecordType(Fields, Size, Alignment, UnadjustedAlign,
533 llvm::abi::StructPacking::Default, BaseClasses,
534 VirtualBaseClasses, RecFlags);
543const llvm::abi::Type *
544QualTypeMapper::convertEnumType(
const clang::EnumType *ET) {
545 const EnumDecl *ED = ET->getDecl();
546 QualType UnderlyingType = ED->getIntegerType();
548 if (UnderlyingType.isNull())
549 UnderlyingType = ASTCtx.IntTy;
560const llvm::abi::RecordType *
561QualTypeMapper::convertStructType(
const clang::RecordDecl *RD) {
562 const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(RD);
565 SmallVector<llvm::abi::FieldInfo, 16> Fields;
566 computeFieldInfo(RD, Fields, Layout);
568 llvm::TypeSize
Size =
569 llvm::TypeSize::getFixed(Layout.getSize().getQuantity() * 8);
570 llvm::Align Alignment = llvm::Align(Layout.getAlignment().getQuantity());
571 llvm::Align UnadjustedAlign =
572 llvm::Align(Layout.getUnadjustedAlignment().getQuantity());
574 llvm::abi::RecordFlags RecFlags = llvm::abi::RecordFlags::None;
576 RecFlags |= llvm::abi::RecordFlags::IsCXXRecord;
578 RecFlags |= llvm::abi::RecordFlags::CanPassInRegisters;
580 RecFlags |= llvm::abi::RecordFlags::HasFlexibleArrayMember;
582 return Builder.getRecordType(Fields, Size, Alignment, UnadjustedAlign,
583 llvm::abi::StructPacking::Default, {}, {},
593const llvm::abi::RecordType *
594QualTypeMapper::convertUnionType(
const clang::RecordDecl *RD) {
595 const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(RD);
597 SmallVector<llvm::abi::FieldInfo, 16> AllFields;
598 computeFieldInfo(RD, AllFields, Layout);
600 llvm::TypeSize
Size =
601 llvm::TypeSize::getFixed(Layout.getSize().getQuantity() * 8);
602 llvm::Align Alignment = llvm::Align(Layout.getAlignment().getQuantity());
603 llvm::Align UnadjustedAlign =
604 llvm::Align(Layout.getUnadjustedAlignment().getQuantity());
606 llvm::abi::RecordFlags RecFlags = llvm::abi::RecordFlags::None;
607 if (RD->
hasAttr<TransparentUnionAttr>())
608 RecFlags |= llvm::abi::RecordFlags::IsTransparent;
610 RecFlags |= llvm::abi::RecordFlags::CanPassInRegisters;
612 RecFlags |= llvm::abi::RecordFlags::IsCXXRecord;
614 return Builder.getUnionType(AllFields, Size, Alignment, UnadjustedAlign,
615 llvm::abi::StructPacking::Default, RecFlags);
618llvm::Align QualTypeMapper::getTypeAlign(QualType QT)
const {
620 return llvm::Align(ASTCtx.getTypeAlignInChars(QT).getQuantity());
623const llvm::abi::Type *
624QualTypeMapper::createPointerTypeForPointee(QualType PointeeType) {
625 auto AddrSpace = PointeeType.getAddressSpace();
626 auto PointerSize = ASTCtx.getTargetInfo().getPointerWidth(AddrSpace);
627 llvm::Align Alignment =
628 llvm::Align(ASTCtx.getTargetInfo().getPointerAlign(AddrSpace));
632 unsigned TargetAddrSpace =
633 PointeeType->isFunctionType() && !PointeeType.hasAddressSpace()
634 ? DL.getProgramAddressSpace()
635 : ASTCtx.getTargetInfo().getTargetAddressSpace(AddrSpace);
636 return Builder.getPointerType(PointerSize, llvm::Align(Alignment.value() / 8),
637 TargetAddrSpace, PointeeType.hasAddressSpace());
647void QualTypeMapper::computeFieldInfo(
648 const RecordDecl *RD, SmallVectorImpl<llvm::abi::FieldInfo> &Fields,
649 const ASTRecordLayout &Layout) {
650 unsigned FieldIndex = 0;
652 for (
const auto *FD : RD->fields()) {
653 const llvm::abi::Type *FieldType =
convertType(FD->getType());
654 uint64_t OffsetInBits = Layout.getFieldOffset(FieldIndex);
656 bool IsBitField = FD->isBitField();
658 bool IsUnnamedBitField =
false;
661 BitFieldWidth = FD->getBitWidthValue();
662 IsUnnamedBitField = FD->isUnnamedBitField();
665 bool HasNoUniqueAddress = FD->hasAttr<NoUniqueAddressAttr>();
666 Fields.emplace_back(FieldType, OffsetInBits, IsBitField, BitFieldWidth,
667 IsUnnamedBitField, HasNoUniqueAddress);
Defines the clang::ASTContext interface.
Forward declaration of all AST node types.
Provides definitions for the various language-specific address spaces.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Maps Clang QualType instances to corresponding LLVM ABI type representations.
static QualType getUnderlyingType(const SubRegion *R)
static QualType getPointeeType(const MemRegion *R)
C Language Family Type Representation.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
QualType getElementType() const
This class is used for builtin types like 'int'.
const llvm::abi::Type * convertType(clang::QualType QT)
Main entry point for converting Clang QualType to LLVM ABI Type.
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
bool hasFlexibleArrayMember() const
bool isMemberFunctionPointerType() const
TypeClass getTypeClass() const
Defines the clang::TargetInfo interface.
static llvm::abi::VectorKind getABIVectorKind(clang::VectorKind Kind)
Maps a Clang vector kind onto the ABI library's notion of a vector flavor.
static bool isSVEPredicateBuiltinType(const BuiltinType *BT)
Returns true if BT is one of the AArch64 SVE predicate types, i.e.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
@ Result
The result type of a method or function.
@ SveFixedLengthData
is AArch64 SVE fixed-length data vector
@ SveFixedLengthPredicate
is AArch64 SVE fixed-length predicate vector
U cast(CodeGen::Address addr)