cindex.py revision 64e7bdc1d4c8c2f40f32e699014e85fbe1be57f7
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('libclang.dylib') 75 elif name == 'Windows': 76 return cdll.LoadLibrary('libclang.dll') 77 else: 78 return cdll.LoadLibrary('libclang.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 if f: 115 f = File(f) 116 else: 117 f = None 118 self._data = (f, int(l.value), int(c.value), int(o.value)) 119 return self._data 120 121 @staticmethod 122 def from_position(tu, file, line, column): 123 """ 124 Retrieve the source location associated with a given file/line/column in 125 a particular translation unit. 126 """ 127 return SourceLocation_getLocation(tu, file, line, column) 128 129 @property 130 def file(self): 131 """Get the file represented by this source location.""" 132 return self._get_instantiation()[0] 133 134 @property 135 def line(self): 136 """Get the line represented by this source location.""" 137 return self._get_instantiation()[1] 138 139 @property 140 def column(self): 141 """Get the column represented by this source location.""" 142 return self._get_instantiation()[2] 143 144 @property 145 def offset(self): 146 """Get the file offset represented by this source location.""" 147 return self._get_instantiation()[3] 148 149 def __eq__(self, other): 150 return SourceLocation_equalLocations(self, other) 151 152 def __ne__(self, other): 153 return not self.__eq__(other) 154 155 def __repr__(self): 156 if self.file: 157 filename = self.file.name 158 else: 159 filename = None 160 return "<SourceLocation file %r, line %r, column %r>" % ( 161 filename, self.line, self.column) 162 163class SourceRange(Structure): 164 """ 165 A SourceRange describes a range of source locations within the source 166 code. 167 """ 168 _fields_ = [ 169 ("ptr_data", c_void_p * 2), 170 ("begin_int_data", c_uint), 171 ("end_int_data", c_uint)] 172 173 # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes 174 # object. 175 @staticmethod 176 def from_locations(start, end): 177 return SourceRange_getRange(start, end) 178 179 @property 180 def start(self): 181 """ 182 Return a SourceLocation representing the first character within a 183 source range. 184 """ 185 return SourceRange_start(self) 186 187 @property 188 def end(self): 189 """ 190 Return a SourceLocation representing the last character within a 191 source range. 192 """ 193 return SourceRange_end(self) 194 195 def __eq__(self, other): 196 return SourceRange_equalRanges(self, other) 197 198 def __ne__(self, other): 199 return not self.__eq__(other) 200 201 def __repr__(self): 202 return "<SourceRange start %r, end %r>" % (self.start, self.end) 203 204class Diagnostic(object): 205 """ 206 A Diagnostic is a single instance of a Clang diagnostic. It includes the 207 diagnostic severity, the message, the location the diagnostic occurred, as 208 well as additional source ranges and associated fix-it hints. 209 """ 210 211 Ignored = 0 212 Note = 1 213 Warning = 2 214 Error = 3 215 Fatal = 4 216 217 def __init__(self, ptr): 218 self.ptr = ptr 219 220 def __del__(self): 221 _clang_disposeDiagnostic(self) 222 223 @property 224 def severity(self): 225 return _clang_getDiagnosticSeverity(self) 226 227 @property 228 def location(self): 229 return _clang_getDiagnosticLocation(self) 230 231 @property 232 def spelling(self): 233 return _clang_getDiagnosticSpelling(self) 234 235 @property 236 def ranges(self): 237 class RangeIterator: 238 def __init__(self, diag): 239 self.diag = diag 240 241 def __len__(self): 242 return int(_clang_getDiagnosticNumRanges(self.diag)) 243 244 def __getitem__(self, key): 245 if (key >= len(self)): 246 raise IndexError 247 return _clang_getDiagnosticRange(self.diag, key) 248 249 return RangeIterator(self) 250 251 @property 252 def fixits(self): 253 class FixItIterator: 254 def __init__(self, diag): 255 self.diag = diag 256 257 def __len__(self): 258 return int(_clang_getDiagnosticNumFixIts(self.diag)) 259 260 def __getitem__(self, key): 261 range = SourceRange() 262 value = _clang_getDiagnosticFixIt(self.diag, key, byref(range)) 263 if len(value) == 0: 264 raise IndexError 265 266 return FixIt(range, value) 267 268 return FixItIterator(self) 269 270 @property 271 def category_number(self): 272 """The category number for this diagnostic.""" 273 return _clang_getDiagnosticCategory(self) 274 275 @property 276 def category_name(self): 277 """The string name of the category for this diagnostic.""" 278 return _clang_getDiagnosticCategoryName(self.category_number) 279 280 @property 281 def option(self): 282 """The command-line option that enables this diagnostic.""" 283 return _clang_getDiagnosticOption(self, None) 284 285 @property 286 def disable_option(self): 287 """The command-line option that disables this diagnostic.""" 288 disable = _CXString() 289 _clang_getDiagnosticOption(self, byref(disable)) 290 291 return _CXString_getCString(disable) 292 293 def __repr__(self): 294 return "<Diagnostic severity %r, location %r, spelling %r>" % ( 295 self.severity, self.location, self.spelling) 296 297 def from_param(self): 298 return self.ptr 299 300class FixIt(object): 301 """ 302 A FixIt represents a transformation to be applied to the source to 303 "fix-it". The fix-it shouldbe applied by replacing the given source range 304 with the given value. 305 """ 306 307 def __init__(self, range, value): 308 self.range = range 309 self.value = value 310 311 def __repr__(self): 312 return "<FixIt range %r, value %r>" % (self.range, self.value) 313 314### Cursor Kinds ### 315 316class CursorKind(object): 317 """ 318 A CursorKind describes the kind of entity that a cursor points to. 319 """ 320 321 # The unique kind objects, indexed by id. 322 _kinds = [] 323 _name_map = None 324 325 def __init__(self, value): 326 if value >= len(CursorKind._kinds): 327 CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1) 328 if CursorKind._kinds[value] is not None: 329 raise ValueError,'CursorKind already loaded' 330 self.value = value 331 CursorKind._kinds[value] = self 332 CursorKind._name_map = None 333 334 def from_param(self): 335 return self.value 336 337 @property 338 def name(self): 339 """Get the enumeration name of this cursor kind.""" 340 if self._name_map is None: 341 self._name_map = {} 342 for key,value in CursorKind.__dict__.items(): 343 if isinstance(value,CursorKind): 344 self._name_map[value] = key 345 return self._name_map[self] 346 347 @staticmethod 348 def from_id(id): 349 if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None: 350 raise ValueError,'Unknown cursor kind' 351 return CursorKind._kinds[id] 352 353 @staticmethod 354 def get_all_kinds(): 355 """Return all CursorKind enumeration instances.""" 356 return filter(None, CursorKind._kinds) 357 358 def is_declaration(self): 359 """Test if this is a declaration kind.""" 360 return CursorKind_is_decl(self) 361 362 def is_reference(self): 363 """Test if this is a reference kind.""" 364 return CursorKind_is_ref(self) 365 366 def is_expression(self): 367 """Test if this is an expression kind.""" 368 return CursorKind_is_expr(self) 369 370 def is_statement(self): 371 """Test if this is a statement kind.""" 372 return CursorKind_is_stmt(self) 373 374 def is_attribute(self): 375 """Test if this is an attribute kind.""" 376 return CursorKind_is_attribute(self) 377 378 def is_invalid(self): 379 """Test if this is an invalid kind.""" 380 return CursorKind_is_inv(self) 381 382 def __repr__(self): 383 return 'CursorKind.%s' % (self.name,) 384 385# FIXME: Is there a nicer way to expose this enumeration? We could potentially 386# represent the nested structure, or even build a class hierarchy. The main 387# things we want for sure are (a) simple external access to kinds, (b) a place 388# to hang a description and name, (c) easy to keep in sync with Index.h. 389 390### 391# Declaration Kinds 392 393# A declaration whose specific kind is not exposed via this interface. 394# 395# Unexposed declarations have the same operations as any other kind of 396# declaration; one can extract their location information, spelling, find their 397# definitions, etc. However, the specific kind of the declaration is not 398# reported. 399CursorKind.UNEXPOSED_DECL = CursorKind(1) 400 401# A C or C++ struct. 402CursorKind.STRUCT_DECL = CursorKind(2) 403 404# A C or C++ union. 405CursorKind.UNION_DECL = CursorKind(3) 406 407# A C++ class. 408CursorKind.CLASS_DECL = CursorKind(4) 409 410# An enumeration. 411CursorKind.ENUM_DECL = CursorKind(5) 412 413# A field (in C) or non-static data member (in C++) in a struct, union, or C++ 414# class. 415CursorKind.FIELD_DECL = CursorKind(6) 416 417# An enumerator constant. 418CursorKind.ENUM_CONSTANT_DECL = CursorKind(7) 419 420# A function. 421CursorKind.FUNCTION_DECL = CursorKind(8) 422 423# A variable. 424CursorKind.VAR_DECL = CursorKind(9) 425 426# A function or method parameter. 427CursorKind.PARM_DECL = CursorKind(10) 428 429# An Objective-C @interface. 430CursorKind.OBJC_INTERFACE_DECL = CursorKind(11) 431 432# An Objective-C @interface for a category. 433CursorKind.OBJC_CATEGORY_DECL = CursorKind(12) 434 435# An Objective-C @protocol declaration. 436CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13) 437 438# An Objective-C @property declaration. 439CursorKind.OBJC_PROPERTY_DECL = CursorKind(14) 440 441# An Objective-C instance variable. 442CursorKind.OBJC_IVAR_DECL = CursorKind(15) 443 444# An Objective-C instance method. 445CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16) 446 447# An Objective-C class method. 448CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17) 449 450# An Objective-C @implementation. 451CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18) 452 453# An Objective-C @implementation for a category. 454CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19) 455 456# A typedef. 457CursorKind.TYPEDEF_DECL = CursorKind(20) 458 459# A C++ class method. 460CursorKind.CXX_METHOD = CursorKind(21) 461 462# A C++ namespace. 463CursorKind.NAMESPACE = CursorKind(22) 464 465# A linkage specification, e.g. 'extern "C"'. 466CursorKind.LINKAGE_SPEC = CursorKind(23) 467 468# A C++ constructor. 469CursorKind.CONSTRUCTOR = CursorKind(24) 470 471# A C++ destructor. 472CursorKind.DESTRUCTOR = CursorKind(25) 473 474# A C++ conversion function. 475CursorKind.CONVERSION_FUNCTION = CursorKind(26) 476 477# A C++ template type parameter 478CursorKind.TEMPLATE_TYPE_PARAMETER = CursorKind(27) 479 480# A C++ non-type template paramater. 481CursorKind.TEMPLATE_NON_TYPE_PARAMETER = CursorKind(28) 482 483# A C++ template template parameter. 484CursorKind.TEMPLATE_TEMPLATE_PARAMTER = CursorKind(29) 485 486# A C++ function template. 487CursorKind.FUNCTION_TEMPLATE = CursorKind(30) 488 489# A C++ class template. 490CursorKind.CLASS_TEMPLATE = CursorKind(31) 491 492# A C++ class template partial specialization. 493CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION = CursorKind(32) 494 495# A C++ namespace alias declaration. 496CursorKind.NAMESPACE_ALIAS = CursorKind(33) 497 498# A C++ using directive 499CursorKind.USING_DIRECTIVE = CursorKind(34) 500 501# A C++ using declaration 502CursorKind.USING_DECLARATION = CursorKind(35) 503 504# A Type alias decl. 505CursorKind.TYPE_ALIAS_DECL = CursorKind(36) 506 507# A Objective-C synthesize decl 508CursorKind.OBJC_SYNTHESIZE_DECL = CursorKind(37) 509 510# A Objective-C dynamic decl 511CursorKind.OBJC_DYNAMIC_DECL = CursorKind(38) 512 513# A C++ access specifier decl. 514CursorKind.CXX_ACCESS_SPEC_DECL = CursorKind(39) 515 516 517### 518# Reference Kinds 519 520CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40) 521CursorKind.OBJC_PROTOCOL_REF = CursorKind(41) 522CursorKind.OBJC_CLASS_REF = CursorKind(42) 523 524# A reference to a type declaration. 525# 526# A type reference occurs anywhere where a type is named but not 527# declared. For example, given: 528# typedef unsigned size_type; 529# size_type size; 530# 531# The typedef is a declaration of size_type (CXCursor_TypedefDecl), 532# while the type of the variable "size" is referenced. The cursor 533# referenced by the type of size is the typedef for size_type. 534CursorKind.TYPE_REF = CursorKind(43) 535CursorKind.CXX_BASE_SPECIFIER = CursorKind(44) 536 537# A reference to a class template, function template, template 538# template parameter, or class template partial specialization. 539CursorKind.TEMPLATE_REF = CursorKind(45) 540 541# A reference to a namespace or namepsace alias. 542CursorKind.NAMESPACE_REF = CursorKind(46) 543 544# A reference to a member of a struct, union, or class that occurs in 545# some non-expression context, e.g., a designated initializer. 546CursorKind.MEMBER_REF = CursorKind(47) 547 548# A reference to a labeled statement. 549CursorKind.LABEL_REF = CursorKind(48) 550 551# A reference toa a set of overloaded functions or function templates 552# that has not yet been resolved to a specific function or function template. 553CursorKind.OVERLOADED_DECL_REF = CursorKind(49) 554 555### 556# Invalid/Error Kinds 557 558CursorKind.INVALID_FILE = CursorKind(70) 559CursorKind.NO_DECL_FOUND = CursorKind(71) 560CursorKind.NOT_IMPLEMENTED = CursorKind(72) 561CursorKind.INVALID_CODE = CursorKind(73) 562 563### 564# Expression Kinds 565 566# An expression whose specific kind is not exposed via this interface. 567# 568# Unexposed expressions have the same operations as any other kind of 569# expression; one can extract their location information, spelling, children, 570# etc. However, the specific kind of the expression is not reported. 571CursorKind.UNEXPOSED_EXPR = CursorKind(100) 572 573# An expression that refers to some value declaration, such as a function, 574# varible, or enumerator. 575CursorKind.DECL_REF_EXPR = CursorKind(101) 576 577# An expression that refers to a member of a struct, union, class, Objective-C 578# class, etc. 579CursorKind.MEMBER_REF_EXPR = CursorKind(102) 580 581# An expression that calls a function. 582CursorKind.CALL_EXPR = CursorKind(103) 583 584# An expression that sends a message to an Objective-C object or class. 585CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104) 586 587# An expression that represents a block literal. 588CursorKind.BLOCK_EXPR = CursorKind(105) 589 590# An integer literal. 591CursorKind.INTEGER_LITERAL = CursorKind(106) 592 593# A floating point number literal. 594CursorKind.FLOATING_LITERAL = CursorKind(107) 595 596# An imaginary number literal. 597CursorKind.IMAGINARY_LITERAL = CursorKind(108) 598 599# A string literal. 600CursorKind.STRING_LITERAL = CursorKind(109) 601 602# A character literal. 603CursorKind.CHARACTER_LITERAL = CursorKind(110) 604 605# A parenthesized expression, e.g. "(1)". 606# 607# This AST node is only formed if full location information is requested. 608CursorKind.PAREN_EXPR = CursorKind(111) 609 610# This represents the unary-expression's (except sizeof and 611# alignof). 612CursorKind.UNARY_OPERATOR = CursorKind(112) 613 614# [C99 6.5.2.1] Array Subscripting. 615CursorKind.ARRAY_SUBSCRIPT_EXPR = CursorKind(113) 616 617# A builtin binary operation expression such as "x + y" or 618# "x <= y". 619CursorKind.BINARY_OPERATOR = CursorKind(114) 620 621# Compound assignment such as "+=". 622CursorKind.COMPOUND_ASSIGNMENT_OPERATOR = CursorKind(115) 623 624# The ?: ternary operator. 625CursorKind.CONDITONAL_OPERATOR = CursorKind(116) 626 627# An explicit cast in C (C99 6.5.4) or a C-style cast in C++ 628# (C++ [expr.cast]), which uses the syntax (Type)expr. 629# 630# For example: (int)f. 631CursorKind.CSTYLE_CAST_EXPR = CursorKind(117) 632 633# [C99 6.5.2.5] 634CursorKind.COMPOUND_LITERAL_EXPR = CursorKind(118) 635 636# Describes an C or C++ initializer list. 637CursorKind.INIT_LIST_EXPR = CursorKind(119) 638 639# The GNU address of label extension, representing &&label. 640CursorKind.ADDR_LABEL_EXPR = CursorKind(120) 641 642# This is the GNU Statement Expression extension: ({int X=4; X;}) 643CursorKind.StmtExpr = CursorKind(121) 644 645# Represents a C11 generic selection. 646CursorKind.GENERIC_SELECTION_EXPR = CursorKind(122) 647 648# Implements the GNU __null extension, which is a name for a null 649# pointer constant that has integral type (e.g., int or long) and is the same 650# size and alignment as a pointer. 651# 652# The __null extension is typically only used by system headers, which define 653# NULL as __null in C++ rather than using 0 (which is an integer that may not 654# match the size of a pointer). 655CursorKind.GNU_NULL_EXPR = CursorKind(123) 656 657# C++'s static_cast<> expression. 658CursorKind.CXX_STATIC_CAST_EXPR = CursorKind(124) 659 660# C++'s dynamic_cast<> expression. 661CursorKind.CXX_DYNAMIC_CAST_EXPR = CursorKind(125) 662 663# C++'s reinterpret_cast<> expression. 664CursorKind.CXX_REINTERPRET_CAST_EXPR = CursorKind(126) 665 666# C++'s const_cast<> expression. 667CursorKind.CXX_CONST_CAST_EXPR = CursorKind(127) 668 669# Represents an explicit C++ type conversion that uses "functional" 670# notion (C++ [expr.type.conv]). 671# 672# Example: 673# \code 674# x = int(0.5); 675# \endcode 676CursorKind.CXX_FUNCTIONAL_CAST_EXPR = CursorKind(128) 677 678# A C++ typeid expression (C++ [expr.typeid]). 679CursorKind.CXX_TYPEID_EXPR = CursorKind(129) 680 681# [C++ 2.13.5] C++ Boolean Literal. 682CursorKind.CXX_BOOL_LITERAL_EXPR = CursorKind(130) 683 684# [C++0x 2.14.7] C++ Pointer Literal. 685CursorKind.CXX_NULL_PTR_LITERAL_EXPR = CursorKind(131) 686 687# Represents the "this" expression in C++ 688CursorKind.CXX_THIS_EXPR = CursorKind(132) 689 690# [C++ 15] C++ Throw Expression. 691# 692# This handles 'throw' and 'throw' assignment-expression. When 693# assignment-expression isn't present, Op will be null. 694CursorKind.CXX_THROW_EXPR = CursorKind(133) 695 696# A new expression for memory allocation and constructor calls, e.g: 697# "new CXXNewExpr(foo)". 698CursorKind.CXX_NEW_EXPR = CursorKind(134) 699 700# A delete expression for memory deallocation and destructor calls, 701# e.g. "delete[] pArray". 702CursorKind.CXX_DELETE_EXPR = CursorKind(135) 703 704# Represents a unary expression. 705CursorKind.CXX_UNARY_EXPR = CursorKind(136) 706 707# ObjCStringLiteral, used for Objective-C string literals i.e. "foo". 708CursorKind.OBJC_STRING_LITERAL = CursorKind(137) 709 710# ObjCEncodeExpr, used for in Objective-C. 711CursorKind.OBJC_ENCODE_EXPR = CursorKind(138) 712 713# ObjCSelectorExpr used for in Objective-C. 714CursorKind.OBJC_SELECTOR_EXPR = CursorKind(139) 715 716# Objective-C's protocol expression. 717CursorKind.OBJC_PROTOCOL_EXPR = CursorKind(140) 718 719# An Objective-C "bridged" cast expression, which casts between 720# Objective-C pointers and C pointers, transferring ownership in the process. 721# 722# \code 723# NSString *str = (__bridge_transfer NSString *)CFCreateString(); 724# \endcode 725CursorKind.OBJC_BRIDGE_CAST_EXPR = CursorKind(141) 726 727# Represents a C++0x pack expansion that produces a sequence of 728# expressions. 729# 730# A pack expansion expression contains a pattern (which itself is an 731# expression) followed by an ellipsis. For example: 732CursorKind.PACK_EXPANSION_EXPR = CursorKind(142) 733 734# Represents an expression that computes the length of a parameter 735# pack. 736CursorKind.SIZE_OF_PACK_EXPR = CursorKind(143) 737 738# A statement whose specific kind is not exposed via this interface. 739# 740# Unexposed statements have the same operations as any other kind of statement; 741# one can extract their location information, spelling, children, etc. However, 742# the specific kind of the statement is not reported. 743CursorKind.UNEXPOSED_STMT = CursorKind(200) 744 745# A labelled statement in a function. 746CursorKind.LABEL_STMT = CursorKind(201) 747 748# A compound statement 749CursorKind.COMPOUND_STMT = CursorKind(202) 750 751# A case statement. 752CursorKind.CASE_STMT = CursorKind(203) 753 754# A default statement. 755CursorKind.DEFAULT_STMT = CursorKind(204) 756 757# An if statement. 758CursorKind.IF_STMT = CursorKind(205) 759 760# A switch statement. 761CursorKind.SWITCH_STMT = CursorKind(206) 762 763# A while statement. 764CursorKind.WHILE_STMT = CursorKind(207) 765 766# A do statement. 767CursorKind.DO_STMT = CursorKind(208) 768 769# A for statement. 770CursorKind.FOR_STMT = CursorKind(209) 771 772# A goto statement. 773CursorKind.GOTO_STMT = CursorKind(210) 774 775# An indirect goto statement. 776CursorKind.INDIRECT_GOTO_STMT = CursorKind(211) 777 778# A continue statement. 779CursorKind.CONTINUE_STMT = CursorKind(212) 780 781# A break statement. 782CursorKind.BREAK_STMT = CursorKind(213) 783 784# A return statement. 785CursorKind.RETURN_STMT = CursorKind(214) 786 787# A GNU-style inline assembler statement. 788CursorKind.ASM_STMT = CursorKind(215) 789 790# Objective-C's overall @try-@catch-@finally statement. 791CursorKind.OBJC_AT_TRY_STMT = CursorKind(216) 792 793# Objective-C's @catch statement. 794CursorKind.OBJC_AT_CATCH_STMT = CursorKind(217) 795 796# Objective-C's @finally statement. 797CursorKind.OBJC_AT_FINALLY_STMT = CursorKind(218) 798 799# Objective-C's @throw statement. 800CursorKind.OBJC_AT_THROW_STMT = CursorKind(219) 801 802# Objective-C's @synchronized statement. 803CursorKind.OBJC_AT_SYNCHRONIZED_STMT = CursorKind(220) 804 805# Objective-C's autorealease pool statement. 806CursorKind.OBJC_AUTORELEASE_POOL_STMT = CursorKind(221) 807 808# Objective-C's for collection statement. 809CursorKind.OBJC_FOR_COLLECTION_STMT = CursorKind(222) 810 811# C++'s catch statement. 812CursorKind.CXX_CATCH_STMT = CursorKind(223) 813 814# C++'s try statement. 815CursorKind.CXX_TRY_STMT = CursorKind(224) 816 817# C++'s for (* : *) statement. 818CursorKind.CXX_FOR_RANGE_STMT = CursorKind(225) 819 820# Windows Structured Exception Handling's try statement. 821CursorKind.SEH_TRY_STMT = CursorKind(226) 822 823# Windows Structured Exception Handling's except statement. 824CursorKind.SEH_EXCEPT_STMT = CursorKind(227) 825 826# Windows Structured Exception Handling's finally statement. 827CursorKind.SEH_FINALLY_STMT = CursorKind(228) 828 829# The null statement. 830CursorKind.NULL_STMT = CursorKind(230) 831 832# Adaptor class for mixing declarations with statements and expressions. 833CursorKind.DECL_STMT = CursorKind(231) 834 835### 836# Other Kinds 837 838# Cursor that represents the translation unit itself. 839# 840# The translation unit cursor exists primarily to act as the root cursor for 841# traversing the contents of a translation unit. 842CursorKind.TRANSLATION_UNIT = CursorKind(300) 843 844### 845# Attributes 846 847# An attribute whoe specific kind is note exposed via this interface 848CursorKind.UNEXPOSED_ATTR = CursorKind(400) 849 850CursorKind.IB_ACTION_ATTR = CursorKind(401) 851CursorKind.IB_OUTLET_ATTR = CursorKind(402) 852CursorKind.IB_OUTLET_COLLECTION_ATTR = CursorKind(403) 853 854CursorKind.CXX_FINAL_ATTR = CursorKind(404) 855CursorKind.CXX_OVERRIDE_ATTR = CursorKind(405) 856CursorKind.ANNOTATE_ATTR = CursorKind(406) 857CursorKind.ASM_LABEL_ATTR = CursorKind(407) 858 859### 860# Preprocessing 861CursorKind.PREPROCESSING_DIRECTIVE = CursorKind(500) 862CursorKind.MACRO_DEFINITION = CursorKind(501) 863CursorKind.MACRO_INSTANTIATION = CursorKind(502) 864CursorKind.INCLUSION_DIRECTIVE = CursorKind(503) 865 866### Cursors ### 867 868class Cursor(Structure): 869 """ 870 The Cursor class represents a reference to an element within the AST. It 871 acts as a kind of iterator. 872 """ 873 _fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)] 874 875 @staticmethod 876 def from_location(tu, location): 877 return Cursor_get(tu, location) 878 879 def __eq__(self, other): 880 return Cursor_eq(self, other) 881 882 def __ne__(self, other): 883 return not Cursor_eq(self, other) 884 885 def is_definition(self): 886 """ 887 Returns true if the declaration pointed at by the cursor is also a 888 definition of that entity. 889 """ 890 return Cursor_is_def(self) 891 892 def get_definition(self): 893 """ 894 If the cursor is a reference to a declaration or a declaration of 895 some entity, return a cursor that points to the definition of that 896 entity. 897 """ 898 # TODO: Should probably check that this is either a reference or 899 # declaration prior to issuing the lookup. 900 return Cursor_def(self) 901 902 def get_usr(self): 903 """Return the Unified Symbol Resultion (USR) for the entity referenced 904 by the given cursor (or None). 905 906 A Unified Symbol Resolution (USR) is a string that identifies a 907 particular entity (function, class, variable, etc.) within a 908 program. USRs can be compared across translation units to determine, 909 e.g., when references in one translation refer to an entity defined in 910 another translation unit.""" 911 return Cursor_usr(self) 912 913 @property 914 def kind(self): 915 """Return the kind of this cursor.""" 916 return CursorKind.from_id(self._kind_id) 917 918 @property 919 def spelling(self): 920 """Return the spelling of the entity pointed at by the cursor.""" 921 if not self.kind.is_declaration(): 922 # FIXME: clang_getCursorSpelling should be fixed to not assert on 923 # this, for consistency with clang_getCursorUSR. 924 return None 925 if not hasattr(self, '_spelling'): 926 self._spelling = Cursor_spelling(self) 927 return self._spelling 928 929 @property 930 def displayname(self): 931 """ 932 Return the display name for the entity referenced by this cursor. 933 934 The display name contains extra information that helps identify the cursor, 935 such as the parameters of a function or template or the arguments of a 936 class template specialization. 937 """ 938 if not hasattr(self, '_displayname'): 939 self._displayname = Cursor_displayname(self) 940 return self._displayname 941 942 @property 943 def location(self): 944 """ 945 Return the source location (the starting character) of the entity 946 pointed at by the cursor. 947 """ 948 if not hasattr(self, '_loc'): 949 self._loc = Cursor_loc(self) 950 return self._loc 951 952 @property 953 def extent(self): 954 """ 955 Return the source range (the range of text) occupied by the entity 956 pointed at by the cursor. 957 """ 958 if not hasattr(self, '_extent'): 959 self._extent = Cursor_extent(self) 960 return self._extent 961 962 @property 963 def type(self): 964 """ 965 Retrieve the type (if any) of of the entity pointed at by the 966 cursor. 967 """ 968 if not hasattr(self, '_type'): 969 self._type = Cursor_type(self) 970 return self._type 971 972 @property 973 def hash(self): 974 """Returns a hash of the cursor as an int.""" 975 if not hasattr(self, '_hash'): 976 self._hash = Cursor_hash(self) 977 978 return self._hash 979 980 def get_children(self): 981 """Return an iterator for accessing the children of this cursor.""" 982 983 # FIXME: Expose iteration from CIndex, PR6125. 984 def visitor(child, parent, children): 985 # FIXME: Document this assertion in API. 986 # FIXME: There should just be an isNull method. 987 assert child != Cursor_null() 988 children.append(child) 989 return 1 # continue 990 children = [] 991 Cursor_visit(self, Cursor_visit_callback(visitor), children) 992 return iter(children) 993 994 @staticmethod 995 def from_result(res, fn, args): 996 assert isinstance(res, Cursor) 997 # FIXME: There should just be an isNull method. 998 if res == Cursor_null(): 999 return None 1000 return res 1001 1002 1003### Type Kinds ### 1004 1005class TypeKind(object): 1006 """ 1007 Describes the kind of type. 1008 """ 1009 1010 # The unique kind objects, indexed by id. 1011 _kinds = [] 1012 _name_map = None 1013 1014 def __init__(self, value): 1015 if value >= len(TypeKind._kinds): 1016 TypeKind._kinds += [None] * (value - len(TypeKind._kinds) + 1) 1017 if TypeKind._kinds[value] is not None: 1018 raise ValueError,'TypeKind already loaded' 1019 self.value = value 1020 TypeKind._kinds[value] = self 1021 TypeKind._name_map = None 1022 1023 def from_param(self): 1024 return self.value 1025 1026 @property 1027 def name(self): 1028 """Get the enumeration name of this cursor kind.""" 1029 if self._name_map is None: 1030 self._name_map = {} 1031 for key,value in TypeKind.__dict__.items(): 1032 if isinstance(value,TypeKind): 1033 self._name_map[value] = key 1034 return self._name_map[self] 1035 1036 @staticmethod 1037 def from_id(id): 1038 if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None: 1039 raise ValueError,'Unknown type kind %d' % id 1040 return TypeKind._kinds[id] 1041 1042 def __repr__(self): 1043 return 'TypeKind.%s' % (self.name,) 1044 1045 1046 1047TypeKind.INVALID = TypeKind(0) 1048TypeKind.UNEXPOSED = TypeKind(1) 1049TypeKind.VOID = TypeKind(2) 1050TypeKind.BOOL = TypeKind(3) 1051TypeKind.CHAR_U = TypeKind(4) 1052TypeKind.UCHAR = TypeKind(5) 1053TypeKind.CHAR16 = TypeKind(6) 1054TypeKind.CHAR32 = TypeKind(7) 1055TypeKind.USHORT = TypeKind(8) 1056TypeKind.UINT = TypeKind(9) 1057TypeKind.ULONG = TypeKind(10) 1058TypeKind.ULONGLONG = TypeKind(11) 1059TypeKind.UINT128 = TypeKind(12) 1060TypeKind.CHAR_S = TypeKind(13) 1061TypeKind.SCHAR = TypeKind(14) 1062TypeKind.WCHAR = TypeKind(15) 1063TypeKind.SHORT = TypeKind(16) 1064TypeKind.INT = TypeKind(17) 1065TypeKind.LONG = TypeKind(18) 1066TypeKind.LONGLONG = TypeKind(19) 1067TypeKind.INT128 = TypeKind(20) 1068TypeKind.FLOAT = TypeKind(21) 1069TypeKind.DOUBLE = TypeKind(22) 1070TypeKind.LONGDOUBLE = TypeKind(23) 1071TypeKind.NULLPTR = TypeKind(24) 1072TypeKind.OVERLOAD = TypeKind(25) 1073TypeKind.DEPENDENT = TypeKind(26) 1074TypeKind.OBJCID = TypeKind(27) 1075TypeKind.OBJCCLASS = TypeKind(28) 1076TypeKind.OBJCSEL = TypeKind(29) 1077TypeKind.COMPLEX = TypeKind(100) 1078TypeKind.POINTER = TypeKind(101) 1079TypeKind.BLOCKPOINTER = TypeKind(102) 1080TypeKind.LVALUEREFERENCE = TypeKind(103) 1081TypeKind.RVALUEREFERENCE = TypeKind(104) 1082TypeKind.RECORD = TypeKind(105) 1083TypeKind.ENUM = TypeKind(106) 1084TypeKind.TYPEDEF = TypeKind(107) 1085TypeKind.OBJCINTERFACE = TypeKind(108) 1086TypeKind.OBJCOBJECTPOINTER = TypeKind(109) 1087TypeKind.FUNCTIONNOPROTO = TypeKind(110) 1088TypeKind.FUNCTIONPROTO = TypeKind(111) 1089TypeKind.CONSTANTARRAY = TypeKind(112) 1090 1091class Type(Structure): 1092 """ 1093 The type of an element in the abstract syntax tree. 1094 """ 1095 _fields_ = [("_kind_id", c_int), ("data", c_void_p * 2)] 1096 1097 @property 1098 def kind(self): 1099 """Return the kind of this type.""" 1100 return TypeKind.from_id(self._kind_id) 1101 1102 @staticmethod 1103 def from_result(res, fn, args): 1104 assert isinstance(res, Type) 1105 return res 1106 1107 def get_canonical(self): 1108 """ 1109 Return the canonical type for a Type. 1110 1111 Clang's type system explicitly models typedefs and all the 1112 ways a specific type can be represented. The canonical type 1113 is the underlying type with all the "sugar" removed. For 1114 example, if 'T' is a typedef for 'int', the canonical type for 1115 'T' would be 'int'. 1116 """ 1117 return Type_get_canonical(self) 1118 1119 def is_const_qualified(self): 1120 """ 1121 Determine whether a Type has the "const" qualifier set, 1122 without looking through typedefs that may have added "const" 1123 at a different level. 1124 """ 1125 return Type_is_const_qualified(self) 1126 1127 def is_volatile_qualified(self): 1128 """ 1129 Determine whether a Type has the "volatile" qualifier set, 1130 without looking through typedefs that may have added 1131 "volatile" at a different level. 1132 """ 1133 return Type_is_volatile_qualified(self) 1134 1135 def is_restrict_qualified(self): 1136 """ 1137 Determine whether a Type has the "restrict" qualifier set, 1138 without looking through typedefs that may have added 1139 "restrict" at a different level. 1140 """ 1141 return Type_is_restrict_qualified(self) 1142 1143 def get_pointee(self): 1144 """ 1145 For pointer types, returns the type of the pointee. 1146 """ 1147 return Type_get_pointee(self) 1148 1149 def get_declaration(self): 1150 """ 1151 Return the cursor for the declaration of the given type. 1152 """ 1153 return Type_get_declaration(self) 1154 1155 def get_result(self): 1156 """ 1157 Retrieve the result type associated with a function type. 1158 """ 1159 return Type_get_result(self) 1160 1161 def get_array_element_type(self): 1162 """ 1163 Retrieve the type of the elements of the array type. 1164 """ 1165 return Type_get_array_element(self) 1166 1167 def get_array_size(self): 1168 """ 1169 Retrieve the size of the constant array. 1170 """ 1171 return Type_get_array_size(self) 1172 1173## CIndex Objects ## 1174 1175# CIndex objects (derived from ClangObject) are essentially lightweight 1176# wrappers attached to some underlying object, which is exposed via CIndex as 1177# a void*. 1178 1179class ClangObject(object): 1180 """ 1181 A helper for Clang objects. This class helps act as an intermediary for 1182 the ctypes library and the Clang CIndex library. 1183 """ 1184 def __init__(self, obj): 1185 assert isinstance(obj, c_object_p) and obj 1186 self.obj = self._as_parameter_ = obj 1187 1188 def from_param(self): 1189 return self._as_parameter_ 1190 1191 1192class _CXUnsavedFile(Structure): 1193 """Helper for passing unsaved file arguments.""" 1194 _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)] 1195 1196## Diagnostic Conversion ## 1197 1198_clang_getNumDiagnostics = lib.clang_getNumDiagnostics 1199_clang_getNumDiagnostics.argtypes = [c_object_p] 1200_clang_getNumDiagnostics.restype = c_uint 1201 1202_clang_getDiagnostic = lib.clang_getDiagnostic 1203_clang_getDiagnostic.argtypes = [c_object_p, c_uint] 1204_clang_getDiagnostic.restype = c_object_p 1205 1206_clang_disposeDiagnostic = lib.clang_disposeDiagnostic 1207_clang_disposeDiagnostic.argtypes = [Diagnostic] 1208 1209_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity 1210_clang_getDiagnosticSeverity.argtypes = [Diagnostic] 1211_clang_getDiagnosticSeverity.restype = c_int 1212 1213_clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation 1214_clang_getDiagnosticLocation.argtypes = [Diagnostic] 1215_clang_getDiagnosticLocation.restype = SourceLocation 1216 1217_clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling 1218_clang_getDiagnosticSpelling.argtypes = [Diagnostic] 1219_clang_getDiagnosticSpelling.restype = _CXString 1220_clang_getDiagnosticSpelling.errcheck = _CXString.from_result 1221 1222_clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges 1223_clang_getDiagnosticNumRanges.argtypes = [Diagnostic] 1224_clang_getDiagnosticNumRanges.restype = c_uint 1225 1226_clang_getDiagnosticRange = lib.clang_getDiagnosticRange 1227_clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint] 1228_clang_getDiagnosticRange.restype = SourceRange 1229 1230_clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts 1231_clang_getDiagnosticNumFixIts.argtypes = [Diagnostic] 1232_clang_getDiagnosticNumFixIts.restype = c_uint 1233 1234_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt 1235_clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint, POINTER(SourceRange)] 1236_clang_getDiagnosticFixIt.restype = _CXString 1237_clang_getDiagnosticFixIt.errcheck = _CXString.from_result 1238 1239_clang_getDiagnosticCategory = lib.clang_getDiagnosticCategory 1240_clang_getDiagnosticCategory.argtypes = [Diagnostic] 1241_clang_getDiagnosticCategory.restype = c_uint 1242 1243_clang_getDiagnosticCategoryName = lib.clang_getDiagnosticCategoryName 1244_clang_getDiagnosticCategoryName.argtypes = [c_uint] 1245_clang_getDiagnosticCategoryName.restype = _CXString 1246_clang_getDiagnosticCategoryName.errcheck = _CXString.from_result 1247 1248_clang_getDiagnosticOption = lib.clang_getDiagnosticOption 1249_clang_getDiagnosticOption.argtypes = [Diagnostic, POINTER(_CXString)] 1250_clang_getDiagnosticOption.restype = _CXString 1251_clang_getDiagnosticOption.errcheck = _CXString.from_result 1252 1253### 1254 1255class CompletionChunk: 1256 class Kind: 1257 def __init__(self, name): 1258 self.name = name 1259 1260 def __str__(self): 1261 return self.name 1262 1263 def __repr__(self): 1264 return "<ChunkKind: %s>" % self 1265 1266 def __init__(self, completionString, key): 1267 self.cs = completionString 1268 self.key = key 1269 1270 def __repr__(self): 1271 return "{'" + self.spelling + "', " + str(self.kind) + "}" 1272 1273 @property 1274 def spelling(self): 1275 return _clang_getCompletionChunkText(self.cs, self.key).spelling 1276 1277 @property 1278 def kind(self): 1279 res = _clang_getCompletionChunkKind(self.cs, self.key) 1280 return completionChunkKindMap[res] 1281 1282 @property 1283 def string(self): 1284 res = _clang_getCompletionChunkCompletionString(self.cs, self.key) 1285 1286 if (res): 1287 return CompletionString(res) 1288 else: 1289 None 1290 1291 def isKindOptional(self): 1292 return self.kind == completionChunkKindMap[0] 1293 1294 def isKindTypedText(self): 1295 return self.kind == completionChunkKindMap[1] 1296 1297 def isKindPlaceHolder(self): 1298 return self.kind == completionChunkKindMap[3] 1299 1300 def isKindInformative(self): 1301 return self.kind == completionChunkKindMap[4] 1302 1303 def isKindResultType(self): 1304 return self.kind == completionChunkKindMap[15] 1305 1306completionChunkKindMap = { 1307 0: CompletionChunk.Kind("Optional"), 1308 1: CompletionChunk.Kind("TypedText"), 1309 2: CompletionChunk.Kind("Text"), 1310 3: CompletionChunk.Kind("Placeholder"), 1311 4: CompletionChunk.Kind("Informative"), 1312 5: CompletionChunk.Kind("CurrentParameter"), 1313 6: CompletionChunk.Kind("LeftParen"), 1314 7: CompletionChunk.Kind("RightParen"), 1315 8: CompletionChunk.Kind("LeftBracket"), 1316 9: CompletionChunk.Kind("RightBracket"), 1317 10: CompletionChunk.Kind("LeftBrace"), 1318 11: CompletionChunk.Kind("RightBrace"), 1319 12: CompletionChunk.Kind("LeftAngle"), 1320 13: CompletionChunk.Kind("RightAngle"), 1321 14: CompletionChunk.Kind("Comma"), 1322 15: CompletionChunk.Kind("ResultType"), 1323 16: CompletionChunk.Kind("Colon"), 1324 17: CompletionChunk.Kind("SemiColon"), 1325 18: CompletionChunk.Kind("Equal"), 1326 19: CompletionChunk.Kind("HorizontalSpace"), 1327 20: CompletionChunk.Kind("VerticalSpace")} 1328 1329class CompletionString(ClangObject): 1330 class Availability: 1331 def __init__(self, name): 1332 self.name = name 1333 1334 def __str__(self): 1335 return self.name 1336 1337 def __repr__(self): 1338 return "<Availability: %s>" % self 1339 1340 def __len__(self): 1341 return _clang_getNumCompletionChunks(self.obj) 1342 1343 def __getitem__(self, key): 1344 if len(self) <= key: 1345 raise IndexError 1346 return CompletionChunk(self.obj, key) 1347 1348 @property 1349 def priority(self): 1350 return _clang_getCompletionPriority(self.obj) 1351 1352 @property 1353 def availability(self): 1354 res = _clang_getCompletionAvailability(self.obj) 1355 return availabilityKinds[res] 1356 1357 def __repr__(self): 1358 return " | ".join([str(a) for a in self]) \ 1359 + " || Priority: " + str(self.priority) \ 1360 + " || Availability: " + str(self.availability) 1361 1362availabilityKinds = { 1363 0: CompletionChunk.Kind("Available"), 1364 1: CompletionChunk.Kind("Deprecated"), 1365 2: CompletionChunk.Kind("NotAvailable")} 1366 1367class CodeCompletionResult(Structure): 1368 _fields_ = [('cursorKind', c_int), ('completionString', c_object_p)] 1369 1370 def __repr__(self): 1371 return str(CompletionString(self.completionString)) 1372 1373 @property 1374 def kind(self): 1375 return CursorKind.from_id(self.cursorKind) 1376 1377 @property 1378 def string(self): 1379 return CompletionString(self.completionString) 1380 1381class CCRStructure(Structure): 1382 _fields_ = [('results', POINTER(CodeCompletionResult)), 1383 ('numResults', c_int)] 1384 1385 def __len__(self): 1386 return self.numResults 1387 1388 def __getitem__(self, key): 1389 if len(self) <= key: 1390 raise IndexError 1391 1392 return self.results[key] 1393 1394class CodeCompletionResults(ClangObject): 1395 def __init__(self, ptr): 1396 assert isinstance(ptr, POINTER(CCRStructure)) and ptr 1397 self.ptr = self._as_parameter_ = ptr 1398 1399 def from_param(self): 1400 return self._as_parameter_ 1401 1402 def __del__(self): 1403 CodeCompletionResults_dispose(self) 1404 1405 @property 1406 def results(self): 1407 return self.ptr.contents 1408 1409 @property 1410 def diagnostics(self): 1411 class DiagnosticsItr: 1412 def __init__(self, ccr): 1413 self.ccr= ccr 1414 1415 def __len__(self): 1416 return int(_clang_codeCompleteGetNumDiagnostics(self.ccr)) 1417 1418 def __getitem__(self, key): 1419 return _clang_codeCompleteGetDiagnostic(self.ccr, key) 1420 1421 return DiagnosticsItr(self) 1422 1423 1424class Index(ClangObject): 1425 """ 1426 The Index type provides the primary interface to the Clang CIndex library, 1427 primarily by providing an interface for reading and parsing translation 1428 units. 1429 """ 1430 1431 @staticmethod 1432 def create(excludeDecls=False): 1433 """ 1434 Create a new Index. 1435 Parameters: 1436 excludeDecls -- Exclude local declarations from translation units. 1437 """ 1438 return Index(Index_create(excludeDecls, 0)) 1439 1440 def __del__(self): 1441 Index_dispose(self) 1442 1443 def read(self, path): 1444 """Load the translation unit from the given AST file.""" 1445 ptr = TranslationUnit_read(self, path) 1446 if ptr: 1447 return TranslationUnit(ptr) 1448 return None 1449 1450 def parse(self, path, args = [], unsaved_files = [], options = 0): 1451 """ 1452 Load the translation unit from the given source code file by running 1453 clang and generating the AST before loading. Additional command line 1454 parameters can be passed to clang via the args parameter. 1455 1456 In-memory contents for files can be provided by passing a list of pairs 1457 to as unsaved_files, the first item should be the filenames to be mapped 1458 and the second should be the contents to be substituted for the 1459 file. The contents may be passed as strings or file objects. 1460 """ 1461 arg_array = 0 1462 if len(args): 1463 arg_array = (c_char_p * len(args))(* args) 1464 unsaved_files_array = 0 1465 if len(unsaved_files): 1466 unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() 1467 for i,(name,value) in enumerate(unsaved_files): 1468 if not isinstance(value, str): 1469 # FIXME: It would be great to support an efficient version 1470 # of this, one day. 1471 value = value.read() 1472 print value 1473 if not isinstance(value, str): 1474 raise TypeError,'Unexpected unsaved file contents.' 1475 unsaved_files_array[i].name = name 1476 unsaved_files_array[i].contents = value 1477 unsaved_files_array[i].length = len(value) 1478 ptr = TranslationUnit_parse(self, path, arg_array, len(args), 1479 unsaved_files_array, len(unsaved_files), 1480 options) 1481 if ptr: 1482 return TranslationUnit(ptr) 1483 return None 1484 1485 1486class TranslationUnit(ClangObject): 1487 """ 1488 The TranslationUnit class represents a source code translation unit and 1489 provides read-only access to its top-level declarations. 1490 """ 1491 1492 def __init__(self, ptr): 1493 ClangObject.__init__(self, ptr) 1494 1495 def __del__(self): 1496 TranslationUnit_dispose(self) 1497 1498 @property 1499 def cursor(self): 1500 """Retrieve the cursor that represents the given translation unit.""" 1501 return TranslationUnit_cursor(self) 1502 1503 @property 1504 def spelling(self): 1505 """Get the original translation unit source file name.""" 1506 return TranslationUnit_spelling(self) 1507 1508 def get_includes(self): 1509 """ 1510 Return an iterable sequence of FileInclusion objects that describe the 1511 sequence of inclusions in a translation unit. The first object in 1512 this sequence is always the input file. Note that this method will not 1513 recursively iterate over header files included through precompiled 1514 headers. 1515 """ 1516 def visitor(fobj, lptr, depth, includes): 1517 if depth > 0: 1518 loc = lptr.contents 1519 includes.append(FileInclusion(loc.file, File(fobj), loc, depth)) 1520 1521 # Automatically adapt CIndex/ctype pointers to python objects 1522 includes = [] 1523 TranslationUnit_includes(self, 1524 TranslationUnit_includes_callback(visitor), 1525 includes) 1526 return iter(includes) 1527 1528 @property 1529 def diagnostics(self): 1530 """ 1531 Return an iterable (and indexable) object containing the diagnostics. 1532 """ 1533 class DiagIterator: 1534 def __init__(self, tu): 1535 self.tu = tu 1536 1537 def __len__(self): 1538 return int(_clang_getNumDiagnostics(self.tu)) 1539 1540 def __getitem__(self, key): 1541 diag = _clang_getDiagnostic(self.tu, key) 1542 if not diag: 1543 raise IndexError 1544 return Diagnostic(diag) 1545 1546 return DiagIterator(self) 1547 1548 def reparse(self, unsaved_files = [], options = 0): 1549 """ 1550 Reparse an already parsed translation unit. 1551 1552 In-memory contents for files can be provided by passing a list of pairs 1553 as unsaved_files, the first items should be the filenames to be mapped 1554 and the second should be the contents to be substituted for the 1555 file. The contents may be passed as strings or file objects. 1556 """ 1557 unsaved_files_array = 0 1558 if len(unsaved_files): 1559 unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() 1560 for i,(name,value) in enumerate(unsaved_files): 1561 if not isinstance(value, str): 1562 # FIXME: It would be great to support an efficient version 1563 # of this, one day. 1564 value = value.read() 1565 print value 1566 if not isinstance(value, str): 1567 raise TypeError,'Unexpected unsaved file contents.' 1568 unsaved_files_array[i].name = name 1569 unsaved_files_array[i].contents = value 1570 unsaved_files_array[i].length = len(value) 1571 ptr = TranslationUnit_reparse(self, len(unsaved_files), 1572 unsaved_files_array, 1573 options) 1574 def codeComplete(self, path, line, column, unsaved_files = [], options = 0): 1575 """ 1576 Code complete in this translation unit. 1577 1578 In-memory contents for files can be provided by passing a list of pairs 1579 as unsaved_files, the first items should be the filenames to be mapped 1580 and the second should be the contents to be substituted for the 1581 file. The contents may be passed as strings or file objects. 1582 """ 1583 unsaved_files_array = 0 1584 if len(unsaved_files): 1585 unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))() 1586 for i,(name,value) in enumerate(unsaved_files): 1587 if not isinstance(value, str): 1588 # FIXME: It would be great to support an efficient version 1589 # of this, one day. 1590 value = value.read() 1591 print value 1592 if not isinstance(value, str): 1593 raise TypeError,'Unexpected unsaved file contents.' 1594 unsaved_files_array[i].name = name 1595 unsaved_files_array[i].contents = value 1596 unsaved_files_array[i].length = len(value) 1597 ptr = TranslationUnit_codeComplete(self, path, 1598 line, column, 1599 unsaved_files_array, 1600 len(unsaved_files), 1601 options) 1602 if ptr: 1603 return CodeCompletionResults(ptr) 1604 return None 1605 1606class File(ClangObject): 1607 """ 1608 The File class represents a particular source file that is part of a 1609 translation unit. 1610 """ 1611 1612 @staticmethod 1613 def from_name(translation_unit, file_name): 1614 """Retrieve a file handle within the given translation unit.""" 1615 return File(File_getFile(translation_unit, file_name)) 1616 1617 @property 1618 def name(self): 1619 """Return the complete file and path name of the file.""" 1620 return _CXString_getCString(File_name(self)) 1621 1622 @property 1623 def time(self): 1624 """Return the last modification time of the file.""" 1625 return File_time(self) 1626 1627 def __str__(self): 1628 return self.name 1629 1630 def __repr__(self): 1631 return "<File: %s>" % (self.name) 1632 1633class FileInclusion(object): 1634 """ 1635 The FileInclusion class represents the inclusion of one source file by 1636 another via a '#include' directive or as the input file for the translation 1637 unit. This class provides information about the included file, the including 1638 file, the location of the '#include' directive and the depth of the included 1639 file in the stack. Note that the input file has depth 0. 1640 """ 1641 1642 def __init__(self, src, tgt, loc, depth): 1643 self.source = src 1644 self.include = tgt 1645 self.location = loc 1646 self.depth = depth 1647 1648 @property 1649 def is_input_file(self): 1650 """True if the included file is the input file.""" 1651 return self.depth == 0 1652 1653# Additional Functions and Types 1654 1655# String Functions 1656_CXString_dispose = lib.clang_disposeString 1657_CXString_dispose.argtypes = [_CXString] 1658 1659_CXString_getCString = lib.clang_getCString 1660_CXString_getCString.argtypes = [_CXString] 1661_CXString_getCString.restype = c_char_p 1662 1663# Source Location Functions 1664SourceLocation_loc = lib.clang_getInstantiationLocation 1665SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p), 1666 POINTER(c_uint), POINTER(c_uint), 1667 POINTER(c_uint)] 1668 1669SourceLocation_getLocation = lib.clang_getLocation 1670SourceLocation_getLocation.argtypes = [TranslationUnit, File, c_uint, c_uint] 1671SourceLocation_getLocation.restype = SourceLocation 1672 1673SourceLocation_equalLocations = lib.clang_equalLocations 1674SourceLocation_equalLocations.argtypes = [SourceLocation, SourceLocation] 1675SourceLocation_equalLocations.restype = bool 1676 1677# Source Range Functions 1678SourceRange_getRange = lib.clang_getRange 1679SourceRange_getRange.argtypes = [SourceLocation, SourceLocation] 1680SourceRange_getRange.restype = SourceRange 1681 1682SourceRange_start = lib.clang_getRangeStart 1683SourceRange_start.argtypes = [SourceRange] 1684SourceRange_start.restype = SourceLocation 1685 1686SourceRange_end = lib.clang_getRangeEnd 1687SourceRange_end.argtypes = [SourceRange] 1688SourceRange_end.restype = SourceLocation 1689 1690SourceRange_equalRanges = lib.clang_equalRanges 1691SourceRange_equalRanges.argtypes = [SourceRange, SourceRange] 1692SourceRange_equalRanges.restype = bool 1693 1694# CursorKind Functions 1695CursorKind_is_decl = lib.clang_isDeclaration 1696CursorKind_is_decl.argtypes = [CursorKind] 1697CursorKind_is_decl.restype = bool 1698 1699CursorKind_is_ref = lib.clang_isReference 1700CursorKind_is_ref.argtypes = [CursorKind] 1701CursorKind_is_ref.restype = bool 1702 1703CursorKind_is_expr = lib.clang_isExpression 1704CursorKind_is_expr.argtypes = [CursorKind] 1705CursorKind_is_expr.restype = bool 1706 1707CursorKind_is_stmt = lib.clang_isStatement 1708CursorKind_is_stmt.argtypes = [CursorKind] 1709CursorKind_is_stmt.restype = bool 1710 1711CursorKind_is_attribute = lib.clang_isAttribute 1712CursorKind_is_attribute.argtypes = [CursorKind] 1713CursorKind_is_attribute.restype = bool 1714 1715CursorKind_is_inv = lib.clang_isInvalid 1716CursorKind_is_inv.argtypes = [CursorKind] 1717CursorKind_is_inv.restype = bool 1718 1719# Cursor Functions 1720# TODO: Implement this function 1721Cursor_get = lib.clang_getCursor 1722Cursor_get.argtypes = [TranslationUnit, SourceLocation] 1723Cursor_get.restype = Cursor 1724 1725Cursor_null = lib.clang_getNullCursor 1726Cursor_null.restype = Cursor 1727 1728Cursor_usr = lib.clang_getCursorUSR 1729Cursor_usr.argtypes = [Cursor] 1730Cursor_usr.restype = _CXString 1731Cursor_usr.errcheck = _CXString.from_result 1732 1733Cursor_is_def = lib.clang_isCursorDefinition 1734Cursor_is_def.argtypes = [Cursor] 1735Cursor_is_def.restype = bool 1736 1737Cursor_def = lib.clang_getCursorDefinition 1738Cursor_def.argtypes = [Cursor] 1739Cursor_def.restype = Cursor 1740Cursor_def.errcheck = Cursor.from_result 1741 1742Cursor_eq = lib.clang_equalCursors 1743Cursor_eq.argtypes = [Cursor, Cursor] 1744Cursor_eq.restype = c_uint 1745 1746Cursor_hash = lib.clang_hashCursor 1747Cursor_hash.argtypes = [Cursor] 1748Cursor_hash.restype = c_uint 1749 1750Cursor_spelling = lib.clang_getCursorSpelling 1751Cursor_spelling.argtypes = [Cursor] 1752Cursor_spelling.restype = _CXString 1753Cursor_spelling.errcheck = _CXString.from_result 1754 1755Cursor_displayname = lib.clang_getCursorDisplayName 1756Cursor_displayname.argtypes = [Cursor] 1757Cursor_displayname.restype = _CXString 1758Cursor_displayname.errcheck = _CXString.from_result 1759 1760Cursor_loc = lib.clang_getCursorLocation 1761Cursor_loc.argtypes = [Cursor] 1762Cursor_loc.restype = SourceLocation 1763 1764Cursor_extent = lib.clang_getCursorExtent 1765Cursor_extent.argtypes = [Cursor] 1766Cursor_extent.restype = SourceRange 1767 1768Cursor_ref = lib.clang_getCursorReferenced 1769Cursor_ref.argtypes = [Cursor] 1770Cursor_ref.restype = Cursor 1771Cursor_ref.errcheck = Cursor.from_result 1772 1773Cursor_type = lib.clang_getCursorType 1774Cursor_type.argtypes = [Cursor] 1775Cursor_type.restype = Type 1776Cursor_type.errcheck = Type.from_result 1777 1778Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object) 1779Cursor_visit = lib.clang_visitChildren 1780Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object] 1781Cursor_visit.restype = c_uint 1782 1783# Type Functions 1784Type_get_canonical = lib.clang_getCanonicalType 1785Type_get_canonical.argtypes = [Type] 1786Type_get_canonical.restype = Type 1787Type_get_canonical.errcheck = Type.from_result 1788 1789Type_is_const_qualified = lib.clang_isConstQualifiedType 1790Type_is_const_qualified.argtypes = [Type] 1791Type_is_const_qualified.restype = bool 1792 1793Type_is_volatile_qualified = lib.clang_isVolatileQualifiedType 1794Type_is_volatile_qualified.argtypes = [Type] 1795Type_is_volatile_qualified.restype = bool 1796 1797Type_is_restrict_qualified = lib.clang_isRestrictQualifiedType 1798Type_is_restrict_qualified.argtypes = [Type] 1799Type_is_restrict_qualified.restype = bool 1800 1801Type_get_pointee = lib.clang_getPointeeType 1802Type_get_pointee.argtypes = [Type] 1803Type_get_pointee.restype = Type 1804Type_get_pointee.errcheck = Type.from_result 1805 1806Type_get_declaration = lib.clang_getTypeDeclaration 1807Type_get_declaration.argtypes = [Type] 1808Type_get_declaration.restype = Cursor 1809Type_get_declaration.errcheck = Cursor.from_result 1810 1811Type_get_result = lib.clang_getResultType 1812Type_get_result.argtypes = [Type] 1813Type_get_result.restype = Type 1814Type_get_result.errcheck = Type.from_result 1815 1816Type_get_array_element = lib.clang_getArrayElementType 1817Type_get_array_element.argtypes = [Type] 1818Type_get_array_element.restype = Type 1819Type_get_array_element.errcheck = Type.from_result 1820 1821Type_get_array_size = lib.clang_getArraySize 1822Type_get_array_size.argtype = [Type] 1823Type_get_array_size.restype = c_longlong 1824 1825# Index Functions 1826Index_create = lib.clang_createIndex 1827Index_create.argtypes = [c_int, c_int] 1828Index_create.restype = c_object_p 1829 1830Index_dispose = lib.clang_disposeIndex 1831Index_dispose.argtypes = [Index] 1832 1833# Translation Unit Functions 1834TranslationUnit_read = lib.clang_createTranslationUnit 1835TranslationUnit_read.argtypes = [Index, c_char_p] 1836TranslationUnit_read.restype = c_object_p 1837 1838TranslationUnit_parse = lib.clang_parseTranslationUnit 1839TranslationUnit_parse.argtypes = [Index, c_char_p, c_void_p, 1840 c_int, c_void_p, c_int, c_int] 1841TranslationUnit_parse.restype = c_object_p 1842 1843TranslationUnit_reparse = lib.clang_reparseTranslationUnit 1844TranslationUnit_reparse.argtypes = [TranslationUnit, c_int, c_void_p, c_int] 1845TranslationUnit_reparse.restype = c_int 1846 1847TranslationUnit_codeComplete = lib.clang_codeCompleteAt 1848TranslationUnit_codeComplete.argtypes = [TranslationUnit, c_char_p, c_int, 1849 c_int, c_void_p, c_int, c_int] 1850TranslationUnit_codeComplete.restype = POINTER(CCRStructure) 1851 1852TranslationUnit_cursor = lib.clang_getTranslationUnitCursor 1853TranslationUnit_cursor.argtypes = [TranslationUnit] 1854TranslationUnit_cursor.restype = Cursor 1855TranslationUnit_cursor.errcheck = Cursor.from_result 1856 1857TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling 1858TranslationUnit_spelling.argtypes = [TranslationUnit] 1859TranslationUnit_spelling.restype = _CXString 1860TranslationUnit_spelling.errcheck = _CXString.from_result 1861 1862TranslationUnit_dispose = lib.clang_disposeTranslationUnit 1863TranslationUnit_dispose.argtypes = [TranslationUnit] 1864 1865TranslationUnit_includes_callback = CFUNCTYPE(None, 1866 c_object_p, 1867 POINTER(SourceLocation), 1868 c_uint, py_object) 1869TranslationUnit_includes = lib.clang_getInclusions 1870TranslationUnit_includes.argtypes = [TranslationUnit, 1871 TranslationUnit_includes_callback, 1872 py_object] 1873 1874# File Functions 1875File_getFile = lib.clang_getFile 1876File_getFile.argtypes = [TranslationUnit, c_char_p] 1877File_getFile.restype = c_object_p 1878 1879File_name = lib.clang_getFileName 1880File_name.argtypes = [File] 1881File_name.restype = _CXString 1882 1883File_time = lib.clang_getFileTime 1884File_time.argtypes = [File] 1885File_time.restype = c_uint 1886 1887# Code completion 1888 1889CodeCompletionResults_dispose = lib.clang_disposeCodeCompleteResults 1890CodeCompletionResults_dispose.argtypes = [CodeCompletionResults] 1891 1892_clang_codeCompleteGetNumDiagnostics = lib.clang_codeCompleteGetNumDiagnostics 1893_clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults] 1894_clang_codeCompleteGetNumDiagnostics.restype = c_int 1895 1896_clang_codeCompleteGetDiagnostic = lib.clang_codeCompleteGetDiagnostic 1897_clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults, c_int] 1898_clang_codeCompleteGetDiagnostic.restype = Diagnostic 1899 1900_clang_getCompletionChunkText = lib.clang_getCompletionChunkText 1901_clang_getCompletionChunkText.argtypes = [c_void_p, c_int] 1902_clang_getCompletionChunkText.restype = _CXString 1903 1904_clang_getCompletionChunkKind = lib.clang_getCompletionChunkKind 1905_clang_getCompletionChunkKind.argtypes = [c_void_p, c_int] 1906_clang_getCompletionChunkKind.restype = c_int 1907 1908_clang_getCompletionChunkCompletionString = lib.clang_getCompletionChunkCompletionString 1909_clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int] 1910_clang_getCompletionChunkCompletionString.restype = c_object_p 1911 1912_clang_getNumCompletionChunks = lib.clang_getNumCompletionChunks 1913_clang_getNumCompletionChunks.argtypes = [c_void_p] 1914_clang_getNumCompletionChunks.restype = c_int 1915 1916_clang_getCompletionAvailability = lib.clang_getCompletionAvailability 1917_clang_getCompletionAvailability.argtypes = [c_void_p] 1918_clang_getCompletionAvailability.restype = c_int 1919 1920_clang_getCompletionPriority = lib.clang_getCompletionPriority 1921_clang_getCompletionPriority.argtypes = [c_void_p] 1922_clang_getCompletionPriority.restype = c_int 1923 1924 1925### 1926 1927__all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind', 'Type', 'TypeKind', 1928 'Diagnostic', 'FixIt', 'CodeCompletionResults', 'SourceRange', 1929 'SourceLocation', 'File'] 1930