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}