cindex.py revision 13102ffbb00f1397fa02950e0cbc82d17be21792
1#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
2#
3#                     The LLVM Compiler Infrastructure
4#
5# This file is distributed under the University of Illinois Open Source
6# License. See LICENSE.TXT for details.
7#
8#===------------------------------------------------------------------------===#
9
10r"""
11Clang Indexing Library Bindings
12===============================
13
14This module provides an interface to the Clang indexing library. It is a
15low-level interface to the indexing library which attempts to match the Clang
16API directly while also being "pythonic". Notable differences from the C API
17are:
18
19 * string results are returned as Python strings, not CXString objects.
20
21 * null cursors are translated to None.
22
23 * access to child cursors is done via iteration, not visitation.
24
25The major indexing objects are:
26
27  Index
28
29    The top-level object which manages some global library state.
30
31  TranslationUnit
32
33    High-level object encapsulating the AST for a single translation unit. These
34    can be loaded from .ast files or parsed on the fly.
35
36  Cursor
37
38    Generic object for representing a node in the AST.
39
40  SourceRange, SourceLocation, and File
41
42    Objects representing information about the input source.
43
44Most object information is exposed using properties, when the underlying API
45call is efficient.
46"""
47
48# TODO
49# ====
50#
51# o API support for invalid translation units. Currently we can't even get the
52#   diagnostics on failure because they refer to locations in an object that
53#   will have been invalidated.
54#
55# o fix memory management issues (currently client must hold on to index and
56#   translation unit, or risk crashes).
57#
58# o expose code completion APIs.
59#
60# o cleanup ctypes wrapping, would be nice to separate the ctypes details more
61#   clearly, and hide from the external interface (i.e., help(cindex)).
62#
63# o implement additional SourceLocation, SourceRange, and File methods.
64
65from ctypes import *
66
67def get_cindex_library():
68    # FIXME: It's probably not the case that the library is actually found in
69    # this location. We need a better system of identifying and loading the
70    # CIndex library. It could be on path or elsewhere, or versioned, etc.
71    import platform
72    name = platform.system()
73    if name == 'Darwin':
74        return cdll.LoadLibrary('libclang.dylib')
75    elif name == 'Windows':
76        return cdll.LoadLibrary('libclang.dll')
77    else:
78        return cdll.LoadLibrary('libclang.so')
79
80# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
81# object. This is a problem, because it means that from_parameter will see an
82# integer and pass the wrong value on platforms where int != void*. Work around
83# this by marshalling object arguments as void**.
84c_object_p = POINTER(c_void_p)
85
86lib = get_cindex_library()
87
88### Structures and Utility Classes ###
89
90class _CXString(Structure):
91    """Helper for transforming CXString results."""
92
93    _fields_ = [("spelling", c_char_p), ("free", c_int)]
94
95    def __del__(self):
96        _CXString_dispose(self)
97
98    @staticmethod
99    def from_result(res, fn, args):
100        assert isinstance(res, _CXString)
101        return _CXString_getCString(res)
102
103class SourceLocation(Structure):
104    """
105    A SourceLocation represents a particular location within a source file.
106    """
107    _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
108    _data = None
109
110    def _get_instantiation(self):
111        if self._data is None:
112            f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
113            SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o))
114            f = File(f) if f else None
115            self._data = (f, int(l.value), int(c.value), int(o.value))
116        return self._data
117
118    @property
119    def file(self):
120        """Get the file represented by this source location."""
121        return self._get_instantiation()[0]
122
123    @property
124    def line(self):
125        """Get the line represented by this source location."""
126        return self._get_instantiation()[1]
127
128    @property
129    def column(self):
130        """Get the column represented by this source location."""
131        return self._get_instantiation()[2]
132
133    @property
134    def offset(self):
135        """Get the file offset represented by this source location."""
136        return self._get_instantiation()[3]
137
138    def __repr__(self):
139        return "<SourceLocation file %r, line %r, column %r>" % (
140            self.file.name if self.file else None, self.line, self.column)
141
142class SourceRange(Structure):
143    """
144    A SourceRange describes a range of source locations within the source
145    code.
146    """
147    _fields_ = [
148        ("ptr_data", c_void_p * 2),
149        ("begin_int_data", c_uint),
150        ("end_int_data", c_uint)]
151
152    # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
153    # object.
154    @staticmethod
155    def from_locations(start, end):
156        return SourceRange_getRange(start, end)
157
158    @property
159    def start(self):
160        """
161        Return a SourceLocation representing the first character within a
162        source range.
163        """
164        return SourceRange_start(self)
165
166    @property
167    def end(self):
168        """
169        Return a SourceLocation representing the last character within a
170        source range.
171        """
172        return SourceRange_end(self)
173
174    def __repr__(self):
175        return "<SourceRange start %r, end %r>" % (self.start, self.end)
176
177class Diagnostic(object):
178    """
179    A Diagnostic is a single instance of a Clang diagnostic. It includes the
180    diagnostic severity, the message, the location the diagnostic occurred, as
181    well as additional source ranges and associated fix-it hints.
182    """
183
184    Ignored = 0
185    Note    = 1
186    Warning = 2
187    Error   = 3
188    Fatal   = 4
189
190    def __init__(self, ptr):
191        self.ptr = ptr
192
193    def __del__(self):
194        _clang_disposeDiagnostic(self)
195
196    @property
197    def severity(self):
198        return _clang_getDiagnosticSeverity(self)
199
200    @property
201    def location(self):
202        return _clang_getDiagnosticLocation(self)
203
204    @property
205    def spelling(self):
206        return _clang_getDiagnosticSpelling(self)
207
208    @property
209    def ranges(self):
210        class RangeIterator:
211            def __init__(self, diag):
212                self.diag = diag
213
214            def __len__(self):
215                return int(_clang_getDiagnosticNumRanges(self.diag))
216
217            def __getitem__(self, key):
218		if (key >= len(self)):
219			raise IndexError
220                return _clang_getDiagnosticRange(self.diag, key)
221
222        return RangeIterator(self)
223
224    @property
225    def fixits(self):
226        class FixItIterator:
227            def __init__(self, diag):
228                self.diag = diag
229
230            def __len__(self):
231                return int(_clang_getDiagnosticNumFixIts(self.diag))
232
233            def __getitem__(self, key):
234                range = SourceRange()
235                value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
236                if len(value) == 0:
237                    raise IndexError
238
239                return FixIt(range, value)
240
241        return FixItIterator(self)
242
243    def __repr__(self):
244        return "<Diagnostic severity %r, location %r, spelling %r>" % (
245            self.severity, self.location, self.spelling)
246
247    def from_param(self):
248      return self.ptr
249
250class FixIt(object):
251    """
252    A FixIt represents a transformation to be applied to the source to
253    "fix-it". The fix-it shouldbe applied by replacing the given source range
254    with the given value.
255    """
256
257    def __init__(self, range, value):
258        self.range = range
259        self.value = value
260
261    def __repr__(self):
262        return "<FixIt range %r, value %r>" % (self.range, self.value)
263
264### Cursor Kinds ###
265
266class CursorKind(object):
267    """
268    A CursorKind describes the kind of entity that a cursor points to.
269    """
270
271    # The unique kind objects, indexed by id.
272    _kinds = []
273    _name_map = None
274
275    def __init__(self, value):
276        if value >= len(CursorKind._kinds):
277            CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
278        if CursorKind._kinds[value] is not None:
279            raise ValueError,'CursorKind already loaded'
280        self.value = value
281        CursorKind._kinds[value] = self
282        CursorKind._name_map = None
283
284    def from_param(self):
285        return self.value
286
287    @property
288    def name(self):
289        """Get the enumeration name of this cursor kind."""
290        if self._name_map is None:
291            self._name_map = {}
292            for key,value in CursorKind.__dict__.items():
293                if isinstance(value,CursorKind):
294                    self._name_map[value] = key
295        return self._name_map[self]
296
297    @staticmethod
298    def from_id(id):
299        if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
300            raise ValueError,'Unknown cursor kind'
301        return CursorKind._kinds[id]
302
303    @staticmethod
304    def get_all_kinds():
305        """Return all CursorKind enumeration instances."""
306        return filter(None, CursorKind._kinds)
307
308    def is_declaration(self):
309        """Test if this is a declaration kind."""
310        return CursorKind_is_decl(self)
311
312    def is_reference(self):
313        """Test if this is a reference kind."""
314        return CursorKind_is_ref(self)
315
316    def is_expression(self):
317        """Test if this is an expression kind."""
318        return CursorKind_is_expr(self)
319
320    def is_statement(self):
321        """Test if this is a statement kind."""
322        return CursorKind_is_stmt(self)
323
324    def is_attribute(self):
325        """Test if this is an attribute kind."""
326        return CursorKind_is_attribute(self)
327
328    def is_invalid(self):
329        """Test if this is an invalid kind."""
330        return CursorKind_is_inv(self)
331
332    def __repr__(self):
333        return 'CursorKind.%s' % (self.name,)
334
335# FIXME: Is there a nicer way to expose this enumeration? We could potentially
336# represent the nested structure, or even build a class hierarchy. The main
337# things we want for sure are (a) simple external access to kinds, (b) a place
338# to hang a description and name, (c) easy to keep in sync with Index.h.
339
340###
341# Declaration Kinds
342
343# A declaration whose specific kind is not exposed via this interface.
344#
345# Unexposed declarations have the same operations as any other kind of
346# declaration; one can extract their location information, spelling, find their
347# definitions, etc. However, the specific kind of the declaration is not
348# reported.
349CursorKind.UNEXPOSED_DECL = CursorKind(1)
350
351# A C or C++ struct.
352CursorKind.STRUCT_DECL = CursorKind(2)
353
354# A C or C++ union.
355CursorKind.UNION_DECL = CursorKind(3)
356
357# A C++ class.
358CursorKind.CLASS_DECL = CursorKind(4)
359
360# An enumeration.
361CursorKind.ENUM_DECL = CursorKind(5)
362
363# A field (in C) or non-static data member (in C++) in a struct, union, or C++
364# class.
365CursorKind.FIELD_DECL = CursorKind(6)
366
367# An enumerator constant.
368CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
369
370# A function.
371CursorKind.FUNCTION_DECL = CursorKind(8)
372
373# A variable.
374CursorKind.VAR_DECL = CursorKind(9)
375
376# A function or method parameter.
377CursorKind.PARM_DECL = CursorKind(10)
378
379# An Objective-C @interface.
380CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
381
382# An Objective-C @interface for a category.
383CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
384
385# An Objective-C @protocol declaration.
386CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
387
388# An Objective-C @property declaration.
389CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
390
391# An Objective-C instance variable.
392CursorKind.OBJC_IVAR_DECL = CursorKind(15)
393
394# An Objective-C instance method.
395CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
396
397# An Objective-C class method.
398CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
399
400# An Objective-C @implementation.
401CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
402
403# An Objective-C @implementation for a category.
404CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
405
406# A typedef.
407CursorKind.TYPEDEF_DECL = CursorKind(20)
408
409# A C++ class method.
410CursorKind.CXX_METHOD = CursorKind(21)
411
412# A C++ namespace.
413CursorKind.NAMESPACE = CursorKind(22)
414
415# A linkage specification, e.g. 'extern "C"'.
416CursorKind.LINKAGE_SPEC = CursorKind(23)
417
418# A C++ constructor.
419CursorKind.CONSTRUCTOR = CursorKind(24)
420
421# A C++ destructor.
422CursorKind.DESTRUCTOR = CursorKind(25)
423
424# A C++ conversion function.
425CursorKind.CONVERSION_FUNCTION = CursorKind(26)
426
427# A C++ template type parameter
428CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27)
429
430# A C++ non-type template paramater.
431CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28)
432
433# A C++ template template parameter.
434CursorKind.TEMPLATE_TEMPLATE_PARAMTER = CursorKind(29)
435
436# A C++ function template.
437CursorKind.FUNCTION_TEMPLATE = CursorKind(30)
438
439# A C++ class template.
440CursorKind.CLASS_TEMPLATE = CursorKind(31)
441
442# A C++ class template partial specialization.
443CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32)
444
445# A C++ namespace alias declaration.
446CursorKind.NAMESPACE_ALIAS = CursorKind(33)
447
448# A C++ using directive
449CursorKind.USING_DIRECTIVE = CursorKind(34)
450
451# A C++ using declaration
452CursorKind.USING_DECLARATION = CursorKind(35)
453
454# A Type alias decl.
455CursorKind.TYPE_ALIAS_DECL = CursorKind(36)
456
457# A Objective-C synthesize decl
458CursorKind.OBJC_SYNTHESIZE_DECL = CursorKind(37)
459
460# A Objective-C dynamic decl
461CursorKind.OBJC_DYNAMIC_DECL = CursorKind(38)
462
463# A C++ access specifier decl.
464CursorKind.CXX_ACCESS_SPEC_DECL = CursorKind(39)
465
466
467###
468# Reference Kinds
469
470CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
471CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
472CursorKind.OBJC_CLASS_REF = CursorKind(42)
473
474# A reference to a type declaration.
475#
476# A type reference occurs anywhere where a type is named but not
477# declared. For example, given:
478#   typedef unsigned size_type;
479#   size_type size;
480#
481# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
482# while the type of the variable "size" is referenced. The cursor
483# referenced by the type of size is the typedef for size_type.
484CursorKind.TYPE_REF = CursorKind(43)
485CursorKind.CXX_BASE_SPECIFIER = CursorKind(44)
486
487# A reference to a class template, function template, template
488# template parameter, or class template partial specialization.
489CursorKind.TEMPLATE_REF = CursorKind(45)
490
491# A reference to a namespace or namepsace alias.
492CursorKind.NAMESPACE_REF = CursorKind(46)
493
494# A reference to a member of a struct, union, or class that occurs in
495# some non-expression context, e.g., a designated initializer.
496CursorKind.MEMBER_REF = CursorKind(47)
497
498# A reference to a labeled statement.
499CursorKind.LABEL_REF = CursorKind(48)
500
501# A reference toa a set of overloaded functions or function templates
502# that has not yet been resolved to a specific function or function template.
503CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
504
505###
506# Invalid/Error Kinds
507
508CursorKind.INVALID_FILE = CursorKind(70)
509CursorKind.NO_DECL_FOUND = CursorKind(71)
510CursorKind.NOT_IMPLEMENTED = CursorKind(72)
511CursorKind.INVALID_CODE = CursorKind(73)
512
513###
514# Expression Kinds
515
516# An expression whose specific kind is not exposed via this interface.
517#
518# Unexposed expressions have the same operations as any other kind of
519# expression; one can extract their location information, spelling, children,
520# etc. However, the specific kind of the expression is not reported.
521CursorKind.UNEXPOSED_EXPR = CursorKind(100)
522
523# An expression that refers to some value declaration, such as a function,
524# varible, or enumerator.
525CursorKind.DECL_REF_EXPR = CursorKind(101)
526
527# An expression that refers to a member of a struct, union, class, Objective-C
528# class, etc.
529CursorKind.MEMBER_REF_EXPR = CursorKind(102)
530
531# An expression that calls a function.
532CursorKind.CALL_EXPR = CursorKind(103)
533
534# An expression that sends a message to an Objective-C object or class.
535CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
536
537# An expression that represents a block literal.
538CursorKind.BLOCK_EXPR = CursorKind(105)
539
540# An integer literal.
541CursorKind.INTEGER_LITERAL = CursorKind(106)
542
543# A floating point number literal.
544CursorKind.FLOATING_LITERAL = CursorKind(107)
545
546# An imaginary number literal.
547CursorKind.IMAGINARY_LITERAL = CursorKind(108)
548
549# A string literal.
550CursorKind.STRING_LITERAL = CursorKind(109)
551
552# A character literal.
553CursorKind.CHARACTER_LITERAL = CursorKind(110)
554
555# A parenthesized expression, e.g. "(1)".
556#
557# This AST node is only formed if full location information is requested.
558CursorKind.PAREN_EXPR = CursorKind(111)
559
560# This represents the unary-expression's (except sizeof and
561# alignof).
562CursorKind.UNARY_OPERATOR = CursorKind(112)
563
564# [C99 6.5.2.1] Array Subscripting.
565CursorKind.ARRAY_SUBSCRIPT_EXPR = CursorKind(113)
566
567# A builtin binary operation expression such as "x + y" or
568# "x <= y".
569CursorKind.BINARY_OPERATOR = CursorKind(114)
570
571# Compound assignment such as "+=".
572CursorKind.COMPOUND_ASSIGNMENT_OPERATOR = CursorKind(115)
573
574# The ?: ternary operator.
575CursorKind.CONDITONAL_OPERATOR = CursorKind(116)
576
577# An explicit cast in C (C99 6.5.4) or a C-style cast in C++
578# (C++ [expr.cast]), which uses the syntax (Type)expr.
579#
580# For example: (int)f.
581CursorKind.CSTYLE_CAST_EXPR = CursorKind(117)
582
583# [C99 6.5.2.5]
584CursorKind.COMPOUND_LITERAL_EXPR = CursorKind(118)
585
586# Describes an C or C++ initializer list.
587CursorKind.INIT_LIST_EXPR = CursorKind(119)
588
589# The GNU address of label extension, representing &&label.
590CursorKind.ADDR_LABEL_EXPR = CursorKind(120)
591
592# This is the GNU Statement Expression extension: ({int X=4; X;})
593CursorKind.StmtExpr = CursorKind(121)
594
595# Represents a C1X generic selection.
596CursorKind.GENERIC_SELECTION_EXPR = CursorKind(122)
597
598# Implements the GNU __null extension, which is a name for a null
599# pointer constant that has integral type (e.g., int or long) and is the same
600# size and alignment as a pointer.
601#
602# The __null extension is typically only used by system headers, which define
603# NULL as __null in C++ rather than using 0 (which is an integer that may not
604# match the size of a pointer).
605CursorKind.GNU_NULL_EXPR = CursorKind(123)
606
607# C++'s static_cast<> expression.
608CursorKind.CXX_STATIC_CAST_EXPR = CursorKind(124)
609
610# C++'s dynamic_cast<> expression.
611CursorKind.CXX_DYNAMIC_CAST_EXPR = CursorKind(125)
612
613# C++'s reinterpret_cast<> expression.
614CursorKind.CXX_REINTERPRET_CAST_EXPR = CursorKind(126)
615
616# C++'s const_cast<> expression.
617CursorKind.CXX_CONST_CAST_EXPR = CursorKind(127)
618
619# Represents an explicit C++ type conversion that uses "functional"
620# notion (C++ [expr.type.conv]).
621#
622# Example:
623# \code
624#   x = int(0.5);
625# \endcode
626CursorKind.CXX_FUNCTIONAL_CAST_EXPR = CursorKind(128)
627
628# A C++ typeid expression (C++ [expr.typeid]).
629CursorKind.CXX_TYPEID_EXPR = CursorKind(129)
630
631# [C++ 2.13.5] C++ Boolean Literal.
632CursorKind.CXX_BOOL_LITERAL_EXPR = CursorKind(130)
633
634# [C++0x 2.14.7] C++ Pointer Literal.
635CursorKind.CXX_NULL_PTR_LITERAL_EXPR = CursorKind(131)
636
637# Represents the "this" expression in C++
638CursorKind.CXX_THIS_EXPR = CursorKind(132)
639
640# [C++ 15] C++ Throw Expression.
641#
642# This handles 'throw' and 'throw' assignment-expression. When
643# assignment-expression isn't present, Op will be null.
644CursorKind.CXX_THROW_EXPR = CursorKind(133)
645
646# A new expression for memory allocation and constructor calls, e.g:
647# "new CXXNewExpr(foo)".
648CursorKind.CXX_NEW_EXPR = CursorKind(134)
649
650# A delete expression for memory deallocation and destructor calls,
651# e.g. "delete[] pArray".
652CursorKind.CXX_DELETE_EXPR = CursorKind(135)
653
654# Represents a unary expression.
655CursorKind.CXX_UNARY_EXPR = CursorKind(136)
656
657# ObjCStringLiteral, used for Objective-C string literals i.e. "foo".
658CursorKind.OBJC_STRING_LITERAL = CursorKind(137)
659
660# ObjCEncodeExpr, used for in Objective-C.
661CursorKind.OBJC_ENCODE_EXPR = CursorKind(138)
662
663# ObjCSelectorExpr used for in Objective-C.
664CursorKind.OBJC_SELECTOR_EXPR = CursorKind(139)
665
666# Objective-C's protocol expression.
667CursorKind.OBJC_PROTOCOL_EXPR = CursorKind(140)
668
669# An Objective-C "bridged" cast expression, which casts between
670# Objective-C pointers and C pointers, transferring ownership in the process.
671#
672# \code
673#   NSString *str = (__bridge_transfer NSString *)CFCreateString();
674# \endcode
675CursorKind.OBJC_BRIDGE_CAST_EXPR = CursorKind(141)
676
677# Represents a C++0x pack expansion that produces a sequence of
678# expressions.
679#
680# A pack expansion expression contains a pattern (which itself is an
681# expression) followed by an ellipsis. For example:
682CursorKind.PACK_EXPANSION_EXPR = CursorKind(142)
683
684# Represents an expression that computes the length of a parameter
685# pack.
686CursorKind.SIZE_OF_PACK_EXPR = CursorKind(143)
687
688# A statement whose specific kind is not exposed via this interface.
689#
690# Unexposed statements have the same operations as any other kind of statement;
691# one can extract their location information, spelling, children, etc. However,
692# the specific kind of the statement is not reported.
693CursorKind.UNEXPOSED_STMT = CursorKind(200)
694
695# A labelled statement in a function.
696CursorKind.LABEL_STMT = CursorKind(201)
697
698# A compound statement
699CursorKind.COMPOUND_STMT = CursorKind(202)
700
701# A case statement.
702CursorKind.CASE_STMT = CursorKind(203)
703
704# A default statement.
705CursorKind.DEFAULT_STMT = CursorKind(204)
706
707# An if statement.
708CursorKind.IF_STMT = CursorKind(205)
709
710# A switch statement.
711CursorKind.SWITCH_STMT = CursorKind(206)
712
713# A while statement.
714CursorKind.WHILE_STMT = CursorKind(207)
715
716# A do statement.
717CursorKind.DO_STMT = CursorKind(208)
718
719# A for statement.
720CursorKind.FOR_STMT = CursorKind(209)
721
722# A goto statement.
723CursorKind.GOTO_STMT = CursorKind(210)
724
725# An indirect goto statement.
726CursorKind.INDIRECT_GOTO_STMT = CursorKind(211)
727
728# A continue statement.
729CursorKind.CONTINUE_STMT = CursorKind(212)
730
731# A break statement.
732CursorKind.BREAK_STMT = CursorKind(213)
733
734# A return statement.
735CursorKind.RETURN_STMT = CursorKind(214)
736
737# A GNU-style inline assembler statement.
738CursorKind.ASM_STMT = CursorKind(215)
739
740# Objective-C's overall @try-@catch-@finally statement.
741CursorKind.OBJC_AT_TRY_STMT = CursorKind(216)
742
743# Objective-C's @catch statement.
744CursorKind.OBJC_AT_CATCH_STMT = CursorKind(217)
745
746# Objective-C's @finally statement.
747CursorKind.OBJC_AT_FINALLY_STMT = CursorKind(218)
748
749# Objective-C's @throw statement.
750CursorKind.OBJC_AT_THROW_STMT = CursorKind(219)
751
752# Objective-C's @synchronized statement.
753CursorKind.OBJC_AT_SYNCHRONIZED_STMT = CursorKind(220)
754
755# Objective-C's autorealease pool statement.
756CursorKind.OBJC_AUTORELEASE_POOL_STMT = CursorKind(221)
757
758# Objective-C's for collection statement.
759CursorKind.OBJC_FOR_COLLECTION_STMT = CursorKind(222)
760
761# C++'s catch statement.
762CursorKind.CXX_CATCH_STMT = CursorKind(223)
763
764# C++'s try statement.
765CursorKind.CXX_TRY_STMT = CursorKind(224)
766
767# C++'s for (* : *) statement.
768CursorKind.CXX_FOR_RANGE_STMT = CursorKind(225)
769
770# Windows Structured Exception Handling's try statement.
771CursorKind.SEH_TRY_STMT = CursorKind(226)
772
773# Windows Structured Exception Handling's except statement.
774CursorKind.SEH_EXCEPT_STMT = CursorKind(227)
775
776# Windows Structured Exception Handling's finally statement.
777CursorKind.SEH_FINALLY_STMT = CursorKind(228)
778
779# The null statement.
780CursorKind.NULL_STMT = CursorKind(230)
781
782# Adaptor class for mixing declarations with statements and expressions.
783CursorKind.DECL_STMT = CursorKind(231)
784
785###
786# Other Kinds
787
788# Cursor that represents the translation unit itself.
789#
790# The translation unit cursor exists primarily to act as the root cursor for
791# traversing the contents of a translation unit.
792CursorKind.TRANSLATION_UNIT = CursorKind(300)
793
794###
795# Attributes
796
797# An attribute whoe specific kind is note exposed via this interface
798CursorKind.UNEXPOSED_ATTR = CursorKind(400)
799
800CursorKind.IB_ACTION_ATTR = CursorKind(401)
801CursorKind.IB_OUTLET_ATTR = CursorKind(402)
802CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403)
803
804###
805# Preprocessing
806CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500)
807CursorKind.MACRO_DEFINITION = CursorKind(501)
808CursorKind.MACRO_INSTANTIATION = CursorKind(502)
809CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
810
811### Cursors ###
812
813class Cursor(Structure):
814    """
815    The Cursor class represents a reference to an element within the AST. It
816    acts as a kind of iterator.
817    """
818    _fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)]
819
820    def __eq__(self, other):
821        return Cursor_eq(self, other)
822
823    def __ne__(self, other):
824        return not Cursor_eq(self, other)
825
826    def is_definition(self):
827        """
828        Returns true if the declaration pointed at by the cursor is also a
829        definition of that entity.
830        """
831        return Cursor_is_def(self)
832
833    def get_definition(self):
834        """
835        If the cursor is a reference to a declaration or a declaration of
836        some entity, return a cursor that points to the definition of that
837        entity.
838        """
839        # TODO: Should probably check that this is either a reference or
840        # declaration prior to issuing the lookup.
841        return Cursor_def(self)
842
843    def get_usr(self):
844        """Return the Unified Symbol Resultion (USR) for the entity referenced
845        by the given cursor (or None).
846
847        A Unified Symbol Resolution (USR) is a string that identifies a
848        particular entity (function, class, variable, etc.) within a
849        program. USRs can be compared across translation units to determine,
850        e.g., when references in one translation refer to an entity defined in
851        another translation unit."""
852        return Cursor_usr(self)
853
854    @property
855    def kind(self):
856        """Return the kind of this cursor."""
857        return CursorKind.from_id(self._kind_id)
858
859    @property
860    def spelling(self):
861        """Return the spelling of the entity pointed at by the cursor."""
862        if not self.kind.is_declaration():
863            # FIXME: clang_getCursorSpelling should be fixed to not assert on
864            # this, for consistency with clang_getCursorUSR.
865            return None
866        if not hasattr(self, '_spelling'):
867            self._spelling = Cursor_spelling(self)
868        return self._spelling
869
870    @property
871    def displayname(self):
872        """
873        Return the display name for the entity referenced by this cursor.
874
875        The display name contains extra information that helps identify the cursor,
876        such as the parameters of a function or template or the arguments of a
877        class template specialization.
878        """
879        if not hasattr(self, '_displayname'):
880            self._displayname = Cursor_displayname(self)
881        return self._displayname
882
883    @property
884    def location(self):
885        """
886        Return the source location (the starting character) of the entity
887        pointed at by the cursor.
888        """
889        if not hasattr(self, '_loc'):
890            self._loc = Cursor_loc(self)
891        return self._loc
892
893    @property
894    def extent(self):
895        """
896        Return the source range (the range of text) occupied by the entity
897        pointed at by the cursor.
898        """
899        if not hasattr(self, '_extent'):
900            self._extent = Cursor_extent(self)
901        return self._extent
902
903    @property
904    def type(self):
905        """
906        Retrieve the type (if any) of of the entity pointed at by the
907        cursor.
908        """
909        if not hasattr(self, '_type'):
910            self._type = Cursor_type(self)
911        return self._type
912
913    def get_children(self):
914        """Return an iterator for accessing the children of this cursor."""
915
916        # FIXME: Expose iteration from CIndex, PR6125.
917        def visitor(child, parent, children):
918            # FIXME: Document this assertion in API.
919            # FIXME: There should just be an isNull method.
920            assert child != Cursor_null()
921            children.append(child)
922            return 1 # continue
923        children = []
924        Cursor_visit(self, Cursor_visit_callback(visitor), children)
925        return iter(children)
926
927    @staticmethod
928    def from_result(res, fn, args):
929        assert isinstance(res, Cursor)
930        # FIXME: There should just be an isNull method.
931        if res == Cursor_null():
932            return None
933        return res
934
935
936### Type Kinds ###
937
938class TypeKind(object):
939    """
940    Describes the kind of type.
941    """
942
943    # The unique kind objects, indexed by id.
944    _kinds = []
945    _name_map = None
946
947    def __init__(self, value):
948        if value >= len(TypeKind._kinds):
949            TypeKind._kinds += [None] * (value - len(TypeKind._kinds) + 1)
950        if TypeKind._kinds[value] is not None:
951            raise ValueError,'TypeKind already loaded'
952        self.value = value
953        TypeKind._kinds[value] = self
954        TypeKind._name_map = None
955
956    def from_param(self):
957        return self.value
958
959    @property
960    def name(self):
961        """Get the enumeration name of this cursor kind."""
962        if self._name_map is None:
963            self._name_map = {}
964            for key,value in TypeKind.__dict__.items():
965                if isinstance(value,TypeKind):
966                    self._name_map[value] = key
967        return self._name_map[self]
968
969    @staticmethod
970    def from_id(id):
971        if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None:
972            raise ValueError,'Unknown type kind %d' % id
973        return TypeKind._kinds[id]
974
975    def __repr__(self):
976        return 'TypeKind.%s' % (self.name,)
977
978
979
980TypeKind.INVALID = TypeKind(0)
981TypeKind.UNEXPOSED = TypeKind(1)
982TypeKind.VOID = TypeKind(2)
983TypeKind.BOOL = TypeKind(3)
984TypeKind.CHAR_U = TypeKind(4)
985TypeKind.UCHAR = TypeKind(5)
986TypeKind.CHAR16 = TypeKind(6)
987TypeKind.CHAR32 = TypeKind(7)
988TypeKind.USHORT = TypeKind(8)
989TypeKind.UINT = TypeKind(9)
990TypeKind.ULONG = TypeKind(10)
991TypeKind.ULONGLONG = TypeKind(11)
992TypeKind.UINT128 = TypeKind(12)
993TypeKind.CHAR_S = TypeKind(13)
994TypeKind.SCHAR = TypeKind(14)
995TypeKind.WCHAR = TypeKind(15)
996TypeKind.SHORT = TypeKind(16)
997TypeKind.INT = TypeKind(17)
998TypeKind.LONG = TypeKind(18)
999TypeKind.LONGLONG = TypeKind(19)
1000TypeKind.INT128 = TypeKind(20)
1001TypeKind.FLOAT = TypeKind(21)
1002TypeKind.DOUBLE = TypeKind(22)
1003TypeKind.LONGDOUBLE = TypeKind(23)
1004TypeKind.NULLPTR = TypeKind(24)
1005TypeKind.OVERLOAD = TypeKind(25)
1006TypeKind.DEPENDENT = TypeKind(26)
1007TypeKind.OBJCID = TypeKind(27)
1008TypeKind.OBJCCLASS = TypeKind(28)
1009TypeKind.OBJCSEL = TypeKind(29)
1010TypeKind.COMPLEX = TypeKind(100)
1011TypeKind.POINTER = TypeKind(101)
1012TypeKind.BLOCKPOINTER = TypeKind(102)
1013TypeKind.LVALUEREFERENCE = TypeKind(103)
1014TypeKind.RVALUEREFERENCE = TypeKind(104)
1015TypeKind.RECORD = TypeKind(105)
1016TypeKind.ENUM = TypeKind(106)
1017TypeKind.TYPEDEF = TypeKind(107)
1018TypeKind.OBJCINTERFACE = TypeKind(108)
1019TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
1020TypeKind.FUNCTIONNOPROTO = TypeKind(110)
1021TypeKind.FUNCTIONPROTO = TypeKind(111)
1022TypeKind.CONSTANTARRAY = TypeKind(112)
1023
1024class Type(Structure):
1025    """
1026    The type of an element in the abstract syntax tree.
1027    """
1028    _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
1029
1030    @property
1031    def kind(self):
1032        """Return the kind of this type."""
1033        return TypeKind.from_id(self._kind_id)
1034
1035    @staticmethod
1036    def from_result(res, fn, args):
1037        assert isinstance(res, Type)
1038        return res
1039
1040    def get_canonical(self):
1041        """
1042        Return the canonical type for a Type.
1043
1044        Clang's type system explicitly models typedefs and all the
1045        ways a specific type can be represented.  The canonical type
1046        is the underlying type with all the "sugar" removed.  For
1047        example, if 'T' is a typedef for 'int', the canonical type for
1048        'T' would be 'int'.
1049        """
1050        return Type_get_canonical(self)
1051
1052    def is_const_qualified(self):
1053        """
1054        Determine whether a Type has the "const" qualifier set,
1055        without looking through typedefs that may have added "const"
1056        at a different level.
1057        """
1058        return Type_is_const_qualified(self)
1059
1060    def is_volatile_qualified(self):
1061        """
1062        Determine whether a Type has the "volatile" qualifier set,
1063        without looking through typedefs that may have added
1064        "volatile" at a different level.
1065        """
1066        return Type_is_volatile_qualified(self)
1067
1068    def is_restrict_qualified(self):
1069        """
1070        Determine whether a Type has the "restrict" qualifier set,
1071        without looking through typedefs that may have added
1072        "restrict" at a different level.
1073        """
1074        return Type_is_restrict_qualified(self)
1075
1076    def get_pointee(self):
1077        """
1078        For pointer types, returns the type of the pointee.
1079        """
1080        return Type_get_pointee(self)
1081
1082    def get_declaration(self):
1083        """
1084        Return the cursor for the declaration of the given type.
1085        """
1086        return Type_get_declaration(self)
1087
1088    def get_result(self):
1089        """
1090        Retrieve the result type associated with a function type.
1091        """
1092        return Type_get_result(self)
1093
1094    def get_array_element_type(self):
1095        """
1096        Retrieve the type of the elements of the array type.
1097        """
1098        return Type_get_array_element(self)
1099
1100    def get_array_size(self):
1101        """
1102        Retrieve the size of the constant array.
1103        """
1104        return Type_get_array_size(self)
1105
1106## CIndex Objects ##
1107
1108# CIndex objects (derived from ClangObject) are essentially lightweight
1109# wrappers attached to some underlying object, which is exposed via CIndex as
1110# a void*.
1111
1112class ClangObject(object):
1113    """
1114    A helper for Clang objects. This class helps act as an intermediary for
1115    the ctypes library and the Clang CIndex library.
1116    """
1117    def __init__(self, obj):
1118        assert isinstance(obj, c_object_p) and obj
1119        self.obj = self._as_parameter_ = obj
1120
1121    def from_param(self):
1122        return self._as_parameter_
1123
1124
1125class _CXUnsavedFile(Structure):
1126    """Helper for passing unsaved file arguments."""
1127    _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
1128
1129## Diagnostic Conversion ##
1130
1131_clang_getNumDiagnostics = lib.clang_getNumDiagnostics
1132_clang_getNumDiagnostics.argtypes = [c_object_p]
1133_clang_getNumDiagnostics.restype = c_uint
1134
1135_clang_getDiagnostic = lib.clang_getDiagnostic
1136_clang_getDiagnostic.argtypes = [c_object_p, c_uint]
1137_clang_getDiagnostic.restype = c_object_p
1138
1139_clang_disposeDiagnostic = lib.clang_disposeDiagnostic
1140_clang_disposeDiagnostic.argtypes = [Diagnostic]
1141
1142_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
1143_clang_getDiagnosticSeverity.argtypes = [Diagnostic]
1144_clang_getDiagnosticSeverity.restype = c_int
1145
1146_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
1147_clang_getDiagnosticLocation.argtypes = [Diagnostic]
1148_clang_getDiagnosticLocation.restype = SourceLocation
1149
1150_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
1151_clang_getDiagnosticSpelling.argtypes = [Diagnostic]
1152_clang_getDiagnosticSpelling.restype = _CXString
1153_clang_getDiagnosticSpelling.errcheck = _CXString.from_result
1154
1155_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
1156_clang_getDiagnosticNumRanges.argtypes = [Diagnostic]
1157_clang_getDiagnosticNumRanges.restype = c_uint
1158
1159_clang_getDiagnosticRange = lib.clang_getDiagnosticRange
1160_clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint]
1161_clang_getDiagnosticRange.restype = SourceRange
1162
1163_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
1164_clang_getDiagnosticNumFixIts.argtypes = [Diagnostic]
1165_clang_getDiagnosticNumFixIts.restype = c_uint
1166
1167_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
1168_clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint, POINTER(SourceRange)]
1169_clang_getDiagnosticFixIt.restype = _CXString
1170_clang_getDiagnosticFixIt.errcheck = _CXString.from_result
1171
1172###
1173
1174class CompletionChunk:
1175    class Kind:
1176        def __init__(self, name):
1177            self.name = name
1178
1179        def __str__(self):
1180            return self.name
1181
1182        def __repr__(self):
1183            return "<ChunkKind: %s>" % self
1184
1185    def __init__(self, completionString, key):
1186        self.cs = completionString
1187        self.key = key
1188
1189    def __repr__(self):
1190        return "{'" + self.spelling + "', " + str(self.kind) + "}"
1191
1192    @property
1193    def spelling(self):
1194        return _clang_getCompletionChunkText(self.cs, self.key).spelling
1195
1196    @property
1197    def kind(self):
1198        res = _clang_getCompletionChunkKind(self.cs, self.key)
1199        return completionChunkKindMap[res]
1200
1201    @property
1202    def string(self):
1203        res = _clang_getCompletionChunkCompletionString(self.cs, self.key)
1204
1205        if (res):
1206          return CompletionString(res)
1207        else:
1208          None
1209
1210    def isKindOptional(self):
1211      return self.kind == completionChunkKindMap[0]
1212
1213    def isKindTypedText(self):
1214      return self.kind == completionChunkKindMap[1]
1215
1216    def isKindPlaceHolder(self):
1217      return self.kind == completionChunkKindMap[3]
1218
1219    def isKindInformative(self):
1220      return self.kind == completionChunkKindMap[4]
1221
1222    def isKindResultType(self):
1223      return self.kind == completionChunkKindMap[15]
1224
1225completionChunkKindMap = {
1226            0: CompletionChunk.Kind("Optional"),
1227            1: CompletionChunk.Kind("TypedText"),
1228            2: CompletionChunk.Kind("Text"),
1229            3: CompletionChunk.Kind("Placeholder"),
1230            4: CompletionChunk.Kind("Informative"),
1231            5: CompletionChunk.Kind("CurrentParameter"),
1232            6: CompletionChunk.Kind("LeftParen"),
1233            7: CompletionChunk.Kind("RightParen"),
1234            8: CompletionChunk.Kind("LeftBracket"),
1235            9: CompletionChunk.Kind("RightBracket"),
1236            10: CompletionChunk.Kind("LeftBrace"),
1237            11: CompletionChunk.Kind("RightBrace"),
1238            12: CompletionChunk.Kind("LeftAngle"),
1239            13: CompletionChunk.Kind("RightAngle"),
1240            14: CompletionChunk.Kind("Comma"),
1241            15: CompletionChunk.Kind("ResultType"),
1242            16: CompletionChunk.Kind("Colon"),
1243            17: CompletionChunk.Kind("SemiColon"),
1244            18: CompletionChunk.Kind("Equal"),
1245            19: CompletionChunk.Kind("HorizontalSpace"),
1246            20: CompletionChunk.Kind("VerticalSpace")}
1247
1248class CompletionString(ClangObject):
1249    class Availability:
1250        def __init__(self, name):
1251            self.name = name
1252
1253        def __str__(self):
1254            return self.name
1255
1256        def __repr__(self):
1257            return "<Availability: %s>" % self
1258
1259    def __len__(self):
1260        return _clang_getNumCompletionChunks(self.obj)
1261
1262    def __getitem__(self, key):
1263        if len(self) <= key:
1264            raise IndexError
1265        return CompletionChunk(self.obj, key)
1266
1267    @property
1268    def priority(self):
1269        return _clang_getCompletionPriority(self.obj)
1270
1271    @property
1272    def availability(self):
1273        res = _clang_getCompletionAvailability(self.obj)
1274        return availabilityKinds[res]
1275
1276    def __repr__(self):
1277        return " | ".join([str(a) for a in self]) \
1278               + " || Priority: " + str(self.priority) \
1279               + " || Availability: " + str(self.availability)
1280
1281availabilityKinds = {
1282            0: CompletionChunk.Kind("Available"),
1283            1: CompletionChunk.Kind("Deprecated"),
1284            2: CompletionChunk.Kind("NotAvailable")}
1285
1286class CodeCompletionResult(Structure):
1287    _fields_ = [('cursorKind', c_int), ('completionString', c_object_p)]
1288
1289    def __repr__(self):
1290        return str(CompletionString(self.completionString))
1291
1292    @property
1293    def kind(self):
1294        return CursorKind.from_id(self.cursorKind)
1295
1296    @property
1297    def string(self):
1298        return CompletionString(self.completionString)
1299
1300class CCRStructure(Structure):
1301    _fields_ = [('results', POINTER(CodeCompletionResult)),
1302                ('numResults', c_int)]
1303
1304    def __len__(self):
1305        return self.numResults
1306
1307    def __getitem__(self, key):
1308        if len(self) <= key:
1309            raise IndexError
1310
1311        return self.results[key]
1312
1313class CodeCompletionResults(ClangObject):
1314    def __init__(self, ptr):
1315        assert isinstance(ptr, POINTER(CCRStructure)) and ptr
1316        self.ptr = self._as_parameter_ = ptr
1317
1318    def from_param(self):
1319        return self._as_parameter_
1320
1321    def __del__(self):
1322        CodeCompletionResults_dispose(self)
1323
1324    @property
1325    def results(self):
1326        return self.ptr.contents
1327
1328    @property
1329    def diagnostics(self):
1330        class DiagnosticsItr:
1331            def __init__(self, ccr):
1332                self.ccr= ccr
1333
1334            def __len__(self):
1335                return int(_clang_codeCompleteGetNumDiagnostics(self.ccr))
1336
1337            def __getitem__(self, key):
1338                return _clang_codeCompleteGetDiagnostic(self.ccr, key)
1339
1340        return DiagnosticsItr(self)
1341
1342
1343class Index(ClangObject):
1344    """
1345    The Index type provides the primary interface to the Clang CIndex library,
1346    primarily by providing an interface for reading and parsing translation
1347    units.
1348    """
1349
1350    @staticmethod
1351    def create(excludeDecls=False):
1352        """
1353        Create a new Index.
1354        Parameters:
1355        excludeDecls -- Exclude local declarations from translation units.
1356        """
1357        return Index(Index_create(excludeDecls, 0))
1358
1359    def __del__(self):
1360        Index_dispose(self)
1361
1362    def read(self, path):
1363        """Load the translation unit from the given AST file."""
1364        ptr = TranslationUnit_read(self, path)
1365        return TranslationUnit(ptr) if ptr else None
1366
1367    def parse(self, path, args = [], unsaved_files = [], options = 0):
1368        """
1369        Load the translation unit from the given source code file by running
1370        clang and generating the AST before loading. Additional command line
1371        parameters can be passed to clang via the args parameter.
1372
1373        In-memory contents for files can be provided by passing a list of pairs
1374        to as unsaved_files, the first item should be the filenames to be mapped
1375        and the second should be the contents to be substituted for the
1376        file. The contents may be passed as strings or file objects.
1377        """
1378        arg_array = 0
1379        if len(args):
1380            arg_array = (c_char_p * len(args))(* args)
1381        unsaved_files_array = 0
1382        if len(unsaved_files):
1383            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1384            for i,(name,value) in enumerate(unsaved_files):
1385                if not isinstance(value, str):
1386                    # FIXME: It would be great to support an efficient version
1387                    # of this, one day.
1388                    value = value.read()
1389                    print value
1390                if not isinstance(value, str):
1391                    raise TypeError,'Unexpected unsaved file contents.'
1392                unsaved_files_array[i].name = name
1393                unsaved_files_array[i].contents = value
1394                unsaved_files_array[i].length = len(value)
1395        ptr = TranslationUnit_parse(self, path, arg_array, len(args),
1396                                    unsaved_files_array, len(unsaved_files),
1397                                    options)
1398        return TranslationUnit(ptr) if ptr else None
1399
1400
1401class TranslationUnit(ClangObject):
1402    """
1403    The TranslationUnit class represents a source code translation unit and
1404    provides read-only access to its top-level declarations.
1405    """
1406
1407    def __init__(self, ptr):
1408        ClangObject.__init__(self, ptr)
1409
1410    def __del__(self):
1411        TranslationUnit_dispose(self)
1412
1413    @property
1414    def cursor(self):
1415        """Retrieve the cursor that represents the given translation unit."""
1416        return TranslationUnit_cursor(self)
1417
1418    @property
1419    def spelling(self):
1420        """Get the original translation unit source file name."""
1421        return TranslationUnit_spelling(self)
1422
1423    def get_includes(self):
1424        """
1425        Return an iterable sequence of FileInclusion objects that describe the
1426        sequence of inclusions in a translation unit. The first object in
1427        this sequence is always the input file. Note that this method will not
1428        recursively iterate over header files included through precompiled
1429        headers.
1430        """
1431        def visitor(fobj, lptr, depth, includes):
1432            if depth > 0:
1433                loc = lptr.contents
1434                includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
1435
1436        # Automatically adapt CIndex/ctype pointers to python objects
1437        includes = []
1438        TranslationUnit_includes(self,
1439                                 TranslationUnit_includes_callback(visitor),
1440                                 includes)
1441        return iter(includes)
1442
1443    @property
1444    def diagnostics(self):
1445        """
1446        Return an iterable (and indexable) object containing the diagnostics.
1447        """
1448        class DiagIterator:
1449            def __init__(self, tu):
1450                self.tu = tu
1451
1452            def __len__(self):
1453                return int(_clang_getNumDiagnostics(self.tu))
1454
1455            def __getitem__(self, key):
1456                diag = _clang_getDiagnostic(self.tu, key)
1457                if not diag:
1458                    raise IndexError
1459                return Diagnostic(diag)
1460
1461        return DiagIterator(self)
1462
1463    def reparse(self, unsaved_files = [], options = 0):
1464        """
1465        Reparse an already parsed translation unit.
1466
1467        In-memory contents for files can be provided by passing a list of pairs
1468        as unsaved_files, the first items should be the filenames to be mapped
1469        and the second should be the contents to be substituted for the
1470        file. The contents may be passed as strings or file objects.
1471        """
1472        unsaved_files_array = 0
1473        if len(unsaved_files):
1474            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1475            for i,(name,value) in enumerate(unsaved_files):
1476                if not isinstance(value, str):
1477                    # FIXME: It would be great to support an efficient version
1478                    # of this, one day.
1479                    value = value.read()
1480                    print value
1481                if not isinstance(value, str):
1482                    raise TypeError,'Unexpected unsaved file contents.'
1483                unsaved_files_array[i].name = name
1484                unsaved_files_array[i].contents = value
1485                unsaved_files_array[i].length = len(value)
1486        ptr = TranslationUnit_reparse(self, len(unsaved_files),
1487                                      unsaved_files_array,
1488                                      options)
1489    def codeComplete(self, path, line, column, unsaved_files = [], options = 0):
1490        """
1491        Code complete in this translation unit.
1492
1493        In-memory contents for files can be provided by passing a list of pairs
1494        as unsaved_files, the first items should be the filenames to be mapped
1495        and the second should be the contents to be substituted for the
1496        file. The contents may be passed as strings or file objects.
1497        """
1498        unsaved_files_array = 0
1499        if len(unsaved_files):
1500            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1501            for i,(name,value) in enumerate(unsaved_files):
1502                if not isinstance(value, str):
1503                    # FIXME: It would be great to support an efficient version
1504                    # of this, one day.
1505                    value = value.read()
1506                    print value
1507                if not isinstance(value, str):
1508                    raise TypeError,'Unexpected unsaved file contents.'
1509                unsaved_files_array[i].name = name
1510                unsaved_files_array[i].contents = value
1511                unsaved_files_array[i].length = len(value)
1512        ptr = TranslationUnit_codeComplete(self, path,
1513                                           line, column,
1514                                           unsaved_files_array,
1515                                           len(unsaved_files),
1516                                           options)
1517        return CodeCompletionResults(ptr) if ptr else None
1518
1519
1520class File(ClangObject):
1521    """
1522    The File class represents a particular source file that is part of a
1523    translation unit.
1524    """
1525
1526    @property
1527    def name(self):
1528        """Return the complete file and path name of the file."""
1529        return _CXString_getCString(File_name(self))
1530
1531    @property
1532    def time(self):
1533        """Return the last modification time of the file."""
1534        return File_time(self)
1535
1536class FileInclusion(object):
1537    """
1538    The FileInclusion class represents the inclusion of one source file by
1539    another via a '#include' directive or as the input file for the translation
1540    unit. This class provides information about the included file, the including
1541    file, the location of the '#include' directive and the depth of the included
1542    file in the stack. Note that the input file has depth 0.
1543    """
1544
1545    def __init__(self, src, tgt, loc, depth):
1546        self.source = src
1547        self.include = tgt
1548        self.location = loc
1549        self.depth = depth
1550
1551    @property
1552    def is_input_file(self):
1553        """True if the included file is the input file."""
1554        return self.depth == 0
1555
1556# Additional Functions and Types
1557
1558# String Functions
1559_CXString_dispose = lib.clang_disposeString
1560_CXString_dispose.argtypes = [_CXString]
1561
1562_CXString_getCString = lib.clang_getCString
1563_CXString_getCString.argtypes = [_CXString]
1564_CXString_getCString.restype = c_char_p
1565
1566# Source Location Functions
1567SourceLocation_loc = lib.clang_getInstantiationLocation
1568SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
1569                               POINTER(c_uint), POINTER(c_uint),
1570                               POINTER(c_uint)]
1571
1572# Source Range Functions
1573SourceRange_getRange = lib.clang_getRange
1574SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
1575SourceRange_getRange.restype = SourceRange
1576
1577SourceRange_start = lib.clang_getRangeStart
1578SourceRange_start.argtypes = [SourceRange]
1579SourceRange_start.restype = SourceLocation
1580
1581SourceRange_end = lib.clang_getRangeEnd
1582SourceRange_end.argtypes = [SourceRange]
1583SourceRange_end.restype = SourceLocation
1584
1585# CursorKind Functions
1586CursorKind_is_decl = lib.clang_isDeclaration
1587CursorKind_is_decl.argtypes = [CursorKind]
1588CursorKind_is_decl.restype = bool
1589
1590CursorKind_is_ref = lib.clang_isReference
1591CursorKind_is_ref.argtypes = [CursorKind]
1592CursorKind_is_ref.restype = bool
1593
1594CursorKind_is_expr = lib.clang_isExpression
1595CursorKind_is_expr.argtypes = [CursorKind]
1596CursorKind_is_expr.restype = bool
1597
1598CursorKind_is_stmt = lib.clang_isStatement
1599CursorKind_is_stmt.argtypes = [CursorKind]
1600CursorKind_is_stmt.restype = bool
1601
1602CursorKind_is_attribute = lib.clang_isAttribute
1603CursorKind_is_attribute.argtypes = [CursorKind]
1604CursorKind_is_attribute.restype = bool
1605
1606CursorKind_is_inv = lib.clang_isInvalid
1607CursorKind_is_inv.argtypes = [CursorKind]
1608CursorKind_is_inv.restype = bool
1609
1610# Cursor Functions
1611# TODO: Implement this function
1612Cursor_get = lib.clang_getCursor
1613Cursor_get.argtypes = [TranslationUnit, SourceLocation]
1614Cursor_get.restype = Cursor
1615
1616Cursor_null = lib.clang_getNullCursor
1617Cursor_null.restype = Cursor
1618
1619Cursor_usr = lib.clang_getCursorUSR
1620Cursor_usr.argtypes = [Cursor]
1621Cursor_usr.restype = _CXString
1622Cursor_usr.errcheck = _CXString.from_result
1623
1624Cursor_is_def = lib.clang_isCursorDefinition
1625Cursor_is_def.argtypes = [Cursor]
1626Cursor_is_def.restype = bool
1627
1628Cursor_def = lib.clang_getCursorDefinition
1629Cursor_def.argtypes = [Cursor]
1630Cursor_def.restype = Cursor
1631Cursor_def.errcheck = Cursor.from_result
1632
1633Cursor_eq = lib.clang_equalCursors
1634Cursor_eq.argtypes = [Cursor, Cursor]
1635Cursor_eq.restype = c_uint
1636
1637Cursor_spelling = lib.clang_getCursorSpelling
1638Cursor_spelling.argtypes = [Cursor]
1639Cursor_spelling.restype = _CXString
1640Cursor_spelling.errcheck = _CXString.from_result
1641
1642Cursor_displayname = lib.clang_getCursorDisplayName
1643Cursor_displayname.argtypes = [Cursor]
1644Cursor_displayname.restype = _CXString
1645Cursor_displayname.errcheck = _CXString.from_result
1646
1647Cursor_loc = lib.clang_getCursorLocation
1648Cursor_loc.argtypes = [Cursor]
1649Cursor_loc.restype = SourceLocation
1650
1651Cursor_extent = lib.clang_getCursorExtent
1652Cursor_extent.argtypes = [Cursor]
1653Cursor_extent.restype = SourceRange
1654
1655Cursor_ref = lib.clang_getCursorReferenced
1656Cursor_ref.argtypes = [Cursor]
1657Cursor_ref.restype = Cursor
1658Cursor_ref.errcheck = Cursor.from_result
1659
1660Cursor_type = lib.clang_getCursorType
1661Cursor_type.argtypes = [Cursor]
1662Cursor_type.restype = Type
1663Cursor_type.errcheck = Type.from_result
1664
1665Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
1666Cursor_visit = lib.clang_visitChildren
1667Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
1668Cursor_visit.restype = c_uint
1669
1670# Type Functions
1671Type_get_canonical = lib.clang_getCanonicalType
1672Type_get_canonical.argtypes = [Type]
1673Type_get_canonical.restype = Type
1674Type_get_canonical.errcheck = Type.from_result
1675
1676Type_is_const_qualified = lib.clang_isConstQualifiedType
1677Type_is_const_qualified.argtypes = [Type]
1678Type_is_const_qualified.restype = bool
1679
1680Type_is_volatile_qualified = lib.clang_isVolatileQualifiedType
1681Type_is_volatile_qualified.argtypes = [Type]
1682Type_is_volatile_qualified.restype = bool
1683
1684Type_is_restrict_qualified = lib.clang_isRestrictQualifiedType
1685Type_is_restrict_qualified.argtypes = [Type]
1686Type_is_restrict_qualified.restype = bool
1687
1688Type_get_pointee = lib.clang_getPointeeType
1689Type_get_pointee.argtypes = [Type]
1690Type_get_pointee.restype = Type
1691Type_get_pointee.errcheck = Type.from_result
1692
1693Type_get_declaration = lib.clang_getTypeDeclaration
1694Type_get_declaration.argtypes = [Type]
1695Type_get_declaration.restype = Cursor
1696Type_get_declaration.errcheck = Cursor.from_result
1697
1698Type_get_result = lib.clang_getResultType
1699Type_get_result.argtypes = [Type]
1700Type_get_result.restype = Type
1701Type_get_result.errcheck = Type.from_result
1702
1703Type_get_array_element = lib.clang_getArrayElementType
1704Type_get_array_element.argtypes = [Type]
1705Type_get_array_element.restype = Type
1706Type_get_array_element.errcheck = Type.from_result
1707
1708Type_get_array_size = lib.clang_getArraySize
1709Type_get_array_size.argtype = [Type]
1710Type_get_array_size.restype = c_longlong
1711
1712# Index Functions
1713Index_create = lib.clang_createIndex
1714Index_create.argtypes = [c_int, c_int]
1715Index_create.restype = c_object_p
1716
1717Index_dispose = lib.clang_disposeIndex
1718Index_dispose.argtypes = [Index]
1719
1720# Translation Unit Functions
1721TranslationUnit_read = lib.clang_createTranslationUnit
1722TranslationUnit_read.argtypes = [Index, c_char_p]
1723TranslationUnit_read.restype = c_object_p
1724
1725TranslationUnit_parse = lib.clang_parseTranslationUnit
1726TranslationUnit_parse.argtypes = [Index, c_char_p, c_void_p,
1727                                  c_int, c_void_p, c_int, c_int]
1728TranslationUnit_parse.restype = c_object_p
1729
1730TranslationUnit_reparse = lib.clang_reparseTranslationUnit
1731TranslationUnit_reparse.argtypes = [TranslationUnit, c_int, c_void_p, c_int]
1732TranslationUnit_reparse.restype = c_int
1733
1734TranslationUnit_codeComplete = lib.clang_codeCompleteAt
1735TranslationUnit_codeComplete.argtypes = [TranslationUnit, c_char_p, c_int,
1736                                         c_int, c_void_p, c_int, c_int]
1737TranslationUnit_codeComplete.restype = POINTER(CCRStructure)
1738
1739TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
1740TranslationUnit_cursor.argtypes = [TranslationUnit]
1741TranslationUnit_cursor.restype = Cursor
1742TranslationUnit_cursor.errcheck = Cursor.from_result
1743
1744TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
1745TranslationUnit_spelling.argtypes = [TranslationUnit]
1746TranslationUnit_spelling.restype = _CXString
1747TranslationUnit_spelling.errcheck = _CXString.from_result
1748
1749TranslationUnit_dispose = lib.clang_disposeTranslationUnit
1750TranslationUnit_dispose.argtypes = [TranslationUnit]
1751
1752TranslationUnit_includes_callback = CFUNCTYPE(None,
1753                                              c_object_p,
1754                                              POINTER(SourceLocation),
1755                                              c_uint, py_object)
1756TranslationUnit_includes = lib.clang_getInclusions
1757TranslationUnit_includes.argtypes = [TranslationUnit,
1758                                     TranslationUnit_includes_callback,
1759                                     py_object]
1760
1761# File Functions
1762File_name = lib.clang_getFileName
1763File_name.argtypes = [File]
1764File_name.restype = _CXString
1765
1766File_time = lib.clang_getFileTime
1767File_time.argtypes = [File]
1768File_time.restype = c_uint
1769
1770# Code completion
1771
1772CodeCompletionResults_dispose = lib.clang_disposeCodeCompleteResults
1773CodeCompletionResults_dispose.argtypes = [CodeCompletionResults]
1774
1775_clang_codeCompleteGetNumDiagnostics = lib.clang_codeCompleteGetNumDiagnostics
1776_clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults]
1777_clang_codeCompleteGetNumDiagnostics.restype = c_int
1778
1779_clang_codeCompleteGetDiagnostic = lib.clang_codeCompleteGetDiagnostic
1780_clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults, c_int]
1781_clang_codeCompleteGetDiagnostic.restype = Diagnostic
1782
1783_clang_getCompletionChunkText = lib.clang_getCompletionChunkText
1784_clang_getCompletionChunkText.argtypes = [c_void_p, c_int]
1785_clang_getCompletionChunkText.restype = _CXString
1786
1787_clang_getCompletionChunkKind = lib.clang_getCompletionChunkKind
1788_clang_getCompletionChunkKind.argtypes = [c_void_p, c_int]
1789_clang_getCompletionChunkKind.restype = c_int
1790
1791_clang_getCompletionChunkCompletionString = lib.clang_getCompletionChunkCompletionString
1792_clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int]
1793_clang_getCompletionChunkCompletionString.restype = c_object_p
1794
1795_clang_getNumCompletionChunks = lib.clang_getNumCompletionChunks
1796_clang_getNumCompletionChunks.argtypes = [c_void_p]
1797_clang_getNumCompletionChunks.restype = c_int
1798
1799_clang_getCompletionAvailability = lib.clang_getCompletionAvailability
1800_clang_getCompletionAvailability.argtypes = [c_void_p]
1801_clang_getCompletionAvailability.restype = c_int
1802
1803_clang_getCompletionPriority = lib.clang_getCompletionPriority
1804_clang_getCompletionPriority.argtypes = [c_void_p]
1805_clang_getCompletionPriority.restype = c_int
1806
1807
1808###
1809
1810__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind', 'Type', 'TypeKind',
1811           'Diagnostic', 'FixIt', 'CodeCompletionResults', 'SourceRange',
1812           'SourceLocation', 'File']
1813