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