__all__ = [
"lib",
+ "Enums",
"OpCode",
"MemoryBuffer",
"Module",
"Value",
"Function",
"BasicBlock",
+ "Instruction",
"Context",
"PassRegistry"
]
lib = get_library()
+Enums = []
-class OpCode(object):
- """Represents an individual OpCode enumeration."""
-
- _value_map = {}
+class LLVMEnumeration(object):
+ """Represents an individual LLVM enumeration."""
def __init__(self, name, value):
self.name = name
self.value = value
def __repr__(self):
- return 'OpCode.%s' % self.name
+ return '%s.%s' % (self.__class__.__name__,
+ self.name)
- @staticmethod
- def from_value(value):
- """Obtain an OpCode instance from a numeric value."""
- result = OpCode._value_map.get(value, None)
+ @classmethod
+ def from_value(cls, value):
+ """Obtain an enumeration instance from a numeric value."""
+ result = cls._value_map.get(value, None)
if result is None:
- raise ValueError('Unknown OpCode: %d' % value)
+ raise ValueError('Unknown %s: %d' % (cls.__name__,
+ value))
return result
- @staticmethod
- def register(name, value):
- """Registers a new OpCode enumeration.
+ @classmethod
+ def register(cls, name, value):
+ """Registers a new enumeration.
This is called by this module for each enumeration defined in
enumerations. You should not need to call this outside this module.
"""
- if value in OpCode._value_map:
- raise ValueError('OpCode value already registered: %d' % value)
+ if value in cls._value_map:
+ raise ValueError('%s value already registered: %d' % (cls.__name__,
+ value))
+ enum = cls(name, value)
+ cls._value_map[value] = enum
+ setattr(cls, name, enum)
+
+class Attribute(LLVMEnumeration):
+ """Represents an individual Attribute enumeration."""
+
+ _value_map = {}
+
+ def __init__(self, name, value):
+ super(Attribute, self).__init__(name, value)
+
+class OpCode(LLVMEnumeration):
+ """Represents an individual OpCode enumeration."""
+
+ _value_map = {}
+
+ def __init__(self, name, value):
+ super(OpCode, self).__init__(name, value)
+
+class TypeKind(LLVMEnumeration):
+ """Represents an individual TypeKind enumeration."""
+
+ _value_map = {}
+
+ def __init__(self, name, value):
+ super(TypeKind, self).__init__(name, value)
+
+class Linkage(LLVMEnumeration):
+ """Represents an individual Linkage enumeration."""
+
+ _value_map = {}
+
+ def __init__(self, name, value):
+ super(Linkage, self).__init__(name, value)
- opcode = OpCode(name, value)
- OpCode._value_map[value] = opcode
- setattr(OpCode, name, opcode)
+class Visibility(LLVMEnumeration):
+ """Represents an individual visibility enumeration."""
+
+ _value_map = {}
+
+ def __init__(self, name, value):
+ super(Visibility, self).__init__(name, value)
+
+class CallConv(LLVMEnumeration):
+ """Represents an individual calling convention enumeration."""
+
+ _value_map = {}
+
+ def __init__(self, name, value):
+ super(CallConv, self).__init__(name, value)
+
+class IntPredicate(LLVMEnumeration):
+ """Represents an individual IntPredicate enumeration."""
+
+ _value_map = {}
+
+ def __init__(self, name, value):
+ super(IntPredicate, self).__init__(name, value)
+
+class RealPredicate(LLVMEnumeration):
+ """Represents an individual RealPredicate enumeration."""
+
+ _value_map = {}
+
+ def __init__(self, name, value):
+ super(RealPredicate, self).__init__(name, value)
+
+class LandingPadClauseTy(LLVMEnumeration):
+ """Represents an individual LandingPadClauseTy enumeration."""
+
+ _value_map = {}
+
+ def __init__(self, name, value):
+ super(LandingPadClauseTy, self).__init__(name, value)
class MemoryBuffer(LLVMObject):
"""Represents an opaque memory buffer."""
def dump(self):
lib.LLVMDumpValue(self)
+
+ def get_operand(self, i):
+ return Value(lib.LLVMGetOperand(self, i))
+
+ def set_operand(self, i, v):
+ return lib.LLVMSetOperand(self, i, v)
+
+ def __len__(self):
+ return lib.LLVMGetNumOperands(self)
class Module(LLVMObject):
"""Represents the top-level structure of an llvm program in an opaque object."""
@classmethod
def CreateWithName(cls, module_id):
m = Module(lib.LLVMModuleCreateWithName(module_id))
- c = Context.GetGlobalContext().take_ownership(m)
+ Context.GetGlobalContext().take_ownership(m)
return m
@property
b = lib.LLVMGetPreviousBasicBlock(self)
return b and BasicBlock(b)
+ @property
+ def first(self):
+ i = lib.LLVMGetFirstInstruction(self)
+ return i and Instruction(i)
+
+ @property
+ def last(self):
+ i = lib.LLVMGetLastInstruction(self)
+ return i and Instruction(i)
+
+ def __as_value(self):
+ return Value(lib.LLVMBasicBlockAsValue(self))
+
@property
def name(self):
- return lib.LLVMGetValueName(Value(lib.LLVMBasicBlockAsValue(self)))
+ return lib.LLVMGetValueName(self.__as_value())
def dump(self):
- lib.LLVMDumpValue(Value(lib.LLVMBasicBlockAsValue(self)))
+ lib.LLVMDumpValue(self.__as_value())
+
+ def get_operand(self, i):
+ return Value(lib.LLVMGetOperand(self.__as_value(),
+ i))
+
+ def set_operand(self, i, v):
+ return lib.LLVMSetOperand(self.__as_value(),
+ i, v)
+
+ def __len__(self):
+ return lib.LLVMGetNumOperands(self.__as_value())
+
+ class __inst_iterator(object):
+ def __init__(self, bb, reverse=False):
+ self.bb = bb
+ self.reverse = reverse
+ if self.reverse:
+ self.inst = self.bb.last
+ else:
+ self.inst = self.bb.first
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if not isinstance(self.inst, Instruction):
+ raise StopIteration("")
+ result = self.inst
+ if self.reverse:
+ self.inst = self.inst.prev
+ else:
+ self.inst = self.inst.next
+ return result
+
+ def __iter__(self):
+ return BasicBlock.__inst_iterator(self)
+
+ def __reversed__(self):
+ return BasicBlock.__inst_iterator(self, reverse=True)
+
+
+class Instruction(Value):
+
+ def __init__(self, value):
+ Value.__init__(self, value)
+
+ @property
+ def next(self):
+ i = lib.LLVMGetNextInstruction(self)
+ return i and Instruction(i)
+
+ @property
+ def prev(self):
+ i = lib.LLVMGetPreviousInstruction(self)
+ return i and Instruction(i)
+
+ @property
+ def opcode(self):
+ return OpCode.from_value(lib.LLVMGetInstructionOpcode(self))
class Context(LLVMObject):
library.LLVMDumpValue.argtypes = [Value]
library.LLVMDumpValue.restype = None
+ library.LLVMGetOperand.argtypes = [Value, c_uint]
+ library.LLVMGetOperand.restype = c_object_p
+
+ library.LLVMSetOperand.argtypes = [Value, Value, c_uint]
+ library.LLVMSetOperand.restype = None
+
+ library.LLVMGetNumOperands.argtypes = [Value]
+ library.LLVMGetNumOperands.restype = c_uint
+
# Basic Block Declarations.
library.LLVMGetFirstBasicBlock.argtypes = [Function]
library.LLVMGetFirstBasicBlock.restype = c_object_p
library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock]
library.LLVMGetPreviousBasicBlock.restype = c_object_p
+ library.LLVMGetFirstInstruction.argtypes = [BasicBlock]
+ library.LLVMGetFirstInstruction.restype = c_object_p
+
+ library.LLVMGetLastInstruction.argtypes = [BasicBlock]
+ library.LLVMGetLastInstruction.restype = c_object_p
+
library.LLVMBasicBlockAsValue.argtypes = [BasicBlock]
library.LLVMBasicBlockAsValue.restype = c_object_p
library.LLVMCountBasicBlocks.argtypes = [Function]
library.LLVMCountBasicBlocks.restype = c_uint
+ # Instruction Declarations.
+ library.LLVMGetNextInstruction.argtypes = [Instruction]
+ library.LLVMGetNextInstruction.restype = c_object_p
+
+ library.LLVMGetPreviousInstruction.argtypes = [Instruction]
+ library.LLVMGetPreviousInstruction.restype = c_object_p
+
+ library.LLVMGetInstructionOpcode.argtypes = [Instruction]
+ library.LLVMGetInstructionOpcode.restype = c_uint
+
def register_enumerations():
- for name, value in enumerations.OpCodes:
- OpCode.register(name, value)
+ if Enums:
+ return None
+ enums = [
+ (Attribute, enumerations.Attributes),
+ (OpCode, enumerations.OpCodes),
+ (TypeKind, enumerations.TypeKinds),
+ (Linkage, enumerations.Linkages),
+ (Visibility, enumerations.Visibility),
+ (CallConv, enumerations.CallConv),
+ (IntPredicate, enumerations.IntPredicate),
+ (RealPredicate, enumerations.RealPredicate),
+ (LandingPadClauseTy, enumerations.LandingPadClauseTy),
+ ]
+ for enum_class, enum_spec in enums:
+ for name, value in enum_spec:
+ print name, value
+ enum_class.register(name, value)
+ return enums
def initialize_llvm():
- c = Context.GetGlobalContext()
+ Context.GetGlobalContext()
p = PassRegistry()
lib.LLVMInitializeCore(p)
lib.LLVMInitializeTransformUtils(p)
lib.LLVMInitializeTarget(p)
register_library(lib)
-register_enumerations()
+Enums = register_enumerations()
initialize_llvm()