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