Add TestVirtual.py to go with test/cpp/virtual/main.cpp file, which tests
C++ virtual function and virtual inheritance. llvm-svn: 124642
This commit is contained in:
parent
46308e666a
commit
a1c833769e
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -0,0 +1,86 @@
|
|||
"""
|
||||
Test C++ virtual function and virtual inheritance.
|
||||
"""
|
||||
|
||||
import os, time
|
||||
import re
|
||||
import lldb
|
||||
from lldbtest import *
|
||||
|
||||
def Msg(expr, val):
|
||||
return "'expression %s' matches the output (from compiled code): %s" % (expr, val)
|
||||
|
||||
class CppVirtualMadness(TestBase):
|
||||
|
||||
mydir = os.path.join("cpp", "virtual")
|
||||
|
||||
# This is the pattern by design to match the "my_expr = 'value'" output from
|
||||
# printf() stmts (see main.cpp).
|
||||
pattern = re.compile("^([^=]*) = '([^=]*)'$")
|
||||
|
||||
# Assert message.
|
||||
PRINTF_OUTPUT_GROKKED = "The printf output from compiled code is parsed correctly"
|
||||
|
||||
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
|
||||
def test_virtual_madness_dsym(self):
|
||||
"""Test that expression works correctly with virtual inheritance as well as virtual function."""
|
||||
self.buildDsym()
|
||||
self.virtual_madness_test()
|
||||
|
||||
def test_virtual_madness_dwarf(self):
|
||||
"""Test that expression works correctly with virtual inheritance as well as virtual function."""
|
||||
self.buildDwarf()
|
||||
self.virtual_madness_test()
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
TestBase.setUp(self)
|
||||
# Find the line number to break for main.cpp.
|
||||
self.line = line_number('main.cpp', '// Set first breakpoint here.')
|
||||
|
||||
def virtual_madness_test(self):
|
||||
"""Test that variable expressions with basic types are evaluated correctly."""
|
||||
|
||||
# First, capture the golden output emitted by the oracle, i.e., the
|
||||
# series of printf statements.
|
||||
go = system("./a.out", sender=self)
|
||||
# This golden list contains a list of "my_expr = 'value' pairs extracted
|
||||
# from the golden output.
|
||||
gl = []
|
||||
|
||||
# Scan the golden output line by line, looking for the pattern:
|
||||
#
|
||||
# my_expr = 'value'
|
||||
#
|
||||
for line in go.split(os.linesep):
|
||||
match = self.pattern.search(line)
|
||||
if match:
|
||||
my_expr, val = match.group(1), match.group(2)
|
||||
gl.append((my_expr, val))
|
||||
#print "golden list:", gl
|
||||
|
||||
# Bring the program to the point where we can issue a series of
|
||||
# 'expression' command to compare against the golden output.
|
||||
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
|
||||
self.runCmd("breakpoint set -f main.cpp -l %d" % self.line)
|
||||
self.runCmd("run", RUN_SUCCEEDED)
|
||||
|
||||
# Now iterate through the golden list, comparing against the output from
|
||||
# 'expression var'.
|
||||
for my_expr, val in gl:
|
||||
# Don't overwhelm the expression mechanism.
|
||||
# This slows down the test suite quite a bit, to enable it, define
|
||||
# the environment variable LLDB_TYPES_EXPR_TIME_WAIT. For example:
|
||||
#
|
||||
# export LLDB_TYPES_EXPR_TIME_WAIT=0.5
|
||||
#
|
||||
# causes a 0.5 second delay between 'expression' commands.
|
||||
if "LLDB_TYPES_EXPR_TIME_WAIT" in os.environ:
|
||||
time.sleep(float(os.environ["LLDB_TYPES_EXPR_TIME_WAIT"]))
|
||||
|
||||
self.runCmd("expression %s" % my_expr)
|
||||
output = self.res.GetOutput()
|
||||
|
||||
# The expression output must match the oracle.
|
||||
self.expect(output, Msg(my_expr, val), exe=False,
|
||||
substrs = [val])
|
|
@ -84,18 +84,7 @@ int main (int argc, char const *argv[], char const *envp[])
|
|||
C *c_as_C = new C();
|
||||
A *c_as_A = c_as_C;
|
||||
|
||||
printf ("a_as_A->a() = '%s'\n", a_as_A->a());
|
||||
printf ("a_as_A->b() = '%s'\n", a_as_A->b());
|
||||
printf ("a_as_A->c() = '%s'\n", a_as_A->c());
|
||||
printf ("b_as_A->a() = '%s'\n", b_as_A->a());
|
||||
printf ("b_as_A->b() = '%s'\n", b_as_A->b());
|
||||
printf ("b_as_A->c() = '%s'\n", b_as_A->c());
|
||||
printf ("b_as_B->aa() = '%s'\n", b_as_B->aa());
|
||||
printf ("c_as_A->a() = '%s'\n", c_as_A->a());
|
||||
printf ("c_as_A->b() = '%s'\n", c_as_A->b());
|
||||
printf ("c_as_A->c() = '%s'\n", c_as_A->c());
|
||||
printf ("c_as_C->aa() = '%s'\n", c_as_C->aa());
|
||||
return 0; // Set first breakpoint here.
|
||||
// Set first breakpoint here.
|
||||
// then evaluate:
|
||||
// expression a_as_A->a()
|
||||
// expression a_as_A->b()
|
||||
|
@ -108,4 +97,16 @@ int main (int argc, char const *argv[], char const *envp[])
|
|||
// expression c_as_A->b()
|
||||
// expression c_as_A->c()
|
||||
// expression c_as_C->aa()
|
||||
printf ("a_as_A->a() = '%s'\n", a_as_A->a());
|
||||
printf ("a_as_A->b() = '%s'\n", a_as_A->b());
|
||||
printf ("a_as_A->c() = '%s'\n", a_as_A->c());
|
||||
printf ("b_as_A->a() = '%s'\n", b_as_A->a());
|
||||
printf ("b_as_A->b() = '%s'\n", b_as_A->b());
|
||||
printf ("b_as_A->c() = '%s'\n", b_as_A->c());
|
||||
printf ("b_as_B->aa() = '%s'\n", b_as_B->aa());
|
||||
printf ("c_as_A->a() = '%s'\n", c_as_A->a());
|
||||
printf ("c_as_A->b() = '%s'\n", c_as_A->b());
|
||||
printf ("c_as_A->c() = '%s'\n", c_as_A->c());
|
||||
printf ("c_as_C->aa() = '%s'\n", c_as_C->aa());
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue