imping_ir/types.rs
1//! The type table: type definitions, their stable ids, and their kinds.
2
3use serde::{Deserialize, Serialize};
4
5/// A stable id for a type in its module's type table.
6///
7/// The exporter keeps ids stable across re-exports of the same build, so
8/// references and diffs stay meaningful.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
10#[serde(transparent)]
11#[cfg_attr(
12 feature = "schema",
13 derive(schemars::JsonSchema),
14 schemars(transparent)
15)]
16pub struct TypeId(pub u32);
17
18/// A named type definition in a module's type table.
19#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
20#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
21pub struct TypeDef {
22 /// The type's stable id.
23 pub id: TypeId,
24 /// The type's source name (e.g. `"Vector3"`). Not required to be unique.
25 pub name: String,
26 /// The namespace path, outermost first. Empty outside any namespace. Since
27 /// format 1.1.
28 #[serde(default, skip_serializing_if = "Vec::is_empty")]
29 pub namespace: Vec<String>,
30 /// What kind of type this is, and its kind-specific data.
31 #[serde(flatten)]
32 pub kind: TypeKind,
33}
34
35/// A type's kind and the data specific to it.
36///
37/// Serialized flat into the enclosing [`TypeDef`], with a `"kind"`
38/// discriminator.
39#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
40#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
41#[serde(tag = "kind", rename_all = "snake_case")]
42pub enum TypeKind {
43 /// A built-in primitive type.
44 Primitive {
45 /// Which primitive this is.
46 primitive: Primitive,
47 },
48 /// A pointer to another type.
49 Pointer {
50 /// The pointed-to type.
51 pointee: TypeId,
52 /// Whether the pointee is `const`.
53 #[serde(default, rename = "const")]
54 is_const: bool,
55 },
56 /// A fixed-length array.
57 Array {
58 /// The element type.
59 element: TypeId,
60 /// The number of elements.
61 count: u64,
62 },
63 /// A C `struct`.
64 Struct {
65 /// The total size in bytes.
66 size: u64,
67 /// The alignment in bytes.
68 align: u64,
69 /// The fields, in declaration order.
70 #[serde(default)]
71 fields: Vec<Field>,
72 },
73 /// A C `union`.
74 Union {
75 /// The total size in bytes.
76 size: u64,
77 /// The alignment in bytes.
78 align: u64,
79 /// The members.
80 #[serde(default)]
81 fields: Vec<Field>,
82 },
83 /// A C enumeration: a set of named integer constants over an underlying
84 /// integer type.
85 Enum {
86 /// The underlying integer type.
87 underlying: TypeId,
88 /// The named constants.
89 #[serde(default)]
90 variants: Vec<EnumVariant>,
91 },
92 /// A function (pointer) type.
93 Function {
94 /// The calling convention.
95 calling_convention: crate::CallingConvention,
96 /// The parameter types, in order.
97 #[serde(default)]
98 parameters: Vec<TypeId>,
99 /// The return type (the `void` primitive for no return value).
100 return_type: TypeId,
101 /// Whether the function is variadic.
102 #[serde(default)]
103 variadic: bool,
104 },
105 /// An alias for another type (a `typedef`).
106 Typedef {
107 /// The aliased type.
108 target: TypeId,
109 },
110 /// A type whose layout is unknown, with an optional known size.
111 Opaque {
112 /// The size in bytes, if known.
113 #[serde(default, skip_serializing_if = "Option::is_none")]
114 size: Option<u64>,
115 },
116}
117
118/// A member of a [`TypeKind::Struct`] or [`TypeKind::Union`].
119#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
120#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
121pub struct Field {
122 /// The field's name.
123 pub name: String,
124 /// The field's type.
125 #[serde(rename = "type")]
126 pub type_id: TypeId,
127 /// The field's byte offset from the start of the containing type.
128 pub offset: u64,
129 /// Bitfield placement, if this field is a bitfield.
130 #[serde(default, skip_serializing_if = "Option::is_none")]
131 pub bits: Option<BitField>,
132 /// Whether this field is the struct's embedded base class. Only meaningful
133 /// on a struct-typed field at offset 0 of a [`TypeKind::Struct`]; ignored
134 /// elsewhere. Since format 1.1.
135 #[serde(default, skip_serializing_if = "core::ops::Not::not")]
136 pub base: bool,
137}
138
139/// The bit placement of a bitfield [`Field`] within its backing storage.
140#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
141#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
142pub struct BitField {
143 /// The least-significant bit occupied, counted from the field's `offset`.
144 pub bit_offset: u32,
145 /// The number of bits occupied.
146 pub bit_width: u32,
147}
148
149/// A named constant of a [`TypeKind::Enum`].
150#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
151#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
152pub struct EnumVariant {
153 /// The constant's name.
154 pub name: String,
155 /// The constant's value, signed so negative enumerators fit.
156 pub value: i64,
157}
158
159/// A built-in primitive type.
160#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
161#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
162#[serde(rename_all = "lowercase")]
163pub enum Primitive {
164 /// No value; used for `void` returns and `void*` pointees.
165 Void,
166 /// A boolean.
167 Bool,
168 /// An 8-bit unsigned integer.
169 U8,
170 /// A 16-bit unsigned integer.
171 U16,
172 /// A 32-bit unsigned integer.
173 U32,
174 /// A 64-bit unsigned integer.
175 U64,
176 /// An 8-bit signed integer.
177 I8,
178 /// A 16-bit signed integer.
179 I16,
180 /// A 32-bit signed integer.
181 I32,
182 /// A 64-bit signed integer.
183 I64,
184 /// A 32-bit IEEE 754 float.
185 F32,
186 /// A 64-bit IEEE 754 float.
187 F64,
188}