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 *
66import collections
67
68import clang.enumerations
69
70# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
71# object. This is a problem, because it means that from_parameter will see an
72# integer and pass the wrong value on platforms where int != void*. Work around
73# this by marshalling object arguments as void**.
74c_object_p = POINTER(c_void_p)
75
76callbacks = {}
77
78### Exception Classes ###
79
80class TranslationUnitLoadError(Exception):
81    """Represents an error that occurred when loading a TranslationUnit.
82
83    This is raised in the case where a TranslationUnit could not be
84    instantiated due to failure in the libclang library.
85
86    FIXME: Make libclang expose additional error information in this scenario.
87    """
88    pass
89
90class TranslationUnitSaveError(Exception):
91    """Represents an error that occurred when saving a TranslationUnit.
92
93    Each error has associated with it an enumerated value, accessible under
94    e.save_error. Consumers can compare the value with one of the ERROR_
95    constants in this class.
96    """
97
98    # Indicates that an unknown error occurred. This typically indicates that
99    # I/O failed during save.
100    ERROR_UNKNOWN = 1
101
102    # Indicates that errors during translation prevented saving. The errors
103    # should be available via the TranslationUnit's diagnostics.
104    ERROR_TRANSLATION_ERRORS = 2
105
106    # Indicates that the translation unit was somehow invalid.
107    ERROR_INVALID_TU = 3
108
109    def __init__(self, enumeration, message):
110        assert isinstance(enumeration, int)
111
112        if enumeration < 1 or enumeration > 3:
113            raise Exception("Encountered undefined TranslationUnit save error "
114                            "constant: {0}. Please file a bug to have this "
115                            "value supported.".format(enumeration))
116
117        self.save_error = enumeration
118        Exception.__init__(self, 'Error {0}: {1}'.format(enumeration, message))
119
120### Structures and Utility Classes ###
121
122class CachedProperty(object):
123    """Decorator that lazy-loads the value of a property.
124
125    The first time the property is accessed, the original property function is
126    executed. The value it returns is set as the new value of that instance's
127    property, replacing the original method.
128    """
129
130    def __init__(self, wrapped):
131        self.wrapped = wrapped
132        try:
133            self.__doc__ = wrapped.__doc__
134        except:
135            pass
136
137    def __get__(self, instance, instance_type=None):
138        if instance is None:
139            return self
140
141        value = self.wrapped(instance)
142        setattr(instance, self.wrapped.__name__, value)
143
144        return value
145
146
147class _CXString(Structure):
148    """Helper for transforming CXString results."""
149
150    _fields_ = [("spelling", c_char_p), ("free", c_int)]
151
152    def __del__(self):
153        conf.lib.clang_disposeString(self)
154
155    @staticmethod
156    def from_result(res, fn, args):
157        assert isinstance(res, _CXString)
158        return conf.lib.clang_getCString(res)
159
160class SourceLocation(Structure):
161    """
162    A SourceLocation represents a particular location within a source file.
163    """
164    _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
165    _data = None
166
167    def _get_instantiation(self):
168        if self._data is None:
169            f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
170            conf.lib.clang_getInstantiationLocation(self, byref(f), byref(l),
171                    byref(c), byref(o))
172            if f:
173                f = File(f)
174            else:
175                f = None
176            self._data = (f, int(l.value), int(c.value), int(o.value))
177        return self._data
178
179    @staticmethod
180    def from_position(tu, file, line, column):
181        """
182        Retrieve the source location associated with a given file/line/column in
183        a particular translation unit.
184        """
185        return conf.lib.clang_getLocation(tu, file, line, column)
186
187    @staticmethod
188    def from_offset(tu, file, offset):
189        """Retrieve a SourceLocation from a given character offset.
190
191        tu -- TranslationUnit file belongs to
192        file -- File instance to obtain offset from
193        offset -- Integer character offset within file
194        """
195        return conf.lib.clang_getLocationForOffset(tu, file, offset)
196
197    @property
198    def file(self):
199        """Get the file represented by this source location."""
200        return self._get_instantiation()[0]
201
202    @property
203    def line(self):
204        """Get the line represented by this source location."""
205        return self._get_instantiation()[1]
206
207    @property
208    def column(self):
209        """Get the column represented by this source location."""
210        return self._get_instantiation()[2]
211
212    @property
213    def offset(self):
214        """Get the file offset represented by this source location."""
215        return self._get_instantiation()[3]
216
217    def __eq__(self, other):
218        return conf.lib.clang_equalLocations(self, other)
219
220    def __ne__(self, other):
221        return not self.__eq__(other)
222
223    def __repr__(self):
224        if self.file:
225            filename = self.file.name
226        else:
227            filename = None
228        return "<SourceLocation file {0}, line {1}, column {2}>".format(filename, self.line, self.column)
229
230class SourceRange(Structure):
231    """
232    A SourceRange describes a range of source locations within the source
233    code.
234    """
235    _fields_ = [
236        ("ptr_data", c_void_p * 2),
237        ("begin_int_data", c_uint),
238        ("end_int_data", c_uint)]
239
240    # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
241    # object.
242    @staticmethod
243    def from_locations(start, end):
244        return conf.lib.clang_getRange(start, end)
245
246    @property
247    def start(self):
248        """
249        Return a SourceLocation representing the first character within a
250        source range.
251        """
252        return conf.lib.clang_getRangeStart(self)
253
254    @property
255    def end(self):
256        """
257        Return a SourceLocation representing the last character within a
258        source range.
259        """
260        return conf.lib.clang_getRangeEnd(self)
261
262    def __eq__(self, other):
263        return conf.lib.clang_equalRanges(self, other)
264
265    def __ne__(self, other):
266        return not self.__eq__(other)
267
268    def __repr__(self):
269        return "<SourceRange start {0}, end {1}>".format(self.start, self.end)
270
271class Diagnostic(object):
272    """
273    A Diagnostic is a single instance of a Clang diagnostic. It includes the
274    diagnostic severity, the message, the location the diagnostic occurred, as
275    well as additional source ranges and associated fix-it hints.
276    """
277
278    Ignored = 0
279    Note    = 1
280    Warning = 2
281    Error   = 3
282    Fatal   = 4
283
284    def __init__(self, ptr):
285        self.ptr = ptr
286
287    def __del__(self):
288        conf.lib.clang_disposeDiagnostic(self)
289
290    @property
291    def severity(self):
292        return conf.lib.clang_getDiagnosticSeverity(self)
293
294    @property
295    def location(self):
296        return conf.lib.clang_getDiagnosticLocation(self)
297
298    @property
299    def spelling(self):
300        return conf.lib.clang_getDiagnosticSpelling(self)
301
302    @property
303    def ranges(self):
304        class RangeIterator:
305            def __init__(self, diag):
306                self.diag = diag
307
308            def __len__(self):
309                return int(conf.lib.clang_getDiagnosticNumRanges(self.diag))
310
311            def __getitem__(self, key):
312                if (key >= len(self)):
313                    raise IndexError
314                return conf.lib.clang_getDiagnosticRange(self.diag, key)
315
316        return RangeIterator(self)
317
318    @property
319    def fixits(self):
320        class FixItIterator:
321            def __init__(self, diag):
322                self.diag = diag
323
324            def __len__(self):
325                return int(conf.lib.clang_getDiagnosticNumFixIts(self.diag))
326
327            def __getitem__(self, key):
328                range = SourceRange()
329                value = conf.lib.clang_getDiagnosticFixIt(self.diag, key,
330                        byref(range))
331                if len(value) == 0:
332                    raise IndexError
333
334                return FixIt(range, value)
335
336        return FixItIterator(self)
337
338    @property
339    def format(self, options=-1):
340        if options == -1:
341            options = conf.lib.clang_defaultDiagnosticDisplayOptions()
342
343        return conf.lib.clang_formatDiagnostic(self, options)
344
345    @property
346    def category_number(self):
347        """The category number for this diagnostic."""
348        return conf.lib.clang_getDiagnosticCategory(self)
349
350    @property
351    def category_name(self):
352        """The string name of the category for this diagnostic."""
353        return conf.lib.clang_getDiagnosticCategoryName(self.category_number)
354
355    @property
356    def option(self):
357        """The command-line option that enables this diagnostic."""
358        return conf.lib.clang_getDiagnosticOption(self, None)
359
360    @property
361    def disable_option(self):
362        """The command-line option that disables this diagnostic."""
363        disable = _CXString()
364        conf.lib.clang_getDiagnosticOption(self, byref(disable))
365
366        return conf.lib.clang_getCString(disable)
367
368    def __repr__(self):
369        return "<Diagnostic severity {0}, location {1}, spelling {2}>".format(self.severity, self.location, self.spelling)
370
371    def from_param(self):
372      return self.ptr
373
374class FixIt(object):
375    """
376    A FixIt represents a transformation to be applied to the source to
377    "fix-it". The fix-it shouldbe applied by replacing the given source range
378    with the given value.
379    """
380
381    def __init__(self, range, value):
382        self.range = range
383        self.value = value
384
385    def __repr__(self):
386        return "<FixIt range {0}, value {1}>".format(self.range, self.value)
387
388class TokenGroup(object):
389    """Helper class to facilitate token management.
390
391    Tokens are allocated from libclang in chunks. They must be disposed of as a
392    collective group.
393
394    One purpose of this class is for instances to represent groups of allocated
395    tokens. Each token in a group contains a reference back to an instance of
396    this class. When all tokens from a group are garbage collected, it allows
397    this class to be garbage collected. When this class is garbage collected,
398    it calls the libclang destructor which invalidates all tokens in the group.
399
400    You should not instantiate this class outside of this module.
401    """
402    def __init__(self, tu, memory, count):
403        self._tu = tu
404        self._memory = memory
405        self._count = count
406
407    def __del__(self):
408        conf.lib.clang_disposeTokens(self._tu, self._memory, self._count)
409
410    @staticmethod
411    def get_tokens(tu, extent):
412        """Helper method to return all tokens in an extent.
413
414        This functionality is needed multiple places in this module. We define
415        it here because it seems like a logical place.
416        """
417        tokens_memory = POINTER(Token)()
418        tokens_count = c_uint()
419
420        conf.lib.clang_tokenize(tu, extent, byref(tokens_memory),
421                byref(tokens_count))
422
423        count = int(tokens_count.value)
424
425        # If we get no tokens, no memory was allocated. Be sure not to return
426        # anything and potentially call a destructor on nothing.
427        if count < 1:
428            return
429
430        tokens_array = cast(tokens_memory, POINTER(Token * count)).contents
431
432        token_group = TokenGroup(tu, tokens_memory, tokens_count)
433
434        for i in range(0, count):
435            token = Token()
436            token.int_data = tokens_array[i].int_data
437            token.ptr_data = tokens_array[i].ptr_data
438            token._tu = tu
439            token._group = token_group
440
441            yield token
442
443class TokenKind(object):
444    """Describes a specific type of a Token."""
445
446    _value_map = {} # int -> TokenKind
447
448    def __init__(self, value, name):
449        """Create a new TokenKind instance from a numeric value and a name."""
450        self.value = value
451        self.name = name
452
453    def __repr__(self):
454        return 'TokenKind.{0}'.format(self.name)
455
456    @staticmethod
457    def from_value(value):
458        """Obtain a registered TokenKind instance from its value."""
459        result = TokenKind._value_map.get(value, None)
460
461        if result is None:
462            raise ValueError('Unknown TokenKind: {0}'.format(value))
463
464        return result
465
466    @staticmethod
467    def register(value, name):
468        """Register a new TokenKind enumeration.
469
470        This should only be called at module load time by code within this
471        package.
472        """
473        if value in TokenKind._value_map:
474            raise ValueError('TokenKind already registered: {0}'.format(value))
475
476        kind = TokenKind(value, name)
477        TokenKind._value_map[value] = kind
478        setattr(TokenKind, name, kind)
479
480### Cursor Kinds ###
481
482class CursorKind(object):
483    """
484    A CursorKind describes the kind of entity that a cursor points to.
485    """
486
487    # The unique kind objects, indexed by id.
488    _kinds = []
489    _name_map = None
490
491    def __init__(self, value):
492        if value >= len(CursorKind._kinds):
493            CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
494        if CursorKind._kinds[value] is not None:
495            raise ValueError('CursorKind already loaded')
496        self.value = value
497        CursorKind._kinds[value] = self
498        CursorKind._name_map = None
499
500    def from_param(self):
501        return self.value
502
503    @property
504    def name(self):
505        """Get the enumeration name of this cursor kind."""
506        if self._name_map is None:
507            self._name_map = {}
508            for key,value in CursorKind.__dict__.items():
509                if isinstance(value,CursorKind):
510                    self._name_map[value] = key
511        return self._name_map[self]
512
513    @staticmethod
514    def from_id(id):
515        if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
516            raise ValueError('Unknown cursor kind')
517        return CursorKind._kinds[id]
518
519    @staticmethod
520    def get_all_kinds():
521        """Return all CursorKind enumeration instances."""
522        return filter(None, CursorKind._kinds)
523
524    def is_declaration(self):
525        """Test if this is a declaration kind."""
526        return conf.lib.clang_isDeclaration(self)
527
528    def is_reference(self):
529        """Test if this is a reference kind."""
530        return conf.lib.clang_isReference(self)
531
532    def is_expression(self):
533        """Test if this is an expression kind."""
534        return conf.lib.clang_isExpression(self)
535
536    def is_statement(self):
537        """Test if this is a statement kind."""
538        return conf.lib.clang_isStatement(self)
539
540    def is_attribute(self):
541        """Test if this is an attribute kind."""
542        return conf.lib.clang_isAttribute(self)
543
544    def is_invalid(self):
545        """Test if this is an invalid kind."""
546        return conf.lib.clang_isInvalid(self)
547
548    def is_translation_unit(self):
549        """Test if this is a translation unit kind."""
550        return conf.lib.clang_isTranslationUnit(self)
551
552    def is_preprocessing(self):
553        """Test if this is a preprocessing kind."""
554        return conf.lib.clang_isPreprocessing(self)
555
556    def is_unexposed(self):
557        """Test if this is an unexposed kind."""
558        return conf.lib.clang_isUnexposed(self)
559
560    def __repr__(self):
561        return 'CursorKind.{0}'.format(self.name)
562
563# FIXME: Is there a nicer way to expose this enumeration? We could potentially
564# represent the nested structure, or even build a class hierarchy. The main
565# things we want for sure are (a) simple external access to kinds, (b) a place
566# to hang a description and name, (c) easy to keep in sync with Index.h.
567
568###
569# Declaration Kinds
570
571# A declaration whose specific kind is not exposed via this interface.
572#
573# Unexposed declarations have the same operations as any other kind of
574# declaration; one can extract their location information, spelling, find their
575# definitions, etc. However, the specific kind of the declaration is not
576# reported.
577CursorKind.UNEXPOSED_DECL = CursorKind(1)
578
579# A C or C++ struct.
580CursorKind.STRUCT_DECL = CursorKind(2)
581
582# A C or C++ union.
583CursorKind.UNION_DECL = CursorKind(3)
584
585# A C++ class.
586CursorKind.CLASS_DECL = CursorKind(4)
587
588# An enumeration.
589CursorKind.ENUM_DECL = CursorKind(5)
590
591# A field (in C) or non-static data member (in C++) in a struct, union, or C++
592# class.
593CursorKind.FIELD_DECL = CursorKind(6)
594
595# An enumerator constant.
596CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
597
598# A function.
599CursorKind.FUNCTION_DECL = CursorKind(8)
600
601# A variable.
602CursorKind.VAR_DECL = CursorKind(9)
603
604# A function or method parameter.
605CursorKind.PARM_DECL = CursorKind(10)
606
607# An Objective-C @interface.
608CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
609
610# An Objective-C @interface for a category.
611CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
612
613# An Objective-C @protocol declaration.
614CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
615
616# An Objective-C @property declaration.
617CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
618
619# An Objective-C instance variable.
620CursorKind.OBJC_IVAR_DECL = CursorKind(15)
621
622# An Objective-C instance method.
623CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
624
625# An Objective-C class method.
626CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
627
628# An Objective-C @implementation.
629CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
630
631# An Objective-C @implementation for a category.
632CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
633
634# A typedef.
635CursorKind.TYPEDEF_DECL = CursorKind(20)
636
637# A C++ class method.
638CursorKind.CXX_METHOD = CursorKind(21)
639
640# A C++ namespace.
641CursorKind.NAMESPACE = CursorKind(22)
642
643# A linkage specification, e.g. 'extern "C"'.
644CursorKind.LINKAGE_SPEC = CursorKind(23)
645
646# A C++ constructor.
647CursorKind.CONSTRUCTOR = CursorKind(24)
648
649# A C++ destructor.
650CursorKind.DESTRUCTOR = CursorKind(25)
651
652# A C++ conversion function.
653CursorKind.CONVERSION_FUNCTION = CursorKind(26)
654
655# A C++ template type parameter
656CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27)
657
658# A C++ non-type template paramater.
659CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28)
660
661# A C++ template template parameter.
662CursorKind.TEMPLATE_TEMPLATE_PARAMETER = CursorKind(29)
663
664# A C++ function template.
665CursorKind.FUNCTION_TEMPLATE = CursorKind(30)
666
667# A C++ class template.
668CursorKind.CLASS_TEMPLATE = CursorKind(31)
669
670# A C++ class template partial specialization.
671CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32)
672
673# A C++ namespace alias declaration.
674CursorKind.NAMESPACE_ALIAS = CursorKind(33)
675
676# A C++ using directive
677CursorKind.USING_DIRECTIVE = CursorKind(34)
678
679# A C++ using declaration
680CursorKind.USING_DECLARATION = CursorKind(35)
681
682# A Type alias decl.
683CursorKind.TYPE_ALIAS_DECL = CursorKind(36)
684
685# A Objective-C synthesize decl
686CursorKind.OBJC_SYNTHESIZE_DECL = CursorKind(37)
687
688# A Objective-C dynamic decl
689CursorKind.OBJC_DYNAMIC_DECL = CursorKind(38)
690
691# A C++ access specifier decl.
692CursorKind.CXX_ACCESS_SPEC_DECL = CursorKind(39)
693
694
695###
696# Reference Kinds
697
698CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
699CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
700CursorKind.OBJC_CLASS_REF = CursorKind(42)
701
702# A reference to a type declaration.
703#
704# A type reference occurs anywhere where a type is named but not
705# declared. For example, given:
706#   typedef unsigned size_type;
707#   size_type size;
708#
709# The typedef is a declaration of size_type (CXCursor_TypedefDecl),
710# while the type of the variable "size" is referenced. The cursor
711# referenced by the type of size is the typedef for size_type.
712CursorKind.TYPE_REF = CursorKind(43)
713CursorKind.CXX_BASE_SPECIFIER = CursorKind(44)
714
715# A reference to a class template, function template, template
716# template parameter, or class template partial specialization.
717CursorKind.TEMPLATE_REF = CursorKind(45)
718
719# A reference to a namespace or namepsace alias.
720CursorKind.NAMESPACE_REF = CursorKind(46)
721
722# A reference to a member of a struct, union, or class that occurs in
723# some non-expression context, e.g., a designated initializer.
724CursorKind.MEMBER_REF = CursorKind(47)
725
726# A reference to a labeled statement.
727CursorKind.LABEL_REF = CursorKind(48)
728
729# A reference toa a set of overloaded functions or function templates
730# that has not yet been resolved to a specific function or function template.
731CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
732
733###
734# Invalid/Error Kinds
735
736CursorKind.INVALID_FILE = CursorKind(70)
737CursorKind.NO_DECL_FOUND = CursorKind(71)
738CursorKind.NOT_IMPLEMENTED = CursorKind(72)
739CursorKind.INVALID_CODE = CursorKind(73)
740
741###
742# Expression Kinds
743
744# An expression whose specific kind is not exposed via this interface.
745#
746# Unexposed expressions have the same operations as any other kind of
747# expression; one can extract their location information, spelling, children,
748# etc. However, the specific kind of the expression is not reported.
749CursorKind.UNEXPOSED_EXPR = CursorKind(100)
750
751# An expression that refers to some value declaration, such as a function,
752# varible, or enumerator.
753CursorKind.DECL_REF_EXPR = CursorKind(101)
754
755# An expression that refers to a member of a struct, union, class, Objective-C
756# class, etc.
757CursorKind.MEMBER_REF_EXPR = CursorKind(102)
758
759# An expression that calls a function.
760CursorKind.CALL_EXPR = CursorKind(103)
761
762# An expression that sends a message to an Objective-C object or class.
763CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
764
765# An expression that represents a block literal.
766CursorKind.BLOCK_EXPR = CursorKind(105)
767
768# An integer literal.
769CursorKind.INTEGER_LITERAL = CursorKind(106)
770
771# A floating point number literal.
772CursorKind.FLOATING_LITERAL = CursorKind(107)
773
774# An imaginary number literal.
775CursorKind.IMAGINARY_LITERAL = CursorKind(108)
776
777# A string literal.
778CursorKind.STRING_LITERAL = CursorKind(109)
779
780# A character literal.
781CursorKind.CHARACTER_LITERAL = CursorKind(110)
782
783# A parenthesized expression, e.g. "(1)".
784#
785# This AST node is only formed if full location information is requested.
786CursorKind.PAREN_EXPR = CursorKind(111)
787
788# This represents the unary-expression's (except sizeof and
789# alignof).
790CursorKind.UNARY_OPERATOR = CursorKind(112)
791
792# [C99 6.5.2.1] Array Subscripting.
793CursorKind.ARRAY_SUBSCRIPT_EXPR = CursorKind(113)
794
795# A builtin binary operation expression such as "x + y" or
796# "x <= y".
797CursorKind.BINARY_OPERATOR = CursorKind(114)
798
799# Compound assignment such as "+=".
800CursorKind.COMPOUND_ASSIGNMENT_OPERATOR = CursorKind(115)
801
802# The ?: ternary operator.
803CursorKind.CONDITIONAL_OPERATOR = CursorKind(116)
804
805# An explicit cast in C (C99 6.5.4) or a C-style cast in C++
806# (C++ [expr.cast]), which uses the syntax (Type)expr.
807#
808# For example: (int)f.
809CursorKind.CSTYLE_CAST_EXPR = CursorKind(117)
810
811# [C99 6.5.2.5]
812CursorKind.COMPOUND_LITERAL_EXPR = CursorKind(118)
813
814# Describes an C or C++ initializer list.
815CursorKind.INIT_LIST_EXPR = CursorKind(119)
816
817# The GNU address of label extension, representing &&label.
818CursorKind.ADDR_LABEL_EXPR = CursorKind(120)
819
820# This is the GNU Statement Expression extension: ({int X=4; X;})
821CursorKind.StmtExpr = CursorKind(121)
822
823# Represents a C11 generic selection.
824CursorKind.GENERIC_SELECTION_EXPR = CursorKind(122)
825
826# Implements the GNU __null extension, which is a name for a null
827# pointer constant that has integral type (e.g., int or long) and is the same
828# size and alignment as a pointer.
829#
830# The __null extension is typically only used by system headers, which define
831# NULL as __null in C++ rather than using 0 (which is an integer that may not
832# match the size of a pointer).
833CursorKind.GNU_NULL_EXPR = CursorKind(123)
834
835# C++'s static_cast<> expression.
836CursorKind.CXX_STATIC_CAST_EXPR = CursorKind(124)
837
838# C++'s dynamic_cast<> expression.
839CursorKind.CXX_DYNAMIC_CAST_EXPR = CursorKind(125)
840
841# C++'s reinterpret_cast<> expression.
842CursorKind.CXX_REINTERPRET_CAST_EXPR = CursorKind(126)
843
844# C++'s const_cast<> expression.
845CursorKind.CXX_CONST_CAST_EXPR = CursorKind(127)
846
847# Represents an explicit C++ type conversion that uses "functional"
848# notion (C++ [expr.type.conv]).
849#
850# Example:
851# \code
852#   x = int(0.5);
853# \endcode
854CursorKind.CXX_FUNCTIONAL_CAST_EXPR = CursorKind(128)
855
856# A C++ typeid expression (C++ [expr.typeid]).
857CursorKind.CXX_TYPEID_EXPR = CursorKind(129)
858
859# [C++ 2.13.5] C++ Boolean Literal.
860CursorKind.CXX_BOOL_LITERAL_EXPR = CursorKind(130)
861
862# [C++0x 2.14.7] C++ Pointer Literal.
863CursorKind.CXX_NULL_PTR_LITERAL_EXPR = CursorKind(131)
864
865# Represents the "this" expression in C++
866CursorKind.CXX_THIS_EXPR = CursorKind(132)
867
868# [C++ 15] C++ Throw Expression.
869#
870# This handles 'throw' and 'throw' assignment-expression. When
871# assignment-expression isn't present, Op will be null.
872CursorKind.CXX_THROW_EXPR = CursorKind(133)
873
874# A new expression for memory allocation and constructor calls, e.g:
875# "new CXXNewExpr(foo)".
876CursorKind.CXX_NEW_EXPR = CursorKind(134)
877
878# A delete expression for memory deallocation and destructor calls,
879# e.g. "delete[] pArray".
880CursorKind.CXX_DELETE_EXPR = CursorKind(135)
881
882# Represents a unary expression.
883CursorKind.CXX_UNARY_EXPR = CursorKind(136)
884
885# ObjCStringLiteral, used for Objective-C string literals i.e. "foo".
886CursorKind.OBJC_STRING_LITERAL = CursorKind(137)
887
888# ObjCEncodeExpr, used for in Objective-C.
889CursorKind.OBJC_ENCODE_EXPR = CursorKind(138)
890
891# ObjCSelectorExpr used for in Objective-C.
892CursorKind.OBJC_SELECTOR_EXPR = CursorKind(139)
893
894# Objective-C's protocol expression.
895CursorKind.OBJC_PROTOCOL_EXPR = CursorKind(140)
896
897# An Objective-C "bridged" cast expression, which casts between
898# Objective-C pointers and C pointers, transferring ownership in the process.
899#
900# \code
901#   NSString *str = (__bridge_transfer NSString *)CFCreateString();
902# \endcode
903CursorKind.OBJC_BRIDGE_CAST_EXPR = CursorKind(141)
904
905# Represents a C++0x pack expansion that produces a sequence of
906# expressions.
907#
908# A pack expansion expression contains a pattern (which itself is an
909# expression) followed by an ellipsis. For example:
910CursorKind.PACK_EXPANSION_EXPR = CursorKind(142)
911
912# Represents an expression that computes the length of a parameter
913# pack.
914CursorKind.SIZE_OF_PACK_EXPR = CursorKind(143)
915
916# A statement whose specific kind is not exposed via this interface.
917#
918# Unexposed statements have the same operations as any other kind of statement;
919# one can extract their location information, spelling, children, etc. However,
920# the specific kind of the statement is not reported.
921CursorKind.UNEXPOSED_STMT = CursorKind(200)
922
923# A labelled statement in a function.
924CursorKind.LABEL_STMT = CursorKind(201)
925
926# A compound statement
927CursorKind.COMPOUND_STMT = CursorKind(202)
928
929# A case statement.
930CursorKind.CASE_STMT = CursorKind(203)
931
932# A default statement.
933CursorKind.DEFAULT_STMT = CursorKind(204)
934
935# An if statement.
936CursorKind.IF_STMT = CursorKind(205)
937
938# A switch statement.
939CursorKind.SWITCH_STMT = CursorKind(206)
940
941# A while statement.
942CursorKind.WHILE_STMT = CursorKind(207)
943
944# A do statement.
945CursorKind.DO_STMT = CursorKind(208)
946
947# A for statement.
948CursorKind.FOR_STMT = CursorKind(209)
949
950# A goto statement.
951CursorKind.GOTO_STMT = CursorKind(210)
952
953# An indirect goto statement.
954CursorKind.INDIRECT_GOTO_STMT = CursorKind(211)
955
956# A continue statement.
957CursorKind.CONTINUE_STMT = CursorKind(212)
958
959# A break statement.
960CursorKind.BREAK_STMT = CursorKind(213)
961
962# A return statement.
963CursorKind.RETURN_STMT = CursorKind(214)
964
965# A GNU-style inline assembler statement.
966CursorKind.ASM_STMT = CursorKind(215)
967
968# Objective-C's overall @try-@catch-@finally statement.
969CursorKind.OBJC_AT_TRY_STMT = CursorKind(216)
970
971# Objective-C's @catch statement.
972CursorKind.OBJC_AT_CATCH_STMT = CursorKind(217)
973
974# Objective-C's @finally statement.
975CursorKind.OBJC_AT_FINALLY_STMT = CursorKind(218)
976
977# Objective-C's @throw statement.
978CursorKind.OBJC_AT_THROW_STMT = CursorKind(219)
979
980# Objective-C's @synchronized statement.
981CursorKind.OBJC_AT_SYNCHRONIZED_STMT = CursorKind(220)
982
983# Objective-C's autorealease pool statement.
984CursorKind.OBJC_AUTORELEASE_POOL_STMT = CursorKind(221)
985
986# Objective-C's for collection statement.
987CursorKind.OBJC_FOR_COLLECTION_STMT = CursorKind(222)
988
989# C++'s catch statement.
990CursorKind.CXX_CATCH_STMT = CursorKind(223)
991
992# C++'s try statement.
993CursorKind.CXX_TRY_STMT = CursorKind(224)
994
995# C++'s for (* : *) statement.
996CursorKind.CXX_FOR_RANGE_STMT = CursorKind(225)
997
998# Windows Structured Exception Handling's try statement.
999CursorKind.SEH_TRY_STMT = CursorKind(226)
1000
1001# Windows Structured Exception Handling's except statement.
1002CursorKind.SEH_EXCEPT_STMT = CursorKind(227)
1003
1004# Windows Structured Exception Handling's finally statement.
1005CursorKind.SEH_FINALLY_STMT = CursorKind(228)
1006
1007# The null statement.
1008CursorKind.NULL_STMT = CursorKind(230)
1009
1010# Adaptor class for mixing declarations with statements and expressions.
1011CursorKind.DECL_STMT = CursorKind(231)
1012
1013###
1014# Other Kinds
1015
1016# Cursor that represents the translation unit itself.
1017#
1018# The translation unit cursor exists primarily to act as the root cursor for
1019# traversing the contents of a translation unit.
1020CursorKind.TRANSLATION_UNIT = CursorKind(300)
1021
1022###
1023# Attributes
1024
1025# An attribute whoe specific kind is note exposed via this interface
1026CursorKind.UNEXPOSED_ATTR = CursorKind(400)
1027
1028CursorKind.IB_ACTION_ATTR = CursorKind(401)
1029CursorKind.IB_OUTLET_ATTR = CursorKind(402)
1030CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403)
1031
1032CursorKind.CXX_FINAL_ATTR = CursorKind(404)
1033CursorKind.CXX_OVERRIDE_ATTR = CursorKind(405)
1034CursorKind.ANNOTATE_ATTR = CursorKind(406)
1035CursorKind.ASM_LABEL_ATTR = CursorKind(407)
1036
1037###
1038# Preprocessing
1039CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500)
1040CursorKind.MACRO_DEFINITION = CursorKind(501)
1041CursorKind.MACRO_INSTANTIATION = CursorKind(502)
1042CursorKind.INCLUSION_DIRECTIVE = CursorKind(503)
1043
1044### Cursors ###
1045
1046class Cursor(Structure):
1047    """
1048    The Cursor class represents a reference to an element within the AST. It
1049    acts as a kind of iterator.
1050    """
1051    _fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)]
1052
1053    @staticmethod
1054    def from_location(tu, location):
1055        # We store a reference to the TU in the instance so the TU won't get
1056        # collected before the cursor.
1057        cursor = conf.lib.clang_getCursor(tu, location)
1058        cursor._tu = tu
1059
1060        return cursor
1061
1062    def __eq__(self, other):
1063        return conf.lib.clang_equalCursors(self, other)
1064
1065    def __ne__(self, other):
1066        return not self.__eq__(other)
1067
1068    def is_definition(self):
1069        """
1070        Returns true if the declaration pointed at by the cursor is also a
1071        definition of that entity.
1072        """
1073        return conf.lib.clang_isCursorDefinition(self)
1074
1075    def is_static_method(self):
1076        """Returns True if the cursor refers to a C++ member function or member
1077        function template that is declared 'static'.
1078        """
1079        return conf.lib.clang_CXXMethod_isStatic(self)
1080
1081    def get_definition(self):
1082        """
1083        If the cursor is a reference to a declaration or a declaration of
1084        some entity, return a cursor that points to the definition of that
1085        entity.
1086        """
1087        # TODO: Should probably check that this is either a reference or
1088        # declaration prior to issuing the lookup.
1089        return conf.lib.clang_getCursorDefinition(self)
1090
1091    def get_referenced(self):
1092        return conf.lib.clang_getCursorReferenced(self)
1093
1094    def get_usr(self):
1095        """Return the Unified Symbol Resultion (USR) for the entity referenced
1096        by the given cursor (or None).
1097
1098        A Unified Symbol Resolution (USR) is a string that identifies a
1099        particular entity (function, class, variable, etc.) within a
1100        program. USRs can be compared across translation units to determine,
1101        e.g., when references in one translation refer to an entity defined in
1102        another translation unit."""
1103        return conf.lib.clang_getCursorUSR(self)
1104
1105    @property
1106    def kind(self):
1107        """Return the kind of this cursor."""
1108        return CursorKind.from_id(self._kind_id)
1109
1110    @property
1111    def spelling(self):
1112        """Return the spelling of the entity pointed at by the cursor."""
1113        if not self.kind.is_declaration():
1114            # FIXME: clang_getCursorSpelling should be fixed to not assert on
1115            # this, for consistency with clang_getCursorUSR.
1116            return None
1117        if not hasattr(self, '_spelling'):
1118            self._spelling = conf.lib.clang_getCursorSpelling(self)
1119
1120        return self._spelling
1121
1122    @property
1123    def displayname(self):
1124        """
1125        Return the display name for the entity referenced by this cursor.
1126
1127        The display name contains extra information that helps identify the cursor,
1128        such as the parameters of a function or template or the arguments of a
1129        class template specialization.
1130        """
1131        if not hasattr(self, '_displayname'):
1132            self._displayname = conf.lib.clang_getCursorDisplayName(self)
1133
1134        return self._displayname
1135
1136    @property
1137    def location(self):
1138        """
1139        Return the source location (the starting character) of the entity
1140        pointed at by the cursor.
1141        """
1142        if not hasattr(self, '_loc'):
1143            self._loc = conf.lib.clang_getCursorLocation(self)
1144
1145        return self._loc
1146
1147    @property
1148    def extent(self):
1149        """
1150        Return the source range (the range of text) occupied by the entity
1151        pointed at by the cursor.
1152        """
1153        if not hasattr(self, '_extent'):
1154            self._extent = conf.lib.clang_getCursorExtent(self)
1155
1156        return self._extent
1157
1158    @property
1159    def type(self):
1160        """
1161        Retrieve the Type (if any) of the entity pointed at by the cursor.
1162        """
1163        if not hasattr(self, '_type'):
1164            self._type = conf.lib.clang_getCursorType(self)
1165
1166        return self._type
1167
1168    @property
1169    def canonical(self):
1170        """Return the canonical Cursor corresponding to this Cursor.
1171
1172        The canonical cursor is the cursor which is representative for the
1173        underlying entity. For example, if you have multiple forward
1174        declarations for the same class, the canonical cursor for the forward
1175        declarations will be identical.
1176        """
1177        if not hasattr(self, '_canonical'):
1178            self._canonical = conf.lib.clang_getCanonicalCursor(self)
1179
1180        return self._canonical
1181
1182    @property
1183    def result_type(self):
1184        """Retrieve the Type of the result for this Cursor."""
1185        if not hasattr(self, '_result_type'):
1186            self._result_type = conf.lib.clang_getResultType(self.type)
1187
1188        return self._result_type
1189
1190    @property
1191    def underlying_typedef_type(self):
1192        """Return the underlying type of a typedef declaration.
1193
1194        Returns a Type for the typedef this cursor is a declaration for. If
1195        the current cursor is not a typedef, this raises.
1196        """
1197        if not hasattr(self, '_underlying_type'):
1198            assert self.kind.is_declaration()
1199            self._underlying_type = \
1200              conf.lib.clang_getTypedefDeclUnderlyingType(self)
1201
1202        return self._underlying_type
1203
1204    @property
1205    def enum_type(self):
1206        """Return the integer type of an enum declaration.
1207
1208        Returns a Type corresponding to an integer. If the cursor is not for an
1209        enum, this raises.
1210        """
1211        if not hasattr(self, '_enum_type'):
1212            assert self.kind == CursorKind.ENUM_DECL
1213            self._enum_type = conf.lib.clang_getEnumDeclIntegerType(self)
1214
1215        return self._enum_type
1216
1217    @property
1218    def enum_value(self):
1219        """Return the value of an enum constant."""
1220        if not hasattr(self, '_enum_value'):
1221            assert self.kind == CursorKind.ENUM_CONSTANT_DECL
1222            # Figure out the underlying type of the enum to know if it
1223            # is a signed or unsigned quantity.
1224            underlying_type = self.type
1225            if underlying_type.kind == TypeKind.ENUM:
1226                underlying_type = underlying_type.get_declaration().enum_type
1227            if underlying_type.kind in (TypeKind.CHAR_U,
1228                                        TypeKind.UCHAR,
1229                                        TypeKind.CHAR16,
1230                                        TypeKind.CHAR32,
1231                                        TypeKind.USHORT,
1232                                        TypeKind.UINT,
1233                                        TypeKind.ULONG,
1234                                        TypeKind.ULONGLONG,
1235                                        TypeKind.UINT128):
1236                self._enum_value = \
1237                  conf.lib.clang_getEnumConstantDeclUnsignedValue(self)
1238            else:
1239                self._enum_value = conf.lib.clang_getEnumConstantDeclValue(self)
1240        return self._enum_value
1241
1242    @property
1243    def objc_type_encoding(self):
1244        """Return the Objective-C type encoding as a str."""
1245        if not hasattr(self, '_objc_type_encoding'):
1246            self._objc_type_encoding = \
1247              conf.lib.clang_getDeclObjCTypeEncoding(self)
1248
1249        return self._objc_type_encoding
1250
1251    @property
1252    def hash(self):
1253        """Returns a hash of the cursor as an int."""
1254        if not hasattr(self, '_hash'):
1255            self._hash = conf.lib.clang_hashCursor(self)
1256
1257        return self._hash
1258
1259    @property
1260    def semantic_parent(self):
1261        """Return the semantic parent for this cursor."""
1262        if not hasattr(self, '_semantic_parent'):
1263            self._semantic_parent = conf.lib.clang_getCursorSemanticParent(self)
1264
1265        return self._semantic_parent
1266
1267    @property
1268    def lexical_parent(self):
1269        """Return the lexical parent for this cursor."""
1270        if not hasattr(self, '_lexical_parent'):
1271            self._lexical_parent = conf.lib.clang_getCursorLexicalParent(self)
1272
1273        return self._lexical_parent
1274
1275    @property
1276    def translation_unit(self):
1277        """Returns the TranslationUnit to which this Cursor belongs."""
1278        # If this triggers an AttributeError, the instance was not properly
1279        # created.
1280        return self._tu
1281
1282    def get_arguments(self):
1283        """Return an iterator for accessing the arguments of this cursor."""
1284        num_args = conf.lib.clang_Cursor_getNumArguments(self)
1285        for i in range(0, num_args):
1286            yield conf.lib.clang_Cursor_getArgument(self, i)
1287
1288    def get_children(self):
1289        """Return an iterator for accessing the children of this cursor."""
1290
1291        # FIXME: Expose iteration from CIndex, PR6125.
1292        def visitor(child, parent, children):
1293            # FIXME: Document this assertion in API.
1294            # FIXME: There should just be an isNull method.
1295            assert child != conf.lib.clang_getNullCursor()
1296
1297            # Create reference to TU so it isn't GC'd before Cursor.
1298            child._tu = self._tu
1299            children.append(child)
1300            return 1 # continue
1301        children = []
1302        conf.lib.clang_visitChildren(self, callbacks['cursor_visit'](visitor),
1303            children)
1304        return iter(children)
1305
1306    def get_tokens(self):
1307        """Obtain Token instances formulating that compose this Cursor.
1308
1309        This is a generator for Token instances. It returns all tokens which
1310        occupy the extent this cursor occupies.
1311        """
1312        return TokenGroup.get_tokens(self._tu, self.extent)
1313
1314    @staticmethod
1315    def from_result(res, fn, args):
1316        assert isinstance(res, Cursor)
1317        # FIXME: There should just be an isNull method.
1318        if res == conf.lib.clang_getNullCursor():
1319            return None
1320
1321        # Store a reference to the TU in the Python object so it won't get GC'd
1322        # before the Cursor.
1323        tu = None
1324        for arg in args:
1325            if isinstance(arg, TranslationUnit):
1326                tu = arg
1327                break
1328
1329            if hasattr(arg, 'translation_unit'):
1330                tu = arg.translation_unit
1331                break
1332
1333        assert tu is not None
1334
1335        res._tu = tu
1336        return res
1337
1338    @staticmethod
1339    def from_cursor_result(res, fn, args):
1340        assert isinstance(res, Cursor)
1341        if res == conf.lib.clang_getNullCursor():
1342            return None
1343
1344        res._tu = args[0]._tu
1345        return res
1346
1347### Type Kinds ###
1348
1349class TypeKind(object):
1350    """
1351    Describes the kind of type.
1352    """
1353
1354    # The unique kind objects, indexed by id.
1355    _kinds = []
1356    _name_map = None
1357
1358    def __init__(self, value):
1359        if value >= len(TypeKind._kinds):
1360            TypeKind._kinds += [None] * (value - len(TypeKind._kinds) + 1)
1361        if TypeKind._kinds[value] is not None:
1362            raise ValueError('TypeKind already loaded')
1363        self.value = value
1364        TypeKind._kinds[value] = self
1365        TypeKind._name_map = None
1366
1367    def from_param(self):
1368        return self.value
1369
1370    @property
1371    def name(self):
1372        """Get the enumeration name of this cursor kind."""
1373        if self._name_map is None:
1374            self._name_map = {}
1375            for key,value in TypeKind.__dict__.items():
1376                if isinstance(value,TypeKind):
1377                    self._name_map[value] = key
1378        return self._name_map[self]
1379
1380    @property
1381    def spelling(self):
1382        """Retrieve the spelling of this TypeKind."""
1383        return conf.lib.clang_getTypeKindSpelling(self.value)
1384
1385    @staticmethod
1386    def from_id(id):
1387        if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None:
1388            raise ValueError('Unknown type kind {0}'.format(id))
1389        return TypeKind._kinds[id]
1390
1391    def __repr__(self):
1392        return 'TypeKind.{0}'.format(self.name)
1393
1394TypeKind.INVALID = TypeKind(0)
1395TypeKind.UNEXPOSED = TypeKind(1)
1396TypeKind.VOID = TypeKind(2)
1397TypeKind.BOOL = TypeKind(3)
1398TypeKind.CHAR_U = TypeKind(4)
1399TypeKind.UCHAR = TypeKind(5)
1400TypeKind.CHAR16 = TypeKind(6)
1401TypeKind.CHAR32 = TypeKind(7)
1402TypeKind.USHORT = TypeKind(8)
1403TypeKind.UINT = TypeKind(9)
1404TypeKind.ULONG = TypeKind(10)
1405TypeKind.ULONGLONG = TypeKind(11)
1406TypeKind.UINT128 = TypeKind(12)
1407TypeKind.CHAR_S = TypeKind(13)
1408TypeKind.SCHAR = TypeKind(14)
1409TypeKind.WCHAR = TypeKind(15)
1410TypeKind.SHORT = TypeKind(16)
1411TypeKind.INT = TypeKind(17)
1412TypeKind.LONG = TypeKind(18)
1413TypeKind.LONGLONG = TypeKind(19)
1414TypeKind.INT128 = TypeKind(20)
1415TypeKind.FLOAT = TypeKind(21)
1416TypeKind.DOUBLE = TypeKind(22)
1417TypeKind.LONGDOUBLE = TypeKind(23)
1418TypeKind.NULLPTR = TypeKind(24)
1419TypeKind.OVERLOAD = TypeKind(25)
1420TypeKind.DEPENDENT = TypeKind(26)
1421TypeKind.OBJCID = TypeKind(27)
1422TypeKind.OBJCCLASS = TypeKind(28)
1423TypeKind.OBJCSEL = TypeKind(29)
1424TypeKind.COMPLEX = TypeKind(100)
1425TypeKind.POINTER = TypeKind(101)
1426TypeKind.BLOCKPOINTER = TypeKind(102)
1427TypeKind.LVALUEREFERENCE = TypeKind(103)
1428TypeKind.RVALUEREFERENCE = TypeKind(104)
1429TypeKind.RECORD = TypeKind(105)
1430TypeKind.ENUM = TypeKind(106)
1431TypeKind.TYPEDEF = TypeKind(107)
1432TypeKind.OBJCINTERFACE = TypeKind(108)
1433TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
1434TypeKind.FUNCTIONNOPROTO = TypeKind(110)
1435TypeKind.FUNCTIONPROTO = TypeKind(111)
1436TypeKind.CONSTANTARRAY = TypeKind(112)
1437TypeKind.VECTOR = TypeKind(113)
1438
1439class Type(Structure):
1440    """
1441    The type of an element in the abstract syntax tree.
1442    """
1443    _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)]
1444
1445    @property
1446    def kind(self):
1447        """Return the kind of this type."""
1448        return TypeKind.from_id(self._kind_id)
1449
1450    def argument_types(self):
1451        """Retrieve a container for the non-variadic arguments for this type.
1452
1453        The returned object is iterable and indexable. Each item in the
1454        container is a Type instance.
1455        """
1456        class ArgumentsIterator(collections.Sequence):
1457            def __init__(self, parent):
1458                self.parent = parent
1459                self.length = None
1460
1461            def __len__(self):
1462                if self.length is None:
1463                    self.length = conf.lib.clang_getNumArgTypes(self.parent)
1464
1465                return self.length
1466
1467            def __getitem__(self, key):
1468                # FIXME Support slice objects.
1469                if not isinstance(key, int):
1470                    raise TypeError("Must supply a non-negative int.")
1471
1472                if key < 0:
1473                    raise IndexError("Only non-negative indexes are accepted.")
1474
1475                if key >= len(self):
1476                    raise IndexError("Index greater than container length: "
1477                                     "{0} > {1}".format(key, len(self)))
1478
1479                result = conf.lib.clang_getArgType(self.parent, key)
1480                if result.kind == TypeKind.INVALID:
1481                    raise IndexError("Argument could not be retrieved.")
1482
1483                return result
1484
1485        assert self.kind == TypeKind.FUNCTIONPROTO
1486        return ArgumentsIterator(self)
1487
1488    @property
1489    def element_type(self):
1490        """Retrieve the Type of elements within this Type.
1491
1492        If accessed on a type that is not an array, complex, or vector type, an
1493        exception will be raised.
1494        """
1495        result = conf.lib.clang_getElementType(self)
1496        if result.kind == TypeKind.INVALID:
1497            raise Exception('Element type not available on this type.')
1498
1499        return result
1500
1501    @property
1502    def element_count(self):
1503        """Retrieve the number of elements in this type.
1504
1505        Returns an int.
1506
1507        If the Type is not an array or vector, this raises.
1508        """
1509        result = conf.lib.clang_getNumElements(self)
1510        if result < 0:
1511            raise Exception('Type does not have elements.')
1512
1513        return result
1514
1515    @property
1516    def translation_unit(self):
1517        """The TranslationUnit to which this Type is associated."""
1518        # If this triggers an AttributeError, the instance was not properly
1519        # instantiated.
1520        return self._tu
1521
1522    @staticmethod
1523    def from_result(res, fn, args):
1524        assert isinstance(res, Type)
1525
1526        tu = None
1527        for arg in args:
1528            if hasattr(arg, 'translation_unit'):
1529                tu = arg.translation_unit
1530                break
1531
1532        assert tu is not None
1533        res._tu = tu
1534
1535        return res
1536
1537    def get_canonical(self):
1538        """
1539        Return the canonical type for a Type.
1540
1541        Clang's type system explicitly models typedefs and all the
1542        ways a specific type can be represented.  The canonical type
1543        is the underlying type with all the "sugar" removed.  For
1544        example, if 'T' is a typedef for 'int', the canonical type for
1545        'T' would be 'int'.
1546        """
1547        return conf.lib.clang_getCanonicalType(self)
1548
1549    def is_const_qualified(self):
1550        """Determine whether a Type has the "const" qualifier set.
1551
1552        This does not look through typedefs that may have added "const"
1553        at a different level.
1554        """
1555        return conf.lib.clang_isConstQualifiedType(self)
1556
1557    def is_volatile_qualified(self):
1558        """Determine whether a Type has the "volatile" qualifier set.
1559
1560        This does not look through typedefs that may have added "volatile"
1561        at a different level.
1562        """
1563        return conf.lib.clang_isVolatileQualifiedType(self)
1564
1565    def is_restrict_qualified(self):
1566        """Determine whether a Type has the "restrict" qualifier set.
1567
1568        This does not look through typedefs that may have added "restrict" at
1569        a different level.
1570        """
1571        return conf.lib.clang_isRestrictQualifiedType(self)
1572
1573    def is_function_variadic(self):
1574        """Determine whether this function Type is a variadic function type."""
1575        assert self.kind == TypeKind.FUNCTIONPROTO
1576
1577        return conf.lib.clang_isFunctionTypeVariadic(self)
1578
1579    def is_pod(self):
1580        """Determine whether this Type represents plain old data (POD)."""
1581        return conf.lib.clang_isPODType(self)
1582
1583    def get_pointee(self):
1584        """
1585        For pointer types, returns the type of the pointee.
1586        """
1587        return conf.lib.clang_getPointeeType(self)
1588
1589    def get_declaration(self):
1590        """
1591        Return the cursor for the declaration of the given type.
1592        """
1593        return conf.lib.clang_getTypeDeclaration(self)
1594
1595    def get_result(self):
1596        """
1597        Retrieve the result type associated with a function type.
1598        """
1599        return conf.lib.clang_getResultType(self)
1600
1601    def get_array_element_type(self):
1602        """
1603        Retrieve the type of the elements of the array type.
1604        """
1605        return conf.lib.clang_getArrayElementType(self)
1606
1607    def get_array_size(self):
1608        """
1609        Retrieve the size of the constant array.
1610        """
1611        return conf.lib.clang_getArraySize(self)
1612
1613    def __eq__(self, other):
1614        if type(other) != type(self):
1615            return False
1616
1617        return conf.lib.clang_equalTypes(self, other)
1618
1619    def __ne__(self, other):
1620        return not self.__eq__(other)
1621
1622## CIndex Objects ##
1623
1624# CIndex objects (derived from ClangObject) are essentially lightweight
1625# wrappers attached to some underlying object, which is exposed via CIndex as
1626# a void*.
1627
1628class ClangObject(object):
1629    """
1630    A helper for Clang objects. This class helps act as an intermediary for
1631    the ctypes library and the Clang CIndex library.
1632    """
1633    def __init__(self, obj):
1634        assert isinstance(obj, c_object_p) and obj
1635        self.obj = self._as_parameter_ = obj
1636
1637    def from_param(self):
1638        return self._as_parameter_
1639
1640
1641class _CXUnsavedFile(Structure):
1642    """Helper for passing unsaved file arguments."""
1643    _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
1644
1645class CompletionChunk:
1646    class Kind:
1647        def __init__(self, name):
1648            self.name = name
1649
1650        def __str__(self):
1651            return self.name
1652
1653        def __repr__(self):
1654            return "<ChunkKind: {0}>".format(self)
1655
1656    def __init__(self, completionString, key):
1657        self.cs = completionString
1658        self.key = key
1659
1660    def __repr__(self):
1661        return "{'" + self.spelling + "', " + str(self.kind) + "}"
1662
1663    @CachedProperty
1664    def spelling(self):
1665        return conf.lib.clang_getCompletionChunkText(self.cs, self.key).spelling
1666
1667    @CachedProperty
1668    def kind(self):
1669        res = conf.lib.clang_getCompletionChunkKind(self.cs, self.key)
1670        return completionChunkKindMap[res]
1671
1672    @CachedProperty
1673    def string(self):
1674        res = conf.lib.clang_getCompletionChunkCompletionString(self.cs,
1675                                                                self.key)
1676
1677        if (res):
1678          return CompletionString(res)
1679        else:
1680          None
1681
1682    def isKindOptional(self):
1683      return self.kind == completionChunkKindMap[0]
1684
1685    def isKindTypedText(self):
1686      return self.kind == completionChunkKindMap[1]
1687
1688    def isKindPlaceHolder(self):
1689      return self.kind == completionChunkKindMap[3]
1690
1691    def isKindInformative(self):
1692      return self.kind == completionChunkKindMap[4]
1693
1694    def isKindResultType(self):
1695      return self.kind == completionChunkKindMap[15]
1696
1697completionChunkKindMap = {
1698            0: CompletionChunk.Kind("Optional"),
1699            1: CompletionChunk.Kind("TypedText"),
1700            2: CompletionChunk.Kind("Text"),
1701            3: CompletionChunk.Kind("Placeholder"),
1702            4: CompletionChunk.Kind("Informative"),
1703            5: CompletionChunk.Kind("CurrentParameter"),
1704            6: CompletionChunk.Kind("LeftParen"),
1705            7: CompletionChunk.Kind("RightParen"),
1706            8: CompletionChunk.Kind("LeftBracket"),
1707            9: CompletionChunk.Kind("RightBracket"),
1708            10: CompletionChunk.Kind("LeftBrace"),
1709            11: CompletionChunk.Kind("RightBrace"),
1710            12: CompletionChunk.Kind("LeftAngle"),
1711            13: CompletionChunk.Kind("RightAngle"),
1712            14: CompletionChunk.Kind("Comma"),
1713            15: CompletionChunk.Kind("ResultType"),
1714            16: CompletionChunk.Kind("Colon"),
1715            17: CompletionChunk.Kind("SemiColon"),
1716            18: CompletionChunk.Kind("Equal"),
1717            19: CompletionChunk.Kind("HorizontalSpace"),
1718            20: CompletionChunk.Kind("VerticalSpace")}
1719
1720class CompletionString(ClangObject):
1721    class Availability:
1722        def __init__(self, name):
1723            self.name = name
1724
1725        def __str__(self):
1726            return self.name
1727
1728        def __repr__(self):
1729            return "<Availability: {0}>".format(self)
1730
1731    def __len__(self):
1732        self.num_chunks
1733
1734    @CachedProperty
1735    def num_chunks(self):
1736        return conf.lib.clang_getNumCompletionChunks(self.obj)
1737
1738    def __getitem__(self, key):
1739        if self.num_chunks <= key:
1740            raise IndexError
1741        return CompletionChunk(self.obj, key)
1742
1743    @property
1744    def priority(self):
1745        return conf.lib.clang_getCompletionPriority(self.obj)
1746
1747    @property
1748    def availability(self):
1749        res = conf.lib.clang_getCompletionAvailability(self.obj)
1750        return availabilityKinds[res]
1751
1752    @property
1753    def briefComment(self):
1754        if conf.function_exists("clang_getCompletionBriefComment"):
1755            return conf.lib.clang_getCompletionBriefComment(self.obj)
1756        return _CXString()
1757
1758    def __repr__(self):
1759        return " | ".join([str(a) for a in self]) \
1760               + " || Priority: " + str(self.priority) \
1761               + " || Availability: " + str(self.availability) \
1762               + " || Brief comment: " + str(self.briefComment.spelling)
1763
1764availabilityKinds = {
1765            0: CompletionChunk.Kind("Available"),
1766            1: CompletionChunk.Kind("Deprecated"),
1767            2: CompletionChunk.Kind("NotAvailable"),
1768            3: CompletionChunk.Kind("NotAccessible")}
1769
1770class CodeCompletionResult(Structure):
1771    _fields_ = [('cursorKind', c_int), ('completionString', c_object_p)]
1772
1773    def __repr__(self):
1774        return str(CompletionString(self.completionString))
1775
1776    @property
1777    def kind(self):
1778        return CursorKind.from_id(self.cursorKind)
1779
1780    @property
1781    def string(self):
1782        return CompletionString(self.completionString)
1783
1784class CCRStructure(Structure):
1785    _fields_ = [('results', POINTER(CodeCompletionResult)),
1786                ('numResults', c_int)]
1787
1788    def __len__(self):
1789        return self.numResults
1790
1791    def __getitem__(self, key):
1792        if len(self) <= key:
1793            raise IndexError
1794
1795        return self.results[key]
1796
1797class CodeCompletionResults(ClangObject):
1798    def __init__(self, ptr):
1799        assert isinstance(ptr, POINTER(CCRStructure)) and ptr
1800        self.ptr = self._as_parameter_ = ptr
1801
1802    def from_param(self):
1803        return self._as_parameter_
1804
1805    def __del__(self):
1806        conf.lib.clang_disposeCodeCompleteResults(self)
1807
1808    @property
1809    def results(self):
1810        return self.ptr.contents
1811
1812    @property
1813    def diagnostics(self):
1814        class DiagnosticsItr:
1815            def __init__(self, ccr):
1816                self.ccr= ccr
1817
1818            def __len__(self):
1819                return int(\
1820                  conf.lib.clang_codeCompleteGetNumDiagnostics(self.ccr))
1821
1822            def __getitem__(self, key):
1823                return conf.lib.clang_codeCompleteGetDiagnostic(self.ccr, key)
1824
1825        return DiagnosticsItr(self)
1826
1827
1828class Index(ClangObject):
1829    """
1830    The Index type provides the primary interface to the Clang CIndex library,
1831    primarily by providing an interface for reading and parsing translation
1832    units.
1833    """
1834
1835    @staticmethod
1836    def create(excludeDecls=False):
1837        """
1838        Create a new Index.
1839        Parameters:
1840        excludeDecls -- Exclude local declarations from translation units.
1841        """
1842        return Index(conf.lib.clang_createIndex(excludeDecls, 0))
1843
1844    def __del__(self):
1845        conf.lib.clang_disposeIndex(self)
1846
1847    def read(self, path):
1848        """Load a TranslationUnit from the given AST file."""
1849        return TranslationUnit.from_ast(path, self)
1850
1851    def parse(self, path, args=None, unsaved_files=None, options = 0):
1852        """Load the translation unit from the given source code file by running
1853        clang and generating the AST before loading. Additional command line
1854        parameters can be passed to clang via the args parameter.
1855
1856        In-memory contents for files can be provided by passing a list of pairs
1857        to as unsaved_files, the first item should be the filenames to be mapped
1858        and the second should be the contents to be substituted for the
1859        file. The contents may be passed as strings or file objects.
1860
1861        If an error was encountered during parsing, a TranslationUnitLoadError
1862        will be raised.
1863        """
1864        return TranslationUnit.from_source(path, args, unsaved_files, options,
1865                                           self)
1866
1867class TranslationUnit(ClangObject):
1868    """Represents a source code translation unit.
1869
1870    This is one of the main types in the API. Any time you wish to interact
1871    with Clang's representation of a source file, you typically start with a
1872    translation unit.
1873    """
1874
1875    # Default parsing mode.
1876    PARSE_NONE = 0
1877
1878    # Instruct the parser to create a detailed processing record containing
1879    # metadata not normally retained.
1880    PARSE_DETAILED_PROCESSING_RECORD = 1
1881
1882    # Indicates that the translation unit is incomplete. This is typically used
1883    # when parsing headers.
1884    PARSE_INCOMPLETE = 2
1885
1886    # Instruct the parser to create a pre-compiled preamble for the translation
1887    # unit. This caches the preamble (included files at top of source file).
1888    # This is useful if the translation unit will be reparsed and you don't
1889    # want to incur the overhead of reparsing the preamble.
1890    PARSE_PRECOMPILED_PREAMBLE = 4
1891
1892    # Cache code completion information on parse. This adds time to parsing but
1893    # speeds up code completion.
1894    PARSE_CACHE_COMPLETION_RESULTS = 8
1895
1896    # Flags with values 16 and 32 are deprecated and intentionally omitted.
1897
1898    # Do not parse function bodies. This is useful if you only care about
1899    # searching for declarations/definitions.
1900    PARSE_SKIP_FUNCTION_BODIES = 64
1901
1902    # Used to indicate that brief documentation comments should be included
1903    # into the set of code completions returned from this translation unit.
1904    PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION = 128
1905
1906    @classmethod
1907    def from_source(cls, filename, args=None, unsaved_files=None, options=0,
1908                    index=None):
1909        """Create a TranslationUnit by parsing source.
1910
1911        This is capable of processing source code both from files on the
1912        filesystem as well as in-memory contents.
1913
1914        Command-line arguments that would be passed to clang are specified as
1915        a list via args. These can be used to specify include paths, warnings,
1916        etc. e.g. ["-Wall", "-I/path/to/include"].
1917
1918        In-memory file content can be provided via unsaved_files. This is an
1919        iterable of 2-tuples. The first element is the str filename. The
1920        second element defines the content. Content can be provided as str
1921        source code or as file objects (anything with a read() method). If
1922        a file object is being used, content will be read until EOF and the
1923        read cursor will not be reset to its original position.
1924
1925        options is a bitwise or of TranslationUnit.PARSE_XXX flags which will
1926        control parsing behavior.
1927
1928        index is an Index instance to utilize. If not provided, a new Index
1929        will be created for this TranslationUnit.
1930
1931        To parse source from the filesystem, the filename of the file to parse
1932        is specified by the filename argument. Or, filename could be None and
1933        the args list would contain the filename(s) to parse.
1934
1935        To parse source from an in-memory buffer, set filename to the virtual
1936        filename you wish to associate with this source (e.g. "test.c"). The
1937        contents of that file are then provided in unsaved_files.
1938
1939        If an error occurs, a TranslationUnitLoadError is raised.
1940
1941        Please note that a TranslationUnit with parser errors may be returned.
1942        It is the caller's responsibility to check tu.diagnostics for errors.
1943
1944        Also note that Clang infers the source language from the extension of
1945        the input filename. If you pass in source code containing a C++ class
1946        declaration with the filename "test.c" parsing will fail.
1947        """
1948        if args is None:
1949            args = []
1950
1951        if unsaved_files is None:
1952            unsaved_files = []
1953
1954        if index is None:
1955            index = Index.create()
1956
1957        args_array = None
1958        if len(args) > 0:
1959            args = [arg.encode('utf-8') if isinstance(arg, str) else arg
1960                    for arg in args]
1961            args_array = (c_char_p * len(args))(* args)
1962
1963        unsaved_files_array = 0
1964        if len(unsaved_files) > 0:
1965            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1966            for i, (name, contents) in enumerate(unsaved_files):
1967                if hasattr(contents, "read"):
1968                    contents = contents.read()
1969
1970                if isinstance(contents, str):
1971                    contents = contents.encode('utf-8')
1972
1973                if isinstance(name, str):
1974                    name = name.encode('utf-8')
1975
1976                unsaved_files_array[i].name = name
1977                unsaved_files_array[i].contents = contents
1978                unsaved_files_array[i].length = len(contents)
1979
1980        if isinstance(filename, str):
1981            filename = filename.encode('utf-8')
1982
1983        ptr = conf.lib.clang_parseTranslationUnit(index, filename, args_array,
1984                                    len(args), unsaved_files_array,
1985                                    len(unsaved_files), options)
1986
1987        if ptr is None:
1988            raise TranslationUnitLoadError("Error parsing translation unit.")
1989
1990        return cls(ptr, index=index)
1991
1992    @classmethod
1993    def from_ast_file(cls, filename, index=None):
1994        """Create a TranslationUnit instance from a saved AST file.
1995
1996        A previously-saved AST file (provided with -emit-ast or
1997        TranslationUnit.save()) is loaded from the filename specified.
1998
1999        If the file cannot be loaded, a TranslationUnitLoadError will be
2000        raised.
2001
2002        index is optional and is the Index instance to use. If not provided,
2003        a default Index will be created.
2004        """
2005        if index is None:
2006            index = Index.create()
2007
2008        if isinstance(filename, str):
2009            filename = filename.encode('utf-8')
2010
2011        ptr = conf.lib.clang_createTranslationUnit(index, filename)
2012        if ptr is None:
2013            raise TranslationUnitLoadError(filename)
2014
2015        return cls(ptr=ptr, index=index)
2016
2017    def __init__(self, ptr, index):
2018        """Create a TranslationUnit instance.
2019
2020        TranslationUnits should be created using one of the from_* @classmethod
2021        functions above. __init__ is only called internally.
2022        """
2023        assert isinstance(index, Index)
2024
2025        ClangObject.__init__(self, ptr)
2026
2027    def __del__(self):
2028        conf.lib.clang_disposeTranslationUnit(self)
2029
2030    @property
2031    def cursor(self):
2032        """Retrieve the cursor that represents the given translation unit."""
2033        return conf.lib.clang_getTranslationUnitCursor(self)
2034
2035    @property
2036    def spelling(self):
2037        """Get the original translation unit source file name."""
2038        return conf.lib.clang_getTranslationUnitSpelling(self)
2039
2040    def get_includes(self):
2041        """
2042        Return an iterable sequence of FileInclusion objects that describe the
2043        sequence of inclusions in a translation unit. The first object in
2044        this sequence is always the input file. Note that this method will not
2045        recursively iterate over header files included through precompiled
2046        headers.
2047        """
2048        def visitor(fobj, lptr, depth, includes):
2049            if depth > 0:
2050                loc = lptr.contents
2051                includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
2052
2053        # Automatically adapt CIndex/ctype pointers to python objects
2054        includes = []
2055        conf.lib.clang_getInclusions(self,
2056                callbacks['translation_unit_includes'](visitor), includes)
2057
2058        return iter(includes)
2059
2060    def get_file(self, filename):
2061        """Obtain a File from this translation unit."""
2062
2063        return File.from_name(self, filename)
2064
2065    def get_location(self, filename, position):
2066        """Obtain a SourceLocation for a file in this translation unit.
2067
2068        The position can be specified by passing:
2069
2070          - Integer file offset. Initial file offset is 0.
2071          - 2-tuple of (line number, column number). Initial file position is
2072            (0, 0)
2073        """
2074        f = self.get_file(filename)
2075
2076        if isinstance(position, int):
2077            return SourceLocation.from_offset(self, f, position)
2078
2079        return SourceLocation.from_position(self, f, position[0], position[1])
2080
2081    def get_extent(self, filename, locations):
2082        """Obtain a SourceRange from this translation unit.
2083
2084        The bounds of the SourceRange must ultimately be defined by a start and
2085        end SourceLocation. For the locations argument, you can pass:
2086
2087          - 2 SourceLocation instances in a 2-tuple or list.
2088          - 2 int file offsets via a 2-tuple or list.
2089          - 2 2-tuple or lists of (line, column) pairs in a 2-tuple or list.
2090
2091        e.g.
2092
2093        get_extent('foo.c', (5, 10))
2094        get_extent('foo.c', ((1, 1), (1, 15)))
2095        """
2096        f = self.get_file(filename)
2097
2098        if len(locations) < 2:
2099            raise Exception('Must pass object with at least 2 elements')
2100
2101        start_location, end_location = locations
2102
2103        if hasattr(start_location, '__len__'):
2104            start_location = SourceLocation.from_position(self, f,
2105                start_location[0], start_location[1])
2106        elif isinstance(start_location, int):
2107            start_location = SourceLocation.from_offset(self, f,
2108                start_location)
2109
2110        if hasattr(end_location, '__len__'):
2111            end_location = SourceLocation.from_position(self, f,
2112                end_location[0], end_location[1])
2113        elif isinstance(end_location, int):
2114            end_location = SourceLocation.from_offset(self, f, end_location)
2115
2116        assert isinstance(start_location, SourceLocation)
2117        assert isinstance(end_location, SourceLocation)
2118
2119        return SourceRange.from_locations(start_location, end_location)
2120
2121    @property
2122    def diagnostics(self):
2123        """
2124        Return an iterable (and indexable) object containing the diagnostics.
2125        """
2126        class DiagIterator:
2127            def __init__(self, tu):
2128                self.tu = tu
2129
2130            def __len__(self):
2131                return int(conf.lib.clang_getNumDiagnostics(self.tu))
2132
2133            def __getitem__(self, key):
2134                diag = conf.lib.clang_getDiagnostic(self.tu, key)
2135                if not diag:
2136                    raise IndexError
2137                return Diagnostic(diag)
2138
2139        return DiagIterator(self)
2140
2141    def reparse(self, unsaved_files=None, options=0):
2142        """
2143        Reparse an already parsed translation unit.
2144
2145        In-memory contents for files can be provided by passing a list of pairs
2146        as unsaved_files, the first items should be the filenames to be mapped
2147        and the second should be the contents to be substituted for the
2148        file. The contents may be passed as strings or file objects.
2149        """
2150        if unsaved_files is None:
2151            unsaved_files = []
2152
2153        unsaved_files_array = 0
2154        if len(unsaved_files):
2155            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
2156            for i, (name, contents) in enumerate(unsaved_files):
2157                if hasattr(contents, "read"):
2158                    contents = contents.read()
2159
2160                if isinstance(contents, str):
2161                    contents = contents.encode('utf-8')
2162
2163                if isinstance(name, str):
2164                    name = name.encode('utf-8')
2165
2166                unsaved_files_array[i].name = name
2167                unsaved_files_array[i].contents = contents
2168                unsaved_files_array[i].length = len(contents)
2169
2170        ptr = conf.lib.clang_reparseTranslationUnit(self, len(unsaved_files),
2171                unsaved_files_array, options)
2172
2173    def save(self, filename):
2174        """Saves the TranslationUnit to a file.
2175
2176        This is equivalent to passing -emit-ast to the clang frontend. The
2177        saved file can be loaded back into a TranslationUnit. Or, if it
2178        corresponds to a header, it can be used as a pre-compiled header file.
2179
2180        If an error occurs while saving, a TranslationUnitSaveError is raised.
2181        If the error was TranslationUnitSaveError.ERROR_INVALID_TU, this means
2182        the constructed TranslationUnit was not valid at time of save. In this
2183        case, the reason(s) why should be available via
2184        TranslationUnit.diagnostics().
2185
2186        filename -- The path to save the translation unit to.
2187        """
2188        options = conf.lib.clang_defaultSaveOptions(self)
2189
2190        if isinstance(filename, str):
2191            filename = filename.encode('utf-8')
2192
2193        result = int(conf.lib.clang_saveTranslationUnit(self, filename,
2194                                                        options))
2195        if result != 0:
2196            raise TranslationUnitSaveError(result,
2197                'Error saving TranslationUnit.')
2198
2199    def codeComplete(self, path, line, column, unsaved_files=None,
2200                     include_macros=False, include_code_patterns=False,
2201                     include_brief_comments=False):
2202        """
2203        Code complete in this translation unit.
2204
2205        In-memory contents for files can be provided by passing a list of pairs
2206        as unsaved_files, the first items should be the filenames to be mapped
2207        and the second should be the contents to be substituted for the
2208        file. The contents may be passed as strings or file objects.
2209        """
2210        options = 0
2211
2212        if include_macros:
2213            options += 1
2214
2215        if include_code_patterns:
2216            options += 2
2217
2218        if include_brief_comments:
2219            options += 4
2220
2221        if unsaved_files is None:
2222            unsaved_files = []
2223
2224        unsaved_files_array = 0
2225        if len(unsaved_files):
2226            unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
2227            for i, (name, contents) in enumerate(unsaved_files):
2228                if hasattr(contents, "read"):
2229                    contents = contents.read()
2230
2231                if isinstance(contents, str):
2232                    contents = contents.encode('utf-8')
2233
2234                if isinstance(name, str):
2235                    name = name.encode('utf-8')
2236
2237                unsaved_files_array[i].name = name
2238                unsaved_files_array[i].contents = contents
2239                unsaved_files_array[i].length = len(contents)
2240        ptr = conf.lib.clang_codeCompleteAt(self, path, line, column,
2241                unsaved_files_array, len(unsaved_files), options)
2242        if ptr:
2243            return CodeCompletionResults(ptr)
2244        return None
2245
2246    def get_tokens(self, locations=None, extent=None):
2247        """Obtain tokens in this translation unit.
2248
2249        This is a generator for Token instances. The caller specifies a range
2250        of source code to obtain tokens for. The range can be specified as a
2251        2-tuple of SourceLocation or as a SourceRange. If both are defined,
2252        behavior is undefined.
2253        """
2254        if locations is not None:
2255            extent = SourceRange(start=locations[0], end=locations[1])
2256
2257        return TokenGroup.get_tokens(self, extent)
2258
2259class File(ClangObject):
2260    """
2261    The File class represents a particular source file that is part of a
2262    translation unit.
2263    """
2264
2265    @staticmethod
2266    def from_name(translation_unit, file_name):
2267        """Retrieve a file handle within the given translation unit."""
2268        return File(conf.lib.clang_getFile(translation_unit, file_name))
2269
2270    @property
2271    def name(self):
2272        """Return the complete file and path name of the file."""
2273        return conf.lib.clang_getCString(conf.lib.clang_getFileName(self))
2274
2275    @property
2276    def time(self):
2277        """Return the last modification time of the file."""
2278        return conf.lib.clang_getFileTime(self)
2279
2280    def __bytes__(self):
2281        return self.name
2282
2283    def __repr__(self):
2284        return "<File: {0}>".format(self.name)
2285
2286    @staticmethod
2287    def from_cursor_result(res, fn, args):
2288        assert isinstance(res, File)
2289
2290        # Copy a reference to the TranslationUnit to prevent premature GC.
2291        res._tu = args[0]._tu
2292        return res
2293
2294class FileInclusion(object):
2295    """
2296    The FileInclusion class represents the inclusion of one source file by
2297    another via a '#include' directive or as the input file for the translation
2298    unit. This class provides information about the included file, the including
2299    file, the location of the '#include' directive and the depth of the included
2300    file in the stack. Note that the input file has depth 0.
2301    """
2302
2303    def __init__(self, src, tgt, loc, depth):
2304        self.source = src
2305        self.include = tgt
2306        self.location = loc
2307        self.depth = depth
2308
2309    @property
2310    def is_input_file(self):
2311        """True if the included file is the input file."""
2312        return self.depth == 0
2313
2314class CompilationDatabaseError(Exception):
2315    """Represents an error that occurred when working with a CompilationDatabase
2316
2317    Each error is associated to an enumerated value, accessible under
2318    e.cdb_error. Consumers can compare the value with one of the ERROR_
2319    constants in this class.
2320    """
2321
2322    # An unknown error occured
2323    ERROR_UNKNOWN = 0
2324
2325    # The database could not be loaded
2326    ERROR_CANNOTLOADDATABASE = 1
2327
2328    def __init__(self, enumeration, message):
2329        assert isinstance(enumeration, int)
2330
2331        if enumeration > 1:
2332            raise Exception("Encountered undefined CompilationDatabase error "
2333                            "constant: {0}. Please file a bug to have this "
2334                            "value supported.".format(enumeration))
2335
2336        self.cdb_error = enumeration
2337        Exception.__init__(self, 'Error {0}: {1}'.format(enumeration, message))
2338
2339class CompileCommand(object):
2340    """Represents the compile command used to build a file"""
2341    def __init__(self, cmd, ccmds):
2342        self.cmd = cmd
2343        # Keep a reference to the originating CompileCommands
2344        # to prevent garbage collection
2345        self.ccmds = ccmds
2346
2347    @property
2348    def directory(self):
2349        """Get the working directory for this CompileCommand"""
2350        return conf.lib.clang_CompileCommand_getDirectory(self.cmd)
2351
2352    @property
2353    def arguments(self):
2354        """
2355        Get an iterable object providing each argument in the
2356        command line for the compiler invocation as a _CXString.
2357
2358        Invariant : the first argument is the compiler executable
2359        """
2360        length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd)
2361        for i in range(length):
2362            yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
2363
2364class CompileCommands(object):
2365    """
2366    CompileCommands is an iterable object containing all CompileCommand
2367    that can be used for building a specific file.
2368    """
2369    def __init__(self, ccmds):
2370        self.ccmds = ccmds
2371
2372    def __del__(self):
2373        conf.lib.clang_CompileCommands_dispose(self.ccmds)
2374
2375    def __len__(self):
2376        return int(conf.lib.clang_CompileCommands_getSize(self.ccmds))
2377
2378    def __getitem__(self, i):
2379        cc = conf.lib.clang_CompileCommands_getCommand(self.ccmds, i)
2380        if not cc:
2381            raise IndexError
2382        return CompileCommand(cc, self)
2383
2384    @staticmethod
2385    def from_result(res, fn, args):
2386        if not res:
2387            return None
2388        return CompileCommands(res)
2389
2390class CompilationDatabase(ClangObject):
2391    """
2392    The CompilationDatabase is a wrapper class around
2393    clang::tooling::CompilationDatabase
2394
2395    It enables querying how a specific source file can be built.
2396    """
2397
2398    def __del__(self):
2399        conf.lib.clang_CompilationDatabase_dispose(self)
2400
2401    @staticmethod
2402    def from_result(res, fn, args):
2403        if not res:
2404            raise CompilationDatabaseError(0,
2405                                           "CompilationDatabase loading failed")
2406        return CompilationDatabase(res)
2407
2408    @staticmethod
2409    def fromDirectory(buildDir):
2410        """Builds a CompilationDatabase from the database found in buildDir"""
2411        errorCode = c_uint()
2412        try:
2413            cdb = conf.lib.clang_CompilationDatabase_fromDirectory(buildDir,
2414                byref(errorCode))
2415        except CompilationDatabaseError as e:
2416            raise CompilationDatabaseError(int(errorCode.value),
2417                                           "CompilationDatabase loading failed")
2418        return cdb
2419
2420    def getCompileCommands(self, filename):
2421        """
2422        Get an iterable object providing all the CompileCommands available to
2423        build filename. Returns None if filename is not found in the database.
2424        """
2425        return conf.lib.clang_CompilationDatabase_getCompileCommands(self,
2426                                                                     filename)
2427
2428class Token(Structure):
2429    """Represents a single token from the preprocessor.
2430
2431    Tokens are effectively segments of source code. Source code is first parsed
2432    into tokens before being converted into the AST and Cursors.
2433
2434    Tokens are obtained from parsed TranslationUnit instances. You currently
2435    can't create tokens manually.
2436    """
2437    _fields_ = [
2438        ('int_data', c_uint * 4),
2439        ('ptr_data', c_void_p)
2440    ]
2441
2442    @property
2443    def spelling(self):
2444        """The spelling of this token.
2445
2446        This is the textual representation of the token in source.
2447        """
2448        return conf.lib.clang_getTokenSpelling(self._tu, self)
2449
2450    @property
2451    def kind(self):
2452        """Obtain the TokenKind of the current token."""
2453        return TokenKind.from_value(conf.lib.clang_getTokenKind(self))
2454
2455    @property
2456    def location(self):
2457        """The SourceLocation this Token occurs at."""
2458        return conf.lib.clang_getTokenLocation(self._tu, self)
2459
2460    @property
2461    def extent(self):
2462        """The SourceRange this Token occupies."""
2463        return conf.lib.clang_getTokenExtent(self._tu, self)
2464
2465    @property
2466    def cursor(self):
2467        """The Cursor this Token corresponds to."""
2468        cursor = Cursor()
2469
2470        conf.lib.clang_annotateTokens(self._tu, byref(self), 1, byref(cursor))
2471
2472        return cursor
2473
2474# Now comes the plumbing to hook up the C library.
2475
2476# Register callback types in common container.
2477callbacks['translation_unit_includes'] = CFUNCTYPE(None, c_object_p,
2478        POINTER(SourceLocation), c_uint, py_object)
2479callbacks['cursor_visit'] = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
2480
2481# Functions strictly alphabetical order.
2482functionList = [
2483  ("clang_annotateTokens",
2484   [TranslationUnit, POINTER(Token), c_uint, POINTER(Cursor)]),
2485
2486  ("clang_CompilationDatabase_dispose",
2487   [c_object_p]),
2488
2489  ("clang_CompilationDatabase_fromDirectory",
2490   [c_char_p, POINTER(c_uint)],
2491   c_object_p,
2492   CompilationDatabase.from_result),
2493
2494  ("clang_CompilationDatabase_getCompileCommands",
2495   [c_object_p, c_char_p],
2496   c_object_p,
2497   CompileCommands.from_result),
2498
2499  ("clang_CompileCommands_dispose",
2500   [c_object_p]),
2501
2502  ("clang_CompileCommands_getCommand",
2503   [c_object_p, c_uint],
2504   c_object_p),
2505
2506  ("clang_CompileCommands_getSize",
2507   [c_object_p],
2508   c_uint),
2509
2510  ("clang_CompileCommand_getArg",
2511   [c_object_p, c_uint],
2512   _CXString,
2513   _CXString.from_result),
2514
2515  ("clang_CompileCommand_getDirectory",
2516   [c_object_p],
2517   _CXString,
2518   _CXString.from_result),
2519
2520  ("clang_CompileCommand_getNumArgs",
2521   [c_object_p],
2522   c_uint),
2523
2524  ("clang_codeCompleteAt",
2525   [TranslationUnit, c_char_p, c_int, c_int, c_void_p, c_int, c_int],
2526   POINTER(CCRStructure)),
2527
2528  ("clang_codeCompleteGetDiagnostic",
2529   [CodeCompletionResults, c_int],
2530   Diagnostic),
2531
2532  ("clang_codeCompleteGetNumDiagnostics",
2533   [CodeCompletionResults],
2534   c_int),
2535
2536  ("clang_createIndex",
2537   [c_int, c_int],
2538   c_object_p),
2539
2540  ("clang_createTranslationUnit",
2541   [Index, c_char_p],
2542   c_object_p),
2543
2544  ("clang_CXXMethod_isStatic",
2545   [Cursor],
2546   bool),
2547
2548  ("clang_CXXMethod_isVirtual",
2549   [Cursor],
2550   bool),
2551
2552  ("clang_defaultSaveOptions",
2553   [TranslationUnit],
2554   c_uint),
2555
2556  ("clang_disposeCodeCompleteResults",
2557   [CodeCompletionResults]),
2558
2559# ("clang_disposeCXTUResourceUsage",
2560#  [CXTUResourceUsage]),
2561
2562  ("clang_disposeDiagnostic",
2563   [Diagnostic]),
2564
2565  ("clang_defaultDiagnosticDisplayOptions",
2566   [],
2567   c_uint),
2568
2569  ("clang_formatDiagnostic",
2570   [Diagnostic, c_uint],
2571   _CXString,
2572   _CXString.from_result),
2573
2574  ("clang_disposeIndex",
2575   [Index]),
2576
2577  ("clang_disposeString",
2578   [_CXString]),
2579
2580  ("clang_disposeTokens",
2581   [TranslationUnit, POINTER(Token), c_uint]),
2582
2583  ("clang_disposeTranslationUnit",
2584   [TranslationUnit]),
2585
2586  ("clang_equalCursors",
2587   [Cursor, Cursor],
2588   bool),
2589
2590  ("clang_equalLocations",
2591   [SourceLocation, SourceLocation],
2592   bool),
2593
2594  ("clang_equalRanges",
2595   [SourceRange, SourceRange],
2596   bool),
2597
2598  ("clang_equalTypes",
2599   [Type, Type],
2600   bool),
2601
2602  ("clang_getArgType",
2603   [Type, c_uint],
2604   Type,
2605   Type.from_result),
2606
2607  ("clang_getArrayElementType",
2608   [Type],
2609   Type,
2610   Type.from_result),
2611
2612  ("clang_getArraySize",
2613   [Type],
2614   c_longlong),
2615
2616  ("clang_getCanonicalCursor",
2617   [Cursor],
2618   Cursor,
2619   Cursor.from_cursor_result),
2620
2621  ("clang_getCanonicalType",
2622   [Type],
2623   Type,
2624   Type.from_result),
2625
2626  ("clang_getCompletionAvailability",
2627   [c_void_p],
2628   c_int),
2629
2630  ("clang_getCompletionBriefComment",
2631   [c_void_p],
2632   _CXString),
2633
2634  ("clang_getCompletionChunkCompletionString",
2635   [c_void_p, c_int],
2636   c_object_p),
2637
2638  ("clang_getCompletionChunkKind",
2639   [c_void_p, c_int],
2640   c_int),
2641
2642  ("clang_getCompletionChunkText",
2643   [c_void_p, c_int],
2644   _CXString),
2645
2646  ("clang_getCompletionPriority",
2647   [c_void_p],
2648   c_int),
2649
2650  ("clang_getCString",
2651   [_CXString],
2652   c_char_p),
2653
2654  ("clang_getCursor",
2655   [TranslationUnit, SourceLocation],
2656   Cursor),
2657
2658  ("clang_getCursorDefinition",
2659   [Cursor],
2660   Cursor,
2661   Cursor.from_result),
2662
2663  ("clang_getCursorDisplayName",
2664   [Cursor],
2665   _CXString,
2666   _CXString.from_result),
2667
2668  ("clang_getCursorExtent",
2669   [Cursor],
2670   SourceRange),
2671
2672  ("clang_getCursorLexicalParent",
2673   [Cursor],
2674   Cursor,
2675   Cursor.from_cursor_result),
2676
2677  ("clang_getCursorLocation",
2678   [Cursor],
2679   SourceLocation),
2680
2681  ("clang_getCursorReferenced",
2682   [Cursor],
2683   Cursor,
2684   Cursor.from_result),
2685
2686  ("clang_getCursorReferenceNameRange",
2687   [Cursor, c_uint, c_uint],
2688   SourceRange),
2689
2690  ("clang_getCursorSemanticParent",
2691   [Cursor],
2692   Cursor,
2693   Cursor.from_cursor_result),
2694
2695  ("clang_getCursorSpelling",
2696   [Cursor],
2697   _CXString,
2698   _CXString.from_result),
2699
2700  ("clang_getCursorType",
2701   [Cursor],
2702   Type,
2703   Type.from_result),
2704
2705  ("clang_getCursorUSR",
2706   [Cursor],
2707   _CXString,
2708   _CXString.from_result),
2709
2710# ("clang_getCXTUResourceUsage",
2711#  [TranslationUnit],
2712#  CXTUResourceUsage),
2713
2714  ("clang_getCXXAccessSpecifier",
2715   [Cursor],
2716   c_uint),
2717
2718  ("clang_getDeclObjCTypeEncoding",
2719   [Cursor],
2720   _CXString,
2721   _CXString.from_result),
2722
2723  ("clang_getDiagnostic",
2724   [c_object_p, c_uint],
2725   c_object_p),
2726
2727  ("clang_getDiagnosticCategory",
2728   [Diagnostic],
2729   c_uint),
2730
2731  ("clang_getDiagnosticCategoryName",
2732   [c_uint],
2733   _CXString,
2734   _CXString.from_result),
2735
2736  ("clang_getDiagnosticFixIt",
2737   [Diagnostic, c_uint, POINTER(SourceRange)],
2738   _CXString,
2739   _CXString.from_result),
2740
2741  ("clang_getDiagnosticLocation",
2742   [Diagnostic],
2743   SourceLocation),
2744
2745  ("clang_getDiagnosticNumFixIts",
2746   [Diagnostic],
2747   c_uint),
2748
2749  ("clang_getDiagnosticNumRanges",
2750   [Diagnostic],
2751   c_uint),
2752
2753  ("clang_getDiagnosticOption",
2754   [Diagnostic, POINTER(_CXString)],
2755   _CXString,
2756   _CXString.from_result),
2757
2758  ("clang_getDiagnosticRange",
2759   [Diagnostic, c_uint],
2760   SourceRange),
2761
2762  ("clang_getDiagnosticSeverity",
2763   [Diagnostic],
2764   c_int),
2765
2766  ("clang_getDiagnosticSpelling",
2767   [Diagnostic],
2768   _CXString,
2769   _CXString.from_result),
2770
2771  ("clang_getElementType",
2772   [Type],
2773   Type,
2774   Type.from_result),
2775
2776  ("clang_getEnumConstantDeclUnsignedValue",
2777   [Cursor],
2778   c_ulonglong),
2779
2780  ("clang_getEnumConstantDeclValue",
2781   [Cursor],
2782   c_longlong),
2783
2784  ("clang_getEnumDeclIntegerType",
2785   [Cursor],
2786   Type,
2787   Type.from_result),
2788
2789  ("clang_getFile",
2790   [TranslationUnit, c_char_p],
2791   c_object_p),
2792
2793  ("clang_getFileName",
2794   [File],
2795   _CXString), # TODO go through _CXString.from_result?
2796
2797  ("clang_getFileTime",
2798   [File],
2799   c_uint),
2800
2801  ("clang_getIBOutletCollectionType",
2802   [Cursor],
2803   Type,
2804   Type.from_result),
2805
2806  ("clang_getIncludedFile",
2807   [Cursor],
2808   File,
2809   File.from_cursor_result),
2810
2811  ("clang_getInclusions",
2812   [TranslationUnit, callbacks['translation_unit_includes'], py_object]),
2813
2814  ("clang_getInstantiationLocation",
2815   [SourceLocation, POINTER(c_object_p), POINTER(c_uint), POINTER(c_uint),
2816    POINTER(c_uint)]),
2817
2818  ("clang_getLocation",
2819   [TranslationUnit, File, c_uint, c_uint],
2820   SourceLocation),
2821
2822  ("clang_getLocationForOffset",
2823   [TranslationUnit, File, c_uint],
2824   SourceLocation),
2825
2826  ("clang_getNullCursor",
2827   None,
2828   Cursor),
2829
2830  ("clang_getNumArgTypes",
2831   [Type],
2832   c_uint),
2833
2834  ("clang_getNumCompletionChunks",
2835   [c_void_p],
2836   c_int),
2837
2838  ("clang_getNumDiagnostics",
2839   [c_object_p],
2840   c_uint),
2841
2842  ("clang_getNumElements",
2843   [Type],
2844   c_longlong),
2845
2846  ("clang_getNumOverloadedDecls",
2847   [Cursor],
2848   c_uint),
2849
2850  ("clang_getOverloadedDecl",
2851   [Cursor, c_uint],
2852   Cursor,
2853   Cursor.from_cursor_result),
2854
2855  ("clang_getPointeeType",
2856   [Type],
2857   Type,
2858   Type.from_result),
2859
2860  ("clang_getRange",
2861   [SourceLocation, SourceLocation],
2862   SourceRange),
2863
2864  ("clang_getRangeEnd",
2865   [SourceRange],
2866   SourceLocation),
2867
2868  ("clang_getRangeStart",
2869   [SourceRange],
2870   SourceLocation),
2871
2872  ("clang_getResultType",
2873   [Type],
2874   Type,
2875   Type.from_result),
2876
2877  ("clang_getSpecializedCursorTemplate",
2878   [Cursor],
2879   Cursor,
2880   Cursor.from_cursor_result),
2881
2882  ("clang_getTemplateCursorKind",
2883   [Cursor],
2884   c_uint),
2885
2886  ("clang_getTokenExtent",
2887   [TranslationUnit, Token],
2888   SourceRange),
2889
2890  ("clang_getTokenKind",
2891   [Token],
2892   c_uint),
2893
2894  ("clang_getTokenLocation",
2895   [TranslationUnit, Token],
2896   SourceLocation),
2897
2898  ("clang_getTokenSpelling",
2899   [TranslationUnit, Token],
2900   _CXString,
2901   _CXString.from_result),
2902
2903  ("clang_getTranslationUnitCursor",
2904   [TranslationUnit],
2905   Cursor,
2906   Cursor.from_result),
2907
2908  ("clang_getTranslationUnitSpelling",
2909   [TranslationUnit],
2910   _CXString,
2911   _CXString.from_result),
2912
2913  ("clang_getTUResourceUsageName",
2914   [c_uint],
2915   c_char_p),
2916
2917  ("clang_getTypeDeclaration",
2918   [Type],
2919   Cursor,
2920   Cursor.from_result),
2921
2922  ("clang_getTypedefDeclUnderlyingType",
2923   [Cursor],
2924   Type,
2925   Type.from_result),
2926
2927  ("clang_getTypeKindSpelling",
2928   [c_uint],
2929   _CXString,
2930   _CXString.from_result),
2931
2932  ("clang_hashCursor",
2933   [Cursor],
2934   c_uint),
2935
2936  ("clang_isAttribute",
2937   [CursorKind],
2938   bool),
2939
2940  ("clang_isConstQualifiedType",
2941   [Type],
2942   bool),
2943
2944  ("clang_isCursorDefinition",
2945   [Cursor],
2946   bool),
2947
2948  ("clang_isDeclaration",
2949   [CursorKind],
2950   bool),
2951
2952  ("clang_isExpression",
2953   [CursorKind],
2954   bool),
2955
2956  ("clang_isFileMultipleIncludeGuarded",
2957   [TranslationUnit, File],
2958   bool),
2959
2960  ("clang_isFunctionTypeVariadic",
2961   [Type],
2962   bool),
2963
2964  ("clang_isInvalid",
2965   [CursorKind],
2966   bool),
2967
2968  ("clang_isPODType",
2969   [Type],
2970   bool),
2971
2972  ("clang_isPreprocessing",
2973   [CursorKind],
2974   bool),
2975
2976  ("clang_isReference",
2977   [CursorKind],
2978   bool),
2979
2980  ("clang_isRestrictQualifiedType",
2981   [Type],
2982   bool),
2983
2984  ("clang_isStatement",
2985   [CursorKind],
2986   bool),
2987
2988  ("clang_isTranslationUnit",
2989   [CursorKind],
2990   bool),
2991
2992  ("clang_isUnexposed",
2993   [CursorKind],
2994   bool),
2995
2996  ("clang_isVirtualBase",
2997   [Cursor],
2998   bool),
2999
3000  ("clang_isVolatileQualifiedType",
3001   [Type],
3002   bool),
3003
3004  ("clang_parseTranslationUnit",
3005   [Index, c_char_p, c_void_p, c_int, c_void_p, c_int, c_int],
3006   c_object_p),
3007
3008  ("clang_reparseTranslationUnit",
3009   [TranslationUnit, c_int, c_void_p, c_int],
3010   c_int),
3011
3012  ("clang_saveTranslationUnit",
3013   [TranslationUnit, c_char_p, c_uint],
3014   c_int),
3015
3016  ("clang_tokenize",
3017   [TranslationUnit, SourceRange, POINTER(POINTER(Token)), POINTER(c_uint)]),
3018
3019  ("clang_visitChildren",
3020   [Cursor, callbacks['cursor_visit'], py_object],
3021   c_uint),
3022
3023  ("clang_Cursor_getNumArguments",
3024   [Cursor],
3025   c_int),
3026
3027  ("clang_Cursor_getArgument",
3028   [Cursor, c_uint],
3029   Cursor,
3030   Cursor.from_result),
3031]
3032
3033class LibclangError(Exception):
3034    def __init__(self, message):
3035        self.m = message
3036
3037    def __str__(self):
3038        return self.m
3039
3040def register_function(lib, item, ignore_errors):
3041    # A function may not exist, if these bindings are used with an older or
3042    # incompatible version of libclang.so.
3043    try:
3044        func = getattr(lib, item[0])
3045    except AttributeError as e:
3046        msg = str(e) + ". Please ensure that your python bindings are "\
3047                       "compatible with your libclang.so version."
3048        if ignore_errors:
3049            return
3050        raise LibclangError(msg)
3051
3052    if len(item) >= 2:
3053        func.argtypes = item[1]
3054
3055    if len(item) >= 3:
3056        func.restype = item[2]
3057
3058    if len(item) == 4:
3059        func.errcheck = item[3]
3060
3061def register_functions(lib, ignore_errors):
3062    """Register function prototypes with a libclang library instance.
3063
3064    This must be called as part of library instantiation so Python knows how
3065    to call out to the shared library.
3066    """
3067
3068    def register(item):
3069        return register_function(lib, item, ignore_errors)
3070
3071    for f in functionList:
3072        register(f)
3073
3074class Config:
3075    library_path = None
3076    library_file = None
3077    compatibility_check = True
3078    loaded = False
3079
3080    @staticmethod
3081    def set_library_path(path):
3082        """Set the path in which to search for libclang"""
3083        if Config.loaded:
3084            raise Exception("library path must be set before before using " \
3085                            "any other functionalities in libclang.")
3086
3087        Config.library_path = path
3088
3089    @staticmethod
3090    def set_library_file(file):
3091        """Set the exact location of libclang from"""
3092        if Config.loaded:
3093            raise Exception("library file must be set before before using " \
3094                            "any other functionalities in libclang.")
3095
3096        Config.library_file = file
3097
3098    @staticmethod
3099    def set_compatibility_check(check_status):
3100        """ Perform compatibility check when loading libclang
3101
3102        The python bindings are only tested and evaluated with the version of
3103        libclang they are provided with. To ensure correct behavior a (limited)
3104        compatibility check is performed when loading the bindings. This check
3105        will throw an exception, as soon as it fails.
3106
3107        In case these bindings are used with an older version of libclang, parts
3108        that have been stable between releases may still work. Users of the
3109        python bindings can disable the compatibility check. This will cause
3110        the python bindings to load, even though they are written for a newer
3111        version of libclang. Failures now arise if unsupported or incompatible
3112        features are accessed. The user is required to test himself if the
3113        features he is using are available and compatible between different
3114        libclang versions.
3115        """
3116        if Config.loaded:
3117            raise Exception("compatibility_check must be set before before " \
3118                            "using any other functionalities in libclang.")
3119
3120        Config.compatibility_check = check_status
3121
3122    @CachedProperty
3123    def lib(self):
3124        lib = self.get_cindex_library()
3125        register_functions(lib, not Config.compatibility_check)
3126        Config.loaded = True
3127        return lib
3128
3129    def get_filename(self):
3130        if Config.library_file:
3131            return Config.library_file
3132
3133        import platform
3134        name = platform.system()
3135
3136        if name == 'Darwin':
3137            file = 'libclang.dylib'
3138        elif name == 'Windows':
3139            file = 'libclang.dll'
3140        else:
3141            file = 'libclang.so'
3142
3143        if Config.library_path:
3144            file = Config.library_path + '/' + file
3145
3146        return file
3147
3148    def get_cindex_library(self):
3149        try:
3150            library = cdll.LoadLibrary(self.get_filename())
3151        except OSError as e:
3152            msg = str(e) + ". To provide a path to libclang use " \
3153                           "Config.set_library_path() or " \
3154                           "Config.set_library_file()."
3155            raise LibclangError(msg)
3156
3157        return library
3158
3159    def function_exists(self, name):
3160        try:
3161            getattr(self.lib, name)
3162        except AttributeError:
3163            return False
3164
3165        return True
3166
3167def register_enumerations():
3168    for name, value in clang.enumerations.TokenKinds:
3169        TokenKind.register(value, name)
3170
3171conf = Config()
3172register_enumerations()
3173
3174__all__ = [
3175    'Config',
3176    'CodeCompletionResults',
3177    'CompilationDatabase',
3178    'CompileCommands',
3179    'CompileCommand',
3180    'CursorKind',
3181    'Cursor',
3182    'Diagnostic',
3183    'File',
3184    'FixIt',
3185    'Index',
3186    'SourceLocation',
3187    'SourceRange',
3188    'TokenKind',
3189    'Token',
3190    'TranslationUnitLoadError',
3191    'TranslationUnit',
3192    'TypeKind',
3193    'Type',
3194]
3195