ms_codeview/types/
primitive.rs

1//! Primitive types
2
3use super::TypeIndex;
4
5#[allow(missing_docs)]
6pub const PRIMITIVE_TYPE_SPECIAL: u32 = 0;
7#[allow(missing_docs)]
8pub const PRIMITIVE_TYPE_SIGNED_INT: u32 = 1;
9#[allow(missing_docs)]
10pub const PRIMITIVE_TYPE_UNSIGNED_INT: u32 = 2;
11#[allow(missing_docs)]
12pub const PRIMITIVE_TYPE_BOOL: u32 = 3;
13#[allow(missing_docs)]
14pub const PRIMITIVE_TYPE_REAL: u32 = 4;
15#[allow(missing_docs)]
16pub const PRIMITIVE_TYPE_COMPLEX: u32 = 5;
17#[allow(missing_docs)]
18pub const PRIMITIVE_TYPE_SPECIAL2: u32 = 6;
19#[allow(missing_docs)]
20pub const PRIMITIVE_TYPE_REALLY_INT: u32 = 7;
21
22macro_rules! primitives {
23    (
24        $(
25            (
26                $value:expr,
27                $name:ident,
28                $description:expr
29            ),
30        )*
31    ) => {
32        /// Contains the names and descriptions of all primitive types
33        pub static PRIMITIVES: &[(u32, &str, &str)] = &[
34            $(
35                ($value, stringify!($name), $description),
36            )*
37        ];
38
39        impl TypeIndex {
40            $(
41                #[doc = concat!("Primitive type: `", $description, "`")]
42                pub const $name: TypeIndex = TypeIndex($value);
43            )*
44        }
45    }
46}
47
48primitives! {
49    // number, spec name, C/C++ name
50    (0x0000, T_NOTYPE, "none"),
51    (0x0003, T_VOID, "void"),
52    (0x0008, T_HRESULT, "HRESULT"),
53    (0x0007, T_NOTTRANS, "<type-not-translated>"),
54    (0x0010, T_CHAR, "char"),
55    (0x0011, T_SHORT, "short"),
56    (0x0012, T_LONG, "long"),
57    (0x0013, T_QUAD, "long long"),
58    (0x0014, T_OCT, "__int128"),
59    (0x0020, T_UCHAR, "unsigned char"),
60    (0x0021, T_USHORT, "unsigned short"),
61    (0x0022, T_ULONG, "unsigned long"),
62    (0x0023, T_UQUAD, "unsigned long long"),
63    (0x0024, T_UOCT, "unsigned __int128"),
64    (0x0030, T_BOOL8, "bool"),
65    (0x0031, T_BOOL16, "bool16"),
66    (0x0032, T_BOOL32, "bool32"),
67    (0x0033, T_BOOL64, "bool64"),
68    (0x0040, T_REAL32, "float"),
69    (0x0041, T_REAL64, "double"),
70    (0x0068, T_INT1, "__int8"),
71    (0x0066, T_UINT1, "unsigned __int8"),
72    (0x0070, T_RCHAR, "char"), // really a character. This is "char", which is distinct from "signed char" and "unsigned char"
73    (0x0071, T_WCHAR, "wchar_t"),
74    (0x0072, T_INT2, "__int16"),
75    (0x0073, T_UINT2, "unsigned __int16"),
76    (0x0074, T_INT4, "__int32"), // really 32-bit
77    (0x0075, T_UINT4, "unsigned __int32"),
78    (0x0076, T_INT8, "__int64"),
79    (0x0077, T_UINT8, "unsigned __int64"),
80    (0x007a, T_CHAR16, "char16"),
81    (0x007b, T_CHAR32, "char32"),
82    // 32-bit pointer types
83    (0x0403, T_32PVOID, "void *"),
84    (0x0408, T_32PHRESULT, "HRESULT *"),
85    (0x0410, T_32PCHAR, "char *"),
86    (0x0411, T_32PSHORT, "short *"),
87    (0x0412, T_32PLONG, "long *"),
88    (0x0413, T_32PQUAD, "long long *"),
89    (0x0414, T_32POCT, "__int128 *"),
90    (0x0420, T_32PUCHAR, "unsigned char *"),
91    (0x0421, T_32PUSHORT, "unsigned short *"),
92    (0x0422, T_32PULONG, "unsigned __int32 *"),
93    (0x0423, T_32PUQUAD, "long long *"),
94    (0x0424, T_32PUOCT, "unsigned __int128 *"),
95    (0x0430, T_32PBOOL08, "bool *"),
96    (0x0431, T_32PBOOL16, "bool16 *"),
97    (0x0432, T_32PBOOL32, "bool32 *"),
98    (0x0433, T_32PBOOL64, "bool64 *"),
99    (0x0440, T_32PREAL32, "float *"),
100    (0x0441, T_32PREAL64, "double *"),
101    (0x0466, T_32PUINT1, "unsigned __int8 *"),
102    (0x0468, T_32PINT1, "__int8 *"),
103    (0x0470, T_32PRCHAR, "char *"), // really a character
104    (0x0471, T_32PWCHAR, "wchar_t *"),
105    (0x0472, T_32PINT2, "__int16 *"),
106    (0x0473, T_32PUINT2, "unsigned __int16 *"),
107    (0x0474, T_32PINT4, "__int32 *"),
108    (0x0475, T_32PUINT4, "unsigned __int32 *"),
109    (0x0476, T_32PINT8, "__int64 *"),
110    (0x0477, T_32PUINT8, "unsigned __int64 *"),
111    (0x047a, T_32PCHAR16, "char16 *"),
112    (0x047b, T_32PCHAR32, "char32 *"),
113    // 64-bit pointer types
114    (0x0603, T_64PVOID, "void *"),
115    (0x0608, T_64PHRESULT, "HRESULT *"),
116    (0x0610, T_64PCHAR, "char *"),
117    (0x0611, T_64PSHORT, "short *"),
118    (0x0612, T_64PLONG, "long *"),
119    (0x0613, T_64PQUAD, "long long *"),
120    (0x0614, T_64POCT, "__int128 *"),
121    (0x0620, T_64PPUCHAR, "unsigned char *"),
122    (0x0621, T_64PUSHORT, "unsigned short *"),
123    (0x0622, T_64PULONG, "unsigned __int32 *"),
124    (0x0623, T_64PUQUAD, "long long *"),
125    (0x0624, T_64PUOCT, "unsigned __int128 *"),
126    (0x0630, T_64PBOOL08, "bool *"),
127    (0x0631, T_64PBOOL16, "bool16 *"),
128    (0x0632, T_64PBOOL32, "bool32 *"),
129    (0x0633, T_64PBOOL64, "bool64 *"),
130    (0x0640, T_64PREAL32, "float *"),
131    (0x0641, T_64PREAL64, "double *"),
132    (0x0666, T_64PUINT1, "unsigned __int8 *"),
133    (0x0668, T_64PINT1, "__int8 *"),
134    (0x0670, T_64PRCHAR, "char *"), // really a character
135    (0x0671, T_64PWCHAR, "wchar_t *"),
136    (0x0672, T_64PINT2, "__int16 *"),
137    (0x0673, T_64PUINT2, "unsigned __int16 *"),
138    (0x0674, T_64PINT4, "__int32 *"),
139    (0x0675, T_64PUINT4, "unsigned __int32 *"),
140    (0x0676, T_64PINT8, "__int64 *"),
141    (0x0677, T_64PUINT8, "unsigned __int64 *"),
142    (0x067a, T_64PCHAR16, "char16 *"),
143    (0x067b, T_64PCHAR32, "char32 *"),
144}
145
146/// Dumps a `TypeIndex`. For use only with primitive types.
147pub fn dump_primitive_type_index(
148    out: &mut dyn std::fmt::Write,
149    type_index: TypeIndex,
150) -> std::fmt::Result {
151    let mode = (type_index.0 >> 8) & 7;
152    let prim_ty = (type_index.0 >> 4) & 0xf;
153    let size = type_index.0 & 7;
154
155    if let Ok(i) = PRIMITIVES.binary_search_by_key(&type_index.0, |entry| entry.0) {
156        let s = PRIMITIVES[i].1;
157        write!(out, "{}", s)?;
158    } else {
159        write!(out, "??PRIM(0x{:04x}) {{ ty: ", type_index.0)?;
160
161        'a: {
162            let ty_str = match prim_ty {
163                PRIMITIVE_TYPE_SPECIAL => "special",
164                PRIMITIVE_TYPE_SIGNED_INT => "signed_integer",
165                PRIMITIVE_TYPE_UNSIGNED_INT => "unsigned_integer",
166                PRIMITIVE_TYPE_BOOL => "bool",
167                PRIMITIVE_TYPE_REAL => "real",
168                PRIMITIVE_TYPE_COMPLEX => "complex",
169                PRIMITIVE_TYPE_SPECIAL2 => "special2",
170                PRIMITIVE_TYPE_REALLY_INT => "really_integer",
171                _ => {
172                    write!(out, "??{prim_ty}")?;
173                    break 'a;
174                }
175            };
176            write!(out, "{}", ty_str)?;
177        }
178
179        write!(out, ", mode: {mode}, size: {size} }}")?;
180    }
181
182    Ok(())
183}
184
185#[test]
186fn test_dump() {
187    let mut s = String::new();
188    dump_primitive_type_index(&mut s, TypeIndex::T_REAL32).unwrap();
189    assert_eq!(s, "T_REAL32");
190
191    s.clear();
192    dump_primitive_type_index(&mut s, TypeIndex(0x067c)).unwrap();
193}