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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
291         auto r = clang_getCursorReferenced(cx);
292         return Cursor(r);
293     }
294 
295     @property DeclarationVisitor declarations() const @trusted {
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 {
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 {
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 {
353         return clang_getCursorLanguage(cx);
354     }
355 
356     /// Returns: the translation unit that a cursor originated from.
357     @property TranslationUnit translationUnit() const @trusted {
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 {
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 {
384         return ObjcCursor(this);
385     }
386 
387     @property FunctionCursor func() const {
388         return FunctionCursor(this);
389     }
390 
391     @property EnumCursor enum_() const {
392         return EnumCursor(this);
393     }
394 
395     @property AccessCursor access() const {
396         return AccessCursor(this);
397     }
398 
399     @property IncludeCursor include() const {
400         return IncludeCursor(this);
401     }
402 
403     @property Visitor all() const {
404         return Visitor(this);
405     }
406 
407     @property InOrderVisitor allInOrder() const {
408         return InOrderVisitor(this);
409     }
410 
411     private Cursor[] childrenImpl(T)(bool ignorePredefined) const {
412         import std.array : appender;
413 
414         Cursor[] result;
415         auto app = appender(result);
416 
417         if (ignorePredefined && isTranslationUnit) {
418             foreach (cursor, _; T(this)) {
419                 if (!cursor.isPredefined)
420                     app.put(cursor);
421             }
422         } else {
423             foreach (cursor, _; T(this))
424                 app.put(cursor);
425         }
426 
427         return app.data;
428     }
429 
430     /** Array of all children of the cursor.
431      *
432      * Params:
433      *  ignorePredefined = ignore cursors for primitive types.
434      */
435     Cursor[] children(bool ignorePredefined = false) const {
436         return childrenImpl!Visitor(ignorePredefined);
437     }
438 
439     Cursor[] childrenInOrder(bool ignorePredefined = false) const {
440         return childrenImpl!InOrderVisitor(ignorePredefined);
441     }
442 
443     /// Determine whether two cursors are equivalent.
444     equals_t opEquals(const ref Cursor cursor) const @trusted {
445         return clang_equalCursors(cast(CXCursor) cursor.cx, cast(CXCursor) cx) != 0;
446     }
447 
448     /// Compute a hash value for the given cursor.
449     size_t toHash() const nothrow @trusted {
450         //TODO i'm not sure this is a good solution... investigate.
451         try {
452             return clang_hashCursor(cast(CXCursor) cx);
453         } catch (Exception ex) {
454             return 0;
455         }
456     }
457 
458     /// Determine whether the given cursor has any attributes.
459     @property bool hasAttributes() const @trusted {
460         return clang_Cursor_hasAttrs(cx) != 0;
461     }
462 
463     /// Determine whether the given cursor kind represents a declaration.
464     @property bool isDeclaration() const @trusted {
465         return clang_isDeclaration(cx.kind) != 0;
466     }
467 
468     /** Determine whether the given cursor kind represents a simple
469      * reference.
470      *
471      * Note that other kinds of cursors (such as expressions) can also refer to
472      * other cursors. Use clang_getCursorReferenced() to determine whether a
473      * particular cursor refers to another entity.
474      */
475     @property bool isReference() const @trusted {
476         return clang_isReference(cx.kind) != 0;
477     }
478 
479     /// Determine whether the given cursor kind represents an expression.
480     @property bool isExpression() const @trusted {
481         return clang_isExpression(cx.kind) != 0;
482     }
483 
484     /// Determine whether the given cursor kind represents a statement.
485     @property bool isStatement() const @trusted {
486         return clang_isStatement(cx.kind) != 0;
487     }
488 
489     /** Determine whether the given cursor represents an anonymous record
490      * declaration.
491      *
492      * The cursor must be a declaration and either a struct or union.
493      *
494      * Determines whether this field is a representative for an anonymous
495      * struct or union. Such fields are unnamed and are implicitly generated by
496      * the implementation to store the data for the anonymous union or struct.
497      *
498      * If the following is declared inside a struct.
499      *
500      * Example:
501      * ---
502      * union {
503      *     int x;
504      *     char y;
505      * };
506      * ---
507      */
508     @property bool isAnonymous() const @trusted {
509         return clang_Cursor_isAnonymous(cx) != 0;
510     }
511 
512     /// Determine whether the given cursor kind represents an attribute.
513     @property bool isAttribute() const @trusted {
514         return clang_isAttribute(cx.kind) != 0;
515     }
516 
517     int bitFieldWidth() const @trusted {
518         return clang_getFieldDeclBitWidth(cast(CXCursor) cx);
519     }
520 
521     bool isBitField() const @trusted {
522         return clang_Cursor_isBitField(cast(CXCursor) cx) != 0;
523     }
524 
525     /// Determine whether the given cursor kind represents an invalid cursor.
526     @property bool isValid() const @trusted {
527         // note that it checks for invalidity of the cursor, thus the inverse
528         // is the return value.
529         return !clang_isInvalid(cx.kind);
530     }
531 
532     /// Determine whether the given cursor kind represents a translation unit.
533     @property bool isTranslationUnit() const @trusted {
534         return clang_isTranslationUnit(cx.kind) != 0;
535     }
536 
537     /** Determine whether the given cursor represents a preprocessing
538      * element, such as a preprocessor directive or macro instantiation.
539      */
540     @property bool isPreprocessing() const @trusted {
541         return clang_isPreprocessing(cx.kind) != 0;
542 
543         // If clang_isPreprocessing isn't working out this is the
544         // implementation from DStep.
545 
546         //CXCursorKind kind = clang_getCursorKind(cx);
547         //return CXCursorKind.firstPreprocessing <= kind &&
548         //    kind <= CXCursorKind.lastPreprocessing;
549     }
550 
551     /** Determine whether the given cursor represents a currently unexposed
552      * piece of the AST (e.g., CXCursor_UnexposedStmt).
553      */
554     @property bool isUnexposed() const @trusted {
555         return clang_isUnexposed(cx.kind) != 0;
556     }
557 
558     /// Return: if the underlying type is an enum.
559     @property bool isUnderlyingTypeEnum() const @trusted {
560         auto underlying = typedefUnderlyingType;
561         if (!underlying.isValid) {
562             return false;
563         }
564 
565         auto decl = underlying.declaration;
566         if (!decl.isValid) {
567             return false;
568         }
569 
570         return decl.type.isEnum;
571     }
572 
573     /// Return: if cursor is null/empty.
574     @property bool isEmpty() const @trusted {
575         return clang_Cursor_isNull(cx) != 0;
576     }
577 
578     /** Returns true if the declaration pointed at by the cursor is also a
579      * definition of that entity.
580      */
581     bool isDefinition() const @trusted {
582         return clang_isCursorDefinition(cast(CXCursor) cx) != 0;
583     }
584 
585     /// Returns: if the base class specified by the cursor with kind CX_CXXBaseSpecifier is virtual.
586     @property bool isVirtualBase() const @trusted {
587         return clang_isVirtualBase(cx) != 0;
588     }
589 
590     bool isPredefined() const @trusted {
591         auto xkind = usr in predefined;
592         return xkind !is null && *xkind == kind;
593     }
594 
595     /** Determine whether a CXCursor that is a macro, is function like.
596      */
597     bool isMacroFunctionLike() const @trusted {
598         return clang_Cursor_isMacroFunctionLike(cx) != 0;
599     }
600 
601     /** Determine whether a CXCursor that is a macro, is a builtin one.
602      */
603     bool isMacroBuiltin() const @trusted {
604         return clang_Cursor_isMacroBuiltin(cx) != 0;
605     }
606 
607     /** Determine whether a CXCursor that is a function declaration, is an
608      * inline declaration.
609      */
610     bool isFunctionInlined() const @trusted {
611         return clang_Cursor_isFunctionInlined(cx) != 0;
612     }
613 
614     /// Determine if a C++ constructor is a converting constructor.
615     bool isConvertingConstructor() const @trusted {
616         return clang_CXXConstructor_isConvertingConstructor(cx) != 0;
617     }
618 
619     /// Determine if a C++ constructor is a copy constructor.
620     bool isCopyConstructor() const @trusted {
621         return clang_CXXConstructor_isCopyConstructor(cx) != 0;
622     }
623 
624     /// Determine if a C++ constructor is the default constructor.
625     bool isDefaultConstructor() const @trusted {
626         return clang_CXXConstructor_isDefaultConstructor(cx) != 0;
627     }
628 
629     /// Determine if a C++ constructor is a move constructor.
630     bool isMoveConstructor() const @trusted {
631         return clang_CXXConstructor_isMoveConstructor(cx) != 0;
632     }
633 
634     /// Determine if a C++ field is declared 'mutable'.
635     bool isMutable() const @trusted {
636         return clang_CXXField_isMutable(cx) != 0;
637     }
638 
639     /// Determine if a C++ method is declared '= default'.
640     bool isDefaulted() const @trusted {
641         return clang_CXXMethod_isDefaulted(cx) != 0;
642     }
643 
644     /// Determine if a C++ member function or member function template is pure virtual.
645     bool isPureVirtual() @trusted {
646         return clang_CXXMethod_isPureVirtual(cx) != 0;
647     }
648 
649     /** Describe the visibility of the entity referred to by a cursor.
650      *
651      * Note: This is linker visibility.
652      *
653      * This returns the default visibility if not explicitly specified by
654      * a visibility attribute. The default visibility may be changed by
655      * commandline arguments.
656      *
657      * Params:
658      *  cursor The cursor to query.
659      *
660      * Returns: The visibility of the cursor.
661      */
662     CXVisibilityKind visibility() const @trusted {
663         return clang_getCursorVisibility(cx);
664     }
665 }
666 
667 struct ObjcCursor {
668     Cursor cursor;
669     alias cursor this;
670 
671     @property ObjCInstanceMethodVisitor instanceMethods() {
672         return ObjCInstanceMethodVisitor(cursor);
673     }
674 
675     @property ObjCClassMethodVisitor classMethods() {
676         return ObjCClassMethodVisitor(cursor);
677     }
678 
679     @property ObjCPropertyVisitor properties() {
680         return ObjCPropertyVisitor(cursor);
681     }
682 
683     @property Cursor superClass() {
684         foreach (cursor, parent; TypedVisitor!(CXCursorKind.objCSuperClassRef)(cursor))
685             return cursor;
686 
687         return Cursor.empty();
688     }
689 
690     @property ObjCProtocolVisitor protocols() {
691         return ObjCProtocolVisitor(cursor);
692     }
693 
694     @property Cursor category() {
695         assert(cursor.kind == CXCursorKind.objCCategoryDecl);
696 
697         foreach (c, _; TypedVisitor!(CXCursorKind.objCClassRef)(cursor))
698             return c;
699 
700         assert(0, "This cursor does not have a class reference.");
701     }
702 }
703 
704 struct FunctionCursor {
705     Cursor cursor;
706     alias cursor this;
707 
708     /// Return: Retrieve the Type of the result for this Cursor.
709     @property Type resultType() @trusted {
710         auto r = clang_getCursorResultType(cx);
711         return Type(cursor, r);
712     }
713 
714     @property ParamVisitor parameters() {
715         return ParamVisitor(cursor);
716     }
717 
718     /** Determine if a C++ member function or member function template is
719      * pure virtual.
720      */
721     @property bool isPureVirtual() @trusted {
722         return clang_CXXMethod_isPureVirtual(cx) != 0;
723     }
724 
725     /** Returns: True if the cursor refers to a C++ member function or member
726      * function template that is declared 'static'.
727      */
728     @property bool isStatic() @trusted {
729         return clang_CXXMethod_isStatic(cx) != 0;
730     }
731 
732     /** Determine if a C++ member function or member function template is
733      * explicitly declared 'virtual' or if it overrides a virtual method from
734      * one of the base classes.
735      */
736     @property bool isVirtual() @trusted {
737         return clang_CXXMethod_isVirtual(cx) != 0;
738     }
739 
740     /** Determine if a C++ member function or member function template is
741      * declared 'const'.
742      */
743     @property bool isConst() @trusted {
744         return clang_CXXMethod_isConst(cx) != 0;
745     }
746 
747     /** Given a cursor pointing to a C++ method call or an Objective-C
748      * message, returns non-zero if the method/message is "dynamic", meaning:
749      *
750      * For a C++ method: the call is virtual.
751      * For an Objective-C message: the receiver is an object instance, not 'super'
752      * or a specific class.
753      *
754      * If the method/message is "static" or the cursor does not point to a
755      * method/message, it will return zero.
756      */
757     @property bool isDynamicCall() @trusted {
758         return clang_Cursor_isDynamicCall(cx) != 0;
759     }
760 }
761 
762 struct AccessCursor {
763     Cursor cursor;
764     alias cursor this;
765 
766     /** Returns the access control level for the C++ base specifier represented
767      * by a cursor with kind CXCursor_CXXBaseSpecifier or
768      * CXCursor_AccessSpecifier.
769      */
770     @property auto accessSpecifier() @trusted {
771         return clang_getCXXAccessSpecifier(cx);
772     }
773 }
774 
775 struct ParamCursor {
776     Cursor cursor;
777     alias cursor this;
778 }
779 
780 struct IncludeCursor {
781     Cursor cursor;
782     alias cursor this;
783 
784     /** Retrieve the file that is included by the given inclusion directive
785      * cursor.
786      */
787     @property auto file() @trusted {
788         return File(clang_getIncludedFile(cx));
789     }
790 }
791 
792 struct EnumCursor {
793     import std.conv : to;
794 
795     Cursor cursor;
796     alias cursor this;
797 
798     @property string value() @safe {
799         import std.conv : to;
800 
801         return to!string(signedValue);
802     }
803 
804     /** Retrieve the integer type of an enum declaration.
805      *
806      * If the cursor does not reference an enum declaration, an invalid type is
807      * returned.
808      */
809     @property Type type() @trusted {
810         auto r = clang_getEnumDeclIntegerType(cx);
811         return Type(cursor, r);
812     }
813 
814     /** Retrieve the integer value of an enum constant declaration as a signed
815      * long.
816      *
817      * If the cursor does not reference an enum constant declaration, LLONG_MIN
818      * is returned.  Since this is also potentially a valid constant value, the
819      * kind of the cursor must be verified before calling this function.
820      */
821     @property long signedValue() @trusted {
822         return clang_getEnumConstantDeclValue(cx);
823     }
824 
825     /** Retrieve the integer value of an enum constant declaration as an
826      * unsigned long.
827      *
828      * If the cursor does not reference an enum constant declaration,
829      * ULLONG_MAX is returned.  Since this is also potentially a valid constant
830      * value, the kind of the cursor must be verified before calling this
831      * function.
832      */
833     @property ulong unsignedValue() @trusted {
834         return clang_getEnumConstantDeclUnsignedValue(cx);
835     }
836 
837     /// Return: if the type of the enum is signed.
838     @property bool isSigned() const @trusted {
839         Type t;
840 
841         if (isUnderlyingTypeEnum) {
842             t = typedefUnderlyingType.declaration.enum_.type;
843         } else {
844             t = Type(cursor, clang_getCursorType(cx));
845         }
846 
847         return t.isSigned;
848     }
849 }
850 
851 import std.array : appender, Appender;
852 
853 string dump(ref const(Cursor) c) @trusted {
854     import std.conv : to;
855     import std..string;
856 
857     static string stripPrefix(string x) {
858         immutable string prefix = "CXCursor_";
859         immutable size_t prefixSize = prefix.length;
860         return x.startsWith(prefix) ? x[prefixSize .. $] : x;
861     }
862 
863     static string prettyTokens(ref const(Cursor) c, size_t limit = 5) {
864         import std.algorithm.comparison : min;
865 
866         TokenRange tokens = c.tokens;
867 
868         string prettyToken(Token token) {
869             immutable string prefix = "CXToken_";
870             immutable size_t prefixSize = prefix.length;
871             auto x = to!string(token.kind);
872             return "%s \"%s\"".format(x.startsWith(prefix) ? x[prefixSize .. $] : x, token.spelling);
873         }
874 
875         auto result = appender!string("[");
876 
877         if (tokens.length != 0) {
878             result.put(prettyToken(tokens[0]));
879 
880             foreach (Token token; c.tokens[1 .. min($, limit)]) {
881                 result.put(", ");
882                 result.put(prettyToken(token));
883             }
884         }
885 
886         if (tokens.length > limit)
887             result.put(", ..]");
888         else
889             result.put("]");
890 
891         return result.data;
892     }
893 
894     auto text = "%s \"%s\" [%d:%d..%d:%d] %s %s".format(stripPrefix(to!string(c.kind)),
895             c.spelling, c.extent.start.line, c.extent.start.column,
896             c.extent.end.line, c.extent.end.column, prettyTokens(c), c.usr);
897 
898     return text;
899 }
900 
901 void dumpAST(ref const(Cursor) c, ref Appender!string result, size_t indent, File* file) @trusted {
902     import std.ascii : newline;
903     import std.format;
904     import std.array : replicate;
905 
906     immutable size_t step = 4;
907 
908     auto text = dump(c);
909 
910     result.put(" ".replicate(indent));
911     result.put(text);
912     result.put(newline);
913 
914     if (file) {
915         foreach (cursor, _; c.all) {
916             if (!cursor.isPredefined() && cursor.location.file == *file)
917                 dumpAST(cursor, result, indent + step);
918         }
919     } else {
920         foreach (cursor, _; c.all) {
921             if (!cursor.isPredefined())
922                 cursor.dumpAST(result, indent + step);
923         }
924     }
925 }
926 
927 void dumpAST(ref const(Cursor) c, ref Appender!string result, size_t indent) @safe {
928     dumpAST(c, result, indent, null);
929 }