1 | /// The size of a type. |
2 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
3 | #[allow (missing_docs)] |
4 | pub enum Size { |
5 | U8, |
6 | U16, |
7 | U32, |
8 | U64, |
9 | } |
10 | |
11 | impl 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)] |
44 | pub 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 | |
65 | impl 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 | |