Skip to content

Commit 0858b1f

Browse files
committed
[LLVMABI] API for Creating types
1 parent 322c1cf commit 0858b1f

File tree

1 file changed

+213
-31
lines changed

1 file changed

+213
-31
lines changed

llvm/include/llvm/ABI/Types.h

Lines changed: 213 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#ifndef LLVM_ABI_TYPES_H
22
#define LLVM_ABI_TYPES_H
33

4+
#include "llvm/ADT/ArrayRef.h"
5+
#include "llvm/Support/Allocator.h"
46
#include <cstdint>
5-
#include <memory>
6-
#include <string>
77

88
namespace llvm {
99
namespace abi {
@@ -19,6 +19,7 @@ enum class TypeKind {
1919
Union,
2020
Function
2121
};
22+
2223
class Type {
2324
protected:
2425
TypeKind Kind;
@@ -31,8 +32,6 @@ class Type {
3132
IsExplicitlyAligned(ExplicitAlign) {}
3233

3334
public:
34-
virtual ~Type() = default;
35-
3635
TypeKind getKind() const { return Kind; }
3736
uint64_t getSizeInBits() const { return SizeInBits; }
3837
uint64_t getAlignInBits() const { return AlignInBits; }
@@ -52,9 +51,8 @@ class Type {
5251
bool isStruct() const { return Kind == TypeKind::Struct; }
5352
bool isUnion() const { return Kind == TypeKind::Union; }
5453
bool isFunction() const { return Kind == TypeKind::Function; }
55-
56-
static bool classof(const Type *) { return true; }
5754
};
55+
5856
class VoidType : public Type {
5957
public:
6058
VoidType() : Type(TypeKind::Void, 0, 0) {}
@@ -65,53 +63,237 @@ class VoidType : public Type {
6563
class IntegerType : public Type {
6664
private:
6765
bool IsSigned;
68-
bool IsAltRepresentation;
69-
std::string TypeName;
7066

7167
public:
72-
IntegerType(uint64_t BitWidth, uint64_t Align, bool Signed,
73-
bool AltRep = false, const std::string &Name = "")
74-
: Type(TypeKind::Integer, BitWidth, Align), IsSigned(Signed),
75-
IsAltRepresentation(AltRep), TypeName(Name) {}
68+
IntegerType(uint64_t BitWidth, uint64_t Align, bool Signed)
69+
: Type(TypeKind::Integer, BitWidth, Align), IsSigned(Signed) {}
7670

7771
bool isSigned() const { return IsSigned; }
78-
bool isAltRepresentation() const { return IsAltRepresentation; }
79-
const std::string &getTypeName() const { return TypeName; }
8072

8173
static bool classof(const Type *T) {
8274
return T->getKind() == TypeKind::Integer;
8375
}
8476
};
77+
8578
class FloatType : public Type {
79+
public:
80+
FloatType(uint64_t BitWidth, uint64_t Align)
81+
: Type(TypeKind::Float, BitWidth, Align) {}
82+
83+
static bool classof(const Type *T) { return T->getKind() == TypeKind::Float; }
84+
};
85+
86+
class PointerType : public Type {
87+
public:
88+
PointerType(uint64_t Size, uint64_t Align)
89+
: Type(TypeKind::Pointer, Size, Align) {}
90+
91+
static bool classof(const Type *T) {
92+
return T->getKind() == TypeKind::Pointer;
93+
}
94+
};
95+
96+
class ArrayType : public Type {
8697
private:
87-
std::string TypeName;
98+
const Type *ElementType;
99+
uint64_t NumElements;
88100

89101
public:
90-
FloatType(uint64_t BitWidth, uint64_t Align, const std::string &Name)
91-
: Type(TypeKind::Float, BitWidth, Align), TypeName(Name) {}
102+
ArrayType(const Type *ElemType, uint64_t NumElems)
103+
: Type(TypeKind::Array, ElemType->getSizeInBits() * NumElems,
104+
ElemType->getAlignInBits()),
105+
ElementType(ElemType), NumElements(NumElems) {}
92106

93-
const std::string &getTypeName() const { return TypeName; }
107+
const Type *getElementType() const { return ElementType; }
108+
uint64_t getNumElements() const { return NumElements; }
94109

95-
static bool classof(const Type *T) { return T->getKind() == TypeKind::Float; }
110+
static bool classof(const Type *T) { return T->getKind() == TypeKind::Array; }
96111
};
97-
class PointerType : public Type {
112+
113+
class VectorType : public Type {
98114
private:
99-
std::unique_ptr<Type> PointeeType;
100-
bool IsConst;
101-
bool IsVolatile;
115+
const Type *ElementType;
116+
uint64_t NumElements;
102117

103118
public:
104-
PointerType(std::unique_ptr<Type> Pointee, uint64_t Size, uint64_t Align,
105-
bool Const = false, bool Volatile = false)
106-
: Type(TypeKind::Pointer, Size, Align), PointeeType(std::move(Pointee)),
107-
IsConst(Const), IsVolatile(Volatile) {}
119+
VectorType(const Type *ElemType, uint64_t NumElems, uint64_t Align)
120+
: Type(TypeKind::Vector, ElemType->getSizeInBits() * NumElems, Align),
121+
ElementType(ElemType), NumElements(NumElems) {}
108122

109-
const Type *getPointeeType() const { return PointeeType.get(); }
110-
bool isConst() const { return IsConst; }
111-
bool isVolatile() const { return IsVolatile; }
123+
const Type *getElementType() const { return ElementType; }
124+
uint64_t getNumElements() const { return NumElements; }
112125

113126
static bool classof(const Type *T) {
114-
return T->getKind() == TypeKind::Pointer;
127+
return T->getKind() == TypeKind::Vector;
128+
}
129+
};
130+
131+
struct FieldInfo {
132+
const Type *FieldType;
133+
uint64_t OffsetInBits;
134+
bool IsBitField;
135+
uint64_t BitFieldWidth;
136+
137+
FieldInfo(const Type *Type, uint64_t Offset = 0, bool BitField = false,
138+
uint64_t BFWidth = 0)
139+
: FieldType(Type), OffsetInBits(Offset), IsBitField(BitField),
140+
BitFieldWidth(BFWidth) {}
141+
};
142+
143+
enum class StructPacking { Default, Packed, ExplicitPacking };
144+
145+
class StructType : public Type {
146+
private:
147+
const FieldInfo *Fields;
148+
uint32_t NumFields;
149+
StructPacking Packing;
150+
151+
public:
152+
StructType(const FieldInfo *StructFields, uint32_t FieldCount, uint64_t Size,
153+
uint64_t Align, StructPacking Pack = StructPacking::Default)
154+
: Type(TypeKind::Struct, Size, Align), Fields(StructFields),
155+
NumFields(FieldCount), Packing(Pack) {}
156+
157+
const FieldInfo *getFields() const { return Fields; }
158+
uint32_t getNumFields() const { return NumFields; }
159+
StructPacking getPacking() const { return Packing; }
160+
161+
static bool classof(const Type *T) {
162+
return T->getKind() == TypeKind::Struct;
163+
}
164+
};
165+
166+
class UnionType : public Type {
167+
private:
168+
const FieldInfo *Fields;
169+
uint32_t NumFields;
170+
StructPacking Packing;
171+
172+
public:
173+
UnionType(const FieldInfo *UnionFields, uint32_t FieldCount, uint64_t Size,
174+
uint64_t Align, StructPacking Pack = StructPacking::Default)
175+
: Type(TypeKind::Union, Size, Align), Fields(UnionFields),
176+
NumFields(FieldCount), Packing(Pack) {}
177+
178+
const FieldInfo *getFields() const { return Fields; }
179+
uint32_t getNumFields() const { return NumFields; }
180+
StructPacking getPacking() const { return Packing; }
181+
182+
static bool classof(const Type *T) { return T->getKind() == TypeKind::Union; }
183+
};
184+
185+
enum class CallConv {
186+
C,
187+
// TODO: extend for more CallConvs
188+
};
189+
190+
class FunctionType : public Type {
191+
private:
192+
const Type *ReturnType;
193+
const Type *const *ParameterTypes;
194+
uint32_t NumParams;
195+
bool IsVarArg;
196+
CallConv CC;
197+
198+
public:
199+
FunctionType(const Type *RetType, const Type *const *ParamTypes,
200+
uint32_t ParamCount, bool VarArgs, CallConv CallConv)
201+
: Type(TypeKind::Function, 0, 0), ReturnType(RetType),
202+
ParameterTypes(ParamTypes), NumParams(ParamCount), IsVarArg(VarArgs),
203+
CC(CallConv) {}
204+
205+
const Type *getReturnType() const { return ReturnType; }
206+
const Type *const *getParameterTypes() const { return ParameterTypes; }
207+
uint32_t getNumParameters() const { return NumParams; }
208+
const Type *getParameterType(uint32_t Index) const {
209+
assert(Index < NumParams && "Parameter index out of bounds");
210+
return ParameterTypes[Index];
211+
}
212+
bool isVarArg() const { return IsVarArg; }
213+
CallConv getCallingConv() const { return CC; }
214+
215+
static bool classof(const Type *T) {
216+
return T->getKind() == TypeKind::Function;
217+
}
218+
};
219+
220+
// API for creating ABI Types
221+
class TypeBuilder {
222+
private:
223+
BumpPtrAllocator &Allocator;
224+
225+
public:
226+
explicit TypeBuilder(BumpPtrAllocator &Alloc) : Allocator(Alloc) {}
227+
228+
const VoidType *getVoidType() {
229+
return new (Allocator.Allocate<VoidType>()) VoidType();
230+
}
231+
232+
const IntegerType *getIntegerType(uint64_t BitWidth, uint64_t Align,
233+
bool Signed) {
234+
return new (Allocator.Allocate<IntegerType>())
235+
IntegerType(BitWidth, Align, Signed);
236+
}
237+
238+
const FloatType *getFloatType(uint64_t BitWidth, uint64_t Align) {
239+
return new (Allocator.Allocate<FloatType>()) FloatType(BitWidth, Align);
240+
}
241+
242+
const PointerType *getPointerType(uint64_t Size, uint64_t Align) {
243+
return new (Allocator.Allocate<PointerType>()) PointerType(Size, Align);
244+
}
245+
246+
const ArrayType *getArrayType(const Type *ElementType, uint64_t NumElements) {
247+
return new (Allocator.Allocate<ArrayType>())
248+
ArrayType(ElementType, NumElements);
249+
}
250+
251+
const VectorType *getVectorType(const Type *ElementType, uint64_t NumElements,
252+
uint64_t Align) {
253+
return new (Allocator.Allocate<VectorType>())
254+
VectorType(ElementType, NumElements, Align);
255+
}
256+
257+
const StructType *getStructType(ArrayRef<FieldInfo> Fields, uint64_t Size,
258+
uint64_t Align,
259+
StructPacking Pack = StructPacking::Default) {
260+
FieldInfo *FieldArray = Allocator.Allocate<FieldInfo>(Fields.size());
261+
262+
for (size_t I = 0; I < Fields.size(); ++I) {
263+
new (&FieldArray[I]) FieldInfo(Fields[I]);
264+
}
265+
266+
return new (Allocator.Allocate<StructType>()) StructType(
267+
FieldArray, static_cast<uint32_t>(Fields.size()), Size, Align, Pack);
268+
}
269+
270+
const UnionType *getUnionType(ArrayRef<FieldInfo> Fields, uint64_t Size,
271+
uint64_t Align,
272+
StructPacking Pack = StructPacking::Default) {
273+
FieldInfo *FieldArray = Allocator.Allocate<FieldInfo>(Fields.size());
274+
275+
for (size_t I = 0; I < Fields.size(); ++I) {
276+
new (&FieldArray[I]) FieldInfo(Fields[I]);
277+
}
278+
279+
return new (Allocator.Allocate<UnionType>()) UnionType(
280+
FieldArray, static_cast<uint32_t>(Fields.size()), Size, Align, Pack);
281+
}
282+
283+
const FunctionType *getFunctionType(const Type *ReturnType,
284+
ArrayRef<const Type *> ParamTypes,
285+
bool IsVarArg,
286+
CallConv CC = CallConv::C) {
287+
const Type **ParamArray =
288+
Allocator.Allocate<const Type *>(ParamTypes.size());
289+
290+
for (size_t I = 0; I < ParamTypes.size(); ++I) {
291+
ParamArray[I] = ParamTypes[I];
292+
}
293+
294+
return new (Allocator.Allocate<FunctionType>())
295+
FunctionType(ReturnType, ParamArray,
296+
static_cast<uint32_t>(ParamTypes.size()), IsVarArg, CC);
115297
}
116298
};
117299

0 commit comments

Comments
 (0)