1/// The size of a type.
2#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
3#[allow(missing_docs)]
4pub enum Size {
5 U8,
6 U16,
7 U32,
8 U64,
9}
10
11impl Size {
12 /// Return the number of bits this `Size` represents.
13 pub fn bits(self) -> u8 {
14 use Size::*;
15
16 match self {
17 U8 => 8,
18 U16 => 16,
19 U32 => 32,
20 U64 => 64,
21 }
22 }
23
24 /// Return the number of bytes in a size.
25 ///
26 /// A byte is assumed to be 8 bits.
27 pub fn bytes(self) -> u8 {
28 use Size::*;
29
30 match self {
31 U8 => 1,
32 U16 => 2,
33 U32 => 4,
34 U64 => 8,
35 }
36 }
37}
38
39/// The C data model used on a target.
40///
41/// See also https://en.cppreference.com/w/c/language/arithmetic_types
42#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
43#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
44pub enum CDataModel {
45 /// The data model used most commonly on Win16. `long` and `pointer` are 32 bits.
46 LP32,
47 /// The data model used most commonly on Win32 and 32-bit Unix systems.
48 ///
49 /// `int`, `long`, and `pointer` are all 32 bits.
50 ILP32,
51 /// The data model used most commonly on Win64
52 ///
53 /// `long long`, and `pointer` are 64 bits.
54 LLP64,
55 /// The data model used most commonly on 64-bit Unix systems
56 ///
57 /// `long`, and `pointer` are 64 bits.
58 LP64,
59 /// A rare data model used on early 64-bit Unix systems
60 ///
61 /// `int`, `long`, and `pointer` are all 64 bits.
62 ILP64,
63}
64
65impl CDataModel {
66 /// The width of a pointer (in the default address space).
67 pub fn pointer_width(self) -> Size {
68 use CDataModel::*;
69
70 match self {
71 LP32 | ILP32 => Size::U32,
72 LLP64 | LP64 | ILP64 => Size::U64,
73 }
74 }
75 /// The size of a C `short`. This is required to be at least 16 bits.
76 pub fn short_size(self) -> Size {
77 use CDataModel::*;
78
79 match self {
80 LP32 | ILP32 | LLP64 | LP64 | ILP64 => Size::U16,
81 }
82 }
83 /// The size of a C `int`. This is required to be at least 16 bits.
84 pub fn int_size(self) -> Size {
85 use CDataModel::*;
86
87 match self {
88 LP32 => Size::U16,
89 ILP32 | LLP64 | LP64 | ILP64 => Size::U32,
90 }
91 }
92 /// The size of a C `long`. This is required to be at least 32 bits.
93 pub fn long_size(self) -> Size {
94 use CDataModel::*;
95
96 match self {
97 LP32 | ILP32 | LLP64 | ILP64 => Size::U32,
98 LP64 => Size::U64,
99 }
100 }
101 /// The size of a C `long long`. This is required (in C99+) to be at least 64 bits.
102 pub fn long_long_size(self) -> Size {
103 use CDataModel::*;
104
105 match self {
106 LP32 | ILP32 | LLP64 | ILP64 | LP64 => Size::U64,
107 }
108 }
109 /// The size of a C `float`.
110 pub fn float_size(self) -> Size {
111 // TODO: this is probably wrong on at least one architecture
112 Size::U32
113 }
114 /// The size of a C `double`.
115 pub fn double_size(self) -> Size {
116 // TODO: this is probably wrong on at least one architecture
117 Size::U64
118 }
119}
120