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