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