diff --git a/lldb/test/lang/c/struct_types/Makefile b/lldb/test/lang/c/struct_types/Makefile deleted file mode 100644 index b09a579159d4..000000000000 --- a/lldb/test/lang/c/struct_types/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -LEVEL = ../../../make - -C_SOURCES := main.c - -include $(LEVEL)/Makefile.rules diff --git a/lldb/test/lang/c/struct_types/TestStructTypes.py b/lldb/test/lang/c/struct_types/TestStructTypes.py index 3e25dffc914d..a70d2ca74147 100644 --- a/lldb/test/lang/c/struct_types/TestStructTypes.py +++ b/lldb/test/lang/c/struct_types/TestStructTypes.py @@ -1,102 +1,3 @@ -""" -Test that break on a struct declaration has no effect. +import lldbinline -Instead, the first executable statement is set as the breakpoint. -""" - -import os, time -import unittest2 -import lldb -from lldbtest import * -import lldbutil - -class StructTypesTestCase(TestBase): - - mydir = TestBase.compute_mydir(__file__) - - # rdar://problem/12566646 - @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") - @dsym_test - def test_with_dsym(self): - """Test that break on a struct declaration has no effect.""" - self.buildDsym() - self.struct_types() - - # rdar://problem/12566646 - @expectedFailureIcc # llvm.org/pr16793 - # ICC generates DW_AT_byte_size zero with a zero-length - # array and LLDB doesn't process it correctly. - @dwarf_test - def test_with_dwarf(self): - """Test that break on a struct declaration has no effect.""" - self.buildDwarf() - self.struct_types() - - def setUp(self): - # Call super's setUp(). - TestBase.setUp(self) - # Find the line number to break for main.c. - self.source = 'main.c' - self.line = line_number(self.source, '// Set break point at this line.') - self.first_executable_line = line_number(self.source, - '// This is the first executable statement.') - self.return_line = line_number(self.source, '// This is the return statement.') - - def struct_types(self): - """Test that break on a struct declaration has no effect and test structure access for zero sized arrays.""" - exe = os.path.join(os.getcwd(), "a.out") - - # Create a target by the debugger. - target = self.dbg.CreateTarget(exe) - self.assertTrue(target, VALID_TARGET) - - # Break on the struct declration statement in main.c. - lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=False) - lldbutil.run_break_set_by_file_and_line (self, "main.c", self.return_line, num_expected_locations=1, loc_exact=True) - - # Now launch the process, and do not stop at entry point. - process = target.LaunchSimple (None, None, self.get_process_working_directory()) - - if not process: - self.fail("SBTarget.Launch() failed") - - thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) - - # We should be stopped on the first executable statement within the - # function where the original breakpoint was attempted. - self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, - substrs = ['main.c:%d' % self.first_executable_line, - 'stop reason = breakpoint']) - - # The breakpoint should have a hit count of 1. - self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, - substrs = [' resolved, hit count = 1']) - - process.Continue() - thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) - - # Test zero length array access and make sure it succeeds with "frame variable" - self.expect("frame variable pt.padding[0]", - DATA_TYPES_DISPLAYED_CORRECTLY, - substrs = ["pt.padding[0] = "]) - self.expect("frame variable pt.padding[1]", - DATA_TYPES_DISPLAYED_CORRECTLY, - substrs = ["pt.padding[1] = "]) - # Test zero length array access and make sure it succeeds with "expression" - self.expect("expression -- (pt.padding[0])", - DATA_TYPES_DISPLAYED_CORRECTLY, - substrs = ["(char)", " = "]) - - # The padding should be an array of size 0 - self.expect("image lookup -t point_tag", - DATA_TYPES_DISPLAYED_CORRECTLY, - substrs = ['padding[]']) # Once rdar://problem/12566646 is fixed, this should display correctly - - self.expect("expression -- &pt == (struct point_tag*)0", - substrs = ['false']) - -if __name__ == '__main__': - import atexit - lldb.SBDebugger.Initialize() - atexit.register(lambda: lldb.SBDebugger.Terminate()) - unittest2.main() +lldbinline.MakeInlineTest(__file__, globals()) diff --git a/lldb/test/lang/c/struct_types/cmds.txt b/lldb/test/lang/c/struct_types/cmds.txt deleted file mode 100644 index c308a7637fb3..000000000000 --- a/lldb/test/lang/c/struct_types/cmds.txt +++ /dev/null @@ -1,3 +0,0 @@ -break main.c:14 -continue -var diff --git a/lldb/test/lang/c/struct_types/main.c b/lldb/test/lang/c/struct_types/main.c index 551963134bb7..a4051a0fb486 100644 --- a/lldb/test/lang/c/struct_types/main.c +++ b/lldb/test/lang/c/struct_types/main.c @@ -12,13 +12,13 @@ int main (int argc, char const *argv[]) int x; int y; char padding[0]; - }; // Set break point at this line. + }; //% self.expect("frame variable pt.padding[0]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["pt.padding[0] = "]); self.expect("frame variable pt.padding[1]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["pt.padding[1] = "]); self.expect("expression -- (pt.padding[0])", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["(char)", " = "]); self.expect("image lookup -t point_tag", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ['padding[]']) # Once rdar://problem/12566646 is fixed, this should display correctly struct rect_tag { struct point_tag bottom_left; struct point_tag top_right; }; - struct point_tag pt = { 2, 3, {} }; // This is the first executable statement. + struct point_tag pt = { 2, 3, {} }; //% self. struct rect_tag rect = {{1, 2, {}}, {3, 4, {}}}; - return 0; // This is the return statement. + return 0; //% self.expect("expression -- &pt == (struct point_tag*)0", substrs = ['false']) } diff --git a/lldb/test/lldbinline.py b/lldb/test/lldbinline.py new file mode 100644 index 000000000000..ad397b5bef55 --- /dev/null +++ b/lldb/test/lldbinline.py @@ -0,0 +1,161 @@ +import lldb +from lldbtest import * +import lldbutil +import os +import new + +def source_type(filename): + _, extension = os.path.splitext(filename) + return { + '.c' : 'C_SOURCES', + '.cpp' : 'CXX_SOURCES', + '.cxx' : 'CXX_SOURCES', + '.cc' : 'CXX_SOURCES', + '.m' : 'OBJC_SOURCES', + '.mm' : 'OBJCXX_SOURCES' + }.get(extension, None) + +class CommandParser: + def __init__(self): + self.breakpoints = [] + + def parse_one_command(self, line): + parts = line.split('//%') + if len(parts) != 2: + return None + else: + return parts[1].strip() # take off trailing whitespace + + def parse_source_files(self, source_files): + for source_file in source_files: + file_handle = open(source_file) + lines = file_handle.readlines() + line_number = 0 + for line in lines: + line_number = line_number + 1 # 1-based, so we do this first + command = self.parse_one_command(line) + if command != None: + breakpoint = {} + breakpoint['file_name'] = source_file + breakpoint['line_number'] = line_number + breakpoint['command'] = command + self.breakpoints.append(breakpoint) + + def set_breakpoints(self, target): + for breakpoint in self.breakpoints: + breakpoint['breakpoint'] = target.BreakpointCreateByLocation(breakpoint['file_name'], breakpoint['line_number']) + + def handle_breakpoint(self, test, breakpoint_id): + for breakpoint in self.breakpoints: + if breakpoint['breakpoint'].GetID() == breakpoint_id: + test.execute_user_command(breakpoint['command']) + return + +def BuildMakefile(mydir): + categories = {} + + for f in os.listdir(os.getcwd()): + t = source_type(f) + if t: + if t in categories.keys(): + categories[t].append(f) + else: + categories[t] = [f] + + makefile = open("Makefile", 'w+') + + level = os.sep.join([".."] * len(mydir.split(os.sep))) + os.sep + "make" + + makefile.write("LEVEL = " + level + "\n") + + for t in categories.keys(): + line = t + " := " + " ".join(categories[t]) + makefile.write(line + "\n") + + if ('OBJCXX_SOURCES' in categories.keys()) or ('OBJC_SOURCES' in categories.keys()): + makefile.write("LDFLAGS = $(CFLAGS) -lobjc -framework Foundation\n") + + if ('CXX_SOURCES' in categories.keys()): + makefile.write("CXXFLAGS += -std-c++11\n") + + makefile.write("include $(LEVEL)/Makefile.rules\n") + makefile.flush() + makefile.close() + +def CleanMakefile(): + if (os.path.isfile("Makefile")): + os.unlink("Makefile") + +class InlineTest(TestBase): + # Internal implementation + + def buildDsymWithImplicitMakefile(self): + BuildMakefile(self.mydir) + self.buildDsym() + + def buildDwarfWithImplicitMakefile(self): + BuildMakefile(self.mydir) + self.buildDwarf() + + def test_with_dsym(self): + self.buildDsymWithImplicitMakefile() + self.do_test() + + def test_with_dwarf(self): + self.buildDwarfWithImplicitMakefile() + self.do_test() + + def execute_user_command(self, __command): + exec __command in globals(), locals() + + def do_test(self): + exe_name = "a.out" + exe = os.path.join(os.getcwd(), exe_name) + source_files = [ f for f in os.listdir(os.getcwd()) if source_type(f) ] + target = self.dbg.CreateTarget(exe) + + parser = CommandParser() + parser.parse_source_files(source_files) + parser.set_breakpoints(target) + + process = target.LaunchSimple(None, None, os.getcwd()) + + while lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint): + thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) + breakpoint_id = thread.GetStopReasonDataAtIndex (0) + parser.handle_breakpoint(self, breakpoint_id) + process.Continue() + + @classmethod + def classCleanup(cls): + CleanMakefile() + + # Utilities for testcases + + def check_expression (self, expression, expected_result, use_summary = True): + value = self.frame().EvaluateExpression (expression) + self.assertTrue(value.IsValid(), expression+"returned a valid value") + if self.TraceOn(): + print value.GetSummary() + print value.GetValue() + if use_summary: + answer = value.GetSummary() + else: + answer = value.GetValue() + report_str = "%s expected: %s got: %s"%(expression, expected_result, answer) + self.assertTrue(answer == expected_result, report_str) + +def MakeInlineTest(__file, __globals): + # Derive the test name from the current file name + file_basename = os.path.basename(__file) + InlineTest.mydir = TestBase.compute_mydir(__file) + + test_name, _ = os.path.splitext(file_basename) + # Build the test case + test = new.classobj(test_name, (InlineTest,), {}) + test.name = test_name + # Add the test case to the globals, and hide InlineTest + __globals.update({test_name : test}) + del globals()["InlineTest"] + +