Skip to main content

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}