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