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)] 5 pub enum IntKind { 6 /// A `bool`. 7 Bool, 8 9 /// A `signed char`. 10 SChar, 11 12 /// An `unsigned char`. 13 UChar, 14 15 /// An `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 /// Either a `char16_t` or a `wchar_t`. 58 U16, 59 60 /// A 32-bit signed integer. 61 I32, 62 63 /// A 32-bit unsigned integer. 64 U32, 65 66 /// A 64-bit signed integer. 67 I64, 68 69 /// A 64-bit unsigned integer. 70 U64, 71 72 /// An `int128_t` 73 I128, 74 75 /// A `uint128_t`. 76 U128, 77 78 /// A custom integer type, used to allow custom macro types depending on 79 /// range. 80 Custom { 81 /// The name of the type, which would be used without modification. 82 name: &'static str, 83 /// Whether the type is signed or not. 84 is_signed: bool, 85 }, 86 } 87 88 impl IntKind { 89 /// Is this integral type signed? is_signed(&self) -> bool90 pub fn is_signed(&self) -> bool { 91 use self::IntKind::*; 92 match *self { 93 // TODO(emilio): wchar_t can in theory be signed, but we have no way 94 // to know whether it is or not right now (unlike char, there's no 95 // WChar_S / WChar_U). 96 Bool | UChar | UShort | UInt | ULong | ULongLong | U8 | U16 | 97 WChar | U32 | U64 | U128 => false, 98 99 SChar | Short | Int | Long | LongLong | I8 | I16 | I32 | I64 | 100 I128 => true, 101 102 Char { is_signed } => is_signed, 103 104 Custom { is_signed, .. } => is_signed, 105 } 106 } 107 108 /// If this type has a known size, return it (in bytes). This is to 109 /// alleviate libclang sometimes not giving us a layout (like in the case 110 /// when an enum is defined inside a class with template parameters). known_size(&self) -> Option<usize>111 pub fn known_size(&self) -> Option<usize> { 112 use self::IntKind::*; 113 Some(match *self { 114 Bool | UChar | SChar | U8 | I8 | Char { .. } => 1, 115 U16 | I16 => 2, 116 U32 | I32 => 4, 117 U64 | I64 => 8, 118 I128 | U128 => 16, 119 _ => return None, 120 }) 121 } 122 123 /// Whether this type's signedness matches the value. signedness_matches(&self, val: i64) -> bool124 pub fn signedness_matches(&self, val: i64) -> bool { 125 val >= 0 || self.is_signed() 126 } 127 } 128