Home | History | Annotate | Line # | Download | only in llvm
      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 #===------------------------------------------------------------------------===#
      8 from __future__ import print_function
      9 
     10 from .common import LLVMObject
     11 from .common import c_object_p
     12 from .common import get_library
     13 
     14 from . import enumerations
     15 
     16 from ctypes import POINTER
     17 from ctypes import byref
     18 from ctypes import c_char_p
     19 from ctypes import c_uint
     20 
     21 import 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 
     37 lib = get_library()
     38 Enums = []
     39 
     40 class 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 
     76 class 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 
     84 class 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 
     92 class 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 
    100 class 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 
    108 class 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 
    116 class 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 
    124 class 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 
    132 class 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 
    140 class 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 
    148 class 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 
    174 class 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 
    195 class 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 
    274 class 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 
    333 class 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 
    411 class 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 
    430 class 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 
    443 class PassRegistry(LLVMObject):
    444     """Represents an opaque pass registry object."""
    445 
    446     def __init__(self):
    447         LLVMObject.__init__(self,
    448                             lib.LLVMGetGlobalPassRegistry())
    449 
    450 def 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 
    603 def 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 
    623 def 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 
    638 register_library(lib)
    639 Enums = register_enumerations()
    640 initialize_llvm()
    641