1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[python-bindings] Added support for getting a module's functions, iterating f/b over said functions, dumping/print name of functions.

Tests are included as well.

llvm-svn: 190471
This commit is contained in:
Michael Gottesman 2013-09-11 00:52:47 +00:00
parent 2ac0a76d79
commit b956e822b0
2 changed files with 101 additions and 0 deletions

View File

@ -23,6 +23,8 @@ __all__ = [
"OpCode",
"MemoryBuffer",
"Module",
"Value",
"Function",
"Context",
"PassRegistry"
]
@ -91,6 +93,18 @@ class MemoryBuffer(LLVMObject):
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)
class Module(LLVMObject):
"""Represents the top-level structure of an llvm program in an opaque object."""
@ -124,6 +138,42 @@ class Module(LLVMObject):
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.
@ -131,6 +181,21 @@ class Module(LLVMObject):
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)
class Context(LLVMObject):
def __init__(self, context=None):
@ -241,6 +306,25 @@ def register_library(library):
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
def register_enumerations():
for name, value in enumerations.OpCodes:
OpCode.register(name, value)

View File

@ -4,6 +4,7 @@ from ..core import MemoryBuffer
from ..core import PassRegistry
from ..core import Context
from ..core import Module
from ..bit_reader import parse_bitcode
class TestCore(TestBase):
def test_opcode(self):
@ -61,3 +62,19 @@ class TestCore(TestBase):
m.target = target
m.print_module_to_file("test2.ll")
def test_module_function_iteration(self):
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
i = 0
functions = ["f", "f2", "f3", "f4", "f5", "f6", "g1", "g2", "h1", "h2",
"h3"]
# Forward
for f in m:
self.assertEqual(f.name, functions[i])
f.dump()
i += 1
# Backwards
for f in reversed(m):
i -= 1
self.assertEqual(f.name, functions[i])
f.dump()