LLVM 24.0.0git
Types.h
Go to the documentation of this file.
1//===- ABI/Types.h ----------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines the type system for the LLVMABI library, which mirrors
11/// ABI-relevant aspects of frontend types.
12///
13//===----------------------------------------------------------------------===//
14#ifndef LLVM_ABI_TYPES_H
15#define LLVM_ABI_TYPES_H
16
17#include "llvm/ADT/APFloat.h"
18#include "llvm/ADT/ArrayRef.h"
24
25namespace llvm {
26namespace abi {
27
39
40/// Represents the ABI-specific view of a type in LLVM.
41///
42/// This abstracts platform and language-specific ABI details from the
43/// frontend, providing a consistent interface for the ABI Library.
44class Type {
45private:
46 TypeSize getTypeStoreSize() const {
47 TypeSize StoreSizeInBits = getTypeStoreSizeInBits();
48 return {StoreSizeInBits.getKnownMinValue() / 8,
49 StoreSizeInBits.isScalable()};
50 }
51 TypeSize getTypeStoreSizeInBits() const {
52 TypeSize BaseSize = getSizeInBits();
53 uint64_t AlignedSizeInBits =
54 alignToPowerOf2(BaseSize.getKnownMinValue(), 8);
55 return {AlignedSizeInBits, BaseSize.isScalable()};
56 }
57
58protected:
62
65
66public:
67 TypeKind getKind() const { return Kind; }
68 TypeSize getSizeInBits() const { return SizeInBits; }
69 Align getAlignment() const { return ABIAlignment; }
70
72 return alignTo(getTypeStoreSize(), getAlignment().value());
73 }
74
75 bool isVoid() const { return Kind == TypeKind::Void; }
76 bool isInteger() const { return Kind == TypeKind::Integer; }
77 bool isFloat() const { return Kind == TypeKind::Float; }
78 bool isPointer() const { return Kind == TypeKind::Pointer; }
79 bool isArray() const { return Kind == TypeKind::Array; }
80 bool isVector() const { return Kind == TypeKind::Vector; }
81 bool isRecord() const { return Kind == TypeKind::Record; }
82 bool isMemberPointer() const { return Kind == TypeKind::MemberPointer; }
83 bool isComplex() const { return Kind == TypeKind::Complex; }
84 bool isZeroSize() const { return getSizeInBits().getFixedValue() == 0; }
85};
86
87class VoidType : public Type {
88public:
89 VoidType() : Type(TypeKind::Void, TypeSize::getFixed(0), Align(1)) {}
90
91 static bool classof(const Type *T) { return T->getKind() == TypeKind::Void; }
92};
93
94class ComplexType : public Type {
95public:
96 ComplexType(const Type *ElementType, uint64_t SizeInBits, Align Alignment)
97 : Type(TypeKind::Complex, TypeSize::getFixed(SizeInBits), Alignment),
98 ElementType(ElementType) {}
99
100 const Type *getElementType() const { return ElementType; }
101
102 static bool classof(const Type *T) {
103 return T->getKind() == TypeKind::Complex;
104 }
105
106private:
107 const Type *ElementType;
108};
109
110class IntegerType : public Type {
111private:
112 bool IsSigned;
113 bool IsBitInt;
114
115public:
116 IntegerType(uint64_t BitWidth, Align ABIAlign, bool IsSigned,
117 bool IsBitInt = false)
118 : Type(TypeKind::Integer, TypeSize::getFixed(BitWidth), ABIAlign),
119 IsSigned(IsSigned), IsBitInt(IsBitInt) {}
120
121 bool isSigned() const { return IsSigned; }
122 bool isBitInt() const { return IsBitInt; }
123 bool isBool() const {
124 return getSizeInBits().getFixedValue() == 1 && !IsBitInt;
125 }
126
127 static bool classof(const Type *T) {
128 return T->getKind() == TypeKind::Integer;
129 }
130};
131
132class FloatType : public Type {
133private:
134 const fltSemantics *Semantics;
135
136public:
137 FloatType(const fltSemantics &FloatSemantics, Align ABIAlign)
139 TypeSize::getFixed(APFloat::getSizeInBits(FloatSemantics)),
140 ABIAlign),
141 Semantics(&FloatSemantics) {}
142
143 const fltSemantics *getSemantics() const { return Semantics; }
144 static bool classof(const Type *T) { return T->getKind() == TypeKind::Float; }
145};
146
147class PointerLikeType : public Type {
148protected:
149 unsigned AddrSpace;
151 : Type(K, SizeInBits, ABIAlign), AddrSpace(AS) {}
152
153public:
154 unsigned getAddrSpace() const { return AddrSpace; }
155 bool isMemberPointer() const { return getKind() == TypeKind::MemberPointer; }
156
157 static bool classof(const Type *T) {
158 return T->getKind() == TypeKind::Pointer ||
159 T->getKind() == TypeKind::MemberPointer;
160 }
161};
162
164public:
165 PointerType(uint64_t Size, Align ABIAlign, unsigned AddressSpace = 0)
166 : PointerLikeType(TypeKind::Pointer, TypeSize::getFixed(Size), ABIAlign,
167 AddressSpace) {}
168
169 static bool classof(const Type *T) {
170 return T->getKind() == TypeKind::Pointer;
171 }
172};
173
175private:
176 bool IsFunctionPointer;
177
178public:
179 MemberPointerType(bool IsFunctionPointer, uint64_t SizeInBits, Align ABIAlign,
180 unsigned AddressSpace = 0)
182 ABIAlign, AddressSpace),
183 IsFunctionPointer(IsFunctionPointer) {}
184 bool isFunctionPointer() const { return IsFunctionPointer; }
185
186 static bool classof(const Type *T) {
187 return T->getKind() == TypeKind::MemberPointer;
188 }
189};
190
191class ArrayType : public Type {
192private:
193 const Type *ElementType;
194 uint64_t NumElements;
195 bool IsMatrix;
196
197public:
198 ArrayType(const Type *ElementType, uint64_t NumElements, uint64_t SizeInBits,
199 bool IsMatrixType = false)
200 : Type(TypeKind::Array, TypeSize::getFixed(SizeInBits),
201 ElementType->getAlignment()),
202 ElementType(ElementType), NumElements(NumElements),
203 IsMatrix(IsMatrixType) {}
204
205 const Type *getElementType() const { return ElementType; }
206 uint64_t getNumElements() const { return NumElements; }
207 bool isMatrixType() const { return IsMatrix; }
208
209 static bool classof(const Type *T) { return T->getKind() == TypeKind::Array; }
210};
211
212class VectorType : public Type {
213private:
214 const Type *ElementType;
215 ElementCount NumElements;
216
217public:
218 VectorType(const Type *ElementType, ElementCount NumElements, Align ABIAlign)
220 TypeSize(ElementType->getSizeInBits().getFixedValue() *
221 NumElements.getKnownMinValue(),
222 NumElements.isScalable()),
223 ABIAlign),
224 ElementType(ElementType), NumElements(NumElements) {}
225
226 const Type *getElementType() const { return ElementType; }
227 ElementCount getNumElements() const { return NumElements; }
228
229 static bool classof(const Type *T) {
230 return T->getKind() == TypeKind::Vector;
231 }
232};
233
251
253
254enum RecordFlags : unsigned {
255 None = 0,
257 IsUnion = 1 << 1,
259 IsCXXRecord = 1 << 3,
263};
264
265class RecordType : public Type {
266private:
267 ArrayRef<FieldInfo> Fields;
268 ArrayRef<FieldInfo> BaseClasses;
269 ArrayRef<FieldInfo> VirtualBaseClasses;
270 StructPacking Packing;
271 RecordFlags Flags;
272
273public:
278 : Type(TypeKind::Record, Size, Align), Fields(StructFields),
279 BaseClasses(Bases), VirtualBaseClasses(VBases), Packing(Pack),
280 Flags(RecFlags) {}
281 uint32_t getNumFields() const { return Fields.size(); }
282 StructPacking getPacking() const { return Packing; }
283
284 bool isUnion() const {
285 return static_cast<unsigned>(Flags & RecordFlags::IsUnion) != 0;
286 }
287 bool isCXXRecord() const {
288 return static_cast<unsigned>(Flags & RecordFlags::IsCXXRecord) != 0;
289 }
290 bool isPolymorphic() const {
291 return static_cast<unsigned>(Flags & RecordFlags::IsPolymorphic) != 0;
292 }
293 bool canPassInRegisters() const {
294 return static_cast<unsigned>(Flags & RecordFlags::CanPassInRegisters) != 0;
295 }
297 return static_cast<unsigned>(Flags & RecordFlags::HasFlexibleArrayMember) !=
298 0;
299 }
300 uint32_t getNumBaseClasses() const { return BaseClasses.size(); }
302 return VirtualBaseClasses.size();
303 }
304 bool isTransparentUnion() const {
305 return static_cast<unsigned>(Flags & RecordFlags::IsTransparent) != 0;
306 }
307 ArrayRef<FieldInfo> getFields() const { return Fields; }
308
309 /// Returns the direct base classes, both virtual and non-virtual, mirroring
310 /// clang::CXXRecordDecl::bases(). A virtual base is marked with
311 /// FieldInfo::IsVirtualBase, and its offset is only meaningful when this
312 /// record is the most-derived object.
313 ArrayRef<FieldInfo> getBaseClasses() const { return BaseClasses; }
314
315 /// Returns the virtual base classes, both direct and indirect, mirroring
316 /// clang::CXXRecordDecl::vbases(). Direct virtual bases therefore appear
317 /// both here and in getBaseClasses().
319 return VirtualBaseClasses;
320 }
321
322 LLVM_ABI bool isEmpty() const;
323
324 /// Returns the field, base, or virtual base whose extent contains
325 /// \p OffsetInBits, or nullptr if no such element exists. Empty bases and
326 /// unnamed bitfields are skipped.
327 LLVM_ABI const FieldInfo *
328 getElementContainingOffset(unsigned OffsetInBits) const;
329
330 static bool classof(const Type *T) {
331 return T->getKind() == TypeKind::Record;
332 }
333};
334
335/// TypeBuilder manages the lifecycle of ABI types using bump pointer
336/// allocation. Types created by a TypeBuilder are valid for the lifetime of the
337/// allocator.
338///
339/// Example usage:
340/// \code
341/// BumpPtrAllocator Alloc;
342/// TypeBuilder Builder(Alloc);
343/// const auto *IntTy = Builder.getIntegerType(32, Align(4), true);
344/// \endcode
346private:
347 BumpPtrAllocator &Allocator;
348
349public:
350 explicit TypeBuilder(BumpPtrAllocator &Alloc) : Allocator(Alloc) {}
351
353 return new (Allocator.Allocate<VoidType>()) VoidType();
354 }
355
357 bool IsBitInt = false) {
358 return new (Allocator.Allocate<IntegerType>())
359 IntegerType(BitWidth, Align, Signed, IsBitInt);
360 }
361
362 const FloatType *getFloatType(const fltSemantics &Semantics, Align Align) {
363 return new (Allocator.Allocate<FloatType>()) FloatType(Semantics, Align);
364 }
365
367 unsigned Addrspace = 0) {
368 return new (Allocator.Allocate<PointerType>())
369 PointerType(Size, Align, Addrspace);
370 }
371
372 const ArrayType *getArrayType(const Type *ElementType, uint64_t NumElements,
373 uint64_t SizeInBits,
374 bool IsMatrixType = false) {
375 return new (Allocator.Allocate<ArrayType>())
376 ArrayType(ElementType, NumElements, SizeInBits, IsMatrixType);
377 }
378
379 const VectorType *getVectorType(const Type *ElementType,
380 ElementCount NumElements, Align Align) {
381 return new (Allocator.Allocate<VectorType>())
382 VectorType(ElementType, NumElements, Align);
383 }
384
386 Align Align,
388 ArrayRef<FieldInfo> BaseClasses = {},
389 ArrayRef<FieldInfo> VirtualBaseClasses = {},
390 RecordFlags RecFlags = RecordFlags::None) {
391 FieldInfo *FieldArray = Allocator.Allocate<FieldInfo>(Fields.size());
392 std::copy(Fields.begin(), Fields.end(), FieldArray);
393
394 FieldInfo *BaseArray = nullptr;
395 if (!BaseClasses.empty()) {
396 BaseArray = Allocator.Allocate<FieldInfo>(BaseClasses.size());
397 std::copy(BaseClasses.begin(), BaseClasses.end(), BaseArray);
398 }
399
400 FieldInfo *VBaseArray = nullptr;
401 if (!VirtualBaseClasses.empty()) {
402 VBaseArray = Allocator.Allocate<FieldInfo>(VirtualBaseClasses.size());
403 std::copy(VirtualBaseClasses.begin(), VirtualBaseClasses.end(),
404 VBaseArray);
405 }
406
407 ArrayRef<FieldInfo> FieldsRef(FieldArray, Fields.size());
408 ArrayRef<FieldInfo> BasesRef(BaseArray, BaseClasses.size());
409 ArrayRef<FieldInfo> VBasesRef(VBaseArray, VirtualBaseClasses.size());
410
411 return new (Allocator.Allocate<RecordType>())
412 RecordType(FieldsRef, BasesRef, VBasesRef, Size, Align, Pack, RecFlags);
413 }
414
416 Align Align,
418 RecordFlags RecFlags = RecordFlags::None) {
419 FieldInfo *FieldArray = Allocator.Allocate<FieldInfo>(Fields.size());
420
421 for (size_t I = 0, E = Fields.size(); I != E; ++I) {
422 const FieldInfo &Field = Fields[I];
423 new (&FieldArray[I])
424 FieldInfo(Field.FieldType, 0, Field.IsBitField, Field.BitFieldWidth,
425 Field.IsUnnamedBitfield);
426 }
427
428 ArrayRef<FieldInfo> FieldsRef(FieldArray, Fields.size());
429
430 return new (Allocator.Allocate<RecordType>())
432 Size, Align, Pack, RecFlags | RecordFlags::IsUnion);
433 }
434
435 const ComplexType *getComplexType(const Type *ElementType, Align Align) {
436 // Complex types have two elements (real and imaginary parts)
437 uint64_t ElementSizeInBits = ElementType->getSizeInBits().getFixedValue();
438 uint64_t ComplexSizeInBits = ElementSizeInBits * 2;
439
440 return new (Allocator.Allocate<ComplexType>())
441 ComplexType(ElementType, ComplexSizeInBits, Align);
442 }
443
444 const MemberPointerType *getMemberPointerType(bool IsFunctionPointer,
445 uint64_t SizeInBits,
446 Align Align) {
447 return new (Allocator.Allocate<MemberPointerType>())
448 MemberPointerType(IsFunctionPointer, SizeInBits, Align);
449 }
450};
451
452} // namespace abi
453} // namespace llvm
454
455#endif
unsigned uint64_t
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
#define I(x, y, z)
Definition MD5.cpp:57
#define T
OptimizedStructLayoutField Field
Basic Register Allocator
FunctionLoweringInfo::StatepointRelocationRecord RecordType
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
size_t size() const
Get the array size.
Definition ArrayRef.h:141
iterator begin() const
Definition ArrayRef.h:129
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
const Type * getElementType() const
Definition Types.h:205
bool isMatrixType() const
Definition Types.h:207
static bool classof(const Type *T)
Definition Types.h:209
ArrayType(const Type *ElementType, uint64_t NumElements, uint64_t SizeInBits, bool IsMatrixType=false)
Definition Types.h:198
uint64_t getNumElements() const
Definition Types.h:206
ComplexType(const Type *ElementType, uint64_t SizeInBits, Align Alignment)
Definition Types.h:96
const Type * getElementType() const
Definition Types.h:100
static bool classof(const Type *T)
Definition Types.h:102
FloatType(const fltSemantics &FloatSemantics, Align ABIAlign)
Definition Types.h:137
const fltSemantics * getSemantics() const
Definition Types.h:143
static bool classof(const Type *T)
Definition Types.h:144
static bool classof(const Type *T)
Definition Types.h:127
bool isBitInt() const
Definition Types.h:122
IntegerType(uint64_t BitWidth, Align ABIAlign, bool IsSigned, bool IsBitInt=false)
Definition Types.h:116
bool isBool() const
Definition Types.h:123
bool isSigned() const
Definition Types.h:121
bool isFunctionPointer() const
Definition Types.h:184
static bool classof(const Type *T)
Definition Types.h:186
MemberPointerType(bool IsFunctionPointer, uint64_t SizeInBits, Align ABIAlign, unsigned AddressSpace=0)
Definition Types.h:179
PointerLikeType(TypeKind K, TypeSize SizeInBits, Align ABIAlign, unsigned AS)
Definition Types.h:150
static bool classof(const Type *T)
Definition Types.h:157
bool isMemberPointer() const
Definition Types.h:155
unsigned getAddrSpace() const
Definition Types.h:154
PointerType(uint64_t Size, Align ABIAlign, unsigned AddressSpace=0)
Definition Types.h:165
static bool classof(const Type *T)
Definition Types.h:169
bool isPolymorphic() const
Definition Types.h:290
bool isUnion() const
Definition Types.h:284
bool canPassInRegisters() const
Definition Types.h:293
LLVM_ABI const FieldInfo * getElementContainingOffset(unsigned OffsetInBits) const
Returns the field, base, or virtual base whose extent contains OffsetInBits, or nullptr if no such el...
Definition Types.cpp:34
ArrayRef< FieldInfo > getBaseClasses() const
Returns the direct base classes, both virtual and non-virtual, mirroring clang::CXXRecordDecl::bases(...
Definition Types.h:313
uint32_t getNumBaseClasses() const
Definition Types.h:300
ArrayRef< FieldInfo > getFields() const
Definition Types.h:307
uint32_t getNumVirtualBaseClasses() const
Definition Types.h:301
bool hasFlexibleArrayMember() const
Definition Types.h:296
bool isCXXRecord() const
Definition Types.h:287
bool isTransparentUnion() const
Definition Types.h:304
static bool classof(const Type *T)
Definition Types.h:330
LLVM_ABI bool isEmpty() const
Definition Types.cpp:15
RecordType(ArrayRef< FieldInfo > StructFields, ArrayRef< FieldInfo > Bases, ArrayRef< FieldInfo > VBases, TypeSize Size, Align Align, StructPacking Pack=StructPacking::Default, RecordFlags RecFlags=RecordFlags::None)
Definition Types.h:274
uint32_t getNumFields() const
Definition Types.h:281
ArrayRef< FieldInfo > getVirtualBaseClasses() const
Returns the virtual base classes, both direct and indirect, mirroring clang::CXXRecordDecl::vbases().
Definition Types.h:318
StructPacking getPacking() const
Definition Types.h:282
const ComplexType * getComplexType(const Type *ElementType, Align Align)
Definition Types.h:435
const FloatType * getFloatType(const fltSemantics &Semantics, Align Align)
Definition Types.h:362
const IntegerType * getIntegerType(uint64_t BitWidth, Align Align, bool Signed, bool IsBitInt=false)
Definition Types.h:356
const MemberPointerType * getMemberPointerType(bool IsFunctionPointer, uint64_t SizeInBits, Align Align)
Definition Types.h:444
const RecordType * getRecordType(ArrayRef< FieldInfo > Fields, TypeSize Size, Align Align, StructPacking Pack=StructPacking::Default, ArrayRef< FieldInfo > BaseClasses={}, ArrayRef< FieldInfo > VirtualBaseClasses={}, RecordFlags RecFlags=RecordFlags::None)
Definition Types.h:385
TypeBuilder(BumpPtrAllocator &Alloc)
Definition Types.h:350
const ArrayType * getArrayType(const Type *ElementType, uint64_t NumElements, uint64_t SizeInBits, bool IsMatrixType=false)
Definition Types.h:372
const PointerType * getPointerType(uint64_t Size, Align Align, unsigned Addrspace=0)
Definition Types.h:366
const VoidType * getVoidType()
Definition Types.h:352
const RecordType * getUnionType(ArrayRef< FieldInfo > Fields, TypeSize Size, Align Align, StructPacking Pack=StructPacking::Default, RecordFlags RecFlags=RecordFlags::None)
Definition Types.h:415
const VectorType * getVectorType(const Type *ElementType, ElementCount NumElements, Align Align)
Definition Types.h:379
Represents the ABI-specific view of a type in LLVM.
Definition Types.h:44
TypeSize getTypeAllocSize() const
Definition Types.h:71
Align ABIAlignment
Definition Types.h:61
bool isMemberPointer() const
Definition Types.h:82
bool isVoid() const
Definition Types.h:75
TypeSize SizeInBits
Definition Types.h:60
TypeSize getSizeInBits() const
Definition Types.h:68
bool isInteger() const
Definition Types.h:76
Type(TypeKind K, TypeSize SizeInBits, Align ABIAlign)
Definition Types.h:63
TypeKind Kind
Definition Types.h:59
bool isRecord() const
Definition Types.h:81
bool isArray() const
Definition Types.h:79
bool isZeroSize() const
Definition Types.h:84
bool isVector() const
Definition Types.h:80
bool isFloat() const
Definition Types.h:77
Align getAlignment() const
Definition Types.h:69
bool isComplex() const
Definition Types.h:83
TypeKind getKind() const
Definition Types.h:67
bool isPointer() const
Definition Types.h:78
ElementCount getNumElements() const
Definition Types.h:227
const Type * getElementType() const
Definition Types.h:226
static bool classof(const Type *T)
Definition Types.h:229
VectorType(const Type *ElementType, ElementCount NumElements, Align ABIAlign)
Definition Types.h:218
static bool classof(const Type *T)
Definition Types.h:91
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
RecordFlags
Definition Types.h:254
@ IsPolymorphic
Definition Types.h:260
@ IsCXXRecord
Definition Types.h:259
@ CanPassInRegisters
Definition Types.h:256
@ IsTransparent
Definition Types.h:258
@ LLVM_MARK_AS_BITMASK_ENUM
Definition Types.h:262
@ IsUnion
Definition Types.h:257
@ HasFlexibleArrayMember
Definition Types.h:261
StructPacking
Definition Types.h:252
This is an optimization pass for GlobalISel generic memory operations.
constexpr T alignToPowerOf2(U Value, V Align)
Will overflow only if result is not representable in T.
Definition MathExtras.h:488
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:390
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
FieldInfo(const Type *FieldType, uint64_t OffsetInBits=0, bool IsBitField=false, uint64_t BitFieldWidth=0, bool IsUnnamedBitField=false, bool IsVirtualBase=false)
Definition Types.h:242
const Type * FieldType
Definition Types.h:235
uint64_t BitFieldWidth
Definition Types.h:237
LLVM_ABI bool isEmpty() const
Definition Types.cpp:67
uint64_t OffsetInBits
Definition Types.h:236