1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//! Turning a type Clang resolved into the category two languages can share.
//!
//! The category is deliberately coarse, for the reason the protocol gives: two
//! languages do not agree on what a type *is*, and comparing spelled type names
//! compares vocabularies rather than programs. What survives translation is the
//! shape — whether a thing is a number, a sequence, a handle to something
//! elsewhere.
//!
//! # Why the category comes from the canonical type
//!
//! C and C++ let a program name the same type many ways. `Total`, `uint32_t`
//! and `unsigned int` can all be one type, and a helper that categorised what
//! was written would report three shapes for one. So the shape is read off the
//! canonical type, while the display name keeps what the code said — the first
//! is what two fragments are compared on, the second is what a person reads.
//!
//! # Why a handful of standard names are listed
//!
//! `std::string` is a class template, and reporting it as a record would be
//! true and useless: the point of the category is that a C++ `std::string` and
//! a Rust `String` are the same shape. The list is short and only applies to
//! types declared inside namespace `std`, so a project's own class called
//! `vector` is a record like any other class.
use ;
use TypeCategory;
/// The normalized category of `ty`.
pub
/// The shape of a class or struct.
/// The shape a standard-library type has in every language that has one.
///
/// `None` for anything declared outside `std`, however it is spelled: a class
/// called `vector` in somebody's own namespace is a record, and treating it as
/// a sequence because of its name would be reading the vocabulary again.
/// Whether `entity` is declared inside the standard library's namespace.
///
/// The walk allows for the inline versioning namespace an implementation puts
/// between `std` and everything in it: `std::__1::vector` is `std::vector`, and
/// a check that only looked at the immediate parent would miss every type in
/// the library that ships it.
pub
/// Whether a declaration is a type parameter rather than a type.
// The mapping is exercised against a real compiler rather than a mock one: it
// is a claim about what libclang reports for `std::vector<std::uint32_t>` and
// for a typedef to `uint64_t`, and only libclang can settle that. See
// `tests/analyzes_a_translation_unit.rs`.