ReleaseNotes: -femultated-tls; by Chih-hung Hsieh
[oota-llvm.git] / bindings / python / llvm / core.py
index fa5486a7e11ab7434388e52085077e8f9329f0f1..47e81dd1a4f948192b73e8b152d7ba28ccee3304 100644 (file)
@@ -20,50 +20,128 @@ from ctypes import c_uint
 
 __all__ = [
     "lib",
 
 __all__ = [
     "lib",
+    "Enums",
     "OpCode",
     "MemoryBuffer",
     "Module",
     "OpCode",
     "MemoryBuffer",
     "Module",
+    "Value",
+    "Function",
+    "BasicBlock",
+    "Instruction",
     "Context",
     "PassRegistry"
 ]
 
 lib = get_library()
     "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):
 
     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:
 
         if result is None:
-            raise ValueError('Unknown OpCode: %d' % value)
+            raise ValueError('Unknown %s: %d' % (cls.__name__,
+                                                 value))
 
         return result
 
 
         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.
         """
 
         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 = {}
 
 
-        opcode = OpCode(name, value)
-        OpCode._value_map[value] = opcode
-        setattr(OpCode, name, opcode)
+    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)
+
+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."""
 
 class MemoryBuffer(LLVMObject):
     """Represents an opaque memory buffer."""
@@ -91,6 +169,27 @@ class MemoryBuffer(LLVMObject):
     def __len__(self):
         return lib.LLVMGetBufferSize(self)
 
     def __len__(self):
         return lib.LLVMGetBufferSize(self)
 
+class Value(LLVMObject):
+    
+    def __init__(self, value):
+        LLVMObject.__init__(self, value)
+
+    @property
+    def name(self):
+        return lib.LLVMGetValueName(self)
+
+    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."""
 
 class Module(LLVMObject):
     """Represents the top-level structure of an llvm program in an opaque object."""
 
@@ -100,7 +199,7 @@ class Module(LLVMObject):
     @classmethod
     def CreateWithName(cls, module_id):
         m = Module(lib.LLVMModuleCreateWithName(module_id))
     @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
         return m
 
     @property
@@ -124,6 +223,42 @@ class Module(LLVMObject):
     def dump(self):
         lib.LLVMDumpModule(self)
 
     def dump(self):
         lib.LLVMDumpModule(self)
 
+    class __function_iterator(object):
+        def __init__(self, module, reverse=False):
+            self.module = module
+            self.reverse = reverse
+            if self.reverse:
+                self.function = self.module.last
+            else:
+                self.function = self.module.first
+        
+        def __iter__(self):
+            return self
+        
+        def next(self):
+            if not isinstance(self.function, Function):
+                raise StopIteration("")
+            result = self.function
+            if self.reverse:
+                self.function = self.function.prev
+            else:
+                self.function = self.function.next
+            return result
+    
+    def __iter__(self):
+        return Module.__function_iterator(self)
+
+    def __reversed__(self):
+        return Module.__function_iterator(self, reverse=True)
+
+    @property
+    def first(self):
+        return Function(lib.LLVMGetFirstFunction(self))
+
+    @property
+    def last(self):
+        return Function(lib.LLVMGetLastFunction(self))
+
     def print_module_to_file(self, filename):
         out = c_char_p(None)
         # Result is inverted so 0 means everything was ok.
     def print_module_to_file(self, filename):
         out = c_char_p(None)
         # Result is inverted so 0 means everything was ok.
@@ -131,6 +266,156 @@ class Module(LLVMObject):
         if result:
             raise RuntimeError("LLVM Error: %s" % out.value)
 
         if result:
             raise RuntimeError("LLVM Error: %s" % out.value)
 
+class Function(Value):
+
+    def __init__(self, value):
+        Value.__init__(self, value)
+    
+    @property
+    def next(self):
+        f = lib.LLVMGetNextFunction(self)
+        return f and Function(f)
+    
+    @property
+    def prev(self):
+        f = lib.LLVMGetPreviousFunction(self)
+        return f and Function(f)
+    
+    @property
+    def first(self):
+        b = lib.LLVMGetFirstBasicBlock(self)
+        return b and BasicBlock(b)
+
+    @property
+    def last(self):
+        b = lib.LLVMGetLastBasicBlock(self)
+        return b and BasicBlock(b)
+
+    class __bb_iterator(object):
+        def __init__(self, function, reverse=False):
+            self.function = function
+            self.reverse = reverse
+            if self.reverse:
+                self.bb = function.last
+            else:
+                self.bb = function.first
+        
+        def __iter__(self):
+            return self
+        
+        def next(self):
+            if not isinstance(self.bb, BasicBlock):
+                raise StopIteration("")
+            result = self.bb
+            if self.reverse:
+                self.bb = self.bb.prev
+            else:
+                self.bb = self.bb.next
+            return result
+    
+    def __iter__(self):
+        return Function.__bb_iterator(self)
+
+    def __reversed__(self):
+        return Function.__bb_iterator(self, reverse=True)
+    
+    def __len__(self):
+        return lib.LLVMCountBasicBlocks(self)
+
+class BasicBlock(LLVMObject):
+    
+    def __init__(self, value):
+        LLVMObject.__init__(self, value)
+
+    @property
+    def next(self):
+        b = lib.LLVMGetNextBasicBlock(self)
+        return b and BasicBlock(b)
+
+    @property
+    def prev(self):
+        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(self.__as_value())
+
+    def dump(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):
 
     def __init__(self, context=None):
 class Context(LLVMObject):
 
     def __init__(self, context=None):
@@ -180,9 +465,6 @@ def register_library(library):
     library.LLVMInitializeAnalysis.argtypes = [PassRegistry]
     library.LLVMInitializeAnalysis.restype = None
 
     library.LLVMInitializeAnalysis.argtypes = [PassRegistry]
     library.LLVMInitializeAnalysis.restype = None
 
-    library.LLVMInitializeIPA.argtypes = [PassRegistry]
-    library.LLVMInitializeIPA.restype = None
-
     library.LLVMInitializeCodeGen.argtypes = [PassRegistry]
     library.LLVMInitializeCodeGen.restype = None
 
     library.LLVMInitializeCodeGen.argtypes = [PassRegistry]
     library.LLVMInitializeCodeGen.restype = None
 
@@ -241,12 +523,91 @@ def register_library(library):
                                               POINTER(c_char_p)]
     library.LLVMPrintModuleToFile.restype = bool
 
                                               POINTER(c_char_p)]
     library.LLVMPrintModuleToFile.restype = bool
 
+    library.LLVMGetFirstFunction.argtypes = [Module]
+    library.LLVMGetFirstFunction.restype = c_object_p
+
+    library.LLVMGetLastFunction.argtypes = [Module]
+    library.LLVMGetLastFunction.restype = c_object_p
+
+    library.LLVMGetNextFunction.argtypes = [Function]
+    library.LLVMGetNextFunction.restype = c_object_p
+
+    library.LLVMGetPreviousFunction.argtypes = [Function]
+    library.LLVMGetPreviousFunction.restype = c_object_p
+
+    # Value declarations.
+    library.LLVMGetValueName.argtypes = [Value]
+    library.LLVMGetValueName.restype = c_char_p
+
+    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.LLVMGetLastBasicBlock.argtypes = [Function]
+    library.LLVMGetLastBasicBlock.restype = c_object_p
+
+    library.LLVMGetNextBasicBlock.argtypes = [BasicBlock]
+    library.LLVMGetNextBasicBlock.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():
 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():
 
 def initialize_llvm():
-    c = Context.GetGlobalContext()
+    Context.GetGlobalContext()
     p = PassRegistry()
     lib.LLVMInitializeCore(p)
     lib.LLVMInitializeTransformUtils(p)
     p = PassRegistry()
     lib.LLVMInitializeCore(p)
     lib.LLVMInitializeTransformUtils(p)
@@ -257,10 +618,9 @@ def initialize_llvm():
     lib.LLVMInitializeIPO(p)
     lib.LLVMInitializeInstrumentation(p)
     lib.LLVMInitializeAnalysis(p)
     lib.LLVMInitializeIPO(p)
     lib.LLVMInitializeInstrumentation(p)
     lib.LLVMInitializeAnalysis(p)
-    lib.LLVMInitializeIPA(p)
     lib.LLVMInitializeCodeGen(p)
     lib.LLVMInitializeTarget(p)
 
 register_library(lib)
     lib.LLVMInitializeCodeGen(p)
     lib.LLVMInitializeTarget(p)
 
 register_library(lib)
-register_enumerations()
+Enums = register_enumerations()
 initialize_llvm()
 initialize_llvm()