1#===- core.py - Python LLVM Bindings -------------------------*- python -*--===# 2# 3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4# See https://llvm.org/LICENSE.txt for license information. 5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6# 7#===------------------------------------------------------------------------===# 8from __future__ import print_function 9 10from .common import LLVMObject 11from .common import c_object_p 12from .common import get_library 13 14from . import enumerations 15 16from ctypes import POINTER 17from ctypes import byref 18from ctypes import c_char_p 19from ctypes import c_uint 20 21import sys 22 23__all__ = [ 24 "lib", 25 "Enums", 26 "OpCode", 27 "MemoryBuffer", 28 "Module", 29 "Value", 30 "Function", 31 "BasicBlock", 32 "Instruction", 33 "Context", 34 "PassRegistry" 35] 36 37lib = get_library() 38Enums = [] 39 40class LLVMEnumeration(object): 41 """Represents an individual LLVM enumeration.""" 42 43 def __init__(self, name, value): 44 self.name = name 45 self.value = value 46 47 def __repr__(self): 48 return '%s.%s' % (self.__class__.__name__, 49 self.name) 50 51 @classmethod 52 def from_value(cls, value): 53 """Obtain an enumeration instance from a numeric value.""" 54 result = cls._value_map.get(value, None) 55 56 if result is None: 57 raise ValueError('Unknown %s: %d' % (cls.__name__, 58 value)) 59 60 return result 61 62 @classmethod 63 def register(cls, name, value): 64 """Registers a new enumeration. 65 66 This is called by this module for each enumeration defined in 67 enumerations. You should not need to call this outside this module. 68 """ 69 if value in cls._value_map: 70 raise ValueError('%s value already registered: %d' % (cls.__name__, 71 value)) 72 enum = cls(name, value) 73 cls._value_map[value] = enum 74 setattr(cls, name, enum) 75 76class Attribute(LLVMEnumeration): 77 """Represents an individual Attribute enumeration.""" 78 79 _value_map = {} 80 81 def __init__(self, name, value): 82 super(Attribute, self).__init__(name, value) 83 84class OpCode(LLVMEnumeration): 85 """Represents an individual OpCode enumeration.""" 86 87 _value_map = {} 88 89 def __init__(self, name, value): 90 super(OpCode, self).__init__(name, value) 91 92class TypeKind(LLVMEnumeration): 93 """Represents an individual TypeKind enumeration.""" 94 95 _value_map = {} 96 97 def __init__(self, name, value): 98 super(TypeKind, self).__init__(name, value) 99 100class Linkage(LLVMEnumeration): 101 """Represents an individual Linkage enumeration.""" 102 103 _value_map = {} 104 105 def __init__(self, name, value): 106 super(Linkage, self).__init__(name, value) 107 108class Visibility(LLVMEnumeration): 109 """Represents an individual visibility enumeration.""" 110 111 _value_map = {} 112 113 def __init__(self, name, value): 114 super(Visibility, self).__init__(name, value) 115 116class CallConv(LLVMEnumeration): 117 """Represents an individual calling convention enumeration.""" 118 119 _value_map = {} 120 121 def __init__(self, name, value): 122 super(CallConv, self).__init__(name, value) 123 124class IntPredicate(LLVMEnumeration): 125 """Represents an individual IntPredicate enumeration.""" 126 127 _value_map = {} 128 129 def __init__(self, name, value): 130 super(IntPredicate, self).__init__(name, value) 131 132class RealPredicate(LLVMEnumeration): 133 """Represents an individual RealPredicate enumeration.""" 134 135 _value_map = {} 136 137 def __init__(self, name, value): 138 super(RealPredicate, self).__init__(name, value) 139 140class LandingPadClauseTy(LLVMEnumeration): 141 """Represents an individual LandingPadClauseTy enumeration.""" 142 143 _value_map = {} 144 145 def __init__(self, name, value): 146 super(LandingPadClauseTy, self).__init__(name, value) 147 148class MemoryBuffer(LLVMObject): 149 """Represents an opaque memory buffer.""" 150 151 def __init__(self, filename=None): 152 """Create a new memory buffer. 153 154 Currently, we support creating from the contents of a file at the 155 specified filename. 156 """ 157 if filename is None: 158 raise Exception("filename argument must be defined") 159 160 memory = c_object_p() 161 out = c_char_p(None) 162 163 result = lib.LLVMCreateMemoryBufferWithContentsOfFile(filename, 164 byref(memory), byref(out)) 165 166 if result: 167 raise Exception("Could not create memory buffer: %s" % out.value) 168 169 LLVMObject.__init__(self, memory, disposer=lib.LLVMDisposeMemoryBuffer) 170 171 def __len__(self): 172 return lib.LLVMGetBufferSize(self) 173 174class Value(LLVMObject): 175 176 def __init__(self, value): 177 LLVMObject.__init__(self, value) 178 179 @property 180 def name(self): 181 return lib.LLVMGetValueName(self) 182 183 def dump(self): 184 lib.LLVMDumpValue(self) 185 186 def get_operand(self, i): 187 return Value(lib.LLVMGetOperand(self, i)) 188 189 def set_operand(self, i, v): 190 return lib.LLVMSetOperand(self, i, v) 191 192 def __len__(self): 193 return lib.LLVMGetNumOperands(self) 194 195class Module(LLVMObject): 196 """Represents the top-level structure of an llvm program in an opaque object.""" 197 198 def __init__(self, module, name=None, context=None): 199 LLVMObject.__init__(self, module, disposer=lib.LLVMDisposeModule) 200 201 @classmethod 202 def CreateWithName(cls, module_id): 203 m = Module(lib.LLVMModuleCreateWithName(module_id)) 204 Context.GetGlobalContext().take_ownership(m) 205 return m 206 207 @property 208 def datalayout(self): 209 return lib.LLVMGetDataLayout(self) 210 211 @datalayout.setter 212 def datalayout(self, new_data_layout): 213 """new_data_layout is a string.""" 214 lib.LLVMSetDataLayout(self, new_data_layout) 215 216 @property 217 def target(self): 218 return lib.LLVMGetTarget(self) 219 220 @target.setter 221 def target(self, new_target): 222 """new_target is a string.""" 223 lib.LLVMSetTarget(self, new_target) 224 225 def dump(self): 226 lib.LLVMDumpModule(self) 227 228 class __function_iterator(object): 229 def __init__(self, module, reverse=False): 230 self.module = module 231 self.reverse = reverse 232 if self.reverse: 233 self.function = self.module.last 234 else: 235 self.function = self.module.first 236 237 def __iter__(self): 238 return self 239 240 def __next__(self): 241 if not isinstance(self.function, Function): 242 raise StopIteration("") 243 result = self.function 244 if self.reverse: 245 self.function = self.function.prev 246 else: 247 self.function = self.function.next 248 return result 249 250 if sys.version_info.major == 2: 251 next = __next__ 252 253 def __iter__(self): 254 return Module.__function_iterator(self) 255 256 def __reversed__(self): 257 return Module.__function_iterator(self, reverse=True) 258 259 @property 260 def first(self): 261 return Function(lib.LLVMGetFirstFunction(self)) 262 263 @property 264 def last(self): 265 return Function(lib.LLVMGetLastFunction(self)) 266 267 def print_module_to_file(self, filename): 268 out = c_char_p(None) 269 # Result is inverted so 0 means everything was ok. 270 result = lib.LLVMPrintModuleToFile(self, filename, byref(out)) 271 if result: 272 raise RuntimeError("LLVM Error: %s" % out.value) 273 274class Function(Value): 275 276 def __init__(self, value): 277 Value.__init__(self, value) 278 279 @property 280 def next(self): 281 f = lib.LLVMGetNextFunction(self) 282 return f and Function(f) 283 284 @property 285 def prev(self): 286 f = lib.LLVMGetPreviousFunction(self) 287 return f and Function(f) 288 289 @property 290 def first(self): 291 b = lib.LLVMGetFirstBasicBlock(self) 292 return b and BasicBlock(b) 293 294 @property 295 def last(self): 296 b = lib.LLVMGetLastBasicBlock(self) 297 return b and BasicBlock(b) 298 299 class __bb_iterator(object): 300 def __init__(self, function, reverse=False): 301 self.function = function 302 self.reverse = reverse 303 if self.reverse: 304 self.bb = function.last 305 else: 306 self.bb = function.first 307 308 def __iter__(self): 309 return self 310 311 def __next__(self): 312 if not isinstance(self.bb, BasicBlock): 313 raise StopIteration("") 314 result = self.bb 315 if self.reverse: 316 self.bb = self.bb.prev 317 else: 318 self.bb = self.bb.next 319 return result 320 321 if sys.version_info.major == 2: 322 next = __next__ 323 324 def __iter__(self): 325 return Function.__bb_iterator(self) 326 327 def __reversed__(self): 328 return Function.__bb_iterator(self, reverse=True) 329 330 def __len__(self): 331 return lib.LLVMCountBasicBlocks(self) 332 333class BasicBlock(LLVMObject): 334 335 def __init__(self, value): 336 LLVMObject.__init__(self, value) 337 338 @property 339 def next(self): 340 b = lib.LLVMGetNextBasicBlock(self) 341 return b and BasicBlock(b) 342 343 @property 344 def prev(self): 345 b = lib.LLVMGetPreviousBasicBlock(self) 346 return b and BasicBlock(b) 347 348 @property 349 def first(self): 350 i = lib.LLVMGetFirstInstruction(self) 351 return i and Instruction(i) 352 353 @property 354 def last(self): 355 i = lib.LLVMGetLastInstruction(self) 356 return i and Instruction(i) 357 358 def __as_value(self): 359 return Value(lib.LLVMBasicBlockAsValue(self)) 360 361 @property 362 def name(self): 363 return lib.LLVMGetValueName(self.__as_value()) 364 365 def dump(self): 366 lib.LLVMDumpValue(self.__as_value()) 367 368 def get_operand(self, i): 369 return Value(lib.LLVMGetOperand(self.__as_value(), 370 i)) 371 372 def set_operand(self, i, v): 373 return lib.LLVMSetOperand(self.__as_value(), 374 i, v) 375 376 def __len__(self): 377 return lib.LLVMGetNumOperands(self.__as_value()) 378 379 class __inst_iterator(object): 380 def __init__(self, bb, reverse=False): 381 self.bb = bb 382 self.reverse = reverse 383 if self.reverse: 384 self.inst = self.bb.last 385 else: 386 self.inst = self.bb.first 387 388 def __iter__(self): 389 return self 390 391 def __next__(self): 392 if not isinstance(self.inst, Instruction): 393 raise StopIteration("") 394 result = self.inst 395 if self.reverse: 396 self.inst = self.inst.prev 397 else: 398 self.inst = self.inst.next 399 return result 400 401 if sys.version_info.major == 2: 402 next = __next__ 403 404 def __iter__(self): 405 return BasicBlock.__inst_iterator(self) 406 407 def __reversed__(self): 408 return BasicBlock.__inst_iterator(self, reverse=True) 409 410 411class Instruction(Value): 412 413 def __init__(self, value): 414 Value.__init__(self, value) 415 416 @property 417 def next(self): 418 i = lib.LLVMGetNextInstruction(self) 419 return i and Instruction(i) 420 421 @property 422 def prev(self): 423 i = lib.LLVMGetPreviousInstruction(self) 424 return i and Instruction(i) 425 426 @property 427 def opcode(self): 428 return OpCode.from_value(lib.LLVMGetInstructionOpcode(self)) 429 430class Context(LLVMObject): 431 432 def __init__(self, context=None): 433 if context is None: 434 context = lib.LLVMContextCreate() 435 LLVMObject.__init__(self, context, disposer=lib.LLVMContextDispose) 436 else: 437 LLVMObject.__init__(self, context) 438 439 @classmethod 440 def GetGlobalContext(cls): 441 return Context(lib.LLVMGetGlobalContext()) 442 443class PassRegistry(LLVMObject): 444 """Represents an opaque pass registry object.""" 445 446 def __init__(self): 447 LLVMObject.__init__(self, 448 lib.LLVMGetGlobalPassRegistry()) 449 450def register_library(library): 451 # Initialization/Shutdown declarations. 452 library.LLVMInitializeCore.argtypes = [PassRegistry] 453 library.LLVMInitializeCore.restype = None 454 455 library.LLVMInitializeTransformUtils.argtypes = [PassRegistry] 456 library.LLVMInitializeTransformUtils.restype = None 457 458 library.LLVMInitializeScalarOpts.argtypes = [PassRegistry] 459 library.LLVMInitializeScalarOpts.restype = None 460 461 library.LLVMInitializeObjCARCOpts.argtypes = [PassRegistry] 462 library.LLVMInitializeObjCARCOpts.restype = None 463 464 library.LLVMInitializeVectorization.argtypes = [PassRegistry] 465 library.LLVMInitializeVectorization.restype = None 466 467 library.LLVMInitializeInstCombine.argtypes = [PassRegistry] 468 library.LLVMInitializeInstCombine.restype = None 469 470 library.LLVMInitializeAggressiveInstCombiner.argtypes = [PassRegistry] 471 library.LLVMInitializeAggressiveInstCombiner.restype = None 472 473 library.LLVMInitializeIPO.argtypes = [PassRegistry] 474 library.LLVMInitializeIPO.restype = None 475 476 library.LLVMInitializeInstrumentation.argtypes = [PassRegistry] 477 library.LLVMInitializeInstrumentation.restype = None 478 479 library.LLVMInitializeAnalysis.argtypes = [PassRegistry] 480 library.LLVMInitializeAnalysis.restype = None 481 482 library.LLVMInitializeCodeGen.argtypes = [PassRegistry] 483 library.LLVMInitializeCodeGen.restype = None 484 485 library.LLVMInitializeTarget.argtypes = [PassRegistry] 486 library.LLVMInitializeTarget.restype = None 487 488 library.LLVMShutdown.argtypes = [] 489 library.LLVMShutdown.restype = None 490 491 # Pass Registry declarations. 492 library.LLVMGetGlobalPassRegistry.argtypes = [] 493 library.LLVMGetGlobalPassRegistry.restype = c_object_p 494 495 # Context declarations. 496 library.LLVMContextCreate.argtypes = [] 497 library.LLVMContextCreate.restype = c_object_p 498 499 library.LLVMContextDispose.argtypes = [Context] 500 library.LLVMContextDispose.restype = None 501 502 library.LLVMGetGlobalContext.argtypes = [] 503 library.LLVMGetGlobalContext.restype = c_object_p 504 505 # Memory buffer declarations 506 library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p, 507 POINTER(c_object_p), POINTER(c_char_p)] 508 library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool 509 510 library.LLVMGetBufferSize.argtypes = [MemoryBuffer] 511 512 library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer] 513 514 # Module declarations 515 library.LLVMModuleCreateWithName.argtypes = [c_char_p] 516 library.LLVMModuleCreateWithName.restype = c_object_p 517 518 library.LLVMDisposeModule.argtypes = [Module] 519 library.LLVMDisposeModule.restype = None 520 521 library.LLVMGetDataLayout.argtypes = [Module] 522 library.LLVMGetDataLayout.restype = c_char_p 523 524 library.LLVMSetDataLayout.argtypes = [Module, c_char_p] 525 library.LLVMSetDataLayout.restype = None 526 527 library.LLVMGetTarget.argtypes = [Module] 528 library.LLVMGetTarget.restype = c_char_p 529 530 library.LLVMSetTarget.argtypes = [Module, c_char_p] 531 library.LLVMSetTarget.restype = None 532 533 library.LLVMDumpModule.argtypes = [Module] 534 library.LLVMDumpModule.restype = None 535 536 library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p, 537 POINTER(c_char_p)] 538 library.LLVMPrintModuleToFile.restype = bool 539 540 library.LLVMGetFirstFunction.argtypes = [Module] 541 library.LLVMGetFirstFunction.restype = c_object_p 542 543 library.LLVMGetLastFunction.argtypes = [Module] 544 library.LLVMGetLastFunction.restype = c_object_p 545 546 library.LLVMGetNextFunction.argtypes = [Function] 547 library.LLVMGetNextFunction.restype = c_object_p 548 549 library.LLVMGetPreviousFunction.argtypes = [Function] 550 library.LLVMGetPreviousFunction.restype = c_object_p 551 552 # Value declarations. 553 library.LLVMGetValueName.argtypes = [Value] 554 library.LLVMGetValueName.restype = c_char_p 555 556 library.LLVMDumpValue.argtypes = [Value] 557 library.LLVMDumpValue.restype = None 558 559 library.LLVMGetOperand.argtypes = [Value, c_uint] 560 library.LLVMGetOperand.restype = c_object_p 561 562 library.LLVMSetOperand.argtypes = [Value, Value, c_uint] 563 library.LLVMSetOperand.restype = None 564 565 library.LLVMGetNumOperands.argtypes = [Value] 566 library.LLVMGetNumOperands.restype = c_uint 567 568 # Basic Block Declarations. 569 library.LLVMGetFirstBasicBlock.argtypes = [Function] 570 library.LLVMGetFirstBasicBlock.restype = c_object_p 571 572 library.LLVMGetLastBasicBlock.argtypes = [Function] 573 library.LLVMGetLastBasicBlock.restype = c_object_p 574 575 library.LLVMGetNextBasicBlock.argtypes = [BasicBlock] 576 library.LLVMGetNextBasicBlock.restype = c_object_p 577 578 library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock] 579 library.LLVMGetPreviousBasicBlock.restype = c_object_p 580 581 library.LLVMGetFirstInstruction.argtypes = [BasicBlock] 582 library.LLVMGetFirstInstruction.restype = c_object_p 583 584 library.LLVMGetLastInstruction.argtypes = [BasicBlock] 585 library.LLVMGetLastInstruction.restype = c_object_p 586 587 library.LLVMBasicBlockAsValue.argtypes = [BasicBlock] 588 library.LLVMBasicBlockAsValue.restype = c_object_p 589 590 library.LLVMCountBasicBlocks.argtypes = [Function] 591 library.LLVMCountBasicBlocks.restype = c_uint 592 593 # Instruction Declarations. 594 library.LLVMGetNextInstruction.argtypes = [Instruction] 595 library.LLVMGetNextInstruction.restype = c_object_p 596 597 library.LLVMGetPreviousInstruction.argtypes = [Instruction] 598 library.LLVMGetPreviousInstruction.restype = c_object_p 599 600 library.LLVMGetInstructionOpcode.argtypes = [Instruction] 601 library.LLVMGetInstructionOpcode.restype = c_uint 602 603def register_enumerations(): 604 if Enums: 605 return None 606 enums = [ 607 (Attribute, enumerations.Attributes), 608 (OpCode, enumerations.OpCodes), 609 (TypeKind, enumerations.TypeKinds), 610 (Linkage, enumerations.Linkages), 611 (Visibility, enumerations.Visibility), 612 (CallConv, enumerations.CallConv), 613 (IntPredicate, enumerations.IntPredicate), 614 (RealPredicate, enumerations.RealPredicate), 615 (LandingPadClauseTy, enumerations.LandingPadClauseTy), 616 ] 617 for enum_class, enum_spec in enums: 618 for name, value in enum_spec: 619 print(name, value) 620 enum_class.register(name, value) 621 return enums 622 623def initialize_llvm(): 624 Context.GetGlobalContext() 625 p = PassRegistry() 626 lib.LLVMInitializeCore(p) 627 lib.LLVMInitializeTransformUtils(p) 628 lib.LLVMInitializeScalarOpts(p) 629 lib.LLVMInitializeObjCARCOpts(p) 630 lib.LLVMInitializeVectorization(p) 631 lib.LLVMInitializeInstCombine(p) 632 lib.LLVMInitializeIPO(p) 633 lib.LLVMInitializeInstrumentation(p) 634 lib.LLVMInitializeAnalysis(p) 635 lib.LLVMInitializeCodeGen(p) 636 lib.LLVMInitializeTarget(p) 637 638register_library(lib) 639Enums = register_enumerations() 640initialize_llvm() 641