cindex.py revision b60a2bebb5f3048f6c53d4f3997ebd84493a2d98
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###
455# Reference Kinds
456
457CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
458CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
459CursorKind.OBJC_CLASS_REF = CursorKind(42)
460
461# A reference to a type declaration.
462#
463# A type reference occurs anywhere where a type is named but not
464# declared. For example, given:
465#   typedef unsigned size_type;
466#   size_type size;
467#
468# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
469# while the type of the variable "size" is referenced. The cursor
470# referenced by the type of size is the typedef for size_type.
471CursorKind.TYPE_REF = CursorKind(43)
472CursorKind.CXX_BASE_SPECIFIER = CursorKind(44)
473
474# A reference to a class template, function template, template
475# template parameter, or class template partial specialization.
476CursorKind.TEMPLATE_REF = CursorKind(45)
477
478# A reference to a namespace or namepsace alias.
479CursorKind.NAMESPACE_REF = CursorKind(46)
480
481# A reference to a member of a struct, union, or class that occurs in
482# some non-expression context, e.g., a designated initializer.
483CursorKind.MEMBER_REF = CursorKind(47)
484
485# A reference to a labeled statement.
486CursorKind.LABEL_REF = CursorKind(48)
487
488# A reference toa a set of overloaded functions or function templates
489# that has not yet been resolved to a specific function or function template.
490CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
491
492###
493# Invalid/Error Kinds
494
495CursorKind.INVALID_FILE = CursorKind(70)
496CursorKind.NO_DECL_FOUND = CursorKind(71)
497CursorKind.NOT_IMPLEMENTED = CursorKind(72)
498CursorKind.INVALID_CODE = CursorKind(73)
499
500###
501# Expression Kinds
502
503# An expression whose specific kind is not exposed via this interface.
504#
505# Unexposed expressions have the same operations as any other kind of
506# expression; one can extract their location information, spelling, children,
507# etc. However, the specific kind of the expression is not reported.
508CursorKind.UNEXPOSED_EXPR = CursorKind(100)
509
510# An expression that refers to some value declaration, such as a function,
511# varible, or enumerator.
512CursorKind.DECL_REF_EXPR = CursorKind(101)
513
514# An expression that refers to a member of a struct, union, class, Objective-C
515# class, etc.
516CursorKind.MEMBER_REF_EXPR = CursorKind(102)
517
518# An expression that calls a function.
519CursorKind.CALL_EXPR = CursorKind(103)
520
521# An expression that sends a message to an Objective-C object or class.
522CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
523
524# An expression that represents a block literal.
525CursorKind.BLOCK_EXPR = CursorKind(105)
526
527# A statement whose specific kind is not exposed via this interface.
528#
529# Unexposed statements have the same operations as any other kind of statement;
530# one can extract their location information, spelling, children, etc. However,
531# the specific kind of the statement is not reported.
532CursorKind.UNEXPOSED_STMT = CursorKind(200)
533
534# A labelled statement in a function.
535CursorKind.LABEL_STMT = CursorKind(201)
536
537
538###
539# Other Kinds
540
541# Cursor that represents the translation unit itself.
542#
543# The translation unit cursor exists primarily to act as the root cursor for
544# traversing the contents of a translation unit.
545CursorKind.TRANSLATION_UNIT = CursorKind(300)
546
547###
548# Attributes
549
550# An attribute whoe specific kind is note exposed via this interface
551CursorKind.UNEXPOSED_ATTR = CursorKind(400)
552
553CursorKind.IB_ACTION_ATTR = CursorKind(401)
554CursorKind.IB_OUTLET_ATTR = CursorKind(402)
555CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403)
556
557###
558# Preprocessing
559CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500)
560CursorKind.MACRO_DEFINITION = CursorKind(501)
561CursorKind.MACRO_INSTANTIATION = CursorKind(502)
562CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
563
564### Cursors ###
565
566class Cursor(Structure):
567    """
568    The Cursor class represents a reference to an element within the AST. It
569    acts as a kind of iterator.
570    """
571    _fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)]
572
573    def __eq__(self, other):
574        return Cursor_eq(self, other)
575
576    def __ne__(self, other):
577        return not Cursor_eq(self, other)
578
579    def is_definition(self):
580        """
581        Returns true if the declaration pointed at by the cursor is also a
582        definition of that entity.
583        """
584        return Cursor_is_def(self)
585
586    def get_definition(self):
587        """
588        If the cursor is a reference to a declaration or a declaration of
589        some entity, return a cursor that points to the definition of that
590        entity.
591        """
592        # TODO: Should probably check that this is either a reference or
593        # declaration prior to issuing the lookup.
594        return Cursor_def(self)
595
596    def get_usr(self):
597        """Return the Unified Symbol Resultion (USR) for the entity referenced
598        by the given cursor (or None).
599
600        A Unified Symbol Resolution (USR) is a string that identifies a
601        particular entity (function, class, variable, etc.) within a
602        program. USRs can be compared across translation units to determine,
603        e.g., when references in one translation refer to an entity defined in
604        another translation unit."""
605        return Cursor_usr(self)
606
607    @property
608    def kind(self):
609        """Return the kind of this cursor."""
610        return CursorKind.from_id(self._kind_id)
611
612    @property
613    def spelling(self):
614        """Return the spelling of the entity pointed at by the cursor."""
615        if not self.kind.is_declaration():
616            # FIXME: clang_getCursorSpelling should be fixed to not assert on
617            # this, for consistency with clang_getCursorUSR.
618            return None
619        return Cursor_spelling(self)
620
621    @property
622    def displayname(self):
623        """
624        Return the display name for the entity referenced by this cursor.
625
626        The display name contains extra information that helps identify the cursor,
627        such as the parameters of a function or template or the arguments of a
628        class template specialization.
629        """
630        return Cursor_displayname(self)
631
632    @property
633    def location(self):
634        """
635        Return the source location (the starting character) of the entity
636        pointed at by the cursor.
637        """
638        return Cursor_loc(self)
639
640    @property
641    def extent(self):
642        """
643        Return the source range (the range of text) occupied by the entity
644        pointed at by the cursor.
645        """
646        return Cursor_extent(self)
647
648    @property
649    def type(self):
650        """
651        Retrieve the type (if any) of of the entity pointed at by the
652        cursor.
653        """
654        return Cursor_type(self)
655
656    def get_children(self):
657        """Return an iterator for accessing the children of this cursor."""
658
659        # FIXME: Expose iteration from CIndex, PR6125.
660        def visitor(child, parent, children):
661            # FIXME: Document this assertion in API.
662            # FIXME: There should just be an isNull method.
663            assert child != Cursor_null()
664            children.append(child)
665            return 1 # continue
666        children = []
667        Cursor_visit(self, Cursor_visit_callback(visitor), children)
668        return iter(children)
669
670    @staticmethod
671    def from_result(res, fn, args):
672        assert isinstance(res, Cursor)
673        # FIXME: There should just be an isNull method.
674        if res == Cursor_null():
675            return None
676        return res
677
678
679### Type Kinds ###
680
681class TypeKind(object):
682    """
683    Describes the kind of type.
684    """
685
686    # The unique kind objects, indexed by id.
687    _kinds = []
688    _name_map = None
689
690    def __init__(self, value):
691        if value >= len(TypeKind._kinds):
692            TypeKind._kinds += [None] * (value - len(TypeKind._kinds) + 1)
693        if TypeKind._kinds[value] is not None:
694            raise ValueError,'TypeKind already loaded'
695        self.value = value
696        TypeKind._kinds[value] = self
697        TypeKind._name_map = None
698
699    def from_param(self):
700        return self.value
701
702    @property
703    def name(self):
704        """Get the enumeration name of this cursor kind."""
705        if self._name_map is None:
706            self._name_map = {}
707            for key,value in TypeKind.__dict__.items():
708                if isinstance(value,TypeKind):
709                    self._name_map[value] = key
710        return self._name_map[self]
711
712    @staticmethod
713    def from_id(id):
714        if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None:
715            raise ValueError,'Unknown cursor kind'
716        return TypeKind._kinds[id]
717
718    def __repr__(self):
719        return 'TypeKind.%s' % (self.name,)
720
721
722
723TypeKind.INVALID = TypeKind(0)
724TypeKind.UNEXPOSED = TypeKind(1)
725TypeKind.VOID = TypeKind(2)
726TypeKind.BOOL = TypeKind(3)
727TypeKind.CHAR_U = TypeKind(4)
728TypeKind.UCHAR = TypeKind(5)
729TypeKind.CHAR16 = TypeKind(6)
730TypeKind.CHAR32 = TypeKind(7)
731TypeKind.USHORT = TypeKind(8)
732TypeKind.UINT = TypeKind(9)
733TypeKind.ULONG = TypeKind(10)
734TypeKind.ULONGLONG = TypeKind(11)
735TypeKind.UINT128 = TypeKind(12)
736TypeKind.CHAR_S = TypeKind(13)
737TypeKind.SCHAR = TypeKind(14)
738TypeKind.WCHAR = TypeKind(15)
739TypeKind.SHORT = TypeKind(16)
740TypeKind.INT = TypeKind(17)
741TypeKind.LONG = TypeKind(18)
742TypeKind.LONGLONG = TypeKind(19)
743TypeKind.INT128 = TypeKind(20)
744TypeKind.FLOAT = TypeKind(21)
745TypeKind.DOUBLE = TypeKind(22)
746TypeKind.LONGDOUBLE = TypeKind(23)
747TypeKind.NULLPTR = TypeKind(24)
748TypeKind.OVERLOAD = TypeKind(25)
749TypeKind.DEPENDENT = TypeKind(26)
750TypeKind.OBJCID = TypeKind(27)
751TypeKind.OBJCCLASS = TypeKind(28)
752TypeKind.OBJCSEL = TypeKind(29)
753TypeKind.COMPLEX = TypeKind(100)
754TypeKind.POINTER = TypeKind(101)
755TypeKind.BLOCKPOINTER = TypeKind(102)
756TypeKind.LVALUEREFERENCE = TypeKind(103)
757TypeKind.RVALUEREFERENCE = TypeKind(104)
758TypeKind.RECORD = TypeKind(105)
759TypeKind.ENUM = TypeKind(106)
760TypeKind.TYPEDEF = TypeKind(107)
761TypeKind.OBJCINTERFACE = TypeKind(108)
762TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
763TypeKind.FUNCTIONNOPROTO = TypeKind(110)
764TypeKind.FUNCTIONPROTO = TypeKind(111)
765
766
767class Type(Structure):
768    """
769    The type of an element in the abstract syntax tree.
770    """
771    _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
772
773    @property
774    def kind(self):
775        """Return the kind of this type."""
776        return TypeKind.from_id(self._kind_id)
777
778    @staticmethod
779    def from_result(res, fn, args):
780        assert isinstance(res, Type)
781        return res
782
783    def get_canonical(self):
784        """
785        Return the canonical type for a Type.
786
787        Clang's type system explicitly models typedefs and all the
788        ways a specific type can be represented.  The canonical type
789        is the underlying type with all the "sugar" removed.  For
790        example, if 'T' is a typedef for 'int', the canonical type for
791        'T' would be 'int'.
792        """
793        return Type_get_canonical(self)
794
795    def is_const_qualified(self):
796        """
797        Determine whether a Type has the "const" qualifier set,
798        without looking through typedefs that may have added "const"
799        at a different level.
800        """
801        return Type_is_const_qualified(self)
802
803    def is_volatile_qualified(self):
804        """
805        Determine whether a Type has the "volatile" qualifier set,
806        without looking through typedefs that may have added
807        "volatile" at a different level.
808        """
809        return Type_is_volatile_qualified(self)
810
811    def is_restrict_qualified(self):
812        """
813        Determine whether a Type has the "restrict" qualifier set,
814        without looking through typedefs that may have added
815        "restrict" at a different level.
816        """
817        return Type_is_restrict_qualified(self)
818
819    def get_pointee(self):
820        """
821        For pointer types, returns the type of the pointee.
822        """
823        return Type_get_pointee(self)
824
825    def get_declaration(self):
826        """
827        Return the cursor for the declaration of the given type.
828        """
829        return Type_get_declaration(self)
830
831    def get_result(self):
832        """
833        Retrieve the result type associated with a function type.
834        """
835        return Type_get_result(self)
836
837## CIndex Objects ##
838
839# CIndex objects (derived from ClangObject) are essentially lightweight
840# wrappers attached to some underlying object, which is exposed via CIndex as
841# a void*.
842
843class ClangObject(object):
844    """
845    A helper for Clang objects. This class helps act as an intermediary for
846    the ctypes library and the Clang CIndex library.
847    """
848    def __init__(self, obj):
849        assert isinstance(obj, c_object_p) and obj
850        self.obj = self._as_parameter_ = obj
851
852    def from_param(self):
853        return self._as_parameter_
854
855
856class _CXUnsavedFile(Structure):
857    """Helper for passing unsaved file arguments."""
858    _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
859
860## Diagnostic Conversion ##
861
862_clang_getNumDiagnostics = lib.clang_getNumDiagnostics
863_clang_getNumDiagnostics.argtypes = [c_object_p]
864_clang_getNumDiagnostics.restype = c_uint
865
866_clang_getDiagnostic = lib.clang_getDiagnostic
867_clang_getDiagnostic.argtypes = [c_object_p, c_uint]
868_clang_getDiagnostic.restype = c_object_p
869
870_clang_disposeDiagnostic = lib.clang_disposeDiagnostic
871_clang_disposeDiagnostic.argtypes = [Diagnostic]
872
873_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
874_clang_getDiagnosticSeverity.argtypes = [Diagnostic]
875_clang_getDiagnosticSeverity.restype = c_int
876
877_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
878_clang_getDiagnosticLocation.argtypes = [Diagnostic]
879_clang_getDiagnosticLocation.restype = SourceLocation
880
881_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
882_clang_getDiagnosticSpelling.argtypes = [Diagnostic]
883_clang_getDiagnosticSpelling.restype = _CXString
884_clang_getDiagnosticSpelling.errcheck = _CXString.from_result
885
886_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
887_clang_getDiagnosticNumRanges.argtypes = [Diagnostic]
888_clang_getDiagnosticNumRanges.restype = c_uint
889
890_clang_getDiagnosticRange = lib.clang_getDiagnosticRange
891_clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint]
892_clang_getDiagnosticRange.restype = SourceRange
893
894_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
895_clang_getDiagnosticNumFixIts.argtypes = [Diagnostic]
896_clang_getDiagnosticNumFixIts.restype = c_uint
897
898_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
899_clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint, POINTER(SourceRange)]
900_clang_getDiagnosticFixIt.restype = _CXString
901_clang_getDiagnosticFixIt.errcheck = _CXString.from_result
902
903###
904
905class CompletionChunk:
906    class Kind:
907        def __init__(self, name):
908            self.name = name
909
910        def __str__(self):
911            return self.name
912
913        def __repr__(self):
914            return "<ChunkKind: %s>" % self
915
916    def __init__(self, completionString, key):
917        self.cs = completionString
918        self.key = key
919
920    def __repr__(self):
921        return "{'" + self.spelling + "', " + str(self.kind) + "}"
922
923    @property
924    def spelling(self):
925        return _clang_getCompletionChunkText(self.cs, self.key).spelling
926
927    @property
928    def kind(self):
929        res = _clang_getCompletionChunkKind(self.cs, self.key)
930        return completionChunkKindMap[res]
931
932    @property
933    def string(self):
934        res = _clang_getCompletionChunkCompletionString(self.cs, self.key)
935
936        if (res):
937          return CompletionString(res)
938        else:
939          None
940
941    def isKindOptional(self):
942      return self.kind == completionChunkKindMap[0]
943
944    def isKindTypedText(self):
945      return self.kind == completionChunkKindMap[1]
946
947    def isKindPlaceHolder(self):
948      return self.kind == completionChunkKindMap[3]
949
950    def isKindInformative(self):
951      return self.kind == completionChunkKindMap[4]
952
953    def isKindResultType(self):
954      return self.kind == completionChunkKindMap[15]
955
956completionChunkKindMap = {
957            0: CompletionChunk.Kind("Optional"),
958            1: CompletionChunk.Kind("TypedText"),
959            2: CompletionChunk.Kind("Text"),
960            3: CompletionChunk.Kind("Placeholder"),
961            4: CompletionChunk.Kind("Informative"),
962            5: CompletionChunk.Kind("CurrentParameter"),
963            6: CompletionChunk.Kind("LeftParen"),
964            7: CompletionChunk.Kind("RightParen"),
965            8: CompletionChunk.Kind("LeftBracket"),
966            9: CompletionChunk.Kind("RightBracket"),
967            10: CompletionChunk.Kind("LeftBrace"),
968            11: CompletionChunk.Kind("RightBrace"),
969            12: CompletionChunk.Kind("LeftAngle"),
970            13: CompletionChunk.Kind("RightAngle"),
971            14: CompletionChunk.Kind("Comma"),
972            15: CompletionChunk.Kind("ResultType"),
973            16: CompletionChunk.Kind("Colon"),
974            17: CompletionChunk.Kind("SemiColon"),
975            18: CompletionChunk.Kind("Equal"),
976            19: CompletionChunk.Kind("HorizontalSpace"),
977            20: CompletionChunk.Kind("VerticalSpace")}
978
979class CompletionString(ClangObject):
980    class Availability:
981        def __init__(self, name):
982            self.name = name
983
984        def __str__(self):
985            return self.name
986
987        def __repr__(self):
988            return "<Availability: %s>" % self
989
990    def __len__(self):
991        return _clang_getNumCompletionChunks(self.obj)
992
993    def __getitem__(self, key):
994        if len(self) <= key:
995            raise IndexError
996        return CompletionChunk(self.obj, key)
997
998    @property
999    def priority(self):
1000        return _clang_getCompletionPriority(self.obj)
1001
1002    @property
1003    def availability(self):
1004        res = _clang_getCompletionAvailability(self.obj)
1005        return availabilityKinds[res]
1006
1007    def __repr__(self):
1008        return " | ".join([str(a) for a in self]) \
1009               + " || Priority: " + str(self.priority) \
1010               + " || Availability: " + str(self.availability)
1011
1012availabilityKinds = {
1013            0: CompletionChunk.Kind("Available"),
1014            1: CompletionChunk.Kind("Deprecated"),
1015            2: CompletionChunk.Kind("NotAvailable")}
1016
1017class CodeCompletionResult(Structure):
1018    _fields_ = [('cursorKind', c_int), ('completionString', c_object_p)]
1019
1020    def __repr__(self):
1021        return str(CompletionString(self.completionString))
1022
1023    @property
1024    def kind(self):
1025        return CursorKind.from_id(self.cursorKind)
1026
1027    @property
1028    def string(self):
1029        return CompletionString(self.completionString)
1030
1031class CCRStructure(Structure):
1032    _fields_ = [('results', POINTER(CodeCompletionResult)),
1033                ('numResults', c_int)]
1034
1035    def __len__(self):
1036        return self.numResults
1037
1038    def __getitem__(self, key):
1039        if len(self) <= key:
1040            raise IndexError
1041
1042        return self.results[key]
1043
1044class CodeCompletionResults(ClangObject):
1045    def __init__(self, ptr):
1046        assert isinstance(ptr, POINTER(CCRStructure)) and ptr
1047        self.ptr = self._as_parameter_ = ptr
1048
1049    def from_param(self):
1050        return self._as_parameter_
1051
1052    def __del__(self):
1053        CodeCompletionResults_dispose(self)
1054
1055    @property
1056    def results(self):
1057        return self.ptr.contents
1058
1059    @property
1060    def diagnostics(self):
1061        class DiagnosticsItr:
1062            def __init__(self, ccr):
1063                self.ccr= ccr
1064
1065            def __len__(self):
1066                return int(_clang_codeCompleteGetNumDiagnostics(self.ccr))
1067
1068            def __getitem__(self, key):
1069                return _clang_codeCompleteGetDiagnostic(self.ccr, key)
1070
1071        return DiagnosticsItr(self)
1072
1073
1074class Index(ClangObject):
1075    """
1076    The Index type provides the primary interface to the Clang CIndex library,
1077    primarily by providing an interface for reading and parsing translation
1078    units.
1079    """
1080
1081    @staticmethod
1082    def create(excludeDecls=False):
1083        """
1084        Create a new Index.
1085        Parameters:
1086        excludeDecls -- Exclude local declarations from translation units.
1087        """
1088        return Index(Index_create(excludeDecls, 0))
1089
1090    def __del__(self):
1091        Index_dispose(self)
1092
1093    def read(self, path):
1094        """Load the translation unit from the given AST file."""
1095        ptr = TranslationUnit_read(self, path)
1096        return TranslationUnit(ptr) if ptr else None
1097
1098    def parse(self, path, args = [], unsaved_files = [], options = 0):
1099        """
1100        Load the translation unit from the given source code file by running
1101        clang and generating the AST before loading. Additional command line
1102        parameters can be passed to clang via the args parameter.
1103
1104        In-memory contents for files can be provided by passing a list of pairs
1105        to as unsaved_files, the first item should be the filenames to be mapped
1106        and the second should be the contents to be substituted for the
1107        file. The contents may be passed as strings or file objects.
1108        """
1109        arg_array = 0
1110        if len(args):
1111            arg_array = (c_char_p * len(args))(* args)
1112        unsaved_files_array = 0
1113        if len(unsaved_files):
1114            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1115            for i,(name,value) in enumerate(unsaved_files):
1116                if not isinstance(value, str):
1117                    # FIXME: It would be great to support an efficient version
1118                    # of this, one day.
1119                    value = value.read()
1120                    print value
1121                if not isinstance(value, str):
1122                    raise TypeError,'Unexpected unsaved file contents.'
1123                unsaved_files_array[i].name = name
1124                unsaved_files_array[i].contents = value
1125                unsaved_files_array[i].length = len(value)
1126        ptr = TranslationUnit_parse(self, path, arg_array, len(args),
1127                                    unsaved_files_array, len(unsaved_files),
1128                                    options)
1129        return TranslationUnit(ptr) if ptr else None
1130
1131
1132class TranslationUnit(ClangObject):
1133    """
1134    The TranslationUnit class represents a source code translation unit and
1135    provides read-only access to its top-level declarations.
1136    """
1137
1138    def __init__(self, ptr):
1139        ClangObject.__init__(self, ptr)
1140
1141    def __del__(self):
1142        TranslationUnit_dispose(self)
1143
1144    @property
1145    def cursor(self):
1146        """Retrieve the cursor that represents the given translation unit."""
1147        return TranslationUnit_cursor(self)
1148
1149    @property
1150    def spelling(self):
1151        """Get the original translation unit source file name."""
1152        return TranslationUnit_spelling(self)
1153
1154    def get_includes(self):
1155        """
1156        Return an iterable sequence of FileInclusion objects that describe the
1157        sequence of inclusions in a translation unit. The first object in
1158        this sequence is always the input file. Note that this method will not
1159        recursively iterate over header files included through precompiled
1160        headers.
1161        """
1162        def visitor(fobj, lptr, depth, includes):
1163            if depth > 0:
1164                loc = lptr.contents
1165                includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
1166
1167        # Automatically adapt CIndex/ctype pointers to python objects
1168        includes = []
1169        TranslationUnit_includes(self,
1170                                 TranslationUnit_includes_callback(visitor),
1171                                 includes)
1172        return iter(includes)
1173
1174    @property
1175    def diagnostics(self):
1176        """
1177        Return an iterable (and indexable) object containing the diagnostics.
1178        """
1179        class DiagIterator:
1180            def __init__(self, tu):
1181                self.tu = tu
1182
1183            def __len__(self):
1184                return int(_clang_getNumDiagnostics(self.tu))
1185
1186            def __getitem__(self, key):
1187                diag = _clang_getDiagnostic(self.tu, key)
1188                if not diag:
1189                    raise IndexError
1190                return Diagnostic(diag)
1191
1192        return DiagIterator(self)
1193
1194    def reparse(self, unsaved_files = [], options = 0):
1195        """
1196        Reparse an already parsed translation unit.
1197
1198        In-memory contents for files can be provided by passing a list of pairs
1199        as unsaved_files, the first items should be the filenames to be mapped
1200        and the second should be the contents to be substituted for the
1201        file. The contents may be passed as strings or file objects.
1202        """
1203        unsaved_files_array = 0
1204        if len(unsaved_files):
1205            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1206            for i,(name,value) in enumerate(unsaved_files):
1207                if not isinstance(value, str):
1208                    # FIXME: It would be great to support an efficient version
1209                    # of this, one day.
1210                    value = value.read()
1211                    print value
1212                if not isinstance(value, str):
1213                    raise TypeError,'Unexpected unsaved file contents.'
1214                unsaved_files_array[i].name = name
1215                unsaved_files_array[i].contents = value
1216                unsaved_files_array[i].length = len(value)
1217        ptr = TranslationUnit_reparse(self, len(unsaved_files),
1218                                      unsaved_files_array,
1219                                      options)
1220    def codeComplete(self, path, line, column, unsaved_files = [], options = 0):
1221        """
1222        Code complete in this translation unit.
1223
1224        In-memory contents for files can be provided by passing a list of pairs
1225        as unsaved_files, the first items should be the filenames to be mapped
1226        and the second should be the contents to be substituted for the
1227        file. The contents may be passed as strings or file objects.
1228        """
1229        unsaved_files_array = 0
1230        if len(unsaved_files):
1231            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1232            for i,(name,value) in enumerate(unsaved_files):
1233                if not isinstance(value, str):
1234                    # FIXME: It would be great to support an efficient version
1235                    # of this, one day.
1236                    value = value.read()
1237                    print value
1238                if not isinstance(value, str):
1239                    raise TypeError,'Unexpected unsaved file contents.'
1240                unsaved_files_array[i].name = name
1241                unsaved_files_array[i].contents = value
1242                unsaved_files_array[i].length = len(value)
1243        ptr = TranslationUnit_codeComplete(self, path,
1244                                           line, column,
1245                                           unsaved_files_array,
1246                                           len(unsaved_files),
1247                                           options)
1248        return CodeCompletionResults(ptr) if ptr else None
1249
1250
1251class File(ClangObject):
1252    """
1253    The File class represents a particular source file that is part of a
1254    translation unit.
1255    """
1256
1257    @property
1258    def name(self):
1259        """Return the complete file and path name of the file."""
1260        return _CXString_getCString(File_name(self))
1261
1262    @property
1263    def time(self):
1264        """Return the last modification time of the file."""
1265        return File_time(self)
1266
1267class FileInclusion(object):
1268    """
1269    The FileInclusion class represents the inclusion of one source file by
1270    another via a '#include' directive or as the input file for the translation
1271    unit. This class provides information about the included file, the including
1272    file, the location of the '#include' directive and the depth of the included
1273    file in the stack. Note that the input file has depth 0.
1274    """
1275
1276    def __init__(self, src, tgt, loc, depth):
1277        self.source = src
1278        self.include = tgt
1279        self.location = loc
1280        self.depth = depth
1281
1282    @property
1283    def is_input_file(self):
1284        """True if the included file is the input file."""
1285        return self.depth == 0
1286
1287# Additional Functions and Types
1288
1289# String Functions
1290_CXString_dispose = lib.clang_disposeString
1291_CXString_dispose.argtypes = [_CXString]
1292
1293_CXString_getCString = lib.clang_getCString
1294_CXString_getCString.argtypes = [_CXString]
1295_CXString_getCString.restype = c_char_p
1296
1297# Source Location Functions
1298SourceLocation_loc = lib.clang_getInstantiationLocation
1299SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
1300                               POINTER(c_uint), POINTER(c_uint),
1301                               POINTER(c_uint)]
1302
1303# Source Range Functions
1304SourceRange_getRange = lib.clang_getRange
1305SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
1306SourceRange_getRange.restype = SourceRange
1307
1308SourceRange_start = lib.clang_getRangeStart
1309SourceRange_start.argtypes = [SourceRange]
1310SourceRange_start.restype = SourceLocation
1311
1312SourceRange_end = lib.clang_getRangeEnd
1313SourceRange_end.argtypes = [SourceRange]
1314SourceRange_end.restype = SourceLocation
1315
1316# CursorKind Functions
1317CursorKind_is_decl = lib.clang_isDeclaration
1318CursorKind_is_decl.argtypes = [CursorKind]
1319CursorKind_is_decl.restype = bool
1320
1321CursorKind_is_ref = lib.clang_isReference
1322CursorKind_is_ref.argtypes = [CursorKind]
1323CursorKind_is_ref.restype = bool
1324
1325CursorKind_is_expr = lib.clang_isExpression
1326CursorKind_is_expr.argtypes = [CursorKind]
1327CursorKind_is_expr.restype = bool
1328
1329CursorKind_is_stmt = lib.clang_isStatement
1330CursorKind_is_stmt.argtypes = [CursorKind]
1331CursorKind_is_stmt.restype = bool
1332
1333CursorKind_is_attribute = lib.clang_isAttribute
1334CursorKind_is_attribute.argtypes = [CursorKind]
1335CursorKind_is_attribute.restype = bool
1336
1337CursorKind_is_inv = lib.clang_isInvalid
1338CursorKind_is_inv.argtypes = [CursorKind]
1339CursorKind_is_inv.restype = bool
1340
1341# Cursor Functions
1342# TODO: Implement this function
1343Cursor_get = lib.clang_getCursor
1344Cursor_get.argtypes = [TranslationUnit, SourceLocation]
1345Cursor_get.restype = Cursor
1346
1347Cursor_null = lib.clang_getNullCursor
1348Cursor_null.restype = Cursor
1349
1350Cursor_usr = lib.clang_getCursorUSR
1351Cursor_usr.argtypes = [Cursor]
1352Cursor_usr.restype = _CXString
1353Cursor_usr.errcheck = _CXString.from_result
1354
1355Cursor_is_def = lib.clang_isCursorDefinition
1356Cursor_is_def.argtypes = [Cursor]
1357Cursor_is_def.restype = bool
1358
1359Cursor_def = lib.clang_getCursorDefinition
1360Cursor_def.argtypes = [Cursor]
1361Cursor_def.restype = Cursor
1362Cursor_def.errcheck = Cursor.from_result
1363
1364Cursor_eq = lib.clang_equalCursors
1365Cursor_eq.argtypes = [Cursor, Cursor]
1366Cursor_eq.restype = c_uint
1367
1368Cursor_spelling = lib.clang_getCursorSpelling
1369Cursor_spelling.argtypes = [Cursor]
1370Cursor_spelling.restype = _CXString
1371Cursor_spelling.errcheck = _CXString.from_result
1372
1373Cursor_displayname = lib.clang_getCursorDisplayName
1374Cursor_displayname.argtypes = [Cursor]
1375Cursor_displayname.restype = _CXString
1376Cursor_displayname.errcheck = _CXString.from_result
1377
1378Cursor_loc = lib.clang_getCursorLocation
1379Cursor_loc.argtypes = [Cursor]
1380Cursor_loc.restype = SourceLocation
1381
1382Cursor_extent = lib.clang_getCursorExtent
1383Cursor_extent.argtypes = [Cursor]
1384Cursor_extent.restype = SourceRange
1385
1386Cursor_ref = lib.clang_getCursorReferenced
1387Cursor_ref.argtypes = [Cursor]
1388Cursor_ref.restype = Cursor
1389Cursor_ref.errcheck = Cursor.from_result
1390
1391Cursor_type = lib.clang_getCursorType
1392Cursor_type.argtypes = [Cursor]
1393Cursor_type.restype = Type
1394Cursor_type.errcheck = Type.from_result
1395
1396Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
1397Cursor_visit = lib.clang_visitChildren
1398Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
1399Cursor_visit.restype = c_uint
1400
1401# Type Functions
1402Type_get_canonical = lib.clang_getCanonicalType
1403Type_get_canonical.argtypes = [Type]
1404Type_get_canonical.restype = Type
1405Type_get_canonical.errcheck = Type.from_result
1406
1407Type_is_const_qualified = lib.clang_isConstQualifiedType
1408Type_is_const_qualified.argtypes = [Type]
1409Type_is_const_qualified.restype = bool
1410
1411Type_is_volatile_qualified = lib.clang_isVolatileQualifiedType
1412Type_is_volatile_qualified.argtypes = [Type]
1413Type_is_volatile_qualified.restype = bool
1414
1415Type_is_restrict_qualified = lib.clang_isRestrictQualifiedType
1416Type_is_restrict_qualified.argtypes = [Type]
1417Type_is_restrict_qualified.restype = bool
1418
1419Type_get_pointee = lib.clang_getPointeeType
1420Type_get_pointee.argtypes = [Type]
1421Type_get_pointee.restype = Type
1422Type_get_pointee.errcheck = Type.from_result
1423
1424Type_get_declaration = lib.clang_getTypeDeclaration
1425Type_get_declaration.argtypes = [Type]
1426Type_get_declaration.restype = Cursor
1427Type_get_declaration.errcheck = Cursor.from_result
1428
1429Type_get_result = lib.clang_getResultType
1430Type_get_result.argtypes = [Type]
1431Type_get_result.restype = Type
1432Type_get_result.errcheck = Type.from_result
1433
1434
1435# Index Functions
1436Index_create = lib.clang_createIndex
1437Index_create.argtypes = [c_int, c_int]
1438Index_create.restype = c_object_p
1439
1440Index_dispose = lib.clang_disposeIndex
1441Index_dispose.argtypes = [Index]
1442
1443# Translation Unit Functions
1444TranslationUnit_read = lib.clang_createTranslationUnit
1445TranslationUnit_read.argtypes = [Index, c_char_p]
1446TranslationUnit_read.restype = c_object_p
1447
1448TranslationUnit_parse = lib.clang_parseTranslationUnit
1449TranslationUnit_parse.argtypes = [Index, c_char_p, c_void_p,
1450                                  c_int, c_void_p, c_int, c_int]
1451TranslationUnit_parse.restype = c_object_p
1452
1453TranslationUnit_reparse = lib.clang_reparseTranslationUnit
1454TranslationUnit_reparse.argtypes = [TranslationUnit, c_int, c_void_p, c_int]
1455TranslationUnit_reparse.restype = c_int
1456
1457TranslationUnit_codeComplete = lib.clang_codeCompleteAt
1458TranslationUnit_codeComplete.argtypes = [TranslationUnit, c_char_p, c_int,
1459                                         c_int, c_void_p, c_int, c_int]
1460TranslationUnit_codeComplete.restype = POINTER(CCRStructure)
1461
1462TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
1463TranslationUnit_cursor.argtypes = [TranslationUnit]
1464TranslationUnit_cursor.restype = Cursor
1465TranslationUnit_cursor.errcheck = Cursor.from_result
1466
1467TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
1468TranslationUnit_spelling.argtypes = [TranslationUnit]
1469TranslationUnit_spelling.restype = _CXString
1470TranslationUnit_spelling.errcheck = _CXString.from_result
1471
1472TranslationUnit_dispose = lib.clang_disposeTranslationUnit
1473TranslationUnit_dispose.argtypes = [TranslationUnit]
1474
1475TranslationUnit_includes_callback = CFUNCTYPE(None,
1476                                              c_object_p,
1477                                              POINTER(SourceLocation),
1478                                              c_uint, py_object)
1479TranslationUnit_includes = lib.clang_getInclusions
1480TranslationUnit_includes.argtypes = [TranslationUnit,
1481                                     TranslationUnit_includes_callback,
1482                                     py_object]
1483
1484# File Functions
1485File_name = lib.clang_getFileName
1486File_name.argtypes = [File]
1487File_name.restype = _CXString
1488
1489File_time = lib.clang_getFileTime
1490File_time.argtypes = [File]
1491File_time.restype = c_uint
1492
1493# Code completion
1494
1495CodeCompletionResults_dispose = lib.clang_disposeCodeCompleteResults
1496CodeCompletionResults_dispose.argtypes = [CodeCompletionResults]
1497
1498_clang_codeCompleteGetNumDiagnostics = lib.clang_codeCompleteGetNumDiagnostics
1499_clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults]
1500_clang_codeCompleteGetNumDiagnostics.restype = c_int
1501
1502_clang_codeCompleteGetDiagnostic = lib.clang_codeCompleteGetDiagnostic
1503_clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults, c_int]
1504_clang_codeCompleteGetDiagnostic.restype = Diagnostic
1505
1506_clang_getCompletionChunkText = lib.clang_getCompletionChunkText
1507_clang_getCompletionChunkText.argtypes = [c_void_p, c_int]
1508_clang_getCompletionChunkText.restype = _CXString
1509
1510_clang_getCompletionChunkKind = lib.clang_getCompletionChunkKind
1511_clang_getCompletionChunkKind.argtypes = [c_void_p, c_int]
1512_clang_getCompletionChunkKind.restype = c_int
1513
1514_clang_getCompletionChunkCompletionString = lib.clang_getCompletionChunkCompletionString
1515_clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int]
1516_clang_getCompletionChunkCompletionString.restype = c_object_p
1517
1518_clang_getNumCompletionChunks = lib.clang_getNumCompletionChunks
1519_clang_getNumCompletionChunks.argtypes = [c_void_p]
1520_clang_getNumCompletionChunks.restype = c_int
1521
1522_clang_getCompletionAvailability = lib.clang_getCompletionAvailability
1523_clang_getCompletionAvailability.argtypes = [c_void_p]
1524_clang_getCompletionAvailability.restype = c_int
1525
1526_clang_getCompletionPriority = lib.clang_getCompletionPriority
1527_clang_getCompletionPriority.argtypes = [c_void_p]
1528_clang_getCompletionPriority.restype = c_int
1529
1530
1531###
1532
1533__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind', 'Type', 'TypeKind',
1534           'Diagnostic', 'FixIt', 'CodeCompletionResults', 'SourceRange',
1535           'SourceLocation', 'File']
1536