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