cindex.py revision 3b0cf09f9c84e75881b261eb4a7a69d99aa0335a
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('libCIndex.dylib')
75    elif name == 'Windows':
76        return cdll.LoadLibrary('libCIndex.dll')
77    else:
78        return cdll.LoadLibrary('libCIndex.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(c.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.ptr)
195
196    @property
197    def severity(self):
198        return _clang_getDiagnosticSeverity(self.ptr)
199
200    @property
201    def location(self):
202        return _clang_getDiagnosticLocation(self.ptr)
203
204    @property
205    def spelling(self):
206        return _clang_getDiagnosticSpelling(self.ptr)
207
208    @property
209    def ranges(self):
210        class Ranges:
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                return _clang_getDiagnosticRange(self.diag, key)
219
220        return Ranges(self.ptr)
221
222    @property
223    def fixits(self):
224        class FixIts:
225            def __init__(self, diag):
226                self.diag = diag
227
228            def __len__(self):
229                return int(_clang_getDiagnosticNumFixIts(self.diag))
230
231            def __getitem__(self, key):
232                range = SourceRange()
233                value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
234
235                return FixIt(range, value)
236
237        return FixIts(self.ptr)
238
239    def __repr__(self):
240        return "<Diagnostic severity %r, location %r, spelling %r>" % (
241            self.severity, self.location, self.spelling)
242
243class FixIt(object):
244    """
245    A FixIt represents a transformation to be applied to the source to
246    "fix-it". The fix-it shouldbe applied by replacing the given source range
247    with the given value.
248    """
249
250    def __init__(self, range, value):
251        self.range = range
252        self.value = value
253
254    def __repr__(self):
255        return "<FixIt range %r, value %r>" % (self.range, self.value)
256
257### Cursor Kinds ###
258
259class CursorKind(object):
260    """
261    A CursorKind describes the kind of entity that a cursor points to.
262    """
263
264    # The unique kind objects, indexed by id.
265    _kinds = []
266    _name_map = None
267
268    def __init__(self, value):
269        if value >= len(CursorKind._kinds):
270            CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
271        if CursorKind._kinds[value] is not None:
272            raise ValueError,'CursorKind already loaded'
273        self.value = value
274        CursorKind._kinds[value] = self
275        CursorKind._name_map = None
276
277    def from_param(self):
278        return self.value
279
280    @property
281    def name(self):
282        """Get the enumeration name of this cursor kind."""
283        if self._name_map is None:
284            self._name_map = {}
285            for key,value in CursorKind.__dict__.items():
286                if isinstance(value,CursorKind):
287                    self._name_map[value] = key
288        return self._name_map[self]
289
290    @staticmethod
291    def from_id(id):
292        if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
293            raise ValueError,'Unknown cursor kind'
294        return CursorKind._kinds[id]
295
296    @staticmethod
297    def get_all_kinds():
298        """Return all CursorKind enumeration instances."""
299        return filter(None, CursorKind._kinds)
300
301    def is_declaration(self):
302        """Test if this is a declaration kind."""
303        return CursorKind_is_decl(self)
304
305    def is_reference(self):
306        """Test if this is a reference kind."""
307        return CursorKind_is_ref(self)
308
309    def is_expression(self):
310        """Test if this is an expression kind."""
311        return CursorKind_is_expr(self)
312
313    def is_statement(self):
314        """Test if this is a statement kind."""
315        return CursorKind_is_stmt(self)
316
317    def is_invalid(self):
318        """Test if this is an invalid kind."""
319        return CursorKind_is_inv(self)
320
321    def __repr__(self):
322        return 'CursorKind.%s' % (self.name,)
323
324# FIXME: Is there a nicer way to expose this enumeration? We could potentially
325# represent the nested structure, or even build a class hierarchy. The main
326# things we want for sure are (a) simple external access to kinds, (b) a place
327# to hang a description and name, (c) easy to keep in sync with Index.h.
328
329###
330# Declaration Kinds
331
332# A declaration whose specific kind is not exposed via this interface.
333#
334# Unexposed declarations have the same operations as any other kind of
335# declaration; one can extract their location information, spelling, find their
336# definitions, etc. However, the specific kind of the declaration is not
337# reported.
338CursorKind.UNEXPOSED_DECL = CursorKind(1)
339
340# A C or C++ struct.
341CursorKind.STRUCT_DECL = CursorKind(2)
342
343# A C or C++ union.
344CursorKind.UNION_DECL = CursorKind(3)
345
346# A C++ class.
347CursorKind.CLASS_DECL = CursorKind(4)
348
349# An enumeration.
350CursorKind.ENUM_DECL = CursorKind(5)
351
352# A field (in C) or non-static data member (in C++) in a struct, union, or C++
353# class.
354CursorKind.FIELD_DECL = CursorKind(6)
355
356# An enumerator constant.
357CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
358
359# A function.
360CursorKind.FUNCTION_DECL = CursorKind(8)
361
362# A variable.
363CursorKind.VAR_DECL = CursorKind(9)
364
365# A function or method parameter.
366CursorKind.PARM_DECL = CursorKind(10)
367
368# An Objective-C @interface.
369CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
370
371# An Objective-C @interface for a category.
372CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
373
374# An Objective-C @protocol declaration.
375CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
376
377# An Objective-C @property declaration.
378CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
379
380# An Objective-C instance variable.
381CursorKind.OBJC_IVAR_DECL = CursorKind(15)
382
383# An Objective-C instance method.
384CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
385
386# An Objective-C class method.
387CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
388
389# An Objective-C @implementation.
390CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
391
392# An Objective-C @implementation for a category.
393CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
394
395# A typedef.
396CursorKind.TYPEDEF_DECL = CursorKind(20)
397
398###
399# Reference Kinds
400
401CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
402CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
403CursorKind.OBJC_CLASS_REF = CursorKind(42)
404
405# A reference to a type declaration.
406#
407# A type reference occurs anywhere where a type is named but not
408# declared. For example, given:
409#   typedef unsigned size_type;
410#   size_type size;
411#
412# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
413# while the type of the variable "size" is referenced. The cursor
414# referenced by the type of size is the typedef for size_type.
415CursorKind.TYPE_REF = CursorKind(43)
416
417###
418# Invalid/Error Kinds
419
420CursorKind.INVALID_FILE = CursorKind(70)
421CursorKind.NO_DECL_FOUND = CursorKind(71)
422CursorKind.NOT_IMPLEMENTED = CursorKind(72)
423
424###
425# Expression Kinds
426
427# An expression whose specific kind is not exposed via this interface.
428#
429# Unexposed expressions have the same operations as any other kind of
430# expression; one can extract their location information, spelling, children,
431# etc. However, the specific kind of the expression is not reported.
432CursorKind.UNEXPOSED_EXPR = CursorKind(100)
433
434# An expression that refers to some value declaration, such as a function,
435# varible, or enumerator.
436CursorKind.DECL_REF_EXPR = CursorKind(101)
437
438# An expression that refers to a member of a struct, union, class, Objective-C
439# class, etc.
440CursorKind.MEMBER_REF_EXPR = CursorKind(102)
441
442# An expression that calls a function.
443CursorKind.CALL_EXPR = CursorKind(103)
444
445# An expression that sends a message to an Objective-C object or class.
446CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
447
448# A statement whose specific kind is not exposed via this interface.
449#
450# Unexposed statements have the same operations as any other kind of statement;
451# one can extract their location information, spelling, children, etc. However,
452# the specific kind of the statement is not reported.
453CursorKind.UNEXPOSED_STMT = CursorKind(200)
454
455###
456# Other Kinds
457
458# Cursor that represents the translation unit itself.
459#
460# The translation unit cursor exists primarily to act as the root cursor for
461# traversing the contents of a translation unit.
462CursorKind.TRANSLATION_UNIT = CursorKind(300)
463
464### Cursors ###
465
466class Cursor(Structure):
467    """
468    The Cursor class represents a reference to an element within the AST. It
469    acts as a kind of iterator.
470    """
471    _fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)]
472
473    def __eq__(self, other):
474        return Cursor_eq(self, other)
475
476    def __ne__(self, other):
477        return not Cursor_eq(self, other)
478
479    def is_definition(self):
480        """
481        Returns true if the declaration pointed at by the cursor is also a
482        definition of that entity.
483        """
484        return Cursor_is_def(self)
485
486    def get_definition(self):
487        """
488        If the cursor is a reference to a declaration or a declaration of
489        some entity, return a cursor that points to the definition of that
490        entity.
491        """
492        # TODO: Should probably check that this is either a reference or
493        # declaration prior to issuing the lookup.
494        return Cursor_def(self)
495
496    def get_usr(self):
497        """Return the Unified Symbol Resultion (USR) for the entity referenced
498        by the given cursor (or None).
499
500        A Unified Symbol Resolution (USR) is a string that identifies a
501        particular entity (function, class, variable, etc.) within a
502        program. USRs can be compared across translation units to determine,
503        e.g., when references in one translation refer to an entity defined in
504        another translation unit."""
505        return Cursor_usr(self)
506
507    @property
508    def kind(self):
509        """Return the kind of this cursor."""
510        return CursorKind.from_id(self._kind_id)
511
512    @property
513    def spelling(self):
514        """Return the spelling of the entity pointed at by the cursor."""
515        if not self.kind.is_declaration():
516            # FIXME: clang_getCursorSpelling should be fixed to not assert on
517            # this, for consistency with clang_getCursorUSR.
518            return None
519        return Cursor_spelling(self)
520
521    @property
522    def location(self):
523        """
524        Return the source location (the starting character) of the entity
525        pointed at by the cursor.
526        """
527        return Cursor_loc(self)
528
529    @property
530    def extent(self):
531        """
532        Return the source range (the range of text) occupied by the entity
533        pointed at by the cursor.
534        """
535        return Cursor_extent(self)
536
537    def get_children(self):
538        """Return an iterator for accessing the children of this cursor."""
539
540        # FIXME: Expose iteration from CIndex, PR6125.
541        def visitor(child, parent, children):
542            # FIXME: Document this assertion in API.
543            # FIXME: There should just be an isNull method.
544            assert child != Cursor_null()
545            children.append(child)
546            return 1 # continue
547        children = []
548        Cursor_visit(self, Cursor_visit_callback(visitor), children)
549        return iter(children)
550
551    @staticmethod
552    def from_result(res, fn, args):
553        assert isinstance(res, Cursor)
554        # FIXME: There should just be an isNull method.
555        if res == Cursor_null():
556            return None
557        return res
558
559## CIndex Objects ##
560
561# CIndex objects (derived from ClangObject) are essentially lightweight
562# wrappers attached to some underlying object, which is exposed via CIndex as
563# a void*.
564
565class ClangObject(object):
566    """
567    A helper for Clang objects. This class helps act as an intermediary for
568    the ctypes library and the Clang CIndex library.
569    """
570    def __init__(self, obj):
571        assert isinstance(obj, c_object_p) and obj
572        self.obj = self._as_parameter_ = obj
573
574    def from_param(self):
575        return self._as_parameter_
576
577
578class _CXUnsavedFile(Structure):
579    """Helper for passing unsaved file arguments."""
580    _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
581
582## Diagnostic Conversion ##
583
584# Diagnostic objects are temporary, we must extract all the information from the
585# diagnostic object when it is passed to the callback.
586
587_clang_getNumDiagnostics = lib.clang_getNumDiagnostics
588_clang_getNumDiagnostics.argtypes = [c_object_p]
589_clang_getNumDiagnostics.restype = c_uint
590
591_clang_getDiagnostic = lib.clang_getDiagnostic
592_clang_getDiagnostic.argtypes = [c_object_p, c_uint]
593_clang_getDiagnostic.restype = c_object_p
594
595_clang_disposeDiagnostic = lib.clang_disposeDiagnostic
596_clang_disposeDiagnostic.argtypes = [c_object_p]
597
598_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
599_clang_getDiagnosticSeverity.argtypes = [c_object_p]
600_clang_getDiagnosticSeverity.restype = c_int
601
602_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
603_clang_getDiagnosticLocation.argtypes = [c_object_p]
604_clang_getDiagnosticLocation.restype = SourceLocation
605
606_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
607_clang_getDiagnosticSpelling.argtypes = [c_object_p]
608_clang_getDiagnosticSpelling.restype = _CXString
609_clang_getDiagnosticSpelling.errcheck = _CXString.from_result
610
611_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
612_clang_getDiagnosticNumRanges.argtypes = [c_object_p]
613_clang_getDiagnosticNumRanges.restype = c_uint
614
615_clang_getDiagnosticRange = lib.clang_getDiagnosticRange
616_clang_getDiagnosticRange.argtypes = [c_object_p, c_uint]
617_clang_getDiagnosticRange.restype = SourceRange
618
619_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
620_clang_getDiagnosticNumFixIts.argtypes = [c_object_p]
621_clang_getDiagnosticNumFixIts.restype = c_uint
622
623_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
624_clang_getDiagnosticFixIt.argtypes = [c_object_p, c_uint, POINTER(SourceRange)]
625_clang_getDiagnosticFixIt.restype = _CXString
626_clang_getDiagnosticFixIt.errcheck = _CXString.from_result
627
628###
629
630class Index(ClangObject):
631    """
632    The Index type provides the primary interface to the Clang CIndex library,
633    primarily by providing an interface for reading and parsing translation
634    units.
635    """
636
637    @staticmethod
638    def create(excludeDecls=False):
639        """
640        Create a new Index.
641        Parameters:
642        excludeDecls -- Exclude local declarations from translation units.
643        """
644        return Index(Index_create(excludeDecls, 0))
645
646    def __del__(self):
647        Index_dispose(self)
648
649    def read(self, path):
650        """Load the translation unit from the given AST file."""
651        ptr = TranslationUnit_read(self, path)
652        return TranslationUnit(ptr) if ptr else None
653
654    def parse(self, path, args = [], unsaved_files = []):
655        """
656        Load the translation unit from the given source code file by running
657        clang and generating the AST before loading. Additional command line
658        parameters can be passed to clang via the args parameter.
659
660        In-memory contents for files can be provided by passing a list of pairs
661        to as unsaved_files, the first item should be the filenames to be mapped
662        and the second should be the contents to be substituted for the
663        file. The contents may be passed as strings or file objects.
664        """
665        arg_array = 0
666        if len(args):
667            arg_array = (c_char_p * len(args))(* args)
668        unsaved_files_array = 0
669        if len(unsaved_files):
670            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
671            for i,(name,value) in enumerate(unsaved_files):
672                if not isinstance(value, str):
673                    # FIXME: It would be great to support an efficient version
674                    # of this, one day.
675                    value = value.read()
676                    print value
677                if not isinstance(value, str):
678                    raise TypeError,'Unexpected unsaved file contents.'
679                unsaved_files_array[i].name = name
680                unsaved_files_array[i].contents = value
681                unsaved_files_array[i].length = len(value)
682        ptr = TranslationUnit_parse(self, path, len(args), arg_array,
683                                    len(unsaved_files), unsaved_files_array)
684        return TranslationUnit(ptr) if ptr else None
685
686
687class TranslationUnit(ClangObject):
688    """
689    The TranslationUnit class represents a source code translation unit and
690    provides read-only access to its top-level declarations.
691    """
692
693    def __init__(self, ptr):
694        ClangObject.__init__(self, ptr)
695
696    def __del__(self):
697        TranslationUnit_dispose(self)
698
699    @property
700    def cursor(self):
701        """Retrieve the cursor that represents the given translation unit."""
702        return TranslationUnit_cursor(self)
703
704    @property
705    def spelling(self):
706        """Get the original translation unit source file name."""
707        return TranslationUnit_spelling(self)
708
709    def get_includes(self):
710        """
711        Return an iterable sequence of FileInclusion objects that describe the
712        sequence of inclusions in a translation unit. The first object in
713        this sequence is always the input file. Note that this method will not
714        recursively iterate over header files included through precompiled
715        headers.
716        """
717        def visitor(fobj, lptr, depth, includes):
718            loc = lptr.contents
719            includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
720
721        # Automatically adapt CIndex/ctype pointers to python objects
722        includes = []
723        TranslationUnit_includes(self,
724                                 TranslationUnit_includes_callback(visitor),
725                                 includes)
726        return iter(includes)
727
728    @property
729    def diagnostics(self):
730        """
731        Return an iterable (and indexable) object containing the diagnostics.
732        """
733        class Diags:
734            def __init__(self, tu):
735                self.tu = tu
736
737            def __len__(self):
738                return int(_clang_getNumDiagnostics(self.tu))
739
740            def __getitem__(self, key):
741                return Diagnostic(_clang_getDiagnostic(self.tu, key))
742
743        return Diags(self)
744
745class File(ClangObject):
746    """
747    The File class represents a particular source file that is part of a
748    translation unit.
749    """
750
751    @property
752    def name(self):
753        """Return the complete file and path name of the file."""
754        return File_name(self)
755
756    @property
757    def time(self):
758        """Return the last modification time of the file."""
759        return File_time(self)
760
761class FileInclusion(object):
762    """
763    The FileInclusion class represents the inclusion of one source file by
764    another via a '#include' directive or as the input file for the translation
765    unit. This class provides information about the included file, the including
766    file, the location of the '#include' directive and the depth of the included
767    file in the stack. Note that the input file has depth 0.
768    """
769
770    def __init__(self, src, tgt, loc, depth):
771        self.source = src
772        self.include = tgt
773        self.location = loc
774        self.depth = depth
775
776    @property
777    def is_input_file(self):
778        """True if the included file is the input file."""
779        return self.depth == 0
780
781# Additional Functions and Types
782
783# String Functions
784_CXString_dispose = lib.clang_disposeString
785_CXString_dispose.argtypes = [_CXString]
786
787_CXString_getCString = lib.clang_getCString
788_CXString_getCString.argtypes = [_CXString]
789_CXString_getCString.restype = c_char_p
790
791# Source Location Functions
792SourceLocation_loc = lib.clang_getInstantiationLocation
793SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
794                               POINTER(c_uint), POINTER(c_uint),
795                               POINTER(c_uint)]
796
797# Source Range Functions
798SourceRange_getRange = lib.clang_getRange
799SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
800SourceRange_getRange.restype = SourceRange
801
802SourceRange_start = lib.clang_getRangeStart
803SourceRange_start.argtypes = [SourceRange]
804SourceRange_start.restype = SourceLocation
805
806SourceRange_end = lib.clang_getRangeEnd
807SourceRange_end.argtypes = [SourceRange]
808SourceRange_end.restype = SourceLocation
809
810# CursorKind Functions
811CursorKind_is_decl = lib.clang_isDeclaration
812CursorKind_is_decl.argtypes = [CursorKind]
813CursorKind_is_decl.restype = bool
814
815CursorKind_is_ref = lib.clang_isReference
816CursorKind_is_ref.argtypes = [CursorKind]
817CursorKind_is_ref.restype = bool
818
819CursorKind_is_expr = lib.clang_isExpression
820CursorKind_is_expr.argtypes = [CursorKind]
821CursorKind_is_expr.restype = bool
822
823CursorKind_is_stmt = lib.clang_isStatement
824CursorKind_is_stmt.argtypes = [CursorKind]
825CursorKind_is_stmt.restype = bool
826
827CursorKind_is_inv = lib.clang_isInvalid
828CursorKind_is_inv.argtypes = [CursorKind]
829CursorKind_is_inv.restype = bool
830
831# Cursor Functions
832# TODO: Implement this function
833Cursor_get = lib.clang_getCursor
834Cursor_get.argtypes = [TranslationUnit, SourceLocation]
835Cursor_get.restype = Cursor
836
837Cursor_null = lib.clang_getNullCursor
838Cursor_null.restype = Cursor
839
840Cursor_usr = lib.clang_getCursorUSR
841Cursor_usr.argtypes = [Cursor]
842Cursor_usr.restype = _CXString
843Cursor_usr.errcheck = _CXString.from_result
844
845Cursor_is_def = lib.clang_isCursorDefinition
846Cursor_is_def.argtypes = [Cursor]
847Cursor_is_def.restype = bool
848
849Cursor_def = lib.clang_getCursorDefinition
850Cursor_def.argtypes = [Cursor]
851Cursor_def.restype = Cursor
852Cursor_def.errcheck = Cursor.from_result
853
854Cursor_eq = lib.clang_equalCursors
855Cursor_eq.argtypes = [Cursor, Cursor]
856Cursor_eq.restype = c_uint
857
858Cursor_spelling = lib.clang_getCursorSpelling
859Cursor_spelling.argtypes = [Cursor]
860Cursor_spelling.restype = _CXString
861Cursor_spelling.errcheck = _CXString.from_result
862
863Cursor_loc = lib.clang_getCursorLocation
864Cursor_loc.argtypes = [Cursor]
865Cursor_loc.restype = SourceLocation
866
867Cursor_extent = lib.clang_getCursorExtent
868Cursor_extent.argtypes = [Cursor]
869Cursor_extent.restype = SourceRange
870
871Cursor_ref = lib.clang_getCursorReferenced
872Cursor_ref.argtypes = [Cursor]
873Cursor_ref.restype = Cursor
874Cursor_ref.errcheck = Cursor.from_result
875
876Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
877Cursor_visit = lib.clang_visitChildren
878Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
879Cursor_visit.restype = c_uint
880
881# Index Functions
882Index_create = lib.clang_createIndex
883Index_create.argtypes = [c_int, c_int]
884Index_create.restype = c_object_p
885
886Index_dispose = lib.clang_disposeIndex
887Index_dispose.argtypes = [Index]
888
889# Translation Unit Functions
890TranslationUnit_read = lib.clang_createTranslationUnit
891TranslationUnit_read.argtypes = [Index, c_char_p]
892TranslationUnit_read.restype = c_object_p
893
894TranslationUnit_parse = lib.clang_createTranslationUnitFromSourceFile
895TranslationUnit_parse.argtypes = [Index, c_char_p, c_int, c_void_p,
896                                  c_int, c_void_p]
897TranslationUnit_parse.restype = c_object_p
898
899TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
900TranslationUnit_cursor.argtypes = [TranslationUnit]
901TranslationUnit_cursor.restype = Cursor
902TranslationUnit_cursor.errcheck = Cursor.from_result
903
904TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
905TranslationUnit_spelling.argtypes = [TranslationUnit]
906TranslationUnit_spelling.restype = _CXString
907TranslationUnit_spelling.errcheck = _CXString.from_result
908
909TranslationUnit_dispose = lib.clang_disposeTranslationUnit
910TranslationUnit_dispose.argtypes = [TranslationUnit]
911
912TranslationUnit_includes_callback = CFUNCTYPE(None,
913                                              c_object_p,
914                                              POINTER(SourceLocation),
915                                              c_uint, py_object)
916TranslationUnit_includes = lib.clang_getInclusions
917TranslationUnit_includes.argtypes = [TranslationUnit,
918                                     TranslationUnit_includes_callback,
919                                     py_object]
920
921# File Functions
922File_name = lib.clang_getFileName
923File_name.argtypes = [File]
924File_name.restype = c_char_p
925
926File_time = lib.clang_getFileTime
927File_time.argtypes = [File]
928File_time.restype = c_uint
929
930###
931
932__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind',
933           'Diagnostic', 'FixIt', 'SourceRange', 'SourceLocation', 'File']
934