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