bindgen/ir/int.rs
1//! Intermediate representation for integral types.
2
3/// Which integral type are we dealing with?
4#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
5pub enum IntKind {
6 /// A `bool`.
7 Bool,
8
9 /// A `signed char`.
10 SChar,
11
12 /// An `unsigned char`.
13 UChar,
14
15 /// A `wchar_t`.
16 WChar,
17
18 /// A platform-dependent `char` type, with the signedness support.
19 Char {
20 /// Whether the char is signed for the target platform.
21 is_signed: bool,
22 },
23
24 /// A `short`.
25 Short,
26
27 /// An `unsigned short`.
28 UShort,
29
30 /// An `int`.
31 Int,
32
33 /// An `unsigned int`.
34 UInt,
35
36 /// A `long`.
37 Long,
38
39 /// An `unsigned long`.
40 ULong,
41
42 /// A `long long`.
43 LongLong,
44
45 /// An `unsigned long long`.
46 ULongLong,
47
48 /// A 8-bit signed integer.
49 I8,
50
51 /// A 8-bit unsigned integer.
52 U8,
53
54 /// A 16-bit signed integer.
55 I16,
56
57 /// A 16-bit integer, used only for enum size representation.
58 U16,
59
60 /// The C++ type `char16_t`, which is its own type (unlike in C).
61 Char16,
62
63 /// A 32-bit signed integer.
64 I32,
65
66 /// A 32-bit unsigned integer.
67 U32,
68
69 /// A 64-bit signed integer.
70 I64,
71
72 /// A 64-bit unsigned integer.
73 U64,
74
75 /// An `int128_t`
76 I128,
77
78 /// A `uint128_t`.
79 U128,
80
81 /// A custom integer type, used to allow custom macro types depending on
82 /// range.
83 Custom {
84 /// The name of the type, which would be used without modification.
85 name: &'static str,
86 /// Whether the type is signed or not.
87 is_signed: bool,
88 },
89}
90
91impl IntKind {
92 /// Is this integral type signed?
93 pub(crate) fn is_signed(&self) -> bool {
94 use self::IntKind::*;
95 match *self {
96 // TODO(emilio): wchar_t can in theory be signed, but we have no way
97 // to know whether it is or not right now (unlike char, there's no
98 // WChar_S / WChar_U).
99 Bool | UChar | UShort | UInt | ULong | ULongLong | U8 | U16 |
100 Char16 | WChar | U32 | U64 | U128 => false,
101
102 SChar | Short | Int | Long | LongLong | I8 | I16 | I32 | I64 |
103 I128 => true,
104
105 Char { is_signed } | Custom { is_signed, .. } => is_signed,
106 }
107 }
108
109 /// If this type has a known size, return it (in bytes). This is to
110 /// alleviate libclang sometimes not giving us a layout (like in the case
111 /// when an enum is defined inside a class with template parameters).
112 pub(crate) fn known_size(&self) -> Option<usize> {
113 use self::IntKind::*;
114 Some(match *self {
115 Bool | UChar | SChar | U8 | I8 | Char { .. } => 1,
116 U16 | I16 | Char16 => 2,
117 U32 | I32 => 4,
118 U64 | I64 => 8,
119 I128 | U128 => 16,
120 _ => return None,
121 })
122 }
123
124 /// Whether this type's signedness matches the value.
125 pub(crate) fn signedness_matches(&self, val: i64) -> bool {
126 val >= 0 || self.is_signed()
127 }
128}