IR: Return unique_ptr from MDNode::getTemporary()
[oota-llvm.git] / bindings / python / llvm / core.py
index 14b0b4ce7b141cd1c5ce070e9086d569e5148451..c95952db6fc5a283cf8c14d3087890c8a8712f9d 100644 (file)
@@ -20,53 +20,128 @@ from ctypes import c_uint
 
 __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."""
@@ -105,6 +180,15 @@ class Value(LLVMObject):
 
     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."""
@@ -115,7 +199,7 @@ class Module(LLVMObject):
     @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
@@ -253,12 +337,84 @@ class BasicBlock(LLVMObject):
         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):
 
@@ -389,6 +545,15 @@ def register_library(library):
     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
@@ -402,18 +567,50 @@ def register_library(library):
     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)
@@ -429,5 +626,5 @@ def initialize_llvm():
     lib.LLVMInitializeTarget(p)
 
 register_library(lib)
-register_enumerations()
+Enums = register_enumerations()
 initialize_llvm()