1 //! A higher level Clang API built on top of the generated bindings in the
2 //! `clang_sys` module.
3 
4 #![allow(non_upper_case_globals, dead_code)]
5 
6 
7 use cexpr;
8 use clang_sys::*;
9 use regex;
10 use ir::context::BindgenContext;
11 use std::{mem, ptr, slice};
12 use std::ffi::{CStr, CString};
13 use std::fmt;
14 use std::hash::Hash;
15 use std::hash::Hasher;
16 use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_longlong, c_ulonglong};
17 
18 /// A cursor into the Clang AST, pointing to an AST node.
19 ///
20 /// We call the AST node pointed to by the cursor the cursor's "referent".
21 #[derive(Copy, Clone)]
22 pub struct Cursor {
23     x: CXCursor,
24 }
25 
26 impl fmt::Debug for Cursor {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result27     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
28         write!(
29             fmt,
30             "Cursor({} kind: {}, loc: {}, usr: {:?})",
31             self.spelling(),
32             kind_to_str(self.kind()),
33             self.location(),
34             self.usr()
35         )
36     }
37 }
38 
39 impl Cursor {
40     /// Get the Unified Symbol Resolution for this cursor's referent, if
41     /// available.
42     ///
43     /// The USR can be used to compare entities across translation units.
usr(&self) -> Option<String>44     pub fn usr(&self) -> Option<String> {
45         let s = unsafe { cxstring_into_string(clang_getCursorUSR(self.x)) };
46         if s.is_empty() { None } else { Some(s) }
47     }
48 
49     /// Is this cursor's referent a declaration?
is_declaration(&self) -> bool50     pub fn is_declaration(&self) -> bool {
51         unsafe { clang_isDeclaration(self.kind()) != 0 }
52     }
53 
54     /// Get this cursor's referent's spelling.
spelling(&self) -> String55     pub fn spelling(&self) -> String {
56         unsafe { cxstring_into_string(clang_getCursorSpelling(self.x)) }
57     }
58 
59     /// Get this cursor's referent's display name.
60     ///
61     /// This is not necessarily a valid identifier. It includes extra
62     /// information, such as parameters for a function, etc.
display_name(&self) -> String63     pub fn display_name(&self) -> String {
64         unsafe { cxstring_into_string(clang_getCursorDisplayName(self.x)) }
65     }
66 
67     /// Get the mangled name of this cursor's referent.
mangling(&self) -> String68     pub fn mangling(&self) -> String {
69         if clang_Cursor_getMangling::is_loaded() {
70             unsafe { cxstring_into_string(clang_Cursor_getMangling(self.x)) }
71         } else {
72             self.spelling()
73         }
74     }
75 
76     /// Gets the C++ manglings for this cursor, or an error if the function is
77     /// not loaded or the manglings are not available.
cxx_manglings(&self) -> Result<Vec<String>, ()>78     pub fn cxx_manglings(&self) -> Result<Vec<String>, ()> {
79         use clang_sys::*;
80         if !clang_Cursor_getCXXManglings::is_loaded() {
81             return Err(());
82         }
83         unsafe {
84             let manglings = clang_Cursor_getCXXManglings(self.x);
85             if manglings.is_null() {
86                 return Err(());
87             }
88             let count = (*manglings).Count as usize;
89 
90             let mut result = Vec::with_capacity(count);
91             for i in 0..count {
92                 let string_ptr = (*manglings).Strings.offset(i as isize);
93                 result.push(cxstring_to_string_leaky(*string_ptr));
94             }
95             clang_disposeStringSet(manglings);
96             Ok(result)
97         }
98     }
99 
100     /// Returns whether the cursor refers to a built-in definition.
is_builtin(&self) -> bool101     pub fn is_builtin(&self) -> bool {
102         let (file, _, _, _) = self.location().location();
103         file.name().is_none()
104     }
105 
106     /// Get the `Cursor` for this cursor's referent's lexical parent.
107     ///
108     /// The lexical parent is the parent of the definition. The semantic parent
109     /// is the parent of the declaration. Generally, the lexical parent doesn't
110     /// have any effect on semantics, while the semantic parent does.
111     ///
112     /// In the following snippet, the `Foo` class would be the semantic parent
113     /// of the out-of-line `method` definition, while the lexical parent is the
114     /// translation unit.
115     ///
116     /// ```c++
117     /// class Foo {
118     ///     void method();
119     /// };
120     ///
121     /// void Foo::method() { /* ... */ }
122     /// ```
lexical_parent(&self) -> Cursor123     pub fn lexical_parent(&self) -> Cursor {
124         unsafe {
125             Cursor {
126                 x: clang_getCursorLexicalParent(self.x),
127             }
128         }
129     }
130 
131     /// Get the referent's semantic parent, if one is available.
132     ///
133     /// See documentation for `lexical_parent` for details on semantic vs
134     /// lexical parents.
fallible_semantic_parent(&self) -> Option<Cursor>135     pub fn fallible_semantic_parent(&self) -> Option<Cursor> {
136         let sp = unsafe {
137             Cursor {
138                 x: clang_getCursorSemanticParent(self.x),
139             }
140         };
141         if sp == *self || !sp.is_valid() {
142             return None;
143         }
144         Some(sp)
145     }
146 
147     /// Get the referent's semantic parent.
148     ///
149     /// See documentation for `lexical_parent` for details on semantic vs
150     /// lexical parents.
semantic_parent(&self) -> Cursor151     pub fn semantic_parent(&self) -> Cursor {
152         self.fallible_semantic_parent().unwrap()
153     }
154 
155     /// Return the number of template arguments used by this cursor's referent,
156     /// if the referent is either a template instantiation. Returns `None`
157     /// otherwise.
158     ///
159     /// NOTE: This may not return `Some` for partial template specializations,
160     /// see #193 and #194.
num_template_args(&self) -> Option<u32>161     pub fn num_template_args(&self) -> Option<u32> {
162         // XXX: `clang_Type_getNumTemplateArguments` is sort of reliable, while
163         // `clang_Cursor_getNumTemplateArguments` is totally unreliable.
164         // Therefore, try former first, and only fallback to the latter if we
165         // have to.
166         self.cur_type()
167             .num_template_args()
168             .or_else(|| {
169                 let n: c_int =
170                     unsafe { clang_Cursor_getNumTemplateArguments(self.x) };
171 
172                 if n >= 0 {
173                     Some(n as u32)
174                 } else {
175                     debug_assert_eq!(n, -1);
176                     None
177                 }
178             })
179             .or_else(|| {
180                 let canonical = self.canonical();
181                 if canonical != *self {
182                     canonical.num_template_args()
183                 } else {
184                     None
185                 }
186             })
187     }
188 
189     /// Get a cursor pointing to this referent's containing translation unit.
190     ///
191     /// Note that we shouldn't create a `TranslationUnit` struct here, because
192     /// bindgen assumes there will only be one of them alive at a time, and
193     /// disposes it on drop. That can change if this would be required, but I
194     /// think we can survive fine without it.
translation_unit(&self) -> Cursor195     pub fn translation_unit(&self) -> Cursor {
196         assert!(self.is_valid());
197         unsafe {
198             let tu = clang_Cursor_getTranslationUnit(self.x);
199             let cursor = Cursor {
200                 x: clang_getTranslationUnitCursor(tu),
201             };
202             assert!(cursor.is_valid());
203             cursor
204         }
205     }
206 
207     /// Is the referent a top level construct?
is_toplevel(&self) -> bool208     pub fn is_toplevel(&self) -> bool {
209         let mut semantic_parent = self.fallible_semantic_parent();
210 
211         while semantic_parent.is_some() &&
212             (semantic_parent.unwrap().kind() == CXCursor_Namespace ||
213                  semantic_parent.unwrap().kind() == CXCursor_NamespaceAlias ||
214                  semantic_parent.unwrap().kind() == CXCursor_NamespaceRef)
215         {
216             semantic_parent =
217                 semantic_parent.unwrap().fallible_semantic_parent();
218         }
219 
220         let tu = self.translation_unit();
221         // Yes, this can happen with, e.g., macro definitions.
222         semantic_parent == tu.fallible_semantic_parent()
223     }
224 
225     /// There are a few kinds of types that we need to treat specially, mainly
226     /// not tracking the type declaration but the location of the cursor, given
227     /// clang doesn't expose a proper declaration for these types.
is_template_like(&self) -> bool228     pub fn is_template_like(&self) -> bool {
229         match self.kind() {
230             CXCursor_ClassTemplate |
231             CXCursor_ClassTemplatePartialSpecialization |
232             CXCursor_TypeAliasTemplateDecl => true,
233             _ => false,
234         }
235     }
236 
237     /// Get the kind of referent this cursor is pointing to.
kind(&self) -> CXCursorKind238     pub fn kind(&self) -> CXCursorKind {
239         self.x.kind
240     }
241 
242     /// Returns true is the cursor is a definition
is_definition(&self) -> bool243     pub fn is_definition(&self) -> bool {
244         unsafe { clang_isCursorDefinition(self.x) != 0 }
245     }
246 
247     /// Is the referent a template specialization?
is_template_specialization(&self) -> bool248     pub fn is_template_specialization(&self) -> bool {
249         self.specialized().is_some()
250     }
251 
252     /// Is the referent a fully specialized template specialization without any
253     /// remaining free template arguments?
is_fully_specialized_template(&self) -> bool254     pub fn is_fully_specialized_template(&self) -> bool {
255         self.is_template_specialization() &&
256             self.kind() != CXCursor_ClassTemplatePartialSpecialization &&
257             self.num_template_args().unwrap_or(0) > 0
258     }
259 
260     /// Is the referent a template specialization that still has remaining free
261     /// template arguments?
is_in_non_fully_specialized_template(&self) -> bool262     pub fn is_in_non_fully_specialized_template(&self) -> bool {
263         if self.is_toplevel() {
264             return false;
265         }
266 
267         let parent = self.semantic_parent();
268         if parent.is_fully_specialized_template() {
269             return false;
270         }
271 
272         if !parent.is_template_like() {
273             return parent.is_in_non_fully_specialized_template();
274         }
275 
276         return true;
277     }
278 
279     /// Is this cursor pointing a valid referent?
is_valid(&self) -> bool280     pub fn is_valid(&self) -> bool {
281         unsafe { clang_isInvalid(self.kind()) == 0 }
282     }
283 
284     /// Get the source location for the referent.
location(&self) -> SourceLocation285     pub fn location(&self) -> SourceLocation {
286         unsafe {
287             SourceLocation {
288                 x: clang_getCursorLocation(self.x),
289             }
290         }
291     }
292 
293     /// Get the source location range for the referent.
extent(&self) -> CXSourceRange294     pub fn extent(&self) -> CXSourceRange {
295         unsafe { clang_getCursorExtent(self.x) }
296     }
297 
298     /// Get the raw declaration comment for this referent, if one exists.
raw_comment(&self) -> Option<String>299     pub fn raw_comment(&self) -> Option<String> {
300         let s = unsafe {
301             cxstring_into_string(clang_Cursor_getRawCommentText(self.x))
302         };
303         if s.is_empty() { None } else { Some(s) }
304     }
305 
306     /// Get the referent's parsed comment.
comment(&self) -> Comment307     pub fn comment(&self) -> Comment {
308         unsafe {
309             Comment {
310                 x: clang_Cursor_getParsedComment(self.x),
311             }
312         }
313     }
314 
315     /// Get the referent's type.
cur_type(&self) -> Type316     pub fn cur_type(&self) -> Type {
317         unsafe {
318             Type {
319                 x: clang_getCursorType(self.x),
320             }
321         }
322     }
323 
324     /// Given that this cursor's referent is a reference to another type, or is
325     /// a declaration, get the cursor pointing to the referenced type or type of
326     /// the declared thing.
definition(&self) -> Option<Cursor>327     pub fn definition(&self) -> Option<Cursor> {
328         unsafe {
329             let ret = Cursor {
330                 x: clang_getCursorDefinition(self.x),
331             };
332 
333             if ret.is_valid() && ret.kind() != CXCursor_NoDeclFound {
334                 Some(ret)
335             } else {
336                 None
337             }
338         }
339     }
340 
341     /// Given that this cursor's referent is reference type, get the cursor
342     /// pointing to the referenced type.
referenced(&self) -> Option<Cursor>343     pub fn referenced(&self) -> Option<Cursor> {
344         unsafe {
345             let ret = Cursor {
346                 x: clang_getCursorReferenced(self.x),
347             };
348 
349             if ret.is_valid() { Some(ret) } else { None }
350         }
351     }
352 
353     /// Get the canonical cursor for this referent.
354     ///
355     /// Many types can be declared multiple times before finally being properly
356     /// defined. This method allows us to get the canonical cursor for the
357     /// referent type.
canonical(&self) -> Cursor358     pub fn canonical(&self) -> Cursor {
359         unsafe {
360             Cursor {
361                 x: clang_getCanonicalCursor(self.x),
362             }
363         }
364     }
365 
366     /// Given that this cursor points to either a template specialization or a
367     /// template instantiation, get a cursor pointing to the template definition
368     /// that is being specialized.
specialized(&self) -> Option<Cursor>369     pub fn specialized(&self) -> Option<Cursor> {
370         unsafe {
371             let ret = Cursor {
372                 x: clang_getSpecializedCursorTemplate(self.x),
373             };
374             if ret.is_valid() { Some(ret) } else { None }
375         }
376     }
377 
378     /// Assuming that this cursor's referent is a template declaration, get the
379     /// kind of cursor that would be generated for its specializations.
template_kind(&self) -> CXCursorKind380     pub fn template_kind(&self) -> CXCursorKind {
381         unsafe { clang_getTemplateCursorKind(self.x) }
382     }
383 
384     /// Traverse this cursor's referent and its children.
385     ///
386     /// Call the given function on each AST node traversed.
visit<Visitor>(&self, mut visitor: Visitor) where Visitor: FnMut(Cursor) -> CXChildVisitResult,387     pub fn visit<Visitor>(&self, mut visitor: Visitor)
388     where
389         Visitor: FnMut(Cursor) -> CXChildVisitResult,
390     {
391         unsafe {
392             clang_visitChildren(
393                 self.x,
394                 visit_children::<Visitor>,
395                 mem::transmute(&mut visitor),
396             );
397         }
398     }
399 
400     /// Collect all of this cursor's children into a vec and return them.
collect_children(&self) -> Vec<Cursor>401     pub fn collect_children(&self) -> Vec<Cursor> {
402         let mut children = vec![];
403         self.visit(|c| {
404             children.push(c);
405             CXChildVisit_Continue
406         });
407         children
408     }
409 
410     /// Does this cursor have any children?
has_children(&self) -> bool411     pub fn has_children(&self) -> bool {
412         let mut has_children = false;
413         self.visit(|_| {
414             has_children = true;
415             CXChildVisit_Break
416         });
417         has_children
418     }
419 
420     /// Does this cursor have at least `n` children?
has_at_least_num_children(&self, n: usize) -> bool421     pub fn has_at_least_num_children(&self, n: usize) -> bool {
422         assert!(n > 0);
423         let mut num_left = n;
424         self.visit(|_| {
425             num_left -= 1;
426             if num_left == 0 {
427                 CXChildVisit_Break
428             } else {
429                 CXChildVisit_Continue
430             }
431         });
432         num_left == 0
433     }
434 
435     /// Returns whether the given location contains a cursor with the given
436     /// kind in the first level of nesting underneath (doesn't look
437     /// recursively).
contains_cursor(&self, kind: CXCursorKind) -> bool438     pub fn contains_cursor(&self, kind: CXCursorKind) -> bool {
439         let mut found = false;
440 
441         self.visit(|c| if c.kind() == kind {
442             found = true;
443             CXChildVisit_Break
444         } else {
445             CXChildVisit_Continue
446         });
447 
448         found
449     }
450 
451     /// Is the referent an inlined function?
is_inlined_function(&self) -> bool452     pub fn is_inlined_function(&self) -> bool {
453         clang_Cursor_isFunctionInlined::is_loaded() &&
454             unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 }
455     }
456 
457     /// Get the width of this cursor's referent bit field, or `None` if the
458     /// referent is not a bit field.
bit_width(&self) -> Option<u32>459     pub fn bit_width(&self) -> Option<u32> {
460         unsafe {
461             let w = clang_getFieldDeclBitWidth(self.x);
462             if w == -1 { None } else { Some(w as u32) }
463         }
464     }
465 
466     /// Get the integer representation type used to hold this cursor's referent
467     /// enum type.
enum_type(&self) -> Option<Type>468     pub fn enum_type(&self) -> Option<Type> {
469         unsafe {
470             let t = Type {
471                 x: clang_getEnumDeclIntegerType(self.x),
472             };
473             if t.is_valid() { Some(t) } else { None }
474         }
475     }
476 
477     /// Get the signed constant value for this cursor's enum variant referent.
478     ///
479     /// Returns None if the cursor's referent is not an enum variant.
enum_val_signed(&self) -> Option<i64>480     pub fn enum_val_signed(&self) -> Option<i64> {
481         unsafe {
482             if self.kind() == CXCursor_EnumConstantDecl {
483                 Some(clang_getEnumConstantDeclValue(self.x) as i64)
484             } else {
485                 None
486             }
487         }
488     }
489 
490     /// Get the unsigned constant value for this cursor's enum variant referent.
491     ///
492     /// Returns None if the cursor's referent is not an enum variant.
enum_val_unsigned(&self) -> Option<u64>493     pub fn enum_val_unsigned(&self) -> Option<u64> {
494         unsafe {
495             if self.kind() == CXCursor_EnumConstantDecl {
496                 Some(clang_getEnumConstantDeclUnsignedValue(self.x) as u64)
497             } else {
498                 None
499             }
500         }
501     }
502 
503     /// Does this cursor have the given simple attribute?
504     ///
505     /// Note that this will only work for attributes that don't have an existing libclang
506     /// CursorKind, e.g. pure, const, etc.
has_simple_attr(&self, attr: &str) -> bool507     pub fn has_simple_attr(&self, attr: &str) -> bool {
508         let mut found_attr = false;
509         self.visit(|cur| {
510             if cur.kind() == CXCursor_UnexposedAttr {
511                 found_attr = cur.tokens().iter().any(|t| {
512                     t.kind == CXToken_Identifier && t.spelling() == attr.as_bytes()
513                 });
514 
515                 if found_attr {
516                     return CXChildVisit_Break;
517                 }
518             }
519 
520             CXChildVisit_Continue
521         });
522 
523         found_attr
524     }
525 
526     /// Given that this cursor's referent is a `typedef`, get the `Type` that is
527     /// being aliased.
typedef_type(&self) -> Option<Type>528     pub fn typedef_type(&self) -> Option<Type> {
529         let inner = Type {
530             x: unsafe { clang_getTypedefDeclUnderlyingType(self.x) },
531         };
532 
533         if inner.is_valid() { Some(inner) } else { None }
534     }
535 
536     /// Get the linkage kind for this cursor's referent.
537     ///
538     /// This only applies to functions and variables.
linkage(&self) -> CXLinkageKind539     pub fn linkage(&self) -> CXLinkageKind {
540         unsafe { clang_getCursorLinkage(self.x) }
541     }
542 
543     /// Get the visibility of this cursor's referent.
visibility(&self) -> CXVisibilityKind544     pub fn visibility(&self) -> CXVisibilityKind {
545         if clang_getCursorVisibility::is_loaded() {
546             unsafe { clang_getCursorVisibility(self.x) }
547         } else {
548             CXVisibility_Default
549         }
550     }
551 
552     /// Given that this cursor's referent is a function, return cursors to its
553     /// parameters.
554     ///
555     /// Returns None if the cursor's referent is not a function/method call or
556     /// declaration.
args(&self) -> Option<Vec<Cursor>>557     pub fn args(&self) -> Option<Vec<Cursor>> {
558         // match self.kind() {
559         // CXCursor_FunctionDecl |
560         // CXCursor_CXXMethod => {
561         self.num_args().ok().map(|num| {
562             (0..num).map(|i| {
563                 Cursor {
564                     x: unsafe { clang_Cursor_getArgument(self.x, i as c_uint) },
565                 }
566             })
567             .collect()
568         })
569     }
570 
571     /// Given that this cursor's referent is a function/method call or
572     /// declaration, return the number of arguments it takes.
573     ///
574     /// Returns Err if the cursor's referent is not a function/method call or
575     /// declaration.
num_args(&self) -> Result<u32, ()>576     pub fn num_args(&self) -> Result<u32, ()> {
577         unsafe {
578             let w = clang_Cursor_getNumArguments(self.x);
579             if w == -1 { Err(()) } else { Ok(w as u32) }
580         }
581     }
582 
583     /// Get the access specifier for this cursor's referent.
access_specifier(&self) -> CX_CXXAccessSpecifier584     pub fn access_specifier(&self) -> CX_CXXAccessSpecifier {
585         unsafe { clang_getCXXAccessSpecifier(self.x) }
586     }
587 
588     /// Is this cursor's referent a field declaration that is marked as
589     /// `mutable`?
is_mutable_field(&self) -> bool590     pub fn is_mutable_field(&self) -> bool {
591         clang_CXXField_isMutable::is_loaded() &&
592             unsafe { clang_CXXField_isMutable(self.x) != 0 }
593     }
594 
595     /// Get the offset of the field represented by the Cursor.
offset_of_field(&self) -> Result<usize, LayoutError>596     pub fn offset_of_field(&self) -> Result<usize, LayoutError> {
597         if !clang_Cursor_getOffsetOfField::is_loaded() {
598             return Err(LayoutError::from(-1));
599         }
600 
601         let offset = unsafe { clang_Cursor_getOffsetOfField(self.x) };
602 
603         if offset < 0 {
604             Err(LayoutError::from(offset as i32))
605         } else {
606             Ok(offset as usize)
607         }
608     }
609 
610     /// Is this cursor's referent a member function that is declared `static`?
method_is_static(&self) -> bool611     pub fn method_is_static(&self) -> bool {
612         unsafe { clang_CXXMethod_isStatic(self.x) != 0 }
613     }
614 
615     /// Is this cursor's referent a member function that is declared `const`?
method_is_const(&self) -> bool616     pub fn method_is_const(&self) -> bool {
617         unsafe { clang_CXXMethod_isConst(self.x) != 0 }
618     }
619 
620     /// Is this cursor's referent a member function that is virtual?
method_is_virtual(&self) -> bool621     pub fn method_is_virtual(&self) -> bool {
622         unsafe { clang_CXXMethod_isVirtual(self.x) != 0 }
623     }
624 
625     /// Is this cursor's referent a member function that is pure virtual?
method_is_pure_virtual(&self) -> bool626     pub fn method_is_pure_virtual(&self) -> bool {
627         unsafe { clang_CXXMethod_isPureVirtual(self.x) != 0 }
628     }
629 
630     /// Is this cursor's referent a struct or class with virtual members?
is_virtual_base(&self) -> bool631     pub fn is_virtual_base(&self) -> bool {
632         unsafe { clang_isVirtualBase(self.x) != 0 }
633     }
634 
635     /// Try to evaluate this cursor.
evaluate(&self) -> Option<EvalResult>636     pub fn evaluate(&self) -> Option<EvalResult> {
637         EvalResult::new(*self)
638     }
639 
640     /// Return the result type for this cursor
ret_type(&self) -> Option<Type>641     pub fn ret_type(&self) -> Option<Type> {
642         let rt = Type {
643             x: unsafe { clang_getCursorResultType(self.x) },
644         };
645         if rt.is_valid() { Some(rt) } else { None }
646     }
647 
648     /// Gets the tokens that correspond to that cursor.
tokens(&self) -> RawTokens649     pub fn tokens(&self) -> RawTokens {
650         RawTokens::new(self)
651     }
652 
653     /// Gets the tokens that correspond to that cursor as  `cexpr` tokens.
cexpr_tokens(self) -> Vec<cexpr::token::Token>654     pub fn cexpr_tokens(self) -> Vec<cexpr::token::Token> {
655         use cexpr::token;
656 
657         self.tokens().iter().filter_map(|token| {
658             let kind = match token.kind {
659                 CXToken_Punctuation => token::Kind::Punctuation,
660                 CXToken_Literal => token::Kind::Literal,
661                 CXToken_Identifier => token::Kind::Identifier,
662                 CXToken_Keyword => token::Kind::Keyword,
663                 // NB: cexpr is not too happy about comments inside
664                 // expressions, so we strip them down here.
665                 CXToken_Comment => return None,
666                 _ => {
667                     error!("Found unexpected token kind: {:?}", token);
668                     return None;
669                 }
670             };
671 
672             Some(token::Token {
673                 kind,
674                 raw: token.spelling().to_vec().into_boxed_slice(),
675             })
676         }).collect()
677     }
678 }
679 
680 /// A struct that owns the tokenizer result from a given cursor.
681 pub struct RawTokens<'a> {
682     cursor: &'a Cursor,
683     tu: CXTranslationUnit,
684     tokens: *mut CXToken,
685     token_count: c_uint,
686 }
687 
688 impl<'a> RawTokens<'a> {
new(cursor: &'a Cursor) -> Self689     fn new(cursor: &'a Cursor) -> Self {
690         let mut tokens = ptr::null_mut();
691         let mut token_count = 0;
692         let range = cursor.extent();
693         let tu = unsafe {
694             clang_Cursor_getTranslationUnit(cursor.x)
695         };
696         unsafe { clang_tokenize(tu, range, &mut tokens, &mut token_count) };
697         Self { cursor, tu, tokens, token_count }
698     }
699 
as_slice(&self) -> &[CXToken]700     fn as_slice(&self) -> &[CXToken] {
701         if self.tokens.is_null() {
702             return &[];
703         }
704         unsafe { slice::from_raw_parts(self.tokens, self.token_count as usize) }
705     }
706 
707     /// Get an iterator over these tokens.
iter(&self) -> ClangTokenIterator708     pub fn iter(&self) -> ClangTokenIterator {
709         ClangTokenIterator {
710             tu: self.tu,
711             raw: self.as_slice().iter(),
712         }
713     }
714 }
715 
716 impl<'a> Drop for RawTokens<'a> {
drop(&mut self)717     fn drop(&mut self) {
718         if !self.tokens.is_null() {
719             unsafe {
720                 clang_disposeTokens(self.tu, self.tokens, self.token_count as c_uint);
721             }
722         }
723     }
724 }
725 
726 /// A raw clang token, that exposes only the kind and spelling. This is a
727 /// slightly more convenient version of `CXToken` which owns the spelling
728 /// string.
729 #[derive(Debug)]
730 pub struct ClangToken {
731     spelling: CXString,
732     /// The kind of token, this is the same as the relevant member from
733     /// `CXToken`.
734     pub kind: CXTokenKind,
735 }
736 
737 impl ClangToken {
738     /// Get the token spelling, without being converted to utf-8.
spelling(&self) -> &[u8]739     pub fn spelling(&self) -> &[u8] {
740         let c_str = unsafe {
741             CStr::from_ptr(clang_getCString(self.spelling) as *const _)
742         };
743         c_str.to_bytes()
744     }
745 }
746 
747 impl Drop for ClangToken {
drop(&mut self)748     fn drop(&mut self) {
749         unsafe { clang_disposeString(self.spelling) }
750     }
751 }
752 
753 /// An iterator over a set of Tokens.
754 pub struct ClangTokenIterator<'a> {
755     tu: CXTranslationUnit,
756     raw: slice::Iter<'a, CXToken>,
757 }
758 
759 impl<'a> Iterator for ClangTokenIterator<'a> {
760     type Item = ClangToken;
761 
next(&mut self) -> Option<Self::Item>762     fn next(&mut self) -> Option<Self::Item> {
763         let raw = self.raw.next()?;
764         unsafe {
765             let kind = clang_getTokenKind(*raw);
766             let spelling = clang_getTokenSpelling(self.tu, *raw);
767             Some(ClangToken { kind, spelling })
768         }
769     }
770 }
771 
772 /// Checks whether the name looks like an identifier, i.e. is alphanumeric
773 /// (including '_') and does not start with a digit.
is_valid_identifier(name: &str) -> bool774 pub fn is_valid_identifier(name: &str) -> bool {
775     let mut chars = name.chars();
776     let first_valid = chars
777         .next()
778         .map(|c| c.is_alphabetic() || c == '_')
779         .unwrap_or(false);
780 
781     first_valid && chars.all(|c| c.is_alphanumeric() || c == '_')
782 }
783 
visit_children<Visitor>( cur: CXCursor, _parent: CXCursor, data: CXClientData, ) -> CXChildVisitResult where Visitor: FnMut(Cursor) -> CXChildVisitResult,784 extern "C" fn visit_children<Visitor>(
785     cur: CXCursor,
786     _parent: CXCursor,
787     data: CXClientData,
788 ) -> CXChildVisitResult
789 where
790     Visitor: FnMut(Cursor) -> CXChildVisitResult,
791 {
792     let func: &mut Visitor = unsafe { mem::transmute(data) };
793     let child = Cursor {
794         x: cur,
795     };
796 
797     (*func)(child)
798 }
799 
800 impl PartialEq for Cursor {
eq(&self, other: &Cursor) -> bool801     fn eq(&self, other: &Cursor) -> bool {
802         unsafe { clang_equalCursors(self.x, other.x) == 1 }
803     }
804 }
805 
806 impl Eq for Cursor {}
807 
808 impl Hash for Cursor {
hash<H: Hasher>(&self, state: &mut H)809     fn hash<H: Hasher>(&self, state: &mut H) {
810         unsafe { clang_hashCursor(self.x) }.hash(state)
811     }
812 }
813 
814 /// The type of a node in clang's AST.
815 #[derive(Clone, Copy)]
816 pub struct Type {
817     x: CXType,
818 }
819 
820 impl PartialEq for Type {
eq(&self, other: &Self) -> bool821     fn eq(&self, other: &Self) -> bool {
822         unsafe { clang_equalTypes(self.x, other.x) != 0 }
823     }
824 }
825 
826 impl Eq for Type {}
827 
828 impl fmt::Debug for Type {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result829     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
830         write!(
831             fmt,
832             "Type({}, kind: {}, cconv: {}, decl: {:?}, canon: {:?})",
833             self.spelling(),
834             type_to_str(self.kind()),
835             self.call_conv(),
836             self.declaration(),
837             self.declaration().canonical()
838         )
839     }
840 }
841 
842 /// An error about the layout of a struct, class, or type.
843 #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
844 pub enum LayoutError {
845     /// Asked for the layout of an invalid type.
846     Invalid,
847     /// Asked for the layout of an incomplete type.
848     Incomplete,
849     /// Asked for the layout of a dependent type.
850     Dependent,
851     /// Asked for the layout of a type that does not have constant size.
852     NotConstantSize,
853     /// Asked for the layout of a field in a type that does not have such a
854     /// field.
855     InvalidFieldName,
856     /// An unknown layout error.
857     Unknown,
858 }
859 
860 impl ::std::convert::From<i32> for LayoutError {
from(val: i32) -> Self861     fn from(val: i32) -> Self {
862         use self::LayoutError::*;
863 
864         match val {
865             CXTypeLayoutError_Invalid => Invalid,
866             CXTypeLayoutError_Incomplete => Incomplete,
867             CXTypeLayoutError_Dependent => Dependent,
868             CXTypeLayoutError_NotConstantSize => NotConstantSize,
869             CXTypeLayoutError_InvalidFieldName => InvalidFieldName,
870             _ => Unknown,
871         }
872     }
873 }
874 
875 impl Type {
876     /// Get this type's kind.
kind(&self) -> CXTypeKind877     pub fn kind(&self) -> CXTypeKind {
878         self.x.kind
879     }
880 
881     /// Get a cursor pointing to this type's declaration.
declaration(&self) -> Cursor882     pub fn declaration(&self) -> Cursor {
883         unsafe {
884             Cursor {
885                 x: clang_getTypeDeclaration(self.x),
886             }
887         }
888     }
889 
890     /// Get the canonical declaration of this type, if it is available.
canonical_declaration( &self, location: Option<&Cursor>, ) -> Option<CanonicalTypeDeclaration>891     pub fn canonical_declaration(
892         &self,
893         location: Option<&Cursor>,
894     ) -> Option<CanonicalTypeDeclaration> {
895         let mut declaration = self.declaration();
896         if !declaration.is_valid() {
897             if let Some(location) = location {
898                 let mut location = *location;
899                 if let Some(referenced) = location.referenced() {
900                     location = referenced;
901                 }
902                 if location.is_template_like() {
903                     declaration = location;
904                 }
905             }
906         }
907 
908         let canonical = declaration.canonical();
909         if canonical.is_valid() && canonical.kind() != CXCursor_NoDeclFound {
910             Some(CanonicalTypeDeclaration(*self, canonical))
911         } else {
912             None
913         }
914     }
915 
916     /// Get a raw display name for this type.
spelling(&self) -> String917     pub fn spelling(&self) -> String {
918         let s = unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) };
919         // Clang 5.0 introduced changes in the spelling API so it returned the
920         // full qualified name. Let's undo that here.
921         if s.split("::").all(|s| is_valid_identifier(s)) {
922             if let Some(s) = s.split("::").last() {
923                 return s.to_owned();
924             }
925         }
926 
927         s
928     }
929 
930     /// Is this type const qualified?
is_const(&self) -> bool931     pub fn is_const(&self) -> bool {
932         unsafe { clang_isConstQualifiedType(self.x) != 0 }
933     }
934 
935     #[inline]
is_non_deductible_auto_type(&self) -> bool936     fn is_non_deductible_auto_type(&self) -> bool {
937         debug_assert_eq!(self.kind(), CXType_Auto);
938         self.canonical_type() == *self
939     }
940 
941     #[inline]
clang_size_of(&self, ctx: &BindgenContext) -> c_longlong942     fn clang_size_of(&self, ctx: &BindgenContext) -> c_longlong {
943         match self.kind() {
944             // Work-around https://bugs.llvm.org/show_bug.cgi?id=40975
945             CXType_RValueReference |
946             CXType_LValueReference => ctx.target_pointer_size() as c_longlong,
947             // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813
948             CXType_Auto if self.is_non_deductible_auto_type() => return -6,
949             _ => unsafe { clang_Type_getSizeOf(self.x) },
950         }
951     }
952 
953     #[inline]
clang_align_of(&self, ctx: &BindgenContext) -> c_longlong954     fn clang_align_of(&self, ctx: &BindgenContext) -> c_longlong {
955         match self.kind() {
956             // Work-around https://bugs.llvm.org/show_bug.cgi?id=40975
957             CXType_RValueReference |
958             CXType_LValueReference => ctx.target_pointer_size() as c_longlong,
959             // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813
960             CXType_Auto if self.is_non_deductible_auto_type() => return -6,
961             _ => unsafe { clang_Type_getAlignOf(self.x) },
962         }
963     }
964 
965     /// What is the size of this type? Paper over invalid types by returning `0`
966     /// for them.
size(&self, ctx: &BindgenContext) -> usize967     pub fn size(&self, ctx: &BindgenContext) -> usize {
968         let val = self.clang_size_of(ctx);
969         if val < 0 { 0 } else { val as usize }
970     }
971 
972     /// What is the size of this type?
fallible_size(&self, ctx: &BindgenContext) -> Result<usize, LayoutError>973     pub fn fallible_size(&self, ctx: &BindgenContext) -> Result<usize, LayoutError> {
974         let val = self.clang_size_of(ctx);
975         if val < 0 {
976             Err(LayoutError::from(val as i32))
977         } else {
978             Ok(val as usize)
979         }
980     }
981 
982     /// What is the alignment of this type? Paper over invalid types by
983     /// returning `0`.
align(&self, ctx: &BindgenContext) -> usize984     pub fn align(&self, ctx: &BindgenContext) -> usize {
985         let val = self.clang_align_of(ctx);
986         if val < 0 { 0 } else { val as usize }
987     }
988 
989     /// What is the alignment of this type?
fallible_align(&self, ctx: &BindgenContext) -> Result<usize, LayoutError>990     pub fn fallible_align(&self, ctx: &BindgenContext) -> Result<usize, LayoutError> {
991         let val = self.clang_align_of(ctx);
992         if val < 0 {
993             Err(LayoutError::from(val as i32))
994         } else {
995             Ok(val as usize)
996         }
997     }
998 
999     /// Get the layout for this type, or an error describing why it does not
1000     /// have a valid layout.
fallible_layout(&self, ctx: &BindgenContext) -> Result<::ir::layout::Layout, LayoutError>1001     pub fn fallible_layout(&self, ctx: &BindgenContext) -> Result<::ir::layout::Layout, LayoutError> {
1002         use ir::layout::Layout;
1003         let size = self.fallible_size(ctx)?;
1004         let align = self.fallible_align(ctx)?;
1005         Ok(Layout::new(size, align))
1006     }
1007 
1008     /// Get the number of template arguments this type has, or `None` if it is
1009     /// not some kind of template.
num_template_args(&self) -> Option<u32>1010     pub fn num_template_args(&self) -> Option<u32> {
1011         // If an old libclang is loaded, we have no hope of answering this
1012         // question correctly. However, that's no reason to panic when
1013         // generating bindings for simple C headers with an old libclang.
1014         if !clang_Type_getNumTemplateArguments::is_loaded() {
1015             return None
1016         }
1017 
1018         let n = unsafe { clang_Type_getNumTemplateArguments(self.x) };
1019         if n >= 0 {
1020             Some(n as u32)
1021         } else {
1022             debug_assert_eq!(n, -1);
1023             None
1024         }
1025     }
1026 
1027     /// If this type is a class template specialization, return its
1028     /// template arguments. Otherwise, return None.
template_args(&self) -> Option<TypeTemplateArgIterator>1029     pub fn template_args(&self) -> Option<TypeTemplateArgIterator> {
1030         self.num_template_args().map(|n| {
1031             TypeTemplateArgIterator {
1032                 x: self.x,
1033                 length: n,
1034                 index: 0,
1035             }
1036         })
1037     }
1038 
1039     /// Given that this type is a function prototype, return the types of its parameters.
1040     ///
1041     /// Returns None if the type is not a function prototype.
args(&self) -> Option<Vec<Type>>1042     pub fn args(&self) -> Option<Vec<Type>> {
1043         self.num_args().ok().map(|num| {
1044             (0..num).map(|i| {
1045                 Type {
1046                     x: unsafe { clang_getArgType(self.x, i as c_uint) },
1047                 }
1048             })
1049             .collect()
1050         })
1051     }
1052 
1053     /// Given that this type is a function prototype, return the number of arguments it takes.
1054     ///
1055     /// Returns Err if the type is not a function prototype.
num_args(&self) -> Result<u32, ()>1056     pub fn num_args(&self) -> Result<u32, ()> {
1057         unsafe {
1058             let w = clang_getNumArgTypes(self.x);
1059             if w == -1 { Err(()) } else { Ok(w as u32) }
1060         }
1061     }
1062 
1063 
1064     /// Given that this type is a pointer type, return the type that it points
1065     /// to.
pointee_type(&self) -> Option<Type>1066     pub fn pointee_type(&self) -> Option<Type> {
1067         match self.kind() {
1068             CXType_Pointer |
1069             CXType_RValueReference |
1070             CXType_LValueReference |
1071             CXType_MemberPointer |
1072             CXType_BlockPointer |
1073             CXType_ObjCObjectPointer => {
1074                 let ret = Type {
1075                     x: unsafe { clang_getPointeeType(self.x) },
1076                 };
1077                 debug_assert!(ret.is_valid());
1078                 Some(ret)
1079             }
1080             _ => None,
1081         }
1082     }
1083 
1084     /// Given that this type is an array, vector, or complex type, return the
1085     /// type of its elements.
elem_type(&self) -> Option<Type>1086     pub fn elem_type(&self) -> Option<Type> {
1087         let current_type = Type {
1088             x: unsafe { clang_getElementType(self.x) },
1089         };
1090         if current_type.is_valid() {
1091             Some(current_type)
1092         } else {
1093             None
1094         }
1095     }
1096 
1097     /// Given that this type is an array or vector type, return its number of
1098     /// elements.
num_elements(&self) -> Option<usize>1099     pub fn num_elements(&self) -> Option<usize> {
1100         let num_elements_returned = unsafe { clang_getNumElements(self.x) };
1101         if num_elements_returned != -1 {
1102             Some(num_elements_returned as usize)
1103         } else {
1104             None
1105         }
1106     }
1107 
1108     /// Get the canonical version of this type. This sees through `typedef`s and
1109     /// aliases to get the underlying, canonical type.
canonical_type(&self) -> Type1110     pub fn canonical_type(&self) -> Type {
1111         unsafe {
1112             Type {
1113                 x: clang_getCanonicalType(self.x),
1114             }
1115         }
1116     }
1117 
1118     /// Is this type a variadic function type?
is_variadic(&self) -> bool1119     pub fn is_variadic(&self) -> bool {
1120         unsafe { clang_isFunctionTypeVariadic(self.x) != 0 }
1121     }
1122 
1123     /// Given that this type is a function type, get the type of its return
1124     /// value.
ret_type(&self) -> Option<Type>1125     pub fn ret_type(&self) -> Option<Type> {
1126         let rt = Type {
1127             x: unsafe { clang_getResultType(self.x) },
1128         };
1129         if rt.is_valid() { Some(rt) } else { None }
1130     }
1131 
1132     /// Given that this type is a function type, get its calling convention. If
1133     /// this is not a function type, `CXCallingConv_Invalid` is returned.
call_conv(&self) -> CXCallingConv1134     pub fn call_conv(&self) -> CXCallingConv {
1135         unsafe { clang_getFunctionTypeCallingConv(self.x) }
1136     }
1137 
1138     /// For elaborated types (types which use `class`, `struct`, or `union` to
1139     /// disambiguate types from local bindings), get the underlying type.
named(&self) -> Type1140     pub fn named(&self) -> Type {
1141         unsafe {
1142             Type {
1143                 x: if clang_Type_getNamedType::is_loaded() {
1144                     clang_Type_getNamedType(self.x)
1145                 } else {
1146                     self.x
1147                 },
1148             }
1149         }
1150     }
1151 
1152     /// Is this a valid type?
is_valid(&self) -> bool1153     pub fn is_valid(&self) -> bool {
1154         self.kind() != CXType_Invalid
1155     }
1156 
1157     /// Is this a valid and exposed type?
is_valid_and_exposed(&self) -> bool1158     pub fn is_valid_and_exposed(&self) -> bool {
1159         self.is_valid() && self.kind() != CXType_Unexposed
1160     }
1161 
1162     /// Is this type a fully instantiated template?
is_fully_instantiated_template(&self) -> bool1163     pub fn is_fully_instantiated_template(&self) -> bool {
1164         // Yep, the spelling of this containing type-parameter is extremely
1165         // nasty... But can happen in <type_traits>. Unfortunately I couldn't
1166         // reduce it enough :(
1167         self.template_args().map_or(false, |args| args.len() > 0) &&
1168             match self.declaration().kind() {
1169                 CXCursor_ClassTemplatePartialSpecialization |
1170                 CXCursor_TypeAliasTemplateDecl |
1171                 CXCursor_TemplateTemplateParameter => false,
1172                 _ => true,
1173             }
1174     }
1175 
1176     /// Is this type an associated template type? Eg `T::Associated` in
1177     /// this example:
1178     ///
1179     /// ```c++
1180     /// template <typename T>
1181     /// class Foo {
1182     ///     typename T::Associated member;
1183     /// };
1184     /// ```
is_associated_type(&self) -> bool1185     pub fn is_associated_type(&self) -> bool {
1186         // This is terrible :(
1187         fn hacky_parse_associated_type<S: AsRef<str>>(spelling: S) -> bool {
1188             lazy_static! {
1189                 static ref ASSOC_TYPE_RE: regex::Regex =
1190                     regex::Regex::new(r"typename type\-parameter\-\d+\-\d+::.+").unwrap();
1191             }
1192             ASSOC_TYPE_RE.is_match(spelling.as_ref())
1193         }
1194 
1195         self.kind() == CXType_Unexposed &&
1196             (hacky_parse_associated_type(self.spelling()) ||
1197                  hacky_parse_associated_type(self.canonical_type().spelling()))
1198     }
1199 }
1200 
1201 /// The `CanonicalTypeDeclaration` type exists as proof-by-construction that its
1202 /// cursor is the canonical declaration for its type. If you have a
1203 /// `CanonicalTypeDeclaration` instance, you know for sure that the type and
1204 /// cursor match up in a canonical declaration relationship, and it simply
1205 /// cannot be otherwise.
1206 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
1207 pub struct CanonicalTypeDeclaration(Type, Cursor);
1208 
1209 impl CanonicalTypeDeclaration {
1210     /// Get the type.
ty(&self) -> &Type1211     pub fn ty(&self) -> &Type {
1212         &self.0
1213     }
1214 
1215     /// Get the type's canonical declaration cursor.
cursor(&self) -> &Cursor1216     pub fn cursor(&self) -> &Cursor {
1217         &self.1
1218     }
1219 }
1220 
1221 /// An iterator for a type's template arguments.
1222 pub struct TypeTemplateArgIterator {
1223     x: CXType,
1224     length: u32,
1225     index: u32,
1226 }
1227 
1228 impl Iterator for TypeTemplateArgIterator {
1229     type Item = Type;
next(&mut self) -> Option<Type>1230     fn next(&mut self) -> Option<Type> {
1231         if self.index < self.length {
1232             let idx = self.index as c_uint;
1233             self.index += 1;
1234             Some(Type {
1235                 x: unsafe { clang_Type_getTemplateArgumentAsType(self.x, idx) },
1236             })
1237         } else {
1238             None
1239         }
1240     }
1241 }
1242 
1243 impl ExactSizeIterator for TypeTemplateArgIterator {
len(&self) -> usize1244     fn len(&self) -> usize {
1245         assert!(self.index <= self.length);
1246         (self.length - self.index) as usize
1247     }
1248 }
1249 
1250 /// A `SourceLocation` is a file, line, column, and byte offset location for
1251 /// some source text.
1252 pub struct SourceLocation {
1253     x: CXSourceLocation,
1254 }
1255 
1256 impl SourceLocation {
1257     /// Get the (file, line, column, byte offset) tuple for this source
1258     /// location.
location(&self) -> (File, usize, usize, usize)1259     pub fn location(&self) -> (File, usize, usize, usize) {
1260         unsafe {
1261             let mut file = mem::zeroed();
1262             let mut line = 0;
1263             let mut col = 0;
1264             let mut off = 0;
1265             clang_getSpellingLocation(
1266                 self.x,
1267                 &mut file,
1268                 &mut line,
1269                 &mut col,
1270                 &mut off,
1271             );
1272             (
1273                 File {
1274                     x: file,
1275                 },
1276                 line as usize,
1277                 col as usize,
1278                 off as usize,
1279             )
1280         }
1281     }
1282 }
1283 
1284 impl fmt::Display for SourceLocation {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1285     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1286         let (file, line, col, _) = self.location();
1287         if let Some(name) = file.name() {
1288             write!(f, "{}:{}:{}", name, line, col)
1289         } else {
1290             "builtin definitions".fmt(f)
1291         }
1292     }
1293 }
1294 
1295 /// A comment in the source text.
1296 ///
1297 /// Comments are sort of parsed by Clang, and have a tree structure.
1298 pub struct Comment {
1299     x: CXComment,
1300 }
1301 
1302 impl Comment {
1303     /// What kind of comment is this?
kind(&self) -> CXCommentKind1304     pub fn kind(&self) -> CXCommentKind {
1305         unsafe { clang_Comment_getKind(self.x) }
1306     }
1307 
1308     /// Get this comment's children comment
get_children(&self) -> CommentChildrenIterator1309     pub fn get_children(&self) -> CommentChildrenIterator {
1310         CommentChildrenIterator {
1311             parent: self.x,
1312             length: unsafe { clang_Comment_getNumChildren(self.x) },
1313             index: 0,
1314         }
1315     }
1316 
1317     /// Given that this comment is the start or end of an HTML tag, get its tag
1318     /// name.
get_tag_name(&self) -> String1319     pub fn get_tag_name(&self) -> String {
1320         unsafe { cxstring_into_string(clang_HTMLTagComment_getTagName(self.x)) }
1321     }
1322 
1323     /// Given that this comment is an HTML start tag, get its attributes.
get_tag_attrs(&self) -> CommentAttributesIterator1324     pub fn get_tag_attrs(&self) -> CommentAttributesIterator {
1325         CommentAttributesIterator {
1326             x: self.x,
1327             length: unsafe { clang_HTMLStartTag_getNumAttrs(self.x) },
1328             index: 0,
1329         }
1330     }
1331 }
1332 
1333 /// An iterator for a comment's children
1334 pub struct CommentChildrenIterator {
1335     parent: CXComment,
1336     length: c_uint,
1337     index: c_uint,
1338 }
1339 
1340 impl Iterator for CommentChildrenIterator {
1341     type Item = Comment;
next(&mut self) -> Option<Comment>1342     fn next(&mut self) -> Option<Comment> {
1343         if self.index < self.length {
1344             let idx = self.index;
1345             self.index += 1;
1346             Some(Comment {
1347                 x: unsafe { clang_Comment_getChild(self.parent, idx) },
1348             })
1349         } else {
1350             None
1351         }
1352     }
1353 }
1354 
1355 /// An HTML start tag comment attribute
1356 pub struct CommentAttribute {
1357     /// HTML start tag attribute name
1358     pub name: String,
1359     /// HTML start tag attribute value
1360     pub value: String,
1361 }
1362 
1363 /// An iterator for a comment's attributes
1364 pub struct CommentAttributesIterator {
1365     x: CXComment,
1366     length: c_uint,
1367     index: c_uint,
1368 }
1369 
1370 impl Iterator for CommentAttributesIterator {
1371     type Item = CommentAttribute;
next(&mut self) -> Option<CommentAttribute>1372     fn next(&mut self) -> Option<CommentAttribute> {
1373         if self.index < self.length {
1374             let idx = self.index;
1375             self.index += 1;
1376             Some(CommentAttribute {
1377                 name: unsafe {
1378                     cxstring_into_string(
1379                         clang_HTMLStartTag_getAttrName(self.x, idx),
1380                     )
1381                 },
1382                 value: unsafe {
1383                     cxstring_into_string(
1384                         clang_HTMLStartTag_getAttrValue(self.x, idx),
1385                     )
1386                 },
1387             })
1388         } else {
1389             None
1390         }
1391     }
1392 }
1393 
1394 /// A source file.
1395 pub struct File {
1396     x: CXFile,
1397 }
1398 
1399 impl File {
1400     /// Get the name of this source file.
name(&self) -> Option<String>1401     pub fn name(&self) -> Option<String> {
1402         if self.x.is_null() {
1403             return None;
1404         }
1405         Some(unsafe { cxstring_into_string(clang_getFileName(self.x)) })
1406     }
1407 }
1408 
cxstring_to_string_leaky(s: CXString) -> String1409 fn cxstring_to_string_leaky(s: CXString) -> String {
1410     if s.data.is_null() {
1411         return "".to_owned();
1412     }
1413     let c_str = unsafe { CStr::from_ptr(clang_getCString(s) as *const _) };
1414     c_str.to_string_lossy().into_owned()
1415 }
1416 
cxstring_into_string(s: CXString) -> String1417 fn cxstring_into_string(s: CXString) -> String {
1418     let ret = cxstring_to_string_leaky(s);
1419     unsafe { clang_disposeString(s) };
1420     ret
1421 }
1422 
1423 /// An `Index` is an environment for a set of translation units that will
1424 /// typically end up linked together in one final binary.
1425 pub struct Index {
1426     x: CXIndex,
1427 }
1428 
1429 impl Index {
1430     /// Construct a new `Index`.
1431     ///
1432     /// The `pch` parameter controls whether declarations in pre-compiled
1433     /// headers are included when enumerating a translation unit's "locals".
1434     ///
1435     /// The `diag` parameter controls whether debugging diagnostics are enabled.
new(pch: bool, diag: bool) -> Index1436     pub fn new(pch: bool, diag: bool) -> Index {
1437         unsafe {
1438             Index {
1439                 x: clang_createIndex(pch as c_int, diag as c_int),
1440             }
1441         }
1442     }
1443 }
1444 
1445 impl fmt::Debug for Index {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1446     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1447         write!(fmt, "Index {{ }}")
1448     }
1449 }
1450 
1451 impl Drop for Index {
drop(&mut self)1452     fn drop(&mut self) {
1453         unsafe {
1454             clang_disposeIndex(self.x);
1455         }
1456     }
1457 }
1458 
1459 /// A token emitted by clang's lexer.
1460 #[derive(Debug)]
1461 pub struct Token {
1462     /// The kind of token this is.
1463     pub kind: CXTokenKind,
1464     /// A display name for this token.
1465     pub spelling: String,
1466 }
1467 
1468 /// A translation unit (or "compilation unit").
1469 pub struct TranslationUnit {
1470     x: CXTranslationUnit,
1471 }
1472 
1473 impl fmt::Debug for TranslationUnit {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1474     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1475         write!(fmt, "TranslationUnit {{ }}")
1476     }
1477 }
1478 
1479 impl TranslationUnit {
1480     /// Parse a source file into a translation unit.
parse( ix: &Index, file: &str, cmd_args: &[String], unsaved: &[UnsavedFile], opts: CXTranslationUnit_Flags, ) -> Option<TranslationUnit>1481     pub fn parse(
1482         ix: &Index,
1483         file: &str,
1484         cmd_args: &[String],
1485         unsaved: &[UnsavedFile],
1486         opts: CXTranslationUnit_Flags,
1487     ) -> Option<TranslationUnit> {
1488         let fname = CString::new(file).unwrap();
1489         let _c_args: Vec<CString> = cmd_args
1490             .iter()
1491             .map(|s| CString::new(s.clone()).unwrap())
1492             .collect();
1493         let c_args: Vec<*const c_char> =
1494             _c_args.iter().map(|s| s.as_ptr()).collect();
1495         let mut c_unsaved: Vec<CXUnsavedFile> =
1496             unsaved.iter().map(|f| f.x).collect();
1497         let tu = unsafe {
1498             clang_parseTranslationUnit(
1499                 ix.x,
1500                 fname.as_ptr(),
1501                 c_args.as_ptr(),
1502                 c_args.len() as c_int,
1503                 c_unsaved.as_mut_ptr(),
1504                 c_unsaved.len() as c_uint,
1505                 opts,
1506             )
1507         };
1508         if tu.is_null() {
1509             None
1510         } else {
1511             Some(TranslationUnit {
1512                 x: tu,
1513             })
1514         }
1515     }
1516 
1517     /// Get the Clang diagnostic information associated with this translation
1518     /// unit.
diags(&self) -> Vec<Diagnostic>1519     pub fn diags(&self) -> Vec<Diagnostic> {
1520         unsafe {
1521             let num = clang_getNumDiagnostics(self.x) as usize;
1522             let mut diags = vec![];
1523             for i in 0..num {
1524                 diags.push(Diagnostic {
1525                     x: clang_getDiagnostic(self.x, i as c_uint),
1526                 });
1527             }
1528             diags
1529         }
1530     }
1531 
1532     /// Get a cursor pointing to the root of this translation unit's AST.
cursor(&self) -> Cursor1533     pub fn cursor(&self) -> Cursor {
1534         unsafe {
1535             Cursor {
1536                 x: clang_getTranslationUnitCursor(self.x),
1537             }
1538         }
1539     }
1540 
1541     /// Is this the null translation unit?
is_null(&self) -> bool1542     pub fn is_null(&self) -> bool {
1543         self.x.is_null()
1544     }
1545 }
1546 
1547 impl Drop for TranslationUnit {
drop(&mut self)1548     fn drop(&mut self) {
1549         unsafe {
1550             clang_disposeTranslationUnit(self.x);
1551         }
1552     }
1553 }
1554 
1555 
1556 /// A diagnostic message generated while parsing a translation unit.
1557 pub struct Diagnostic {
1558     x: CXDiagnostic,
1559 }
1560 
1561 impl Diagnostic {
1562     /// Format this diagnostic message as a string, using the given option bit
1563     /// flags.
format(&self) -> String1564     pub fn format(&self) -> String {
1565         unsafe {
1566             let opts = clang_defaultDiagnosticDisplayOptions();
1567             cxstring_into_string(clang_formatDiagnostic(self.x, opts))
1568         }
1569     }
1570 
1571     /// What is the severity of this diagnostic message?
severity(&self) -> CXDiagnosticSeverity1572     pub fn severity(&self) -> CXDiagnosticSeverity {
1573         unsafe { clang_getDiagnosticSeverity(self.x) }
1574     }
1575 }
1576 
1577 impl Drop for Diagnostic {
1578     /// Destroy this diagnostic message.
drop(&mut self)1579     fn drop(&mut self) {
1580         unsafe {
1581             clang_disposeDiagnostic(self.x);
1582         }
1583     }
1584 }
1585 
1586 /// A file which has not been saved to disk.
1587 pub struct UnsavedFile {
1588     x: CXUnsavedFile,
1589     /// The name of the unsaved file. Kept here to avoid leaving dangling pointers in
1590     /// `CXUnsavedFile`.
1591     pub name: CString,
1592     contents: CString,
1593 }
1594 
1595 impl UnsavedFile {
1596     /// Construct a new unsaved file with the given `name` and `contents`.
new(name: &str, contents: &str) -> UnsavedFile1597     pub fn new(name: &str, contents: &str) -> UnsavedFile {
1598         let name = CString::new(name).unwrap();
1599         let contents = CString::new(contents).unwrap();
1600         let x = CXUnsavedFile {
1601             Filename: name.as_ptr(),
1602             Contents: contents.as_ptr(),
1603             Length: contents.as_bytes().len() as c_ulong,
1604         };
1605         UnsavedFile {
1606             x: x,
1607             name: name,
1608             contents: contents,
1609         }
1610     }
1611 }
1612 
1613 impl fmt::Debug for UnsavedFile {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result1614     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
1615         write!(
1616             fmt,
1617             "UnsavedFile(name: {:?}, contents: {:?})",
1618             self.name,
1619             self.contents
1620         )
1621     }
1622 }
1623 
1624 /// Convert a cursor kind into a static string.
kind_to_str(x: CXCursorKind) -> String1625 pub fn kind_to_str(x: CXCursorKind) -> String {
1626     unsafe { cxstring_into_string(clang_getCursorKindSpelling(x)) }
1627 }
1628 
1629 /// Convert a type kind to a static string.
type_to_str(x: CXTypeKind) -> String1630 pub fn type_to_str(x: CXTypeKind) -> String {
1631     unsafe { cxstring_into_string(clang_getTypeKindSpelling(x)) }
1632 }
1633 
1634 /// Dump the Clang AST to stdout for debugging purposes.
ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult1635 pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult {
1636     fn print_indent<S: AsRef<str>>(depth: isize, s: S) {
1637         for _ in 0..depth {
1638             print!("    ");
1639         }
1640         println!("{}", s.as_ref());
1641     }
1642 
1643     fn print_cursor<S: AsRef<str>>(depth: isize, prefix: S, c: &Cursor) {
1644         let prefix = prefix.as_ref();
1645         print_indent(
1646             depth,
1647             format!(" {}kind = {}", prefix, kind_to_str(c.kind())),
1648         );
1649         print_indent(
1650             depth,
1651             format!(" {}spelling = \"{}\"", prefix, c.spelling()),
1652         );
1653         print_indent(depth, format!(" {}location = {}", prefix, c.location()));
1654         print_indent(
1655             depth,
1656             format!(" {}is-definition? {}", prefix, c.is_definition()),
1657         );
1658         print_indent(
1659             depth,
1660             format!(" {}is-declaration? {}", prefix, c.is_declaration()),
1661         );
1662         print_indent(
1663             depth,
1664             format!(
1665                 " {}is-inlined-function? {}",
1666                 prefix,
1667                 c.is_inlined_function()
1668             ),
1669         );
1670 
1671         let templ_kind = c.template_kind();
1672         if templ_kind != CXCursor_NoDeclFound {
1673             print_indent(
1674                 depth,
1675                 format!(" {}template-kind = {}", prefix, kind_to_str(templ_kind)),
1676             );
1677         }
1678         if let Some(usr) = c.usr() {
1679             print_indent(depth, format!(" {}usr = \"{}\"", prefix, usr));
1680         }
1681         if let Ok(num) = c.num_args() {
1682             print_indent(depth, format!(" {}number-of-args = {}", prefix, num));
1683         }
1684         if let Some(num) = c.num_template_args() {
1685             print_indent(
1686                 depth,
1687                 format!(" {}number-of-template-args = {}", prefix, num),
1688             );
1689         }
1690         if let Some(width) = c.bit_width() {
1691             print_indent(depth, format!(" {}bit-width = {}", prefix, width));
1692         }
1693         if let Some(ty) = c.enum_type() {
1694             print_indent(
1695                 depth,
1696                 format!(" {}enum-type = {}", prefix, type_to_str(ty.kind())),
1697             );
1698         }
1699         if let Some(val) = c.enum_val_signed() {
1700             print_indent(depth, format!(" {}enum-val = {}", prefix, val));
1701         }
1702         if let Some(ty) = c.typedef_type() {
1703             print_indent(
1704                 depth,
1705                 format!(" {}typedef-type = {}", prefix, type_to_str(ty.kind())),
1706             );
1707         }
1708         if let Some(ty) = c.ret_type() {
1709             print_indent(
1710                 depth,
1711                 format!(" {}ret-type = {}", prefix, type_to_str(ty.kind())),
1712             );
1713         }
1714 
1715         if let Some(refd) = c.referenced() {
1716             if refd != *c {
1717                 println!("");
1718                 print_cursor(
1719                     depth,
1720                     String::from(prefix) + "referenced.",
1721                     &refd,
1722                 );
1723             }
1724         }
1725 
1726         let canonical = c.canonical();
1727         if canonical != *c {
1728             println!("");
1729             print_cursor(
1730                 depth,
1731                 String::from(prefix) + "canonical.",
1732                 &canonical,
1733             );
1734         }
1735 
1736         if let Some(specialized) = c.specialized() {
1737             if specialized != *c {
1738                 println!("");
1739                 print_cursor(
1740                     depth,
1741                     String::from(prefix) + "specialized.",
1742                     &specialized,
1743                 );
1744             }
1745         }
1746 
1747         if let Some(parent) = c.fallible_semantic_parent() {
1748             println!("");
1749             print_cursor(
1750                 depth,
1751                 String::from(prefix) + "semantic-parent.",
1752                 &parent,
1753             );
1754         }
1755     }
1756 
1757     fn print_type<S: AsRef<str>>(depth: isize, prefix: S, ty: &Type) {
1758         let prefix = prefix.as_ref();
1759 
1760         let kind = ty.kind();
1761         print_indent(depth, format!(" {}kind = {}", prefix, type_to_str(kind)));
1762         if kind == CXType_Invalid {
1763             return;
1764         }
1765 
1766         print_indent(depth, format!(" {}cconv = {}", prefix, ty.call_conv()));
1767 
1768         print_indent(
1769             depth,
1770             format!(" {}spelling = \"{}\"", prefix, ty.spelling()),
1771         );
1772         let num_template_args = if clang_Type_getNumTemplateArguments::is_loaded() {
1773             unsafe { clang_Type_getNumTemplateArguments(ty.x) }
1774         } else {
1775             -1
1776         };
1777         if num_template_args >= 0 {
1778             print_indent(
1779                 depth,
1780                 format!(
1781                     " {}number-of-template-args = {}",
1782                     prefix,
1783                     num_template_args
1784                 ),
1785             );
1786         }
1787         if let Some(num) = ty.num_elements() {
1788             print_indent(
1789                 depth,
1790                 format!(" {}number-of-elements = {}", prefix, num),
1791             );
1792         }
1793         print_indent(
1794             depth,
1795             format!(" {}is-variadic? {}", prefix, ty.is_variadic()),
1796         );
1797 
1798         let canonical = ty.canonical_type();
1799         if canonical != *ty {
1800             println!("");
1801             print_type(depth, String::from(prefix) + "canonical.", &canonical);
1802         }
1803 
1804         if let Some(pointee) = ty.pointee_type() {
1805             if pointee != *ty {
1806                 println!("");
1807                 print_type(depth, String::from(prefix) + "pointee.", &pointee);
1808             }
1809         }
1810 
1811         if let Some(elem) = ty.elem_type() {
1812             if elem != *ty {
1813                 println!("");
1814                 print_type(depth, String::from(prefix) + "elements.", &elem);
1815             }
1816         }
1817 
1818         if let Some(ret) = ty.ret_type() {
1819             if ret != *ty {
1820                 println!("");
1821                 print_type(depth, String::from(prefix) + "return.", &ret);
1822             }
1823         }
1824 
1825         let named = ty.named();
1826         if named != *ty && named.is_valid() {
1827             println!("");
1828             print_type(depth, String::from(prefix) + "named.", &named);
1829         }
1830     }
1831 
1832     print_indent(depth, "(");
1833     print_cursor(depth, "", c);
1834 
1835     println!("");
1836     let ty = c.cur_type();
1837     print_type(depth, "type.", &ty);
1838 
1839     let declaration = ty.declaration();
1840     if declaration != *c && declaration.kind() != CXCursor_NoDeclFound {
1841         println!("");
1842         print_cursor(depth, "type.declaration.", &declaration);
1843     }
1844 
1845     // Recurse.
1846     let mut found_children = false;
1847     c.visit(|s| {
1848         if !found_children {
1849             println!("");
1850             found_children = true;
1851         }
1852         ast_dump(&s, depth + 1)
1853     });
1854 
1855     print_indent(depth, ")");
1856 
1857     CXChildVisit_Continue
1858 }
1859 
1860 /// Try to extract the clang version to a string
extract_clang_version() -> String1861 pub fn extract_clang_version() -> String {
1862     unsafe { cxstring_into_string(clang_getClangVersion()) }
1863 }
1864 
1865 /// A wrapper for the result of evaluating an expression.
1866 #[derive(Debug)]
1867 pub struct EvalResult {
1868     x: CXEvalResult,
1869 }
1870 
1871 impl EvalResult {
1872     /// Evaluate `cursor` and return the result.
new(cursor: Cursor) -> Option<Self>1873     pub fn new(cursor: Cursor) -> Option<Self> {
1874         if !clang_Cursor_Evaluate::is_loaded() {
1875             return None;
1876         }
1877 
1878         // Clang has an internal assertion we can trigger if we try to evaluate
1879         // a cursor containing a variadic template type reference. Triggering
1880         // the assertion aborts the process, and we don't want that. Clang
1881         // *also* doesn't expose any API for finding variadic vs non-variadic
1882         // template type references, let alone whether a type referenced is a
1883         // template type, instead they seem to show up as type references to an
1884         // unexposed type. Our solution is to just flat out ban all
1885         // `CXType_Unexposed` from evaluation.
1886         let mut found_cant_eval = false;
1887         cursor.visit(|c| if c.kind() == CXCursor_TypeRef &&
1888             c.cur_type().kind() == CXType_Unexposed
1889         {
1890             found_cant_eval = true;
1891             CXChildVisit_Break
1892         } else {
1893             CXChildVisit_Recurse
1894         });
1895         if found_cant_eval {
1896             return None;
1897         }
1898 
1899         Some(EvalResult {
1900             x: unsafe { clang_Cursor_Evaluate(cursor.x) },
1901         })
1902     }
1903 
kind(&self) -> CXEvalResultKind1904     fn kind(&self) -> CXEvalResultKind {
1905         unsafe { clang_EvalResult_getKind(self.x) }
1906     }
1907 
1908     /// Try to get back the result as a double.
as_double(&self) -> Option<f64>1909     pub fn as_double(&self) -> Option<f64> {
1910         match self.kind() {
1911             CXEval_Float => {
1912                 Some(unsafe { clang_EvalResult_getAsDouble(self.x) } as f64)
1913             }
1914             _ => None,
1915         }
1916     }
1917 
1918     /// Try to get back the result as an integer.
as_int(&self) -> Option<i64>1919     pub fn as_int(&self) -> Option<i64> {
1920         if self.kind() != CXEval_Int {
1921             return None;
1922         }
1923 
1924         if !clang_EvalResult_isUnsignedInt::is_loaded() {
1925             // FIXME(emilio): There's no way to detect underflow here, and clang
1926             // will just happily give us a value.
1927             return Some(unsafe { clang_EvalResult_getAsInt(self.x) } as i64)
1928         }
1929 
1930         if unsafe { clang_EvalResult_isUnsignedInt(self.x) } != 0 {
1931             let value = unsafe { clang_EvalResult_getAsUnsigned(self.x) };
1932             if value > i64::max_value() as c_ulonglong {
1933                 return None;
1934             }
1935 
1936             return Some(value as i64)
1937         }
1938 
1939         let value = unsafe { clang_EvalResult_getAsLongLong(self.x) };
1940         if value > i64::max_value() as c_longlong {
1941             return None;
1942         }
1943         if value < i64::min_value() as c_longlong {
1944             return None;
1945         }
1946         Some(value as i64)
1947     }
1948 
1949     /// Evaluates the expression as a literal string, that may or may not be
1950     /// valid utf-8.
as_literal_string(&self) -> Option<Vec<u8>>1951     pub fn as_literal_string(&self) -> Option<Vec<u8>> {
1952         match self.kind() {
1953             CXEval_StrLiteral => {
1954                 let ret = unsafe {
1955                     CStr::from_ptr(clang_EvalResult_getAsStr(self.x))
1956                 };
1957                 Some(ret.to_bytes().to_vec())
1958             }
1959             _ => None,
1960         }
1961     }
1962 }
1963 
1964 impl Drop for EvalResult {
drop(&mut self)1965     fn drop(&mut self) {
1966         unsafe { clang_EvalResult_dispose(self.x) };
1967     }
1968 }
1969 
1970 /// Target information obtained from libclang.
1971 #[derive(Debug)]
1972 pub struct TargetInfo {
1973     /// The target triple.
1974     pub triple: String,
1975     /// The width of the pointer _in bits_.
1976     pub pointer_width: usize,
1977 }
1978 
1979 impl TargetInfo {
1980     /// Tries to obtain target information from libclang.
new(tu: &TranslationUnit) -> Option<Self>1981     pub fn new(tu: &TranslationUnit) -> Option<Self> {
1982         if !clang_getTranslationUnitTargetInfo::is_loaded() {
1983             return None;
1984         }
1985         let triple;
1986         let pointer_width;
1987         unsafe {
1988             let ti = clang_getTranslationUnitTargetInfo(tu.x);
1989             triple = cxstring_into_string(clang_TargetInfo_getTriple(ti));
1990             pointer_width = clang_TargetInfo_getPointerWidth(ti);
1991             clang_TargetInfo_dispose(ti);
1992         }
1993         assert!(pointer_width > 0);
1994         assert_eq!(pointer_width % 8, 0);
1995         Some(TargetInfo {
1996             triple,
1997             pointer_width: pointer_width as usize,
1998         })
1999     }
2000 }
2001