-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathcursor.go
1303 lines (1179 loc) · 40.5 KB
/
cursor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package clang
// #include <stdlib.h>
// #include "go-clang.h"
import "C"
import (
"sync"
"unsafe"
)
/**
* \brief A cursor representing some element in the abstract syntax tree for
* a translation unit.
*
* The cursor abstraction unifies the different kinds of entities in a
* program--declaration, statements, expressions, references to declarations,
* etc.--under a single "cursor" abstraction with a common set of operations.
* Common operation for a cursor include: getting the physical location in
* a source file where the cursor points, getting the name associated with a
* cursor, and retrieving cursors for any child nodes of a particular cursor.
*
* Cursors can be produced in two specific ways.
* clang_getTranslationUnitCursor() produces a cursor for a translation unit,
* from which one can use clang_visitChildren() to explore the rest of the
* translation unit. clang_getCursor() maps from a physical source location
* to the entity that resides at that location, allowing one to map from the
* source code into the AST.
*/
type Cursor struct {
c C.CXCursor
}
// Retrieve the NULL cursor, which represents no entity.
func NewNullCursor() Cursor {
return Cursor{C.clang_getNullCursor()}
}
// Determine whether two cursors are equivalent
func EqualCursors(c1, c2 Cursor) bool {
o := C.clang_equalCursors(c1.c, c2.c)
if o != C.uint(0) {
return true
}
return false
}
// Spelling returns the name of the entity referenced by this cursor.
func (c Cursor) Spelling() string {
cstr := cxstring{C.clang_getCursorSpelling(c.c)}
defer cstr.Dispose()
return cstr.String()
}
/**
* \brief Retrieve the display name for the entity referenced by this cursor.
*
* The display name contains extra information that helps identify the cursor,
* such as the parameters of a function or template or the arguments of a
* class template specialization.
*/
func (c Cursor) DisplayName() string {
cstr := cxstring{C.clang_getCursorDisplayName(c.c)}
defer cstr.Dispose()
return cstr.String()
}
// IsNull returns true if the underlying Cursor is null
func (c Cursor) IsNull() bool {
o := C.clang_Cursor_isNull(c.c)
if o != C.int(0) {
return true
}
return false
}
// Hash computes a hash value for the cursor
func (c Cursor) Hash() uint {
o := C.clang_hashCursor(c.c)
return uint(o)
}
// Kind returns the cursor's kind.
func (c Cursor) Kind() CursorKind {
o := C.clang_getCursorKind(c.c)
return CursorKind(o)
}
// IsDeclaration determines whether the cursor kind represents a declaration
func (ck CursorKind) IsDeclaration() bool {
o := C.clang_isDeclaration(uint32(ck))
if o != C.uint(0) {
return true
}
return false
}
/**
* IsReference determines whether the given cursor kind represents a simple
* reference.
*
* Note that other kinds of cursors (such as expressions) can also refer to
* other cursors. Use clang_getCursorReferenced() to determine whether a
* particular cursor refers to another entity.
*/
func (ck CursorKind) IsReference() bool {
o := C.clang_isReference(uint32(ck))
if o != C.uint(0) {
return true
}
return false
}
/**
* \brief Determine whether the given cursor kind represents an expression.
*/
func (ck CursorKind) IsExpression() bool {
o := C.clang_isExpression(uint32(ck))
if o != C.uint(0) {
return true
}
return false
}
/**
* \brief Determine whether the given cursor kind represents a statement.
*/
func (ck CursorKind) IsStatement() bool {
o := C.clang_isStatement(uint32(ck))
if o != C.uint(0) {
return true
}
return false
}
/**
* \brief Determine whether the given cursor kind represents an attribute.
*/
func (ck CursorKind) IsAttribute() bool {
o := C.clang_isAttribute(uint32(ck))
if o != C.uint(0) {
return true
}
return false
}
/**
* \brief Determine whether the given cursor kind represents an invalid
* cursor.
*/
func (ck CursorKind) IsInvalid() bool {
o := C.clang_isInvalid(uint32(ck))
if o != C.uint(0) {
return true
}
return false
}
/**
* \brief Determine whether the given cursor kind represents a translation
* unit.
*/
func (ck CursorKind) IsTranslationUnit() bool {
o := C.clang_isTranslationUnit(uint32(ck))
if o != C.uint(0) {
return true
}
return false
}
/***
* \brief Determine whether the given cursor represents a preprocessing
* element, such as a preprocessor directive or macro instantiation.
*/
func (ck CursorKind) IsPreprocessing() bool {
o := C.clang_isPreprocessing(uint32(ck))
if o != C.uint(0) {
return true
}
return false
}
/***
* \brief Determine whether the given cursor represents a currently
* unexposed piece of the AST (e.g., CXCursor_UnexposedStmt).
*/
func (ck CursorKind) IsUnexposed() bool {
o := C.clang_isUnexposed(uint32(ck))
if o != C.uint(0) {
return true
}
return false
}
/**
* \brief Describe the linkage of the entity referred to by a cursor.
*/
type LinkageKind uint32
const (
/** \brief This value indicates that no linkage information is available
* for a provided CXCursor. */
LK_NoLinkage LinkageKind = C.CXLinkage_NoLinkage
// This is the linkage for static variables and static functions.
LK_Internal = C.CXLinkage_Internal
// This is the linkage for entities with external linkage that live
// in C++ anonymous namespaces.
LK_UniqueExternal = C.CXLinkage_UniqueExternal
// This is the linkage for entities with true, external linkage
LK_External = C.CXLinkage_External
)
// Linkage returns the linkage of the entity referred to by a cursor
func (c Cursor) Linkage() LinkageKind {
o := C.clang_getCursorLinkage(c.c)
return LinkageKind(o)
}
// Availability returns the availability of the entity that this cursor refers to
func (c Cursor) Availability() AvailabilityKind {
o := C.clang_getCursorAvailability(c.c)
return AvailabilityKind(o)
}
/**
* \brief Determine the availability of the entity that this cursor refers to
* on any platforms for which availability information is known.
*
* \param cursor The cursor to query.
*
* \param always_deprecated If non-NULL, will be set to indicate whether the
* entity is deprecated on all platforms.
*
* \param deprecated_message If non-NULL, will be set to the message text
* provided along with the unconditional deprecation of this entity. The client
* is responsible for deallocating this string.
*
* \param always_unavailable If non-NULL, will be set to indicate whether the
* entity is unavailable on all platforms.
*
* \param unavailable_message If non-NULL, will be set to the message text
* provided along with the unconditional unavailability of this entity. The
* client is responsible for deallocating this string.
*
* \param availability If non-NULL, an array of CXPlatformAvailability instances
* that will be populated with platform availability information, up to either
* the number of platforms for which availability information is available (as
* returned by this function) or \c availability_size, whichever is smaller.
*
* \param availability_size The number of elements available in the
* \c availability array.
*
* \returns The number of platforms (N) for which availability information is
* available (which is unrelated to \c availability_size).
*
* Note that the client is responsible for calling
* \c clang_disposeCXPlatformAvailability to free each of the
* platform-availability structures returned. There are
* \c min(N, availability_size) such structures.
*/
func (c Cursor) PlatformAvailability(availability []PlatformAvailability) (always_deprecated bool, deprecated_msg string, always_unavailable bool, unavailable_msg string) {
var c_always_deprecated C.int
var c_deprecated_msg cxstring
defer c_deprecated_msg.Dispose()
var c_always_unavailable C.int
var c_unavailable_msg cxstring
defer c_unavailable_msg.Dispose()
c_platforms := make([]C.CXPlatformAvailability, len(availability))
nn := int(C.clang_getCursorPlatformAvailability(
c.c,
&c_always_deprecated,
&c_deprecated_msg.c,
&c_always_unavailable,
&c_unavailable_msg.c,
&c_platforms[0],
C.int(len(c_platforms)),
))
if c_always_deprecated != 0 {
always_deprecated = true
}
deprecated_msg = c_deprecated_msg.String()
if c_always_unavailable != 0 {
always_unavailable = true
}
unavailable_msg = c_unavailable_msg.String()
if nn > len(availability) {
nn = len(availability)
}
availability = make([]PlatformAvailability, nn)
for i := 0; i < nn; i++ {
availability[i] = PlatformAvailability{C._goclang_get_platform_availability_at(&c_platforms[0], C.int(i))}
}
return
}
// LanguageKind describes the "language" of the entity referred to by a cursor.
type LanguageKind uint32
const (
LanguageInvalid LanguageKind = C.CXLanguage_Invalid
LanguageC = C.CXLanguage_C
LanguageObjC = C.CXLanguage_ObjC
LanguageCPlusPlus = C.CXLanguage_CPlusPlus
)
// Language returns the "language" of the entity referred to by a cursor.
func (c Cursor) Language() LanguageKind {
o := C.clang_getCursorLanguage(c.c)
return LanguageKind(o)
}
// TranslationUnit returns the translation unit that a cursor originated from
func (c Cursor) TranslationUnit() TranslationUnit {
o := C.clang_Cursor_getTranslationUnit(c.c)
return TranslationUnit{o}
}
// DeclObjCTypeEncoding returns the Objective-C type encoding for the
// specified declaration.
func (c Cursor) DeclObjCTypeEncoding() string {
o := C.clang_getDeclObjCTypeEncoding(c.c)
cstr := cxstring{o}
defer cstr.Dispose()
return cstr.String()
}
// CursorSet is a fast container representing a set of Cursors.
type CursorSet struct {
c C.CXCursorSet
}
// NewCursorSet creates an empty CursorSet
func NewCursorSet() CursorSet {
return CursorSet{C.clang_createCXCursorSet()}
}
// Dispose releases the memory associated with a CursorSet
func (c CursorSet) Dispose() {
C.clang_disposeCXCursorSet(c.c)
}
// Contains queries a CursorSet to see if it contains a specific Cursor
func (c CursorSet) Contains(cursor Cursor) bool {
o := C.clang_CXCursorSet_contains(c.c, cursor.c)
if o != C.uint(0) {
return true
}
return false
}
// Insert inserts a Cursor into the set and returns false if the cursor was
// already in that set.
func (c CursorSet) Insert(cursor Cursor) bool {
o := C.clang_CXCursorSet_insert(c.c, cursor.c)
if o != C.uint(0) {
return true
}
return false
}
/**
* \brief Determine the semantic parent of the given cursor.
*
* The semantic parent of a cursor is the cursor that semantically contains
* the given \p cursor. For many declarations, the lexical and semantic parents
* are equivalent (the lexical parent is returned by
* \c clang_getCursorLexicalParent()). They diverge when declarations or
* definitions are provided out-of-line. For example:
*
* \code
* class C {
* void f();
* };
*
* void C::f() { }
* \endcode
*
* In the out-of-line definition of \c C::f, the semantic parent is the
* the class \c C, of which this function is a member. The lexical parent is
* the place where the declaration actually occurs in the source code; in this
* case, the definition occurs in the translation unit. In general, the
* lexical parent for a given entity can change without affecting the semantics
* of the program, and the lexical parent of different declarations of the
* same entity may be different. Changing the semantic parent of a declaration,
* on the other hand, can have a major impact on semantics, and redeclarations
* of a particular entity should all have the same semantic context.
*
* In the example above, both declarations of \c C::f have \c C as their
* semantic context, while the lexical context of the first \c C::f is \c C
* and the lexical context of the second \c C::f is the translation unit.
*
* For global declarations, the semantic parent is the translation unit.
*/
func (c Cursor) SemanticParent() Cursor {
o := C.clang_getCursorSemanticParent(c.c)
return Cursor{o}
}
/**
* \brief Determine the lexical parent of the given cursor.
*
* The lexical parent of a cursor is the cursor in which the given \p cursor
* was actually written. For many declarations, the lexical and semantic parents
* are equivalent (the semantic parent is returned by
* \c clang_getCursorSemanticParent()). They diverge when declarations or
* definitions are provided out-of-line. For example:
*
* \code
* class C {
* void f();
* };
*
* void C::f() { }
* \endcode
*
* In the out-of-line definition of \c C::f, the semantic parent is the
* the class \c C, of which this function is a member. The lexical parent is
* the place where the declaration actually occurs in the source code; in this
* case, the definition occurs in the translation unit. In general, the
* lexical parent for a given entity can change without affecting the semantics
* of the program, and the lexical parent of different declarations of the
* same entity may be different. Changing the semantic parent of a declaration,
* on the other hand, can have a major impact on semantics, and redeclarations
* of a particular entity should all have the same semantic context.
*
* In the example above, both declarations of \c C::f have \c C as their
* semantic context, while the lexical context of the first \c C::f is \c C
* and the lexical context of the second \c C::f is the translation unit.
*
* For declarations written in the global scope, the lexical parent is
* the translation unit.
*/
func (c Cursor) LexicalParent() Cursor {
o := C.clang_getCursorLexicalParent(c.c)
return Cursor{o}
}
/**
* \brief Determine the set of methods that are overridden by the given
* method.
*
* In both Objective-C and C++, a method (aka virtual member function,
* in C++) can override a virtual method in a base class. For
* Objective-C, a method is said to override any method in the class's
* interface (if we're coming from an implementation), its protocols,
* or its categories, that has the same selector and is of the same
* kind (class or instance). If no such method exists, the search
* continues to the class's superclass, its protocols, and its
* categories, and so on.
*
* For C++, a virtual member function overrides any virtual member
* function with the same signature that occurs in its base
* classes. With multiple inheritance, a virtual member function can
* override several virtual member functions coming from different
* base classes.
*
* In all cases, this function determines the immediate overridden
* method, rather than all of the overridden methods. For example, if
* a method is originally declared in a class A, then overridden in B
* (which in inherits from A) and also in C (which inherited from B),
* then the only overridden method returned from this function when
* invoked on C's method will be B's method. The client may then
* invoke this function again, given the previously-found overridden
* methods, to map out the complete method-override set.
*
* \param cursor A cursor representing an Objective-C or C++
* method. This routine will compute the set of methods that this
* method overrides.
*
* \param overridden A pointer whose pointee will be replaced with a
* pointer to an array of cursors, representing the set of overridden
* methods. If there are no overridden methods, the pointee will be
* set to NULL. The pointee must be freed via a call to
* \c clang_disposeOverriddenCursors().
*
* \param num_overridden A pointer to the number of overridden
* functions, will be set to the number of overridden functions in the
* array pointed to by \p overridden.
*/
func (c Cursor) OverriddenCursors() (o OverriddenCursors) {
C.clang_getOverriddenCursors(c.c, &o.c, &o.n)
return o
}
type OverriddenCursors struct {
c *C.CXCursor
n C.uint
}
// Dispose frees the set of overridden cursors
func (c OverriddenCursors) Dispose() {
C.clang_disposeOverriddenCursors(c.c)
}
func (c OverriddenCursors) Len() int {
return int(c.n)
}
func (c OverriddenCursors) At(i int) Cursor {
if i >= int(c.n) {
panic("clang: index out of range")
}
return Cursor{C._go_clang_ocursor_at(c.c, C.int(i))}
}
// IncludedFile returns the file that is included by the given inclusion directive
func (c Cursor) IncludedFile() File {
o := C.clang_getIncludedFile(c.c)
return File{o}
}
/**
* \brief Retrieve the physical location of the source constructor referenced
* by the given cursor.
*
* The location of a declaration is typically the location of the name of that
* declaration, where the name of that declaration would occur if it is
* unnamed, or some keyword that introduces that particular declaration.
* The location of a reference is where that reference occurs within the
* source code.
*/
func (c Cursor) Location() SourceLocation {
o := C.clang_getCursorLocation(c.c)
return SourceLocation{o}
}
/**
* \brief Retrieve the physical extent of the source construct referenced by
* the given cursor.
*
* The extent of a cursor starts with the file/line/column pointing at the
* first character within the source construct that the cursor refers to and
* ends with the last character withinin that source construct. For a
* declaration, the extent covers the declaration itself. For a reference,
* the extent covers the location of the reference (e.g., where the referenced
* entity was actually used).
*/
func (c Cursor) Extent() SourceRange {
o := C.clang_getCursorExtent(c.c)
return SourceRange{o}
}
// Type retrieves the type of a cursor (if any).
func (c Cursor) Type() Type {
o := C.clang_getCursorType(c.c)
return Type{o}
}
/**
* \brief Retrieve the underlying type of a typedef declaration.
*
* If the cursor does not reference a typedef declaration, an invalid type is
* returned.
*/
func (c Cursor) TypedefDeclUnderlyingType() Type {
o := C.clang_getTypedefDeclUnderlyingType(c.c)
return Type{o}
}
/**
* \brief Retrieve the integer type of an enum declaration.
*
* If the cursor does not reference an enum declaration, an invalid type is
* returned.
*/
func (c Cursor) EnumDeclIntegerType() Type {
o := C.clang_getEnumDeclIntegerType(c.c)
return Type{o}
}
/**
* \brief Retrieve the integer value of an enum constant declaration as a signed
* long long.
*
* If the cursor does not reference an enum constant declaration, LLONG_MIN is returned.
* Since this is also potentially a valid constant value, the kind of the cursor
* must be verified before calling this function.
*/
func (c Cursor) EnumConstantDeclValue() int64 {
return int64(C.clang_getEnumConstantDeclValue(c.c))
}
/**
* \brief Retrieve the integer value of an enum constant declaration as an unsigned
* long long.
*
* If the cursor does not reference an enum constant declaration, ULLONG_MAX is returned.
* Since this is also potentially a valid constant value, the kind of the cursor
* must be verified before calling this function.
*/
func (c Cursor) EnumConstantDeclUnsignedValue() uint64 {
return uint64(C.clang_getEnumConstantDeclUnsignedValue(c.c))
}
/**
* \brief Retrieve the bit width of a bit field declaration as an integer.
*
* If a cursor that is not a bit field declaration is passed in, -1 is returned.
*/
func (c Cursor) FieldDeclBitWidth() int {
return int(C.clang_getFieldDeclBitWidth(c.c))
}
/**
* \brief Retrieve the number of non-variadic arguments associated with a given
* cursor.
*
* If a cursor that is not a function or method is passed in, -1 is returned.
*/
// CINDEX_LINKAGE int clang_Cursor_getNumArguments(CXCursor C);
func (c Cursor) NumArguments() int {
n := C.clang_Cursor_getNumArguments(c.c)
return int(n)
}
/**
* \brief Retrieve the argument cursor of a function or method.
*
* If a cursor that is not a function or method is passed in or the index
* exceeds the number of arguments, an invalid cursor is returned.
*/
// CINDEX_LINKAGE CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i);
func (c Cursor) Argument(i uint) Cursor {
o := C.clang_Cursor_getArgument(c.c, C.uint(i))
return Cursor{o}
}
/**
* \brief Retrieve the result type associated with a given cursor. This only
* returns a valid type of the cursor refers to a function or method.
*/
func (c Cursor) ResultType() Type {
o := C.clang_getCursorResultType(c.c)
return Type{o}
}
/**
* \brief Returns non-zero if the cursor specifies a Record member that is a
* bitfield.
*/
func (c Cursor) IsBitField() bool {
o := C.clang_Cursor_isBitField(c.c)
if o != 0 {
return true
}
return false
}
/**
* \brief Returns 1 if the base class specified by the cursor with kind
* CX_CXXBaseSpecifier is virtual.
*/
func (c Cursor) IsVirtualBase() bool {
o := C.clang_isVirtualBase(c.c)
return o == C.uint(1)
}
/**
* \brief Represents the C++ access control level to a base class for a
* cursor with kind CX_CXXBaseSpecifier.
*/
type AccessSpecifier uint32
const (
AS_Invalid AccessSpecifier = C.CX_CXXInvalidAccessSpecifier
AS_Public = C.CX_CXXPublic
AS_Protected = C.CX_CXXProtected
AS_Private = C.CX_CXXPrivate
)
/**
* \brief Returns the access control level for the C++ base specifier
* represented by a cursor with kind CXCursor_CXXBaseSpecifier or
* CXCursor_AccessSpecifier.
*/
func (c Cursor) AccessSpecifier() AccessSpecifier {
o := C.clang_getCXXAccessSpecifier(c.c)
return AccessSpecifier(o)
}
/**
* \brief Determine the number of overloaded declarations referenced by a
* \c CXCursor_OverloadedDeclRef cursor.
*
* \param cursor The cursor whose overloaded declarations are being queried.
*
* \returns The number of overloaded declarations referenced by \c cursor. If it
* is not a \c CXCursor_OverloadedDeclRef cursor, returns 0.
*/
func (c Cursor) NumOverloadedDecls() int {
o := C.clang_getNumOverloadedDecls(c.c)
return int(o)
}
/**
* \brief Retrieve a cursor for one of the overloaded declarations referenced
* by a \c CXCursor_OverloadedDeclRef cursor.
*
* \param cursor The cursor whose overloaded declarations are being queried.
*
* \param index The zero-based index into the set of overloaded declarations in
* the cursor.
*
* \returns A cursor representing the declaration referenced by the given
* \c cursor at the specified \c index. If the cursor does not have an
* associated set of overloaded declarations, or if the index is out of bounds,
* returns \c clang_getNullCursor();
*/
func (c Cursor) OverloadedDecl(i int) Cursor {
o := C.clang_getOverloadedDecl(c.c, C.uint(i))
return Cursor{o}
}
/**
* \brief For cursors representing an iboutletcollection attribute,
* this function returns the collection element type.
*
*/
func (c Cursor) IBOutletCollectionType() Type {
o := C.clang_getIBOutletCollectionType(c.c)
return Type{o}
}
/**
* \brief Describes how the traversal of the children of a particular
* cursor should proceed after visiting a particular child cursor.
*
* A value of this enumeration type should be returned by each
* \c CXCursorVisitor to indicate how clang_visitChildren() proceed.
*/
type ChildVisitResult uint32
const (
/**
* \brief Terminates the cursor traversal.
*/
CVR_Break ChildVisitResult = C.CXChildVisit_Break
/**
* \brief Continues the cursor traversal with the next sibling of
* the cursor just visited, without visiting its children.
*/
CVR_Continue = C.CXChildVisit_Continue
/**
* \brief Recursively traverse the children of this cursor, using
* the same visitor and client data.
*/
CVR_Recurse = C.CXChildVisit_Recurse
)
/**
* \brief Visitor invoked for each cursor found by a traversal.
*
* This visitor function will be invoked for each cursor found by
* clang_visitCursorChildren(). Its first argument is the cursor being
* visited, its second argument is the parent visitor for that cursor,
* and its third argument is the client data provided to
* clang_visitCursorChildren().
*
* The visitor should return one of the \c CXChildVisitResult values
* to direct clang_visitCursorChildren().
*/
type CursorVisitor func(cursor, parent Cursor) (status ChildVisitResult)
/**
* \brief Visit the children of a particular cursor.
*
* This function visits all the direct children of the given cursor,
* invoking the given \p visitor function with the cursors of each
* visited child. The traversal may be recursive, if the visitor returns
* \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if
* the visitor returns \c CXChildVisit_Break.
*
* \param parent the cursor whose child may be visited. All kinds of
* cursors can be visited, including invalid cursors (which, by
* definition, have no children).
*
* \param visitor the visitor function that will be invoked for each
* child of \p parent.
*
* \param client_data pointer data supplied by the client, which will
* be passed to the visitor each time it is invoked.
*
* \returns a non-zero value if the traversal was terminated
* prematurely by the visitor returning \c CXChildVisit_Break.
*/
func (c Cursor) Visit(visitor CursorVisitor) bool {
forceEscapeVisitor = &visitor
id := visitorCallbacks.add(visitor)
defer visitorCallbacks.remove(id)
o := C._go_clang_visit_children(c.c, C.uintptr_t(id))
if o != C.uint(0) {
return false
}
return true
}
type visitorCallbackRegistry struct {
lock sync.Mutex
callbacks map[uintptr]CursorVisitor
generation uintptr
}
var visitorCallbacks = visitorCallbackRegistry{
callbacks: map[uintptr]CursorVisitor{},
}
func (r *visitorCallbackRegistry) add(cb CursorVisitor) uintptr {
r.lock.Lock()
defer r.lock.Unlock()
r.generation++
r.callbacks[r.generation] = cb
return r.generation
}
func (r *visitorCallbackRegistry) remove(id uintptr) {
r.lock.Lock()
defer r.lock.Unlock()
delete(r.callbacks, id)
}
func (r *visitorCallbackRegistry) get(id uintptr) CursorVisitor {
r.lock.Lock()
defer r.lock.Unlock()
return r.callbacks[id]
}
// forceEscapeVisitor is write-only: to force compiler to escape the address
// (else the address can become stale if the goroutine stack needs to grow
// and is forced to move)
// Explained by rsc in https://golang.org/issue/9125
var forceEscapeVisitor *CursorVisitor
//export GoClangCursorVisitor
func GoClangCursorVisitor(cursor, parent C.CXCursor, callback_id unsafe.Pointer) (status ChildVisitResult) {
id := uintptr(callback_id)
cb := visitorCallbacks.get(id)
return cb(Cursor{cursor}, Cursor{parent})
}
/**
* \brief Retrieve a Unified Symbol Resolution (USR) for the entity referenced
* by the given cursor.
*
* A Unified Symbol Resolution (USR) is a string that identifies a particular
* entity (function, class, variable, etc.) within a program. USRs can be
* compared across translation units to determine, e.g., when references in
* one translation refer to an entity defined in another translation unit.
*/
func (c Cursor) USR() string {
cstr := cxstring{C.clang_getCursorUSR(c.c)}
defer cstr.Dispose()
return cstr.String()
}
//FIXME
// /**
// * \brief Construct a USR for a specified Objective-C class.
// */
// CINDEX_LINKAGE CXString clang_constructUSR_ObjCClass(const char *class_name);
// /**
// * \brief Construct a USR for a specified Objective-C category.
// */
// CINDEX_LINKAGE CXString
// clang_constructUSR_ObjCCategory(const char *class_name,
// const char *category_name);
// /**
// * \brief Construct a USR for a specified Objective-C protocol.
// */
// CINDEX_LINKAGE CXString
// clang_constructUSR_ObjCProtocol(const char *protocol_name);
// /**
// * \brief Construct a USR for a specified Objective-C instance variable and
// * the USR for its containing class.
// */
// CINDEX_LINKAGE CXString clang_constructUSR_ObjCIvar(const char *name,
// CXString classUSR);
// /**
// * \brief Construct a USR for a specified Objective-C method and
// * the USR for its containing class.
// */
// CINDEX_LINKAGE CXString clang_constructUSR_ObjCMethod(const char *name,
// unsigned isInstanceMethod,
// CXString classUSR);
// /**
// * \brief Construct a USR for a specified Objective-C property and the USR
// * for its containing class.
// */
// CINDEX_LINKAGE CXString clang_constructUSR_ObjCProperty(const char *property,
// CXString classUSR);
/** \brief For a cursor that is a reference, retrieve a cursor representing the
* entity that it references.
*
* Reference cursors refer to other entities in the AST. For example, an
* Objective-C superclass reference cursor refers to an Objective-C class.
* This function produces the cursor for the Objective-C class from the
* cursor for the superclass reference. If the input cursor is a declaration or
* definition, it returns that declaration or definition unchanged.
* Otherwise, returns the NULL cursor.
*/
func (c Cursor) Referenced() Cursor {
o := C.clang_getCursorReferenced(c.c)
return Cursor{o}
}
/**
* \brief For a cursor that is either a reference to or a declaration
* of some entity, retrieve a cursor that describes the definition of
* that entity.
*
* Some entities can be declared multiple times within a translation
* unit, but only one of those declarations can also be a
* definition. For example, given:
*
* \code
* int f(int, int);
* int g(int x, int y) { return f(x, y); }
* int f(int a, int b) { return a + b; }
* int f(int, int);
* \endcode
*
* there are three declarations of the function "f", but only the
* second one is a definition. The clang_getCursorDefinition()
* function will take any cursor pointing to a declaration of "f"
* (the first or fourth lines of the example) or a cursor referenced
* that uses "f" (the call to "f' inside "g") and will return a
* declaration cursor pointing to the definition (the second "f"
* declaration).
*
* If given a cursor for which there is no corresponding definition,
* e.g., because there is no definition of that entity within this
* translation unit, returns a NULL cursor.
*/
func (c Cursor) DefinitionCursor() Cursor {
o := C.clang_getCursorDefinition(c.c)
return Cursor{o}
}
/**
* \brief Determine whether the declaration pointed to by this cursor
* is also a definition of that entity.
*/
func (c Cursor) IsDefinition() bool {
o := C.clang_isCursorDefinition(c.c)
if o != C.uint(0) {
return true
}
return false
}
/**
* \brief Retrieve the canonical cursor corresponding to the given cursor.
*
* In the C family of languages, many kinds of entities can be declared several
* times within a single translation unit. For example, a structure type can
* be forward-declared (possibly multiple times) and later defined:
*
* \code
* struct X;
* struct X;
* struct X {
* int member;
* };
* \endcode
*
* The declarations and the definition of \c X are represented by three
* different cursors, all of which are declarations of the same underlying
* entity. One of these cursor is considered the "canonical" cursor, which
* is effectively the representative for the underlying entity. One can
* determine if two cursors are declarations of the same underlying entity by
* comparing their canonical cursors.
*
* \returns The canonical cursor for the entity referred to by the given cursor.
*/
func (c Cursor) CanonicalCursor() Cursor {
o := C.clang_getCanonicalCursor(c.c)
return Cursor{o}
}
/**