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.LLVMInitializeVectorization.argtypes = [PassRegistry] 462 library.LLVMInitializeVectorization.restype = None 463 464 library.LLVMInitializeInstCombine.argtypes = [PassRegistry] 465 library.LLVMInitializeInstCombine.restype = None 466 467 library.LLVMInitializeIPO.argtypes = [PassRegistry] 468 library.LLVMInitializeIPO.restype = None 469 470 library.LLVMInitializeAnalysis.argtypes = [PassRegistry] 471 library.LLVMInitializeAnalysis.restype = None 472 473 library.LLVMInitializeCodeGen.argtypes = [PassRegistry] 474 library.LLVMInitializeCodeGen.restype = None 475 476 library.LLVMInitializeTarget.argtypes = [PassRegistry] 477 library.LLVMInitializeTarget.restype = None 478 479 library.LLVMShutdown.argtypes = [] 480 library.LLVMShutdown.restype = None 481 482 # Pass Registry declarations. 483 library.LLVMGetGlobalPassRegistry.argtypes = [] 484 library.LLVMGetGlobalPassRegistry.restype = c_object_p 485 486 # Context declarations. 487 library.LLVMContextCreate.argtypes = [] 488 library.LLVMContextCreate.restype = c_object_p 489 490 library.LLVMContextDispose.argtypes = [Context] 491 library.LLVMContextDispose.restype = None 492 493 library.LLVMGetGlobalContext.argtypes = [] 494 library.LLVMGetGlobalContext.restype = c_object_p 495 496 # Memory buffer declarations 497 library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p, 498 POINTER(c_object_p), POINTER(c_char_p)] 499 library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool 500 501 library.LLVMGetBufferSize.argtypes = [MemoryBuffer] 502 503 library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer] 504 505 # Module declarations 506 library.LLVMModuleCreateWithName.argtypes = [c_char_p] 507 library.LLVMModuleCreateWithName.restype = c_object_p 508 509 library.LLVMDisposeModule.argtypes = [Module] 510 library.LLVMDisposeModule.restype = None 511 512 library.LLVMGetDataLayout.argtypes = [Module] 513 library.LLVMGetDataLayout.restype = c_char_p 514 515 library.LLVMSetDataLayout.argtypes = [Module, c_char_p] 516 library.LLVMSetDataLayout.restype = None 517 518 library.LLVMGetTarget.argtypes = [Module] 519 library.LLVMGetTarget.restype = c_char_p 520 521 library.LLVMSetTarget.argtypes = [Module, c_char_p] 522 library.LLVMSetTarget.restype = None 523 524 library.LLVMDumpModule.argtypes = [Module] 525 library.LLVMDumpModule.restype = None 526 527 library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p, 528 POINTER(c_char_p)] 529 library.LLVMPrintModuleToFile.restype = bool 530 531 library.LLVMGetFirstFunction.argtypes = [Module] 532 library.LLVMGetFirstFunction.restype = c_object_p 533 534 library.LLVMGetLastFunction.argtypes = [Module] 535 library.LLVMGetLastFunction.restype = c_object_p 536 537 library.LLVMGetNextFunction.argtypes = [Function] 538 library.LLVMGetNextFunction.restype = c_object_p 539 540 library.LLVMGetPreviousFunction.argtypes = [Function] 541 library.LLVMGetPreviousFunction.restype = c_object_p 542 543 # Value declarations. 544 library.LLVMGetValueName.argtypes = [Value] 545 library.LLVMGetValueName.restype = c_char_p 546 547 library.LLVMDumpValue.argtypes = [Value] 548 library.LLVMDumpValue.restype = None 549 550 library.LLVMGetOperand.argtypes = [Value, c_uint] 551 library.LLVMGetOperand.restype = c_object_p 552 553 library.LLVMSetOperand.argtypes = [Value, Value, c_uint] 554 library.LLVMSetOperand.restype = None 555 556 library.LLVMGetNumOperands.argtypes = [Value] 557 library.LLVMGetNumOperands.restype = c_uint 558 559 # Basic Block Declarations. 560 library.LLVMGetFirstBasicBlock.argtypes = [Function] 561 library.LLVMGetFirstBasicBlock.restype = c_object_p 562 563 library.LLVMGetLastBasicBlock.argtypes = [Function] 564 library.LLVMGetLastBasicBlock.restype = c_object_p 565 566 library.LLVMGetNextBasicBlock.argtypes = [BasicBlock] 567 library.LLVMGetNextBasicBlock.restype = c_object_p 568 569 library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock] 570 library.LLVMGetPreviousBasicBlock.restype = c_object_p 571 572 library.LLVMGetFirstInstruction.argtypes = [BasicBlock] 573 library.LLVMGetFirstInstruction.restype = c_object_p 574 575 library.LLVMGetLastInstruction.argtypes = [BasicBlock] 576 library.LLVMGetLastInstruction.restype = c_object_p 577 578 library.LLVMBasicBlockAsValue.argtypes = [BasicBlock] 579 library.LLVMBasicBlockAsValue.restype = c_object_p 580 581 library.LLVMCountBasicBlocks.argtypes = [Function] 582 library.LLVMCountBasicBlocks.restype = c_uint 583 584 # Instruction Declarations. 585 library.LLVMGetNextInstruction.argtypes = [Instruction] 586 library.LLVMGetNextInstruction.restype = c_object_p 587 588 library.LLVMGetPreviousInstruction.argtypes = [Instruction] 589 library.LLVMGetPreviousInstruction.restype = c_object_p 590 591 library.LLVMGetInstructionOpcode.argtypes = [Instruction] 592 library.LLVMGetInstructionOpcode.restype = c_uint 593 594def register_enumerations(): 595 if Enums: 596 return None 597 enums = [ 598 (Attribute, enumerations.Attributes), 599 (OpCode, enumerations.OpCodes), 600 (TypeKind, enumerations.TypeKinds), 601 (Linkage, enumerations.Linkages), 602 (Visibility, enumerations.Visibility), 603 (CallConv, enumerations.CallConv), 604 (IntPredicate, enumerations.IntPredicate), 605 (RealPredicate, enumerations.RealPredicate), 606 (LandingPadClauseTy, enumerations.LandingPadClauseTy), 607 ] 608 for enum_class, enum_spec in enums: 609 for name, value in enum_spec: 610 print(name, value) 611 enum_class.register(name, value) 612 return enums 613 614def initialize_llvm(): 615 Context.GetGlobalContext() 616 p = PassRegistry() 617 lib.LLVMInitializeCore(p) 618 lib.LLVMInitializeTransformUtils(p) 619 lib.LLVMInitializeScalarOpts(p) 620 lib.LLVMInitializeVectorization(p) 621 lib.LLVMInitializeInstCombine(p) 622 lib.LLVMInitializeIPO(p) 623 lib.LLVMInitializeAnalysis(p) 624 lib.LLVMInitializeCodeGen(p) 625 lib.LLVMInitializeTarget(p) 626 627register_library(lib) 628Enums = register_enumerations() 629initialize_llvm() 630