1 /**
2  * Copyright: Copyright (c) 2011-2016 Jacob Carlborg. All rights reserved.
3  * Authors: Jacob Carlborg, Joakim Brännström (joakim.brannstrom dottli gmx.com)
4  * Version: 1.1+
5  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
6  * History:
7  *  1.0 initial release. 2012-01-29 $(BR)
8  *    Jacob Carlborg
9  *
10  *  1.1+ additional features missing compared to cindex.py. 2015-03-07 $(BR)
11  *    Joakim Brännström
12  *
13  * TODO split the specific C++ stuff to a dedicated cursor.
14  * TODO implement cxxMangling.
15  */
16 module clang.Cursor;
17 
18 import clang.c.Index;
19 
20 import clang.Eval;
21 import clang.File;
22 import clang.SourceLocation;
23 import clang.SourceRange;
24 import clang.Token;
25 import clang.TranslationUnit;
26 import clang.Type;
27 import clang.Util;
28 import clang.Visitor;
29 
30 /** The Cursor class represents a reference to an element within the AST. It
31  * acts as a kind of iterator.
32  */
33 @safe struct Cursor {
34     mixin CX;
35 
36     // for example primitive types are predefined
37     private static const CXCursorKind[string] predefined;
38 
39     static this() {
40         // populate the database once
41         predefined = queryPredefined();
42     }
43 
44     /// Retrieve the NULL cursor, which represents no entity.
45     @property static Cursor empty() @trusted {
46         auto r = clang_getNullCursor();
47         return Cursor(r);
48     }
49 
50     /** Retrieve a Unified Symbol Resolution (USR) for the entity referenced by
51      * the given cursor.
52      *
53      * A Unified Symbol Resolution (USR) is a string that identifies a
54      * particular entity (function, class, variable, etc.) within a program.
55      * USRs can be compared across translation units to determine, e.g., when
56      * references in one translation refer to an entity defined in another
57      * translation unit.
58      */
59     @property string usr() const @trusted {
60         return toD(clang_getCursorUSR(cx));
61     }
62 
63     /// Return: Retrieve a name for the entity referenced by this cursor.
64     @property string spelling() const @trusted {
65         return toD(clang_getCursorSpelling(cx));
66     }
67 
68     /**
69      * Returns the storage class for a function or variable declaration.
70      *
71      * If the passed in Cursor is not a function or variable declaration,
72      * CX_SC_Invalid is returned else the storage class.
73      */
74     @property CX_StorageClass storageClass() const @trusted {
75         return clang_Cursor_getStorageClass(cx);
76     }
77 
78     /** Determine the linkage of the entity referred to by a given cursor.
79      *
80      * This value indicates that no linkage information is available for a
81      * provided CXCursor.
82      * CXLinkage_Invalid,
83      *
84      * This is the linkage for variables, parameters, and so on that have
85      * automatic storage.  This covers normal (non-extern) local variables.
86      * CXLinkage_NoLinkage,
87      *
88      * This is the linkage for static variables and static functions.
89      * CXLinkage_Internal,
90      *
91      * This is the linkage for entities with external linkage that live
92      * in C++ anonymous namespaces.
93      * CXLinkage_UniqueExternal,
94      *
95      * This is the linkage for entities with true, external linkage.
96      * CXLinkage_External
97      */
98     @property CXLinkageKind linkage() const @trusted {
99         return clang_getCursorLinkage(cx);
100     }
101 
102     /** Return the display name for the entity referenced by this cursor.
103      *
104      * The display name contains extra information that helps identify the
105      * cursor, such as the parameters of a function or template or the
106      * arguments of a class template specialization.
107      *
108      * If it is NOT a declaration then the return value is the same as
109      * spelling.
110      */
111     @property string displayName() const @trusted {
112         return toD(clang_getCursorDisplayName(cx));
113     }
114 
115     /** Return the cursor kind of the template specialization that would be
116      * generated when instantiating the template with this cursor.
117      */
118     @property CXCursorKind templateKind() const @trusted {
119         return clang_getTemplateCursorKind(cx);
120     }
121 
122     /** Return the cursor that represents the template that given cursor
123      * specializes (or is instantiated) from.
124      *
125      * It will only work for a cursor that represent a specialization or
126      * insantiation of a template. Otherwise, NULL cursor is returned.
127      */
128     @property CXCursor templateCursor() const @trusted {
129         return clang_getSpecializedCursorTemplate(cx);
130     }
131 
132     /** Retrieve the string representing the mangled name of the cursor.
133      *
134      * Only useful for cursors that are NOT declarations.
135      */
136     @property string mangling() const @trusted {
137         return toD(clang_Cursor_getMangling(cx));
138     }
139 
140     /**
141      * \brief Retrieve the CXStrings representing the mangled symbols of the C++
142      * constructor or destructor at the cursor.
143      */
144     //@property string[] cxxMangling() const @trusted {
145     //    CXStringSet *clang_Cursor_getCXXManglings(CXCursor);
146     //}
147 
148     /// Return: the kind of this cursor.
149     @property CXCursorKind kind() const @trusted {
150         return clang_getCursorKind(cx);
151     }
152 
153     /** Retrieve the physical location of the source constructor referenced by
154      * the given cursor.
155      *
156      * The location of a declaration is typically the location of the name of
157      * that declaration, where the name of that declaration would occur if it
158      * is unnamed, or some keyword that introduces that particular declaration.
159      * The location of a reference is where that reference occurs within the
160      * source code.
161      */
162     @property SourceLocation location() const @trusted {
163         return SourceLocation(clang_getCursorLocation(cx));
164     }
165 
166     /** Type (if any) of the entity pointed at by the cursor.
167      *
168      * The following isDeclaration cursors are handled:
169      *  - TypeDecl
170      *  - DeclaratorDecl (if source info exist)
171      *
172      * isReference cursors may be automatically dereferenced if they are of the
173      * following kind:
174      *  - TypeRef
175      *  - CXXBaseSpecifier
176      *  - MemberRef
177      *  - VariableRef
178      * The following are NOT handled:
179      *  - TemplateRef
180      *  - NamespaceRef
181      *  - OverloadedDeclRef
182      */
183     @property Type type() @trusted const {
184         auto r = clang_getCursorType(cx);
185         return Type(this, r);
186     }
187 
188     /** Return the underlying type of a typedef declaration.
189      *
190      * If the current cursor is not a typedef an empty type is returned.
191      *
192      * Returns: the Type the typedef cursor is a declaration for.
193      */
194     @property Type typedefUnderlyingType() @trusted const {
195         auto r = clang_getTypedefDeclUnderlyingType(cx);
196         return Type(this, r);
197     }
198 
199     /** If the cursor is a reference to a declaration or a declaration of
200      *  some entity, return a cursor that points to the definition of that
201      *  entity.
202      */
203     @property Cursor definition() const @trusted {
204         auto r = clang_getCursorDefinition(cx);
205         return Cursor(r);
206     }
207 
208     /** Determine the semantic parent of the given cursor.
209      *
210      * The semantic parent of a cursor is the cursor that semantically contains
211      * the given cursor. For many declarations, the lexical and semantic
212      * parents are equivalent (the lexical parent is returned by
213      * clang_getCursorLexicalParent()). They diverge when declarations or
214      * definitions are provided out-of-line. For example:
215      *
216      * ---
217      * class C {
218      *  void f();
219      * }
220      *
221      * void C::f() { }
222      * ---
223      *
224      * In the out-of-line definition of C::f, the semantic parent is the the
225      * class C, of which this function is a member. The lexical parent is the
226      * place where the declaration actually occurs in the source code; in this
227      * case, the definition occurs in the translation unit. In general, the
228      * lexical parent for a given entity can change without affecting the
229      * semantics of the program, and the lexical parent of different
230      * declarations of the same entity may be different. Changing the semantic
231      * parent of a declaration, on the other hand, can have a major impact on
232      * semantics, and redeclarations of a particular entity should all have the
233      * same semantic context.
234      *
235      * In the example above, both declarations of C::f have C as their semantic
236      * context, while the lexical context of the first C::f is C and the
237      * lexical context of the second C::f is the translation unit.
238      *
239      * For global declarations, the semantic parent is the translation unit.
240      */
241     @property Cursor semanticParent() const @trusted {
242         auto r = clang_getCursorSemanticParent(cx);
243         return Cursor(r);
244     }
245 
246     /** Determine the lexical parent of the given cursor.
247      *
248      * The lexical parent of a cursor is the cursor in which the given cursor
249      * was actually written. For many declarations, the lexical and semantic
250      * parents are equivalent (the semantic parent is returned by
251      * clang_getCursorSemanticParent()). They diverge when declarations or
252      * definitions are provided out-of-line. For example:
253      *
254      * ---
255      * class C {
256      *  void f();
257      * }
258      *
259      * void C::f() { }
260      * ---
261      *
262      * In the out-of-line definition of C::f, the semantic parent is the the
263      * class C, of which this function is a member. The lexical parent is the
264      * place where the declaration actually occurs in the source code; in this
265      * case, the definition occurs in the translation unit. In general, the
266      * lexical parent for a given entity can change without affecting the
267      * semantics of the program, and the lexical parent of different
268      * declarations of the same entity may be different. Changing the semantic
269      * parent of a declaration, on the other hand, can have a major impact on
270      * semantics, and redeclarations of a particular entity should all have the
271      * same semantic context.
272      *
273      * In the example above, both declarations of C::f have C as their semantic
274      * context, while the lexical context of the first C::f is C and the
275      * lexical context of the second \c C::f is the translation unit.
276      *
277      * For declarations written in the global scope, the lexical parent is
278      * the translation unit.
279      */
280     @property Cursor lexicalParent() const @trusted {
281         auto r = clang_getCursorLexicalParent(cx);
282         return Cursor(r);
283     }
284 
285     /** For a cursor that is a reference, retrieve a cursor representing the
286      * entity that it references.
287      *
288      * Reference cursors refer to other entities in the AST. For example, an
289      * Objective-C superclass reference cursor refers to an Objective-C class.
290      * This function produces the cursor for the Objective-C class from the
291      * cursor for the superclass reference. If the input cursor is a
292      * declaration or definition, it returns that declaration or definition
293      * unchanged.  Otherwise, returns the NULL cursor.
294      */
295     @property Cursor referenced() const @trusted {
296         auto r = clang_getCursorReferenced(cx);
297         return Cursor(r);
298     }
299 
300     @property DeclarationVisitor declarations() const @trusted {
301         return DeclarationVisitor(this);
302     }
303 
304     /** Retrieve the physical extent of the source construct referenced by the
305      * given cursor.
306      *
307      * The extent of a cursor starts with the file/line/column pointing at the
308      * first character within the source construct that the cursor refers to
309      * and ends with the last character withinin that source construct. For a
310      * declaration, the extent covers the declaration itself. For a reference,
311      * the extent covers the location of the reference (e.g., where the
312      * referenced entity was actually used).
313      */
314     @property SourceRange extent() const @trusted {
315         auto r = clang_getCursorExtent(cx);
316         return SourceRange(r);
317     }
318 
319     /** If cursor is a statement declaration tries to evaluate the statement
320      * and if its variable, tries to evaluate its initializer, into its
321      * corresponding type.
322      */
323     Eval eval() const @trusted {
324         return Eval(clang_Cursor_Evaluate(cx));
325     }
326 
327     /** Retrieve the canonical cursor corresponding to the given cursor.
328      *
329      * In the C family of languages, many kinds of entities can be declared
330      * several times within a single translation unit. For example, a structure
331      * type can be forward-declared (possibly multiple times) and later
332      * defined:
333      *
334      * ---
335      * struct X;
336      * struct X;
337      * struct X {
338      *   int member;
339      * }
340      * ---
341      *
342      * The declarations and the definition of X are represented by three
343      * different cursors, all of which are declarations of the same underlying
344      * entity. One of these cursor is considered the "canonical" cursor, which
345      * is effectively the representative for the underlying entity. One can
346      * determine if two cursors are declarations of the same underlying entity
347      * by comparing their canonical cursors.
348      *
349      * Return: The canonical cursor for the entity referred to by the given cursor.
350      */
351     @property Cursor canonical() @trusted const {
352         auto r = clang_getCanonicalCursor(cx);
353         return Cursor(r);
354     }
355 
356     /// Determine the "language" of the entity referred to by a given cursor.
357     @property CXLanguageKind language() const @trusted {
358         return clang_getCursorLanguage(cx);
359     }
360 
361     /// Returns: the translation unit that a cursor originated from.
362     @property TranslationUnit translationUnit() const @trusted {
363         return TranslationUnit(clang_Cursor_getTranslationUnit(cx));
364     }
365 
366     /** Obtain Token instances formulating that compose this Cursor.
367      *
368      * This is a generator for Token instances. It returns all tokens which
369      * occupy the extent this cursor occupies.
370      *
371      * Trusted: the API usage follows the LLVM manual. The potential problem
372      * would be if clang_tokenize write back invalid addresses.
373      *
374      * Returns: A range over the tokens.
375      */
376     @property auto tokens() const @trusted {
377         import std.algorithm.mutation : stripRight;
378 
379         CXToken* tokens = null;
380         uint numTokens = 0;
381         clang_tokenize(translationUnit.cx, extent.cx, &tokens, &numTokens);
382         auto result = TokenRange(translationUnit, tokens, numTokens);
383 
384         // For some reason libclang returns some tokens out of cursors extent.cursor
385         return result.stripRight!(token => !intersects(extent, token.extent));
386     }
387 
388     @property ObjcCursor objc() const {
389         return ObjcCursor(this);
390     }
391 
392     @property FunctionCursor func() const {
393         return FunctionCursor(this);
394     }
395 
396     @property EnumCursor enum_() const {
397         return EnumCursor(this);
398     }
399 
400     @property AccessCursor access() const {
401         return AccessCursor(this);
402     }
403 
404     @property IncludeCursor include() const {
405         return IncludeCursor(this);
406     }
407 
408     @property Visitor all() const {
409         return Visitor(this);
410     }
411 
412     @property InOrderVisitor allInOrder() const {
413         return InOrderVisitor(this);
414     }
415 
416     private Cursor[] childrenImpl(T)(bool ignorePredefined) const {
417         import std.array : appender;
418 
419         Cursor[] result;
420         auto app = appender(result);
421 
422         if (ignorePredefined && isTranslationUnit) {
423             foreach (cursor, _; T(this)) {
424                 if (!cursor.isPredefined)
425                     app.put(cursor);
426             }
427         } else {
428             foreach (cursor, _; T(this))
429                 app.put(cursor);
430         }
431 
432         return app.data;
433     }
434 
435     /** Array of all children of the cursor.
436      *
437      * Params:
438      *  ignorePredefined = ignore cursors for primitive types.
439      */
440     Cursor[] children(bool ignorePredefined = false) const {
441         return childrenImpl!Visitor(ignorePredefined);
442     }
443 
444     Cursor[] childrenInOrder(bool ignorePredefined = false) const {
445         return childrenImpl!InOrderVisitor(ignorePredefined);
446     }
447 
448     /// Determine whether two cursors are equivalent.
449     equals_t opEquals(const ref Cursor cursor) const @trusted {
450         return clang_equalCursors(cast(CXCursor) cursor.cx, cast(CXCursor) cx) != 0;
451     }
452 
453     /// Compute a hash value for the given cursor.
454     size_t toHash() const nothrow @trusted {
455         //TODO i'm not sure this is a good solution... investigate.
456         try {
457             return clang_hashCursor(cast(CXCursor) cx);
458         } catch (Exception ex) {
459             return 0;
460         }
461     }
462 
463     /// Determine whether the given cursor has any attributes.
464     @property bool hasAttributes() const @trusted {
465         return clang_Cursor_hasAttrs(cx) != 0;
466     }
467 
468     /// Determine whether the given cursor kind represents a declaration.
469     @property bool isDeclaration() const @trusted {
470         return clang_isDeclaration(cx.kind) != 0;
471     }
472 
473     /** Determine whether the given cursor kind represents a simple
474      * reference.
475      *
476      * Note that other kinds of cursors (such as expressions) can also refer to
477      * other cursors. Use clang_getCursorReferenced() to determine whether a
478      * particular cursor refers to another entity.
479      */
480     @property bool isReference() const @trusted {
481         return clang_isReference(cx.kind) != 0;
482     }
483 
484     /// Determine whether the given cursor kind represents an expression.
485     @property bool isExpression() const @trusted {
486         return clang_isExpression(cx.kind) != 0;
487     }
488 
489     /// Determine whether the given cursor kind represents a statement.
490     @property bool isStatement() const @trusted {
491         return clang_isStatement(cx.kind) != 0;
492     }
493 
494     /** Determine whether the given cursor represents an anonymous record
495      * declaration.
496      *
497      * The cursor must be a declaration and either a struct or union.
498      *
499      * Determines whether this field is a representative for an anonymous
500      * struct or union. Such fields are unnamed and are implicitly generated by
501      * the implementation to store the data for the anonymous union or struct.
502      *
503      * If the following is declared inside a struct.
504      *
505      * Example:
506      * ---
507      * union {
508      *     int x;
509      *     char y;
510      * };
511      * ---
512      */
513     @property bool isAnonymous() const @trusted {
514         return clang_Cursor_isAnonymous(cx) != 0;
515     }
516 
517     /// Determine whether the given cursor kind represents an attribute.
518     @property bool isAttribute() const @trusted {
519         return clang_isAttribute(cx.kind) != 0;
520     }
521 
522     int bitFieldWidth() const @trusted {
523         return clang_getFieldDeclBitWidth(cast(CXCursor) cx);
524     }
525 
526     bool isBitField() const @trusted {
527         return clang_Cursor_isBitField(cast(CXCursor) cx) != 0;
528     }
529 
530     /// Determine whether the given cursor kind represents an invalid cursor.
531     @property bool isValid() const @trusted {
532         // note that it checks for invalidity of the cursor, thus the inverse
533         // is the return value.
534         return !clang_isInvalid(cx.kind);
535     }
536 
537     /// Determine whether the given cursor kind represents a translation unit.
538     @property bool isTranslationUnit() const @trusted {
539         return clang_isTranslationUnit(cx.kind) != 0;
540     }
541 
542     /** Determine whether the given cursor represents a preprocessing
543      * element, such as a preprocessor directive or macro instantiation.
544      */
545     @property bool isPreprocessing() const @trusted {
546         return clang_isPreprocessing(cx.kind) != 0;
547 
548         // If clang_isPreprocessing isn't working out this is the
549         // implementation from DStep.
550 
551         //CXCursorKind kind = clang_getCursorKind(cx);
552         //return CXCursorKind.firstPreprocessing <= kind &&
553         //    kind <= CXCursorKind.lastPreprocessing;
554     }
555 
556     /** Determine whether the given cursor represents a currently unexposed
557      * piece of the AST (e.g., CXCursor_UnexposedStmt).
558      */
559     @property bool isUnexposed() const @trusted {
560         return clang_isUnexposed(cx.kind) != 0;
561     }
562 
563     /// Return: if the underlying type is an enum.
564     @property bool isUnderlyingTypeEnum() const @trusted {
565         auto underlying = typedefUnderlyingType;
566         if (!underlying.isValid) {
567             return false;
568         }
569 
570         auto decl = underlying.declaration;
571         if (!decl.isValid) {
572             return false;
573         }
574 
575         return decl.type.isEnum;
576     }
577 
578     /// Return: if cursor is null/empty.
579     @property bool isEmpty() const @trusted {
580         return clang_Cursor_isNull(cx) != 0;
581     }
582 
583     /** Returns true if the declaration pointed at by the cursor is also a
584      * definition of that entity.
585      */
586     bool isDefinition() const @trusted {
587         return clang_isCursorDefinition(cast(CXCursor) cx) != 0;
588     }
589 
590     /// Returns: if the base class specified by the cursor with kind CX_CXXBaseSpecifier is virtual.
591     @property bool isVirtualBase() const @trusted {
592         return clang_isVirtualBase(cx) != 0;
593     }
594 
595     bool isPredefined() const @trusted {
596         auto xkind = usr in predefined;
597         return xkind !is null && *xkind == kind;
598     }
599 
600     /** Determine whether a CXCursor that is a macro, is function like.
601      */
602     bool isMacroFunctionLike() const @trusted {
603         return clang_Cursor_isMacroFunctionLike(cx) != 0;
604     }
605 
606     /** Determine whether a CXCursor that is a macro, is a builtin one.
607      */
608     bool isMacroBuiltin() const @trusted {
609         return clang_Cursor_isMacroBuiltin(cx) != 0;
610     }
611 
612     /** Determine whether a CXCursor that is a function declaration, is an
613      * inline declaration.
614      */
615     bool isFunctionInlined() const @trusted {
616         return clang_Cursor_isFunctionInlined(cx) != 0;
617     }
618 
619     /// Determine if a C++ constructor is a converting constructor.
620     bool isConvertingConstructor() const @trusted {
621         return clang_CXXConstructor_isConvertingConstructor(cx) != 0;
622     }
623 
624     /// Determine if a C++ constructor is a copy constructor.
625     bool isCopyConstructor() const @trusted {
626         return clang_CXXConstructor_isCopyConstructor(cx) != 0;
627     }
628 
629     /// Determine if a C++ constructor is the default constructor.
630     bool isDefaultConstructor() const @trusted {
631         return clang_CXXConstructor_isDefaultConstructor(cx) != 0;
632     }
633 
634     /// Determine if a C++ constructor is a move constructor.
635     bool isMoveConstructor() const @trusted {
636         return clang_CXXConstructor_isMoveConstructor(cx) != 0;
637     }
638 
639     /// Determine if a C++ field is declared 'mutable'.
640     bool isMutable() const @trusted {
641         return clang_CXXField_isMutable(cx) != 0;
642     }
643 
644     /// Determine if a C++ method is declared '= default'.
645     bool isDefaulted() const @trusted {
646         return clang_CXXMethod_isDefaulted(cx) != 0;
647     }
648 
649     /// Determine if a C++ member function or member function template is pure virtual.
650     bool isPureVirtual() @trusted {
651         return clang_CXXMethod_isPureVirtual(cx) != 0;
652     }
653 
654     /** Describe the visibility of the entity referred to by a cursor.
655      *
656      * Note: This is linker visibility.
657      *
658      * This returns the default visibility if not explicitly specified by
659      * a visibility attribute. The default visibility may be changed by
660      * commandline arguments.
661      *
662      * Params:
663      *  cursor The cursor to query.
664      *
665      * Returns: The visibility of the cursor.
666      */
667     CXVisibilityKind visibility() const @trusted {
668         return clang_getCursorVisibility(cx);
669     }
670 
671     private static CXCursorKind[string] queryPredefined() @trusted {
672         import clang.Index;
673         import clang.TranslationUnit;
674 
675         CXCursorKind[string] result;
676 
677         Index index = Index(false, false);
678         TranslationUnit unit = TranslationUnit.parseString(index, "", []);
679 
680         foreach (cursor; unit.cursor.children)
681             result[cursor.usr] = cursor.kind;
682 
683         return result;
684     }
685 
686     public static string predefinedToString() @trusted {
687         import std.algorithm : map, joiner;
688         import std.ascii : newline;
689         import std.conv : text;
690         import std.string : leftJustifier;
691 
692         return predefined.byKeyValue().map!(a => leftJustifier(a.key, 50)
693                 .text ~ a.value.text).joiner(newline).text;
694     }
695 }
696 
697 struct ObjcCursor {
698     Cursor cursor;
699     alias cursor this;
700 
701     @property ObjCInstanceMethodVisitor instanceMethods() {
702         return ObjCInstanceMethodVisitor(cursor);
703     }
704 
705     @property ObjCClassMethodVisitor classMethods() {
706         return ObjCClassMethodVisitor(cursor);
707     }
708 
709     @property ObjCPropertyVisitor properties() {
710         return ObjCPropertyVisitor(cursor);
711     }
712 
713     @property Cursor superClass() {
714         foreach (cursor, parent; TypedVisitor!(CXCursorKind.objCSuperClassRef)(cursor))
715             return cursor;
716 
717         return Cursor.empty();
718     }
719 
720     @property ObjCProtocolVisitor protocols() {
721         return ObjCProtocolVisitor(cursor);
722     }
723 
724     @property Cursor category() {
725         assert(cursor.kind == CXCursorKind.objCCategoryDecl);
726 
727         foreach (c, _; TypedVisitor!(CXCursorKind.objCClassRef)(cursor))
728             return c;
729 
730         assert(0, "This cursor does not have a class reference.");
731     }
732 }
733 
734 struct FunctionCursor {
735     Cursor cursor;
736     alias cursor this;
737 
738     /// Return: Retrieve the Type of the result for this Cursor.
739     @property Type resultType() @trusted {
740         auto r = clang_getCursorResultType(cx);
741         return Type(cursor, r);
742     }
743 
744     @property ParamVisitor parameters() {
745         return ParamVisitor(cursor);
746     }
747 
748     /** Determine if a C++ member function or member function template is
749      * pure virtual.
750      */
751     @property bool isPureVirtual() @trusted {
752         return clang_CXXMethod_isPureVirtual(cx) != 0;
753     }
754 
755     /** Returns: True if the cursor refers to a C++ member function or member
756      * function template that is declared 'static'.
757      */
758     @property bool isStatic() @trusted {
759         return clang_CXXMethod_isStatic(cx) != 0;
760     }
761 
762     /** Determine if a C++ member function or member function template is
763      * explicitly declared 'virtual' or if it overrides a virtual method from
764      * one of the base classes.
765      */
766     @property bool isVirtual() @trusted {
767         return clang_CXXMethod_isVirtual(cx) != 0;
768     }
769 
770     /** Determine if a C++ member function or member function template is
771      * declared 'const'.
772      */
773     @property bool isConst() @trusted {
774         return clang_CXXMethod_isConst(cx) != 0;
775     }
776 
777     /** Given a cursor pointing to a C++ method call or an Objective-C
778      * message, returns non-zero if the method/message is "dynamic", meaning:
779      *
780      * For a C++ method: the call is virtual.
781      * For an Objective-C message: the receiver is an object instance, not 'super'
782      * or a specific class.
783      *
784      * If the method/message is "static" or the cursor does not point to a
785      * method/message, it will return zero.
786      */
787     @property bool isDynamicCall() @trusted {
788         return clang_Cursor_isDynamicCall(cx) != 0;
789     }
790 }
791 
792 struct AccessCursor {
793     Cursor cursor;
794     alias cursor this;
795 
796     /** Returns the access control level for the C++ base specifier represented
797      * by a cursor with kind CXCursor_CXXBaseSpecifier or
798      * CXCursor_AccessSpecifier.
799      */
800     @property auto accessSpecifier() @trusted {
801         return clang_getCXXAccessSpecifier(cx);
802     }
803 }
804 
805 struct ParamCursor {
806     Cursor cursor;
807     alias cursor this;
808 }
809 
810 struct IncludeCursor {
811     Cursor cursor;
812     alias cursor this;
813 
814     /** Retrieve the file that is included by the given inclusion directive
815      * cursor.
816      */
817     @property auto file() @trusted {
818         return File(clang_getIncludedFile(cx));
819     }
820 }
821 
822 struct EnumCursor {
823     import std.conv : to;
824 
825     Cursor cursor;
826     alias cursor this;
827 
828     @property string value() @safe {
829         import std.conv : to;
830 
831         return to!string(signedValue);
832     }
833 
834     /** Retrieve the integer type of an enum declaration.
835      *
836      * If the cursor does not reference an enum declaration, an invalid type is
837      * returned.
838      */
839     @property Type type() @trusted {
840         auto r = clang_getEnumDeclIntegerType(cx);
841         return Type(cursor, r);
842     }
843 
844     /** Retrieve the integer value of an enum constant declaration as a signed
845      * long.
846      *
847      * If the cursor does not reference an enum constant declaration, LLONG_MIN
848      * is returned.  Since this is also potentially a valid constant value, the
849      * kind of the cursor must be verified before calling this function.
850      */
851     @property long signedValue() @trusted {
852         return clang_getEnumConstantDeclValue(cx);
853     }
854 
855     /** Retrieve the integer value of an enum constant declaration as an
856      * unsigned long.
857      *
858      * If the cursor does not reference an enum constant declaration,
859      * ULLONG_MAX is returned.  Since this is also potentially a valid constant
860      * value, the kind of the cursor must be verified before calling this
861      * function.
862      */
863     @property ulong unsignedValue() @trusted {
864         return clang_getEnumConstantDeclUnsignedValue(cx);
865     }
866 
867     /// Return: if the type of the enum is signed.
868     @property bool isSigned() const @trusted {
869         Type t;
870 
871         if (isUnderlyingTypeEnum) {
872             t = typedefUnderlyingType.declaration.enum_.type;
873         } else {
874             t = Type(cursor, clang_getCursorType(cx));
875         }
876 
877         return t.isSigned;
878     }
879 }
880 
881 import std.array : appender, Appender;
882 
883 string dump(ref const(Cursor) c) @trusted {
884     import std.conv : to;
885     import std.string;
886 
887     static string stripPrefix(string x) {
888         immutable string prefix = "CXCursor_";
889         immutable size_t prefixSize = prefix.length;
890         return x.startsWith(prefix) ? x[prefixSize .. $] : x;
891     }
892 
893     static string prettyTokens(ref const(Cursor) c, size_t limit = 5) {
894         import std.algorithm.comparison : min;
895 
896         TokenRange tokens = c.tokens;
897 
898         string prettyToken(Token token) {
899             immutable string prefix = "CXToken_";
900             immutable size_t prefixSize = prefix.length;
901             auto x = to!string(token.kind);
902             return "%s \"%s\"".format(x.startsWith(prefix) ? x[prefixSize .. $] : x, token.spelling);
903         }
904 
905         auto result = appender!string("[");
906 
907         if (tokens.length != 0) {
908             result.put(prettyToken(tokens[0]));
909 
910             foreach (Token token; c.tokens[1 .. min($, limit)]) {
911                 result.put(", ");
912                 result.put(prettyToken(token));
913             }
914         }
915 
916         if (tokens.length > limit)
917             result.put(", ..]");
918         else
919             result.put("]");
920 
921         return result.data;
922     }
923 
924     auto text = "%s \"%s\" [%d:%d..%d:%d] %s %s".format(stripPrefix(to!string(c.kind)),
925             c.spelling, c.extent.start.line, c.extent.start.column,
926             c.extent.end.line, c.extent.end.column, prettyTokens(c), c.usr);
927 
928     return text;
929 }
930 
931 void dumpAST(ref const(Cursor) c, ref Appender!string result, size_t indent, File* file) @trusted {
932     import std.ascii : newline;
933     import std.format;
934     import std.array : replicate;
935 
936     immutable size_t step = 4;
937 
938     auto text = dump(c);
939 
940     result.put(" ".replicate(indent));
941     result.put(text);
942     result.put(newline);
943 
944     if (file) {
945         foreach (cursor, _; c.all) {
946             if (!cursor.isPredefined() && cursor.location.file == *file)
947                 dumpAST(cursor, result, indent + step);
948         }
949     } else {
950         foreach (cursor, _; c.all) {
951             if (!cursor.isPredefined())
952                 cursor.dumpAST(result, indent + step);
953         }
954     }
955 }
956 
957 void dumpAST(ref const(Cursor) c, ref Appender!string result, size_t indent) @safe {
958     dumpAST(c, result, indent, null);
959 }
960 
961 unittest {
962     // "Should output the predefined types for inspection"
963     import std.stdio;
964 
965     writeln(Cursor.predefinedToString);
966 }