repr_c_impl/builder/
common.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2#![allow(clippy::match_like_matches_macro)]
3
4use crate::layout::{BuiltinType, Type, TypeLayout, TypeVariant};
5use crate::result::Result;
6use crate::target::Target;
7use crate::util::{MinExt, BITS_PER_BYTE};
8
9pub fn compute_builtin_type_layout(target: Target, bi: BuiltinType) -> Result<Type<TypeLayout>> {
10    Ok(Type {
11        layout: builtin_type_layout(target, bi),
12        // Pre-validation ensures that builtin types do not have annotations.
13        annotations: vec![],
14        variant: TypeVariant::Builtin(bi),
15    })
16}
17
18pub fn compute_opaque_type_layout(layout: TypeLayout) -> Result<Type<TypeLayout>> {
19    Ok(Type {
20        layout,
21        // Pre-validation ensures that opaque types do not have annotations.
22        annotations: vec![],
23        variant: TypeVariant::Opaque(layout),
24    })
25}
26
27pub fn apply_alignment_override(layout: TypeLayout, alignment: Option<u64>) -> TypeLayout {
28    TypeLayout {
29        field_alignment_bits: alignment.unwrap_or(layout.field_alignment_bits),
30        pointer_alignment_bits: alignment.min2(layout.pointer_alignment_bits),
31        ..layout
32    }
33}
34
35pub fn unnamed_field_affects_record_alignment(target: Target) -> bool {
36    use Target::*;
37    match target {
38        | Aarch64Fuchsia
39        | Aarch64LinuxAndroid
40        | Aarch64UnknownFreebsd
41        | Aarch64UnknownHermit
42        | Aarch64UnknownLinuxGnu
43        | Aarch64UnknownLinuxMusl
44        | Aarch64UnknownNetbsd
45        | Aarch64UnknownNone
46        | Aarch64UnknownOpenbsd
47        | Aarch64UnknownRedox
48        | Armebv7rUnknownNoneEabi
49        | Armebv7rUnknownNoneEabihf
50        | ArmLinuxAndroideabi
51        | ArmUnknownLinuxGnueabi
52        | ArmUnknownLinuxGnueabihf
53        | Armv4tUnknownLinuxGnueabi
54        | Armv5teUnknownLinuxGnueabi
55        | Armv5teUnknownLinuxUclibcgnueabi
56        | Armv6UnknownFreebsdGnueabihf
57        | Armv6UnknownNetbsdelfEabihf
58        | Armv7aNoneEabi
59        | Armv7aNoneEabihf
60        | Armv7AppleIos
61        | Armv7NoneLinuxAndroid
62        | Armv7rUnknownNoneEabi
63        | Armv7rUnknownNoneEabihf
64        | Armv7sAppleIos
65        | Armv7UnknownFreebsdGnueabihf
66        | Armv7UnknownLinuxGnueabi
67        | Armv7UnknownLinuxGnueabihf
68        | Armv7UnknownNetbsdelfEabihf
69        | AvrUnknownUnknown
70        | Thumbv4tNoneEabi
71        | Thumbv6mNoneEabi
72        | Thumbv7emNoneEabi
73        | Thumbv7emNoneEabihf
74        | Thumbv7mNoneEabi
75        | Thumbv8mBaseNoneEabi
76        | Thumbv8mMainNoneEabi
77        | Thumbv8mMainNoneEabihf => true,
78        _ => false,
79    }
80}
81
82pub fn min_zero_width_bitfield_alignment(target: Target) -> Option<u64> {
83    use Target::*;
84    match target {
85        AvrUnknownUnknown => Some(8),
86        Armv7AppleIos | Armv7sAppleIos => Some(32),
87        _ => None,
88    }
89}
90
91pub fn builtin_type_layout(target: Target, b: BuiltinType) -> TypeLayout {
92    use BuiltinType::*;
93    use Target::*;
94
95    match target {
96        AvrUnknownUnknown => return avr_builtin_type_layout(b),
97        Msp430NoneElf => return msp430_builtin_type_layout(b),
98        _ => {}
99    }
100
101    // See test case 0013.
102    let (size_bytes, alignment_bytes) = match b {
103        Unit => (0, 1),
104        Char | SignedChar | UnsignedChar | Bool | U8 | I8 => (1, 1),
105        Short | UnsignedShort | U16 | I16 => (2, 2),
106        Float | F32 | Int | UnsignedInt | U32 | I32 => (4, 4),
107        Double | F64 | LongLong | UnsignedLongLong | U64 | I64 => match target {
108            I386AppleIos | I686LinuxAndroid | I686UnknownFreebsd | I686UnknownHaiku
109            | I686UnknownNetbsdelf | I686UnknownOpenbsd | Armv7AppleIos | Armv7sAppleIos
110            | I586UnknownLinuxGnu | I586UnknownLinuxMusl | I686UnknownLinuxGnu
111            | I686UnknownLinuxMusl | I686AppleMacosx => (8, 4),
112            _ => (8, 8),
113        },
114        // See test case 0050.
115        U128 | I128 => match target {
116            S390xUnknownLinuxGnu => (16, 8),
117            _ => (16, 16),
118        },
119        Long | UnsignedLong => match target {
120            | Aarch64PcWindowsMsvc
121            | Armebv7rUnknownNoneEabi
122            | Armebv7rUnknownNoneEabihf
123            | ArmLinuxAndroideabi
124            | ArmUnknownLinuxGnueabi
125            | ArmUnknownLinuxGnueabihf
126            | Armv4tUnknownLinuxGnueabi
127            | Armv5teUnknownLinuxGnueabi
128            | Armv5teUnknownLinuxUclibcgnueabi
129            | Armv6UnknownFreebsdGnueabihf
130            | Armv6UnknownNetbsdelfEabihf
131            | Armv7aNoneEabi
132            | Armv7aNoneEabihf
133            | Armv7AppleIos
134            | Armv7NoneLinuxAndroid
135            | Armv7rUnknownNoneEabi
136            | Armv7rUnknownNoneEabihf
137            | Armv7sAppleIos
138            | Armv7UnknownFreebsdGnueabihf
139            | Armv7UnknownLinuxGnueabi
140            | Armv7UnknownLinuxGnueabihf
141            | Armv7UnknownNetbsdelfEabihf
142            | AvrUnknownUnknown
143            | HexagonUnknownLinuxMusl
144            | I386AppleIos
145            | I586PcWindowsMsvc
146            | I586UnknownLinuxGnu
147            | I586UnknownLinuxMusl
148            | I686AppleMacosx
149            | I686LinuxAndroid
150            | I686PcWindowsGnu
151            | I686PcWindowsMsvc
152            | I686UnknownFreebsd
153            | I686UnknownHaiku
154            | I686UnknownLinuxGnu
155            | I686UnknownLinuxMusl
156            | I686UnknownNetbsdelf
157            | I686UnknownOpenbsd
158            | I686UnknownWindows
159            | MipselSonyPsp
160            | MipselUnknownLinuxGnu
161            | MipselUnknownLinuxMusl
162            | MipselUnknownLinuxUclibc
163            | MipselUnknownNone
164            | Mipsisa32r6elUnknownLinuxGnu
165            | Mipsisa32r6UnknownLinuxGnu
166            | MipsUnknownLinuxGnu
167            | MipsUnknownLinuxMusl
168            | MipsUnknownLinuxUclibc
169            | Msp430NoneElf
170            | PowerpcUnknownLinuxGnu
171            | PowerpcUnknownLinuxGnuspe
172            | PowerpcUnknownLinuxMusl
173            | PowerpcUnknownNetbsd
174            | Riscv32
175            | Riscv32UnknownLinuxGnu
176            | SparcUnknownLinuxGnu
177            | Thumbv4tNoneEabi
178            | Thumbv6mNoneEabi
179            | Thumbv7aPcWindowsMsvc
180            | Thumbv7emNoneEabi
181            | Thumbv7emNoneEabihf
182            | Thumbv7mNoneEabi
183            | Thumbv8mBaseNoneEabi
184            | Thumbv8mMainNoneEabi
185            | Thumbv8mMainNoneEabihf
186            | Wasm32UnknownEmscripten
187            | Wasm32UnknownUnknown
188            | Wasm32Wasi
189            | X86_64PcWindowsGnu
190            | X86_64PcWindowsMsvc
191            | X86_64UnknownWindows => (4, 4),
192            _ => (8, 8),
193        },
194        Pointer => match target {
195            | Armebv7rUnknownNoneEabi
196            | Armebv7rUnknownNoneEabihf
197            | ArmLinuxAndroideabi
198            | ArmUnknownLinuxGnueabi
199            | ArmUnknownLinuxGnueabihf
200            | Armv4tUnknownLinuxGnueabi
201            | Armv5teUnknownLinuxGnueabi
202            | Armv5teUnknownLinuxUclibcgnueabi
203            | Armv6UnknownFreebsdGnueabihf
204            | Armv6UnknownNetbsdelfEabihf
205            | Armv7aNoneEabi
206            | Armv7aNoneEabihf
207            | Armv7AppleIos
208            | Armv7NoneLinuxAndroid
209            | Armv7rUnknownNoneEabi
210            | Armv7rUnknownNoneEabihf
211            | Armv7sAppleIos
212            | Armv7UnknownFreebsdGnueabihf
213            | Armv7UnknownLinuxGnueabi
214            | Armv7UnknownLinuxGnueabihf
215            | Armv7UnknownNetbsdelfEabihf
216            | AvrUnknownUnknown
217            | HexagonUnknownLinuxMusl
218            | I386AppleIos
219            | I586PcWindowsMsvc
220            | I586UnknownLinuxGnu
221            | I586UnknownLinuxMusl
222            | I686AppleMacosx
223            | I686LinuxAndroid
224            | I686PcWindowsGnu
225            | I686PcWindowsMsvc
226            | I686UnknownFreebsd
227            | I686UnknownHaiku
228            | I686UnknownLinuxGnu
229            | I686UnknownLinuxMusl
230            | I686UnknownNetbsdelf
231            | I686UnknownOpenbsd
232            | I686UnknownWindows
233            | MipselSonyPsp
234            | MipselUnknownLinuxGnu
235            | MipselUnknownLinuxMusl
236            | MipselUnknownLinuxUclibc
237            | MipselUnknownNone
238            | Mipsisa32r6elUnknownLinuxGnu
239            | Mipsisa32r6UnknownLinuxGnu
240            | MipsUnknownLinuxGnu
241            | MipsUnknownLinuxMusl
242            | MipsUnknownLinuxUclibc
243            | Msp430NoneElf
244            | PowerpcUnknownLinuxGnu
245            | PowerpcUnknownLinuxGnuspe
246            | PowerpcUnknownLinuxMusl
247            | PowerpcUnknownNetbsd
248            | Riscv32
249            | Riscv32UnknownLinuxGnu
250            | SparcUnknownLinuxGnu
251            | Thumbv4tNoneEabi
252            | Thumbv6mNoneEabi
253            | Thumbv7aPcWindowsMsvc
254            | Thumbv7emNoneEabi
255            | Thumbv7emNoneEabihf
256            | Thumbv7mNoneEabi
257            | Thumbv8mBaseNoneEabi
258            | Thumbv8mMainNoneEabi
259            | Thumbv8mMainNoneEabihf
260            | Wasm32UnknownEmscripten
261            | Wasm32UnknownUnknown
262            | Wasm32Wasi => (4, 4),
263            _ => (8, 8),
264        },
265    };
266    TypeLayout {
267        size_bits: size_bytes * BITS_PER_BYTE,
268        pointer_alignment_bits: alignment_bytes * BITS_PER_BYTE,
269        field_alignment_bits: alignment_bytes * BITS_PER_BYTE,
270        required_alignment_bits: BITS_PER_BYTE,
271    }
272}
273
274pub fn avr_builtin_type_layout(b: BuiltinType) -> TypeLayout {
275    use BuiltinType::*;
276
277    let size_bytes = match b {
278        Unit => 0,
279        Char | SignedChar | UnsignedChar | Bool | U8 | I8 => 1,
280        Pointer | Short | UnsignedShort | U16 | I16 | Int | UnsignedInt => 2,
281        Long | UnsignedLong | Double | Float | F32 | U32 | I32 => 4,
282        F64 | LongLong | UnsignedLongLong | U64 | I64 => 8,
283        U128 | I128 => 16,
284    };
285    TypeLayout {
286        size_bits: size_bytes * BITS_PER_BYTE,
287        pointer_alignment_bits: BITS_PER_BYTE,
288        field_alignment_bits: BITS_PER_BYTE,
289        required_alignment_bits: BITS_PER_BYTE,
290    }
291}
292
293pub fn msp430_builtin_type_layout(b: BuiltinType) -> TypeLayout {
294    use BuiltinType::*;
295
296    let mut alignment = 2;
297
298    let size_bytes = match b {
299        Unit => 0,
300        Char | SignedChar | UnsignedChar | Bool | U8 | I8 => {
301            alignment = 1;
302            1
303        }
304        Pointer | Short | UnsignedShort | U16 | I16 | Int | UnsignedInt => 2,
305        Long | UnsignedLong | Float | F32 | U32 | I32 => 4,
306        Double | F64 | LongLong | UnsignedLongLong | U64 | I64 => 8,
307        U128 | I128 => 16,
308    };
309    TypeLayout {
310        size_bits: size_bytes * BITS_PER_BYTE,
311        pointer_alignment_bits: alignment * BITS_PER_BYTE,
312        field_alignment_bits: alignment * BITS_PER_BYTE,
313        required_alignment_bits: BITS_PER_BYTE,
314    }
315}
316
317pub fn ignore_non_zero_sized_bitfield_type_alignment(target: Target) -> bool {
318    use Target::*;
319    match target {
320        AvrUnknownUnknown | Armv7AppleIos | Armv7sAppleIos => true,
321        _ => false,
322    }
323}
324
325pub fn ignore_zero_sized_bitfield_type_alignmont(target: Target) -> bool {
326    use Target::*;
327    match target {
328        AvrUnknownUnknown => true,
329        _ => false,
330    }
331}
332
333pub fn pack_all_enums(target: Target) -> bool {
334    use Target::*;
335    match target {
336        HexagonUnknownLinuxMusl => true,
337        _ => false,
338    }
339}
340
341pub fn default_aligned_alignment(target: Target) -> u64 {
342    use Target::*;
343    match target {
344        | AvrUnknownUnknown => 8,
345        | ArmUnknownLinuxGnueabi
346        | ArmUnknownLinuxGnueabihf
347        | Armebv7rUnknownNoneEabi
348        | Armebv7rUnknownNoneEabihf
349        | Armv4tUnknownLinuxGnueabi
350        | Armv5teUnknownLinuxGnueabi
351        | Armv5teUnknownLinuxUclibcgnueabi
352        | Armv6UnknownFreebsdGnueabihf
353        | Armv6UnknownNetbsdelfEabihf
354        | Armv7UnknownFreebsdGnueabihf
355        | Armv7UnknownLinuxGnueabi
356        | Armv7UnknownLinuxGnueabihf
357        | Armv7UnknownNetbsdelfEabihf
358        | Armv7aNoneEabi
359        | Armv7aNoneEabihf
360        | Armv7rUnknownNoneEabi
361        | Armv7rUnknownNoneEabihf
362        | MipsUnknownLinuxGnu
363        | MipsUnknownLinuxMusl
364        | MipsUnknownLinuxUclibc
365        | MipselUnknownLinuxGnu
366        | MipselUnknownLinuxMusl
367        | MipselUnknownLinuxUclibc
368        | Mipsisa32r6UnknownLinuxGnu
369        | Mipsisa32r6elUnknownLinuxGnu
370        | S390xUnknownLinuxGnu
371        | SparcUnknownLinuxGnu
372        | Thumbv4tNoneEabi
373        | Thumbv6mNoneEabi
374        | Thumbv7aPcWindowsMsvc
375        | Thumbv7emNoneEabi
376        | Thumbv7emNoneEabihf
377        | Thumbv7mNoneEabi
378        | Thumbv8mBaseNoneEabi
379        | Thumbv8mMainNoneEabi
380        | Thumbv8mMainNoneEabihf => 64,
381        _ => 128,
382    }
383}