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