Skip to content

Commit

Permalink
[python] Add Module.verify
Browse files Browse the repository at this point in the history
  • Loading branch information
wanders committed Sep 12, 2013
1 parent 6e9f93f commit 099f987
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 2 deletions.
2 changes: 1 addition & 1 deletion bindings/python/Makefile
Expand Up @@ -15,7 +15,7 @@ all::
$(Echo) "Building python bindings (which is currently is a no-op)"


GEN_HDRS:=Disassembler.h Object.h Core.h BitReader.h
GEN_HDRS:=Disassembler.h Object.h Core.h BitReader.h Analysis.h

.PHONY: generate-in-src-dir
generate-in-src-dir:
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/llvm/common.py
Expand Up @@ -189,7 +189,7 @@ class OnDemandRegisteredDeclarationsLibrary(object):
"""

BASE = "llvm.generated."
MODULES = ('object', 'disassembler', 'core', 'bitreader')
MODULES = ('object', 'disassembler', 'core', 'bitreader', 'analysis')

def __init__(self):
self.lib = None
Expand Down
13 changes: 13 additions & 0 deletions bindings/python/llvm/core/module.py
Expand Up @@ -120,6 +120,15 @@ def dump(self):
"""
lib.LLVMDumpModule(self)

def verify(self):
"""Run sanity check on module.
"""
msg = ctypes.c_char_p()
r = lib.LLVMVerifyModule(self, VerifierFailureAction.ReturnStatus, ctypes.byref(msg))
if r:
raise ValueError(msg.value)
return True

def to_assembly(self):
"""Return the IR for this module as a human readable string"""
tmp = tempfile.NamedTemporaryFile()
Expand Down Expand Up @@ -221,3 +230,7 @@ def add_global_variable(self, vartype, name):
"""
return value.Value._create_from_ptr(lib.LLVMAddGlobal(self, vartype, name))

@lib.c_enum("LLVMVerifierFailureAction", "LLVM", "Action")
class VerifierFailureAction(LLVMEnum):
pass
37 changes: 37 additions & 0 deletions bindings/python/llvm/generated/analysis.py
@@ -0,0 +1,37 @@
#===-- Generated python interface definitions for 'Analysis.h' -------------===#
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#
#
# This file is automatically generated by 'generate-from-includes.py',
# do not edit manually.
#
#===-----------------------------------------------------------------------====#

import ctypes
from ..common import c_object_p

function_declarations = {
'LLVMVerifyModule': ('LLVMBool',
['LLVMModuleRef', 'LLVMVerifierFailureAction', ctypes.POINTER(ctypes.c_char_p)]),
'LLVMVerifyFunction': ('LLVMBool',
['LLVMValueRef', 'LLVMVerifierFailureAction']),
'LLVMViewFunctionCFG': (None,
['LLVMValueRef']),
'LLVMViewFunctionCFGOnly': (None,
['LLVMValueRef']),
}

enum_declarations = {
'LLVMVerifierFailureAction': {
'LLVMAbortProcessAction': 0,
'LLVMPrintMessageAction': 1,
'LLVMReturnStatusAction': 2,
},

}

16 changes: 16 additions & 0 deletions bindings/python/llvm/tests/test_module.py
@@ -1,7 +1,9 @@
from llvm.core.module import Module
from llvm.core.context import Context
from llvm.core.types import TypeFactory
from llvm.core.value import Constant
from llvm.core.memorybuffer import MemoryBuffer
from llvm.core.builder import Builder


from .base import TestBase, captured_stderr
Expand Down Expand Up @@ -66,3 +68,17 @@ def test_module_add_gv(self):
tf = TypeFactory()
m.add_global_variable(tf.int(), "myglobal")
self.assertTrue("@myglobal = external global i32" in m.to_assembly())

def test_module_verify_broken(self):
m = Module("broken_verify")
tf = TypeFactory()
ft = tf.function(tf.int32(), [])
f = m.add_function(ft, "test_module_verify_broken")
bb = f.append_basic_block("entry")
builder = Builder(bb)
builder.ret(Constant(tf.int8(), 10))

with self.assertRaises(ValueError) as e:
m.verify()

assert e.exception.message.startswith("Function return type does not match operand type of return inst")

0 comments on commit 099f987

Please sign in to comment.