1use std::vec;
18use std::collections::{HashSet};
19use std::str::{FromStr};
20
21use super::{Entity, EntityKind, Type, TypeKind};
22
23#[derive(Copy, Clone, Debug, PartialEq)]
31pub enum DefinitionValue {
32 Integer(bool, u64),
34 Real(f64),
36}
37
38impl DefinitionValue {
39 fn from_entity(entity: Entity) -> Option<DefinitionValue> {
42 let mut tokens = entity.get_range().unwrap().tokenize();
43 if tokens.last().map_or(false, |t| t.get_spelling() == "#") {
44 tokens.pop();
45 }
46
47 let (negated, number) = if tokens.len() == 2 {
48 (false, tokens[1].get_spelling())
49 } else if tokens.len() == 3 && tokens[1].get_spelling() == "-" {
50 (true, tokens[2].get_spelling())
51 } else {
52 return None;
53 };
54
55 if let Ok(integer) = u64::from_str(&number) {
56 Some(DefinitionValue::Integer(negated, integer))
57 } else if let Ok(real) = f64::from_str(&number) {
58 if negated {
59 Some(DefinitionValue::Real(-real))
60 } else {
61 Some(DefinitionValue::Real(real))
62 }
63 } else {
64 None
65 }
66 }
67}
68
69#[derive(Clone, Debug, PartialEq, Eq)]
77pub struct Declaration<'tu> {
78 pub name: String,
80 pub entity: Entity<'tu>,
82 pub source: Option<Entity<'tu>>,
84}
85
86impl<'tu> Declaration<'tu> {
87 fn new(name: String, entity: Entity<'tu>, source: Option<Entity<'tu>>) -> Declaration<'tu> {
90 Declaration { name, entity, source }
91 }
92}
93
94#[derive(Clone, Debug, PartialEq)]
98pub struct Definition<'tu> {
99 pub name: String,
101 pub value: DefinitionValue,
103 pub entity: Entity<'tu>,
105}
106
107impl<'tu> Definition<'tu> {
108 fn new(name: String, value: DefinitionValue, entity: Entity<'tu>) -> Definition<'tu> {
111 Definition { name, value, entity }
112 }
113}
114
115#[allow(missing_debug_implementations)]
119pub struct Definitions<'tu> {
120 entities: vec::IntoIter<Entity<'tu>>,
121 seen: HashSet<String>,
122}
123
124impl<'tu> Definitions<'tu> {
125 fn new(entities: vec::IntoIter<Entity<'tu>>) -> Definitions<'tu> {
128 Definitions { entities, seen: HashSet::new() }
129 }
130}
131
132impl<'tu> Iterator for Definitions<'tu> {
133 type Item = Definition<'tu>;
134
135 fn next(&mut self) -> Option<Definition<'tu>> {
136 for entity in &mut self.entities {
137 if entity.get_kind() == EntityKind::MacroDefinition {
138 let name = entity.get_name().unwrap();
139 if !self.seen.contains(&name) {
140 if let Some(value) = DefinitionValue::from_entity(entity) {
141 self.seen.insert(name.clone());
142 return Some(Definition::new(name, value, entity));
143 }
144 }
145 }
146 }
147 None
148 }
149}
150
151#[allow(missing_debug_implementations)]
155pub struct Enums<'tu> {
156 entities: vec::IntoIter<Entity<'tu>>,
157 seen: HashSet<String>,
158}
159
160impl<'tu> Enums<'tu> {
161 fn new(entities: vec::IntoIter<Entity<'tu>>) -> Enums<'tu> {
164 Enums { entities, seen: HashSet::new() }
165 }
166}
167
168impl<'tu> Iterator for Enums<'tu> {
169 type Item = Declaration<'tu>;
170
171 fn next(&mut self) -> Option<Declaration<'tu>> {
172 next(&mut self.entities, &mut self.seen, EntityKind::EnumDecl, "enum ")
173 }
174}
175
176#[allow(missing_debug_implementations)]
180pub struct Functions<'tu> {
181 entities: vec::IntoIter<Entity<'tu>>,
182 seen: HashSet<String>,
183}
184
185impl<'tu> Functions<'tu> {
186 fn new(entities: vec::IntoIter<Entity<'tu>>) -> Functions<'tu> {
189 Functions { entities, seen: HashSet::new() }
190 }
191}
192
193impl<'tu> Iterator for Functions<'tu> {
194 type Item = Declaration<'tu>;
195
196 fn next(&mut self) -> Option<Declaration<'tu>> {
197 for entity in &mut self.entities {
198 if entity.get_kind() == EntityKind::FunctionDecl {
199 let name = entity.get_name().unwrap();
200 if !self.seen.contains(&name) {
201 self.seen.insert(name.clone());
202 return Some(Declaration::new(name, entity, None));
203 }
204 }
205 }
206 None
207 }
208}
209
210#[allow(missing_debug_implementations)]
214pub struct Structs<'tu> {
215 entities: vec::IntoIter<Entity<'tu>>,
216 seen: HashSet<String>,
217}
218
219impl<'tu> Structs<'tu> {
220 fn new(entities: vec::IntoIter<Entity<'tu>>) -> Structs<'tu> {
223 Structs { entities, seen: HashSet::new() }
224 }
225}
226
227impl<'tu> Iterator for Structs<'tu> {
228 type Item = Declaration<'tu>;
229
230 fn next(&mut self) -> Option<Declaration<'tu>> {
231 next(&mut self.entities, &mut self.seen, EntityKind::StructDecl, "struct ")
232 }
233}
234
235#[allow(missing_debug_implementations)]
239pub struct Typedefs<'tu> {
240 entities: vec::IntoIter<Entity<'tu>>,
241 seen: HashSet<String>,
242}
243
244impl<'tu> Typedefs<'tu> {
245 fn new(entities: vec::IntoIter<Entity<'tu>>) -> Typedefs<'tu> {
248 Typedefs { entities, seen: HashSet::new() }
249 }
250}
251
252impl<'tu> Iterator for Typedefs<'tu> {
253 type Item = Declaration<'tu>;
254
255 fn next(&mut self) -> Option<Declaration<'tu>> {
256 for entity in &mut self.entities {
257 if entity.get_kind() == EntityKind::TypedefDecl {
258 let name = entity.get_name().unwrap();
259 if !self.seen.contains(&name) {
260 let underlying = entity.get_typedef_underlying_type().unwrap();
261 let display = entity.get_type().unwrap().get_display_name();
262
263 let typedef = !is_elaborated(underlying) ||
264 underlying.get_result_type().is_some() ||
265 is_alias(underlying, &display);
266
267 if typedef {
268 self.seen.insert(name.clone());
269 return Some(Declaration::new(name, entity, None));
270 }
271 }
272 }
273 }
274 None
275 }
276}
277
278#[allow(missing_debug_implementations)]
282pub struct Unions<'tu> {
283 entities: vec::IntoIter<Entity<'tu>>,
284 seen: HashSet<String>,
285}
286
287impl<'tu> Unions<'tu> {
288 fn new(entities: vec::IntoIter<Entity<'tu>>) -> Unions<'tu> {
291 Unions { entities, seen: HashSet::new() }
292 }
293}
294
295impl<'tu> Iterator for Unions<'tu> {
296 type Item = Declaration<'tu>;
297
298 fn next(&mut self) -> Option<Declaration<'tu>> {
299 next(&mut self.entities, &mut self.seen, EntityKind::UnionDecl, "union ")
300 }
301}
302
303fn is(type_: Type, prefix: &str) -> bool {
308 is_elaborated(type_) && type_.get_display_name().starts_with(prefix)
309}
310
311fn is_alias(type_: Type, name: &str) -> bool {
312 for prefix in &["enum ", "struct ", "union "] {
313 let display = type_.get_display_name();
314
315 if display.starts_with(prefix) && &display[prefix.len()..] != name {
316 return true;
317 }
318 }
319
320 false
321}
322
323fn is_elaborated(type_: Type) -> bool {
324 type_.is_elaborated().unwrap_or(type_.get_kind() == TypeKind::Unexposed)
325}
326
327fn next<'tu>(
328 entities: &mut vec::IntoIter<Entity<'tu>>,
329 seen: &mut HashSet<String>,
330 kind: EntityKind,
331 prefix: &str,
332) -> Option<Declaration<'tu>> {
333 for entity in entities {
334 if entity.get_kind() == kind {
335 if let Some(name) = entity.get_name() {
336 if !seen.contains(&name) {
337 seen.insert(name);
338 if entity.get_child(0).is_some() {
339 return Some(Declaration::new(entity.get_name().unwrap(), entity, None));
340 }
341 }
342 }
343 } else if entity.get_kind() == EntityKind::TypedefDecl {
344 let underlying = entity.get_typedef_underlying_type().unwrap();
345 let name = entity.get_name().unwrap();
346
347 if is(underlying, prefix) && !seen.contains(&name) {
348 let declaration = underlying.get_declaration().unwrap();
349
350 let complete = declaration.get_type().map_or(false, |t| t.get_sizeof().is_ok());
351 let anonymous = declaration.get_display_name().is_none();
352 let same = entity.get_display_name() == declaration.get_display_name();
353
354 seen.insert(name);
355 if complete && (anonymous || same) {
356 let name = entity.get_name().unwrap();
357 return Some(Declaration::new(name, declaration, Some(entity)));
358 }
359 }
360 }
361 }
362 None
363}
364
365pub fn find_definitions<'tu, E: Into<Vec<Entity<'tu>>>>(entities: E) -> Definitions<'tu> {
372 Definitions::new(entities.into().into_iter())
373}
374
375pub fn find_enums<'tu, E: Into<Vec<Entity<'tu>>>>(entities: E) -> Enums<'tu> {
379 Enums::new(entities.into().into_iter())
380}
381
382pub fn find_functions<'tu, E: Into<Vec<Entity<'tu>>>>(entities: E) -> Functions<'tu> {
386 Functions::new(entities.into().into_iter())
387}
388
389pub fn find_structs<'tu, E: Into<Vec<Entity<'tu>>>>(entities: E) -> Structs<'tu> {
393 Structs::new(entities.into().into_iter())
394}
395
396pub fn find_typedefs<'tu, E: Into<Vec<Entity<'tu>>>>(entities: E) -> Typedefs<'tu> {
400 Typedefs::new(entities.into().into_iter())
401}
402
403pub fn find_unions<'tu, E: Into<Vec<Entity<'tu>>>>(entities: E) -> Unions<'tu> {
407 Unions::new(entities.into().into_iter())
408}