Source

go-clang / pkg / clang / cursor.go

Full commit
  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
package clang

// #include <stdlib.h>
// #cgo LDFLAGS: -L/opt/local/libexec/llvm-3.0/lib -lclang
// #include "/opt/local/libexec/llvm-3.0/include/clang-c/Index.h"
// inline static
// CXCursor _go_clang_ocursor_at(CXCursor *c, int idx) {
//   return c[idx];
// }
//
import "C"
import (
	//"unsafe"
)

/**
 * \brief Describes the kind of entity that a cursor refers to.
 */
type CursorKind uint32 //FIXME: use uint32? int64?
const (
  /**
   * \brief A declaration whose specific kind is not exposed via this
   * interface.
   *
   * Unexposed declarations have the same operations as any other kind
   * of declaration; one can extract their location information,
   * spelling, find their definitions, etc. However, the specific kind
   * of the declaration is not reported.
   */
	CK_UnexposedDecl CursorKind = C.CXCursor_UnexposedDecl

	// A C or C++ struct.
	CK_StructDecl = C.CXCursor_StructDecl
)

/**
 * \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
}

// 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)
}

//
type AvailabilityKind uint32

// 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)
}

// 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}
}

// 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 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 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
)

// EOF