llvmpy/test/test_debuginfo.py
2013-02-27 13:48:08 -06:00

133 lines
4.5 KiB
Python

import os
import unittest
import llvm.ee
from llvm.core import *
from llvm import _dwarf, debuginfo
from llvm.test_llvmpy import TestCase
class TestDebugInfo(TestCase):
def test_dwarf_constants(self):
dwarf_constants = vars(_dwarf)
# Version numbers
self.assertIn("LLVMDebugVersion", dwarf_constants)
self.assertIn("DWARF_VERSION", dwarf_constants)
# Tags
self.assertIn("DW_TAG_compile_unit", dwarf_constants)
# Language identifiers
self.assertIn("DW_LANG_Python", dwarf_constants)
self.assertIn("DW_LANG_C89", dwarf_constants)
self.assertIn("DW_LANG_C99", dwarf_constants)
# print sorted([constname for constname in dwarf_constants
# if constname.startswith("DW_LANG_")])
def test_debug_info_compile_unit(self):
mod = Module.new('test_debug_info')
fty = Type.function(Type.float(), [Type.float()])
square = mod.add_function(fty, 'square')
bb = square.append_basic_block('entry')
bldr = Builder.new(bb)
source_filename = "test_debug_info.py"
source_filedir = os.path.expanduser("~")
# Debug info for our file
filedesc = debuginfo.FileDescriptor(source_filename, source_filedir)
# Debug info for our function
subprogram = debuginfo.SubprogramDescriptor(
filedesc,
"some_function",
"some_function",
"some_function",
filedesc,
1, # line number
debuginfo.empty, # Type descriptor
llvm_func=square,
)
subprograms = debuginfo.MDList([subprogram])
# Debug info for our basic blocks
blockdescr1 = debuginfo.BlockDescriptor(subprogram, 2, 4) # lineno, col
blockdescr2 = debuginfo.BlockDescriptor(blockdescr1, 3, 4) # lineno, col
# Debug info for our instructions
posinfo1 = debuginfo.PositionInfoDescriptor(2, 4, blockdescr1)
posinfo2 = debuginfo.PositionInfoDescriptor(2, 4, blockdescr2)
# Debug info for our module
compile_unit = debuginfo.CompileUnitDescriptor(
# DW_LANG_Python segfaults:
# llvm/ADT/StringRef.h:79: llvm::StringRef::StringRef(const char*):
# Assertion `Str && "StringRef cannot be built from a NULL argument"'
# _dwarf.DW_LANG_Python,
_dwarf.DW_LANG_C89,
source_filename,
source_filedir,
"my_cool_compiler",
subprograms=subprograms,
)
# Define our module debug data
compile_unit.define(mod)
# Build some instructions
value = square.args[0]
# result = bldr.fmul(value, value)
# Generate an instruction that will result in a signal
result = bldr.fdiv(value, llvm.core.Constant.real(value.type, 0))
ltrap = llvm.core.Function.intrinsic(mod, INTR_TRAP, [])
lcall = bldr.call(ltrap, [])
ret = bldr.ret(result)
# Annotate instructions with source position
result.set_metadata("dbg", posinfo1.get_metadata(mod))
lcall.set_metadata("dbg", posinfo1.get_metadata(mod))
ret.set_metadata("dbg", posinfo2.get_metadata(mod))
# ... Aaaand, test...
# print mod
modstr = str(mod)
# Test compile unit
self.assertIn("my_cool_compiler", modstr)
self.assertIn(source_filename, modstr)
self.assertIn(source_filedir, modstr)
self.assertIn("my_cool_compiler", modstr)
# Test subprogram
self.assertIn("some_function", modstr)
self.assertIn("float (float)* @square", modstr)
return square
def debug_in_gdb(lfunc):
# Create an execution engine object. This will create a JIT compiler
# on platforms that support it, or an interpreter otherwise.
module = lfunc.module
ee = llvm.ee.ExecutionEngine.new(module)
float_type = lfunc.args[0].type
# The arguments needs to be passed as "GenericValue" objects.
arg1_value = 5.0
arg1 = llvm.ee.GenericValue.real(float_type, arg1_value)
# Now let's compile and run!
retval = ee.run_function(lfunc, [arg1])
print(retval.as_real(float_type))
if __name__ == '__main__':
# TestDebugInfo("test_dwarf_constants").debug()
# TestDebugInfo("test_debug_info_compile_unit").debug()
# tester = TestDebugInfo("test_debug_info_compile_unit")
# debug_in_gdb(tester.test_debug_info_compile_unit())
unittest.main()