[python-bindings] Added code for loading a module from bitcode, getset its datalayout...
authorMichael Gottesman <mgottesman@apple.com>
Wed, 11 Sep 2013 00:23:14 +0000 (00:23 +0000)
committerMichael Gottesman <mgottesman@apple.com>
Wed, 11 Sep 2013 00:23:14 +0000 (00:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190458 91177308-0d34-0410-b5e6-96231b3b80d8

bindings/python/llvm/bit_reader.py [new file with mode: 0644]
bindings/python/llvm/core.py
bindings/python/llvm/tests/base.py
bindings/python/llvm/tests/test.bc [new file with mode: 0644]
bindings/python/llvm/tests/test_core.py

diff --git a/bindings/python/llvm/bit_reader.py b/bindings/python/llvm/bit_reader.py
new file mode 100644 (file)
index 0000000..5bf5e22
--- /dev/null
@@ -0,0 +1,31 @@
+
+from .common import LLVMObject
+from .common import c_object_p
+from .common import get_library
+from . import enumerations
+from .core import MemoryBuffer
+from .core import Module
+from .core import OpCode
+from ctypes import POINTER
+from ctypes import byref
+from ctypes import c_char_p
+from ctypes import cast
+__all__ = ['parse_bitcode']
+lib = get_library()
+
+def parse_bitcode(mem_buffer):
+    """Input is .core.MemoryBuffer"""
+    module = c_object_p()
+    out = c_char_p(None)
+    result = lib.LLVMParseBitcode(mem_buffer, byref(module), byref(out))
+    if result:
+        raise RuntimeError('LLVM Error: %s' % out.value)
+    m = Module(module)
+    m.take_ownership(mem_buffer)
+    return m
+
+def register_library(library):
+    library.LLVMParseBitcode.argtypes = [MemoryBuffer, POINTER(c_object_p), POINTER(c_char_p)]
+    library.LLVMParseBitcode.restype = bool
+
+register_library(lib)
index 76d1b14..2072d2f 100644 (file)
@@ -16,10 +16,12 @@ from . import enumerations
 from ctypes import POINTER
 from ctypes import byref
 from ctypes import c_char_p
+from ctypes import c_uint
 
 __all__ = [
     "lib",
     "MemoryBuffer",
+    "Module",
     "Context",
     "PassRegistry"
 ]
@@ -88,6 +90,45 @@ class MemoryBuffer(LLVMObject):
     def __len__(self):
         return lib.LLVMGetBufferSize(self)
 
+class Module(LLVMObject):
+    """Represents the top-level structure of an llvm program in an opaque object."""
+
+    def __init__(self, module, name=None, context=None):
+        LLVMObject.__init__(self, module, disposer=lib.LLVMDisposeModule)
+
+    @classmethod
+    def CreateWithName(cls, module_id):
+        m = Module(lib.LLVMModuleCreateWithName(module_id))
+        c = Context.GetGlobalContext().take_ownership(m)
+        return m
+
+    @property
+    def data_layout(self):
+        return lib.LLVMGetDataLayout(self)
+
+    @data_layout.setter
+    def data_layout(self, new_data_layout):
+        """new_data_layout is a string."""
+        lib.LLVMSetDataLayout(self, new_data_layout)
+
+    @property
+    def target(self):
+        return lib.LLVMGetTarget(self)
+
+    @target.setter
+    def target(self, new_target):
+        """new_target is a string."""
+        lib.LLVMSetTarget(self, new_target)
+
+    def dump(self):
+        lib.LLVMDumpModule(self)
+
+    def print_module_to_file(self, filename):
+        out = c_char_p(None)
+        result = lib.LLVMPrintModuleToFile(self, filename, byref(out))
+        if not result:
+            raise RuntimeError("LLVM Error: %s" % out.value)
+
 class Context(LLVMObject):
 
     def __init__(self, context=None):
@@ -172,6 +213,32 @@ def register_library(library):
 
     library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer]
 
+    # Module declarations
+    library.LLVMModuleCreateWithName.argtypes = [c_char_p]
+    library.LLVMModuleCreateWithName.restype = c_object_p
+
+    library.LLVMDisposeModule.argtypes = [Module]
+    library.LLVMDisposeModule.restype = None
+
+    library.LLVMGetDataLayout.argtypes = [Module]
+    library.LLVMGetDataLayout.restype = c_char_p
+
+    library.LLVMSetDataLayout.argtypes = [Module, c_char_p]
+    library.LLVMSetDataLayout.restype = None
+
+    library.LLVMGetTarget.argtypes = [Module]
+    library.LLVMGetTarget.restype = c_char_p
+
+    library.LLVMSetTarget.argtypes = [Module, c_char_p]
+    library.LLVMSetTarget.restype = None
+
+    library.LLVMDumpModule.argtypes = [Module]
+    library.LLVMDumpModule.restype = None
+
+    library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p,
+                                              POINTER(c_char_p)]
+    library.LLVMPrintModuleToFile.restype = bool
+
 def register_enumerations():
     for name, value in enumerations.OpCodes:
         OpCode.register(name, value)
index 22da5fd..194f1a4 100644 (file)
@@ -33,3 +33,6 @@ class TestBase(unittest.TestCase):
 
     def get_test_file(self):
         return os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_file")
+
+    def get_test_bc(self):
+        return os.path.join(os.path.dirname(os.path.abspath(__file__)), "test.bc")
diff --git a/bindings/python/llvm/tests/test.bc b/bindings/python/llvm/tests/test.bc
new file mode 100644 (file)
index 0000000..8d3d28f
Binary files /dev/null and b/bindings/python/llvm/tests/test.bc differ
index 3364a66..e5fffba 100644 (file)
@@ -3,6 +3,7 @@ from ..core import OpCode
 from ..core import MemoryBuffer
 from ..core import PassRegistry
 from ..core import Context
+from ..core import Module
 
 class TestCore(TestBase):
     def test_opcode(self):
@@ -33,3 +34,29 @@ class TestCore(TestBase):
 
     def test_create_context(self):
         Context.GetGlobalContext()
+
+    def test_create_module_with_name(self):
+        # Make sure we can not create a module without a LLVMModuleRef.
+        with self.assertRaises(RuntimeError):
+            m = Module()
+        m = Module.CreateWithName("test-module")
+
+    def test_module_getset_datalayout(self):
+        m = Module.CreateWithName("test-module")
+        dl = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
+        m.datalayout = dl
+        self.assertEqual(m.datalayout, dl)
+
+    def test_module_getset_target(self):
+        m = Module.CreateWithName("test-module")
+        m.target = "thumbv7-apple-ios5.0.0"
+        self.assertEqual(m.target, target)
+
+    def test_module_print_module_to_file(self):
+        m = Module.CreateWithName("test")
+        dl = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32"
+        m.datalayout = dl
+        target = "thumbv7-apple-ios5.0.0"
+        m.target = target
+        m.print_module_to_file("test2.ll")
+