diff options
author | 2020-08-03 14:33:06 +0000 | |
---|---|---|
committer | 2020-08-03 14:33:06 +0000 | |
commit | 061da546b983eb767bad15e67af1174fb0bcf31c (patch) | |
tree | 83c78b820819d70aa40c36d90447978b300078c5 /gnu/llvm/lldb/packages/Python/lldbsuite/test/lang | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.tar.xz wireguard-openbsd-061da546b983eb767bad15e67af1174fb0bcf31c.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/lldb/packages/Python/lldbsuite/test/lang')
560 files changed, 20147 insertions, 0 deletions
diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/anonymous/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/anonymous/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/anonymous/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py new file mode 100644 index 00000000000..69e23e3510b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/anonymous/TestAnonymous.py @@ -0,0 +1,170 @@ +"""Test that anonymous structs/unions are transparent to member access""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class AnonymousTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf( + compiler="icc", + bugnumber="llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC") + def test_expr_nest(self): + self.build() + self.common_setup(self.line0) + + # These should display correctly. + self.expect("expression n->foo.d", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 4"]) + + self.expect("expression n->b", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 2"]) + + def test_expr_child(self): + self.build() + self.common_setup(self.line1) + + # These should display correctly. + self.expect("expression c->foo.d", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 4"]) + + self.expect( + "expression c->grandchild.b", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 2"]) + + @skipIf( + compiler="icc", + bugnumber="llvm.org/pr15036: This particular regression was introduced by r181498") + def test_expr_grandchild(self): + self.build() + self.common_setup(self.line2) + + # These should display correctly. + self.expect("expression g.child.foo.d", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 4"]) + + self.expect("expression g.child.b", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 2"]) + + def test_expr_parent(self): + self.build() + if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion(): + self.skipTest( + "llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef") + self.common_setup(self.line2) + + # These should display correctly. + self.expect("expression pz", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["(type_z *) $", " = 0x0000"]) + + self.expect("expression z.y", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["(type_y) $", "dummy = 2"]) + + def test_expr_null(self): + self.build() + self.common_setup(self.line2) + + # This should fail because pz is 0, but it succeeds on OS/X. + # This fails on Linux with an upstream error "Couldn't dematerialize struct", as does "p *n" with "int *n = 0". + # Note that this can also trigger llvm.org/pr15036 when run + # interactively at the lldb command prompt. + self.expect("expression *(type_z *)pz", error=True) + + def test_child_by_name(self): + self.build() + + # Set debugger into synchronous mode + self.dbg.SetAsync(False) + + # Create a target + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + break_in_main = target.BreakpointCreateBySourceRegex( + '// Set breakpoint 2 here.', lldb.SBFileSpec(self.source)) + self.assertTrue(break_in_main, VALID_BREAKPOINT) + + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, break_in_main) + if len(threads) != 1: + self.fail("Failed to stop at breakpoint in main.") + + thread = threads[0] + frame = thread.frames[0] + + if not frame.IsValid(): + self.fail("Failed to get frame 0.") + + var_n = frame.FindVariable("n") + if not var_n.IsValid(): + self.fail("Failed to get the variable 'n'") + + elem_a = var_n.GetChildMemberWithName("a") + if not elem_a.IsValid(): + self.fail("Failed to get the element a in n") + + error = lldb.SBError() + value = elem_a.GetValueAsSigned(error, 1000) + if not error.Success() or value != 0: + self.fail("failed to get the correct value for element a in n") + + def test_nest_flat(self): + self.build() + self.common_setup(self.line2) + + # These should display correctly. + self.expect('frame variable n --flat', + substrs=['n.a = 0', + 'n.b = 2', + 'n.foo.c = 0', + 'n.foo.d = 4']) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break in main.c. + self.source = 'main.c' + self.line0 = line_number(self.source, '// Set breakpoint 0 here.') + self.line1 = line_number(self.source, '// Set breakpoint 1 here.') + self.line2 = line_number(self.source, '// Set breakpoint 2 here.') + + def common_setup(self, line): + + # Set debugger into synchronous mode + self.dbg.SetAsync(False) + + # Create a target + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set breakpoints inside and outside methods that take pointers to the + # containing struct. + lldbutil.run_break_set_by_file_and_line( + self, self.source, 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()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/anonymous/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/anonymous/main.c new file mode 100644 index 00000000000..58ac85b7d43 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/anonymous/main.c @@ -0,0 +1,82 @@ +#include <stdio.h> + +struct anonymous_nest { + struct { + struct { + int a; + int b; + }; // anonymous + struct { + int c; + int d; + } foo; + }; // anonymous +}; + +struct anonymous_child { + struct { + struct { + int a; + int b; + } grandchild; + struct { + int c; + int d; + } foo; + }; // anonymous +}; + +struct anonymous_grandchild { + struct { + struct { + int a; + int b; + }; // anonymous + struct { + int c; + int d; + } foo; + } child; +}; + +int processor_nest (struct anonymous_nest *n) +{ + return n->foo.d + n->b; // Set breakpoint 0 here. +} + +int processor_child (struct anonymous_child *c) +{ + return c->foo.d + c->grandchild.b; // Set breakpoint 1 here. +} + +int processor_grandchild (struct anonymous_grandchild *g) +{ + return g->child.foo.d + g->child.b; +} + + + +typedef struct { + int dummy; +} type_y; + +typedef struct { + type_y y; +} type_z; + + + +int main() +{ + struct anonymous_nest n = { 0, 2, 0, 4 }; + struct anonymous_child c = { 0, 2, 0, 4 }; + struct anonymous_grandchild g = { 0, 2, 0, 4 }; + type_z *pz = 0; + type_z z = {{2}}; + + printf("%d\n", processor_nest(&n)); + printf("%d\n", processor_child(&c)); + printf("%d\n", processor_grandchild(&g)); // Set breakpoint 2 here. + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py new file mode 100644 index 00000000000..cc9ae8edb6e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/TestArrayTypes.py @@ -0,0 +1,228 @@ +"""Test breakpoint by file/line number; and list variables with array types.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ArrayTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + def test_and_run_command(self): + """Test 'frame variable var_name' on some variables with array types.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line, num_expected_locations=1, loc_exact=False) + + self.runCmd("run", RUN_SUCCEEDED) + + # The test suite sometimes shows that the process has exited without stopping. + # + # CC=clang ./dotest.py -v -t array_types + # ... + # Process 76604 exited with status = 0 (0x00000000) + self.runCmd("process status") + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # Issue 'variable list' command on several array-type variables. + + self.expect( + "frame variable --show-types strings", + VARIABLES_DISPLAYED_CORRECTLY, + startstr='(char *[4])', + substrs=[ + '(char *) [0]', + '(char *) [1]', + '(char *) [2]', + '(char *) [3]', + 'Hello', + 'Hola', + 'Bonjour', + 'Guten Tag']) + + self.expect( + "frame variable --show-types --raw -- char_16", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(char) [0]', + '(char) [15]']) + + self.expect( + "frame variable --show-types ushort_matrix", + VARIABLES_DISPLAYED_CORRECTLY, + startstr='(unsigned short [2][3])') + + self.expect( + "frame variable --show-types long_6", + VARIABLES_DISPLAYED_CORRECTLY, + startstr='(long [6])') + + @expectedFailureNetBSD + @add_test_categories(['pyapi']) + def test_and_python_api(self): + """Use Python APIs to inspect variables with array types.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.c", self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Sanity check the print representation of breakpoint. + bp = str(breakpoint) + self.expect(bp, msg="Breakpoint looks good", exe=False, + substrs=["file = 'main.c'", + "line = %d" % self.line, + "locations = 1"]) + self.expect( + bp, + msg="Breakpoint is not resolved as yet", + exe=False, + matching=False, + substrs=["resolved = 1"]) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # Sanity check the print representation of process. + proc = str(process) + self.expect(proc, msg="Process looks good", exe=False, + substrs=["state = stopped", + "executable = a.out"]) + + # The stop reason of the thread should be breakpoint. + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # Sanity check the print representation of thread. + thr = str(thread) + # TODO(zturner): Whether the TID is printed in hex or decimal should be controlled by a setting, + # and this test should read the value of the setting. This check is currently hardcoded to + # match the check in Core/FormatEntity.cpp in the function FormatEntity::Format() for + # the Entry::Type::ThreadID case of the switch statement. + if self.getPlatform() == "linux" or self.getPlatform() == "freebsd": + tidstr = "tid = %u" % thread.GetThreadID() + else: + tidstr = "tid = 0x%4.4x" % thread.GetThreadID() + self.expect( + thr, + "Thread looks good with stop reason = breakpoint", + exe=False, + substrs=[tidstr]) + + # The breakpoint should have a hit count of 1. + self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE) + + # The breakpoint should be resolved by now. + bp = str(breakpoint) + self.expect(bp, "Breakpoint looks good and is resolved", exe=False, + substrs=["file = 'main.c'", + "line = %d" % self.line, + "locations = 1"]) + + # Sanity check the print representation of frame. + frame = thread.GetFrameAtIndex(0) + frm = str(frame) + self.expect( + frm, + "Frame looks good with correct index %d" % + frame.GetFrameID(), + exe=False, + substrs=[ + "#%d" % + frame.GetFrameID()]) + + # Lookup the "strings" string array variable and sanity check its print + # representation. + variable = frame.FindVariable("strings") + var = str(variable) + self.expect( + var, + "Variable for 'strings' looks good with correct name", + exe=False, + substrs=[ + "%s" % + variable.GetName()]) + self.DebugSBValue(variable) + self.assertTrue(variable.GetNumChildren() == 4, + "Variable 'strings' should have 4 children") + byte_size = variable.GetByteSize() + self.assertTrue(byte_size >= 4*4 and byte_size <= 1024) + + child3 = variable.GetChildAtIndex(3) + self.DebugSBValue(child3) + self.assertTrue(child3.GetSummary() == '"Guten Tag"', + 'strings[3] == "Guten Tag"') + + # Lookup the "char_16" char array variable. + variable = frame.FindVariable("char_16") + self.DebugSBValue(variable) + self.assertTrue(variable.GetNumChildren() == 16, + "Variable 'char_16' should have 16 children") + + # Lookup the "ushort_matrix" ushort[] array variable. + # Notice the pattern of int(child0_2.GetValue(), 0). We pass a + # base of 0 so that the proper radix is determined based on the contents + # of the string. Same applies to long(). + variable = frame.FindVariable("ushort_matrix") + self.DebugSBValue(variable) + self.assertTrue(variable.GetNumChildren() == 2, + "Variable 'ushort_matrix' should have 2 children") + child0 = variable.GetChildAtIndex(0) + self.DebugSBValue(child0) + self.assertTrue(child0.GetNumChildren() == 3, + "Variable 'ushort_matrix[0]' should have 3 children") + child0_2 = child0.GetChildAtIndex(2) + self.DebugSBValue(child0_2) + self.assertTrue(int(child0_2.GetValue(), 0) == 3, + "ushort_matrix[0][2] == 3") + + # Lookup the "long_6" char array variable. + variable = frame.FindVariable("long_6") + self.DebugSBValue(variable) + self.assertTrue(variable.GetNumChildren() == 6, + "Variable 'long_6' should have 6 children") + child5 = variable.GetChildAtIndex(5) + self.DebugSBValue(child5) + self.assertTrue(int(child5.GetValue(), 0) == 6, + "long_6[5] == 6") + + # Last, check that "long_6" has a value type of eValueTypeVariableLocal + # and "argc" has eValueTypeVariableArgument. + from lldbsuite.test.lldbutil import value_type_to_str + self.assertTrue( + variable.GetValueType() == lldb.eValueTypeVariableLocal, + "Variable 'long_6' should have '%s' value type." % + value_type_to_str( + lldb.eValueTypeVariableLocal)) + argc = frame.FindVariable("argc") + self.DebugSBValue(argc) + self.assertTrue(argc.GetValueType() == lldb.eValueTypeVariableArgument, + "Variable 'argc' should have '%s' value type." % + value_type_to_str(lldb.eValueTypeVariableArgument)) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/cmds.txt b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/cmds.txt new file mode 100644 index 00000000000..8feebe21204 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/cmds.txt @@ -0,0 +1,3 @@ +break main.c:42 +continue +var diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/main.c new file mode 100644 index 00000000000..eda7dc3d6ac --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/array_types/main.c @@ -0,0 +1,50 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +int main (int argc, char const *argv[]) +{ + struct point_tag { + int x; + int y; + }; + + struct rect_tag { + struct point_tag bottom_left; + struct point_tag top_right; + }; + char char_16[16] = "Hello World\n"; + char *strings[] = { "Hello", "Hola", "Bonjour", "Guten Tag" }; + char char_matrix[3][3] = {{'a', 'b', 'c' }, {'d', 'e', 'f' }, {'g', 'h', 'i' }}; + char char_matrix_matrix[3][2][3] = + { {{'a', 'b', 'c' }, {'d', 'e', 'f' }}, + {{'A', 'B', 'C' }, {'D', 'E', 'F' }}, + {{'1', '2', '3' }, {'4', '5', '6' }}}; + short short_4[4] = { 1,2,3,4 }; + short short_matrix[1][2] = { {1,2} }; + unsigned short ushort_4[4] = { 1,2,3,4 }; + unsigned short ushort_matrix[2][3] = { + { 1, 2, 3}, + {11,22,33} + }; + int int_2[2] = { 1, 2 }; + unsigned int uint_2[2] = { 1, 2 }; + long long_6[6] = { 1, 2, 3, 4, 5, 6 }; + unsigned long ulong_6[6] = { 1, 2, 3, 4, 5, 6 }; + struct point_tag points_2[2] = { + {1,2}, + {3,4} + }; + struct point_tag points_2_4_matrix[2][4] = { // Set break point at this line. + {{ 1, 2}, { 3, 4}, { 5, 6}, { 7, 8}}, + {{11,22}, {33,44}, {55,66}, {77,88}} + }; + struct rect_tag rects_2[2] = { + {{1,2}, {3,4}}, + {{5,6}, {7,8}} + }; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/bitfields/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/bitfields/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/bitfields/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py new file mode 100644 index 00000000000..7b28a321ff6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/bitfields/TestBitfields.py @@ -0,0 +1,220 @@ +"""Show bitfields and check that they display correctly.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BitfieldsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + # BitFields exhibit crashes in record layout on Windows + # (http://llvm.org/pr21800) + @skipIfWindows + def test_and_run_command(self): + """Test 'frame variable ...' on a variable with bitfields.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # This should display correctly. + self.expect( + "frame variable --show-types bits", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(uint32_t:1) b1 = 1', + '(uint32_t:2) b2 = 3', + '(uint32_t:3) b3 = 7', + '(uint32_t) b4 = 15', + '(uint32_t:5) b5 = 31', + '(uint32_t:6) b6 = 63', + '(uint32_t:7) b7 = 127', + '(uint32_t:4) four = 15']) + + # And so should this. + # rdar://problem/8348251 + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(uint32_t:1) b1 = 1', + '(uint32_t:2) b2 = 3', + '(uint32_t:3) b3 = 7', + '(uint32_t) b4 = 15', + '(uint32_t:5) b5 = 31', + '(uint32_t:6) b6 = 63', + '(uint32_t:7) b7 = 127', + '(uint32_t:4) four = 15']) + + self.expect("expr (bits.b1)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', '1']) + self.expect("expr (bits.b2)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', '3']) + self.expect("expr (bits.b3)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', '7']) + self.expect("expr (bits.b4)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', '15']) + self.expect("expr (bits.b5)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', '31']) + self.expect("expr (bits.b6)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', '63']) + self.expect("expr (bits.b7)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', '127']) + self.expect("expr (bits.four)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', '15']) + + self.expect( + "frame variable --show-types more_bits", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(uint32_t:3) a = 3', + '(uint8_t:1) b = \'\\0\'', + '(uint8_t:1) c = \'\\x01\'', + '(uint8_t:1) d = \'\\0\'']) + + self.expect("expr (more_bits.a)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', '3']) + self.expect("expr (more_bits.b)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint8_t', '\\0']) + self.expect("expr (more_bits.c)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint8_t', '\\x01']) + self.expect("expr (more_bits.d)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint8_t', '\\0']) + + self.expect("expr (packed.a)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['char', "'a'"]) + self.expect("expr (packed.b)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', "10"]) + self.expect("expr/x (packed.c)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint32_t', "7112233"]) + + for bit in range(1,18): + expected = "1" if bit in [1, 5, 7, 13] else "0" + self.expect("expr even_more_bits.b" + str(bit), VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint8_t', expected]) + + for bit in [3, 10, 14]: + self.expect("expr even_more_bits.b" + str(bit) + " = 1", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint8_t', "1"]) + + self.expect( + "frame variable --show-types even_more_bits", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(uint8_t:1) b1 = \'\\x01\'', + '(uint8_t:1) b2 = \'\\0\'', + '(uint8_t:1) b3 = \'\\x01\'', + '(uint8_t:1) b4 = \'\\0\'', + '(uint8_t:1) b5 = \'\\x01\'', + '(uint8_t:1) b6 = \'\\0\'', + '(uint8_t:1) b7 = \'\\x01\'', + '(uint8_t:1) b8 = \'\\0\'', + '(uint8_t:1) b9 = \'\\0\'', + '(uint8_t:1) b10 = \'\\x01\'', + '(uint8_t:1) b12 = \'\\0\'', + '(uint8_t:1) b13 = \'\\x01\'', + '(uint8_t:1) b14 = \'\\x01\'', + '(uint8_t:1) b15 = \'\\0\'', + '(uint8_t:1) b16 = \'\\0\'', + '(uint8_t:1) b17 = \'\\0\'', + ]) + + self.expect("v/x large_packed", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["a = 0x0000000cbbbbaaaa", "b = 0x0000000dffffeee"]) + + + @add_test_categories(['pyapi']) + # BitFields exhibit crashes in record layout on Windows + # (http://llvm.org/pr21800) + @skipIfWindows + def test_and_python_api(self): + """Use Python APIs to inspect a bitfields variable.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.c", self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # The breakpoint should have a hit count of 1. + self.assertEqual(breakpoint.GetHitCount(), 1, BREAKPOINT_HIT_ONCE) + + # Lookup the "bits" variable which contains 8 bitfields. + frame = thread.GetFrameAtIndex(0) + bits = frame.FindVariable("bits") + self.DebugSBValue(bits) + self.assertTrue( + bits.GetTypeName() == 'Bits', + "bits.GetTypeName() == 'Bits'") + self.assertTrue( + bits.GetNumChildren() == 10, + "bits.GetNumChildren() == 10") + test_compiler = self.getCompiler() + self.assertTrue(bits.GetByteSize() == 32, "bits.GetByteSize() == 32") + + # Notice the pattern of int(b1.GetValue(), 0). We pass a base of 0 + # so that the proper radix is determined based on the contents of the + # string. + b1 = bits.GetChildMemberWithName("b1") + self.DebugSBValue(b1) + self.assertTrue(b1.GetName() == "b1" and + b1.GetTypeName() == "uint32_t:1" and + b1.IsInScope() and + int(b1.GetValue(), 0) == 1, + 'bits.b1 has type uint32_t:1, is in scope, and == 1') + + b7 = bits.GetChildMemberWithName("b7") + self.DebugSBValue(b7) + self.assertTrue(b7.GetName() == "b7" and + b7.GetTypeName() == "uint32_t:7" and + b7.IsInScope() and + int(b7.GetValue(), 0) == 127, + 'bits.b7 has type uint32_t:7, is in scope, and == 127') + + four = bits.GetChildMemberWithName("four") + self.DebugSBValue(four) + self.assertTrue(four.GetName() == "four" and + four.GetTypeName() == "uint32_t:4" and + four.IsInScope() and + int(four.GetValue(), 0) == 15, + 'bits.four has type uint32_t:4, is in scope, and == 15') + + # Now kill the process, and we are done. + rc = target.GetProcess().Kill() + self.assertTrue(rc.Success()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/bitfields/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/bitfields/main.c new file mode 100644 index 00000000000..be3a1af76ba --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/bitfields/main.c @@ -0,0 +1,103 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +int main (int argc, char const *argv[]) +{ + struct Bits + { + uint32_t : 1, // Unnamed bitfield + b1 : 1, + b2 : 2, + : 2, // Unnamed bitfield + b3 : 3, + : 2, // Unnamed bitfield (this will get removed) + b4 __attribute__ ((aligned(16))), + b5 : 5, + b6 : 6, + b7 : 7, + four : 4; + }; + + printf("%lu", sizeof(struct Bits)); + + struct Bits bits; + int i; + for (i=0; i<(1<<1); i++) + bits.b1 = i; //// break $source:$line + for (i=0; i<(1<<2); i++) + bits.b2 = i; //// break $source:$line + for (i=0; i<(1<<3); i++) + bits.b3 = i; //// break $source:$line + for (i=0; i<(1<<4); i++) + bits.b4 = i; //// break $source:$line + for (i=0; i<(1<<5); i++) + bits.b5 = i; //// break $source:$line + for (i=0; i<(1<<6); i++) + bits.b6 = i; //// break $source:$line + for (i=0; i<(1<<7); i++) + bits.b7 = i; //// break $source:$line + for (i=0; i<(1<<4); i++) + bits.four = i; //// break $source:$line + + struct MoreBits + { + uint32_t a : 3; + uint8_t : 1; + uint8_t b : 1; + uint8_t c : 1; + uint8_t d : 1; + }; + + struct MoreBits more_bits; + + more_bits.a = 3; + more_bits.b = 0; + more_bits.c = 1; + more_bits.d = 0; + + struct EvenMoreBits + { + uint8_t b1 : 1, b2 : 1, b3 : 1, b4 : 1, b5 : 1, b6 : 1, + b7 : 1, b8 : 1, b9 : 1, b10 : 1, b11 : 1, b12 : 1, + b13 : 1, b14 : 1, b15 : 1, b16 : 1, b17 : 1; + }; + + struct EvenMoreBits even_more_bits; + memset(&even_more_bits, 0, sizeof(even_more_bits)); + even_more_bits.b1 = 1; + even_more_bits.b5 = 1; + even_more_bits.b7 = 1; + even_more_bits.b13 = 1; + +#pragma pack(1) + struct PackedBits + { + char a; + uint32_t b : 5, + c : 27; + }; +#pragma pack() + struct PackedBits packed; + packed.a = 'a'; + packed.b = 10; + packed.c = 0x7112233; + + struct LargePackedBits { + uint64_t a: 36; + uint64_t b: 36; + } __attribute__((packed)); + + struct LargePackedBits large_packed = + (struct LargePackedBits){ 0xcbbbbaaaa, 0xdffffeeee }; + + return 0; //// Set break point at this line. + +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/blocks/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/blocks/Makefile new file mode 100644 index 00000000000..57083c95274 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/blocks/Makefile @@ -0,0 +1,4 @@ +C_SOURCES := main.c +CFLAGS_EXTRAS := -fblocks + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py new file mode 100644 index 00000000000..cd82d159248 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/blocks/TestBlocks.py @@ -0,0 +1,81 @@ +"""Test that lldb can invoke blocks and access variables inside them""" + + + +import unittest2 +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + + +class BlocksTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + lines = [] + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break at. + self.lines.append(line_number('main.c', '// Set breakpoint 0 here.')) + self.lines.append(line_number('main.c', '// Set breakpoint 1 here.')) + + def launch_common(self): + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + self.is_started = False + + # Break inside the foo function which takes a bar_ptr argument. + for line in self.lines: + lldbutil.run_break_set_by_file_and_line( + self, "main.c", line, num_expected_locations=1, loc_exact=True) + + self.wait_for_breakpoint() + + @skipUnlessDarwin + def test_expr(self): + self.launch_common() + + self.expect("expression a + b", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 7"]) + + self.expect("expression c", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 1"]) + + self.wait_for_breakpoint() + + # This should display correctly. + self.expect("expression (int)neg (-12)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 12"]) + + @skipUnlessDarwin + def test_define(self): + self.launch_common() + + self.runCmd( + "expression int (^$add)(int, int) = ^int(int a, int b) { return a + b; };") + self.expect( + "expression $add(2,3)", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[" = 5"]) + + self.runCmd("expression int $a = 3") + self.expect( + "expression int (^$addA)(int) = ^int(int b) { return $a + b; };", + "Proper error is reported on capture", + error=True) + + def wait_for_breakpoint(self): + if not self.is_started: + self.is_started = True + self.runCmd("process launch", RUN_SUCCEEDED) + else: + self.runCmd("process continue", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/blocks/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/blocks/main.c new file mode 100644 index 00000000000..415e6c6d033 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/blocks/main.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int c = 1; + + int (^add)(int, int) = ^int(int a, int b) + { + return a + b + c; // Set breakpoint 0 here. + }; + + int (^neg)(int) = ^int(int a) + { + return -a; + }; + + printf("%d\n", add(3, 4)); + printf("%d\n", neg(-5)); // Set breakpoint 1 here. + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile new file mode 100644 index 00000000000..59778ab5d9f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Makefile @@ -0,0 +1,14 @@ +LD_EXTRAS := -L. -LOne -l$(LIB_PREFIX)One -LTwo -l$(LIB_PREFIX)Two +C_SOURCES := main.c + +include Makefile.rules + +.PHONY: +a.out: lib_One lib_Two + +lib_%: + $(MAKE) VPATH=$(SRCDIR)/$* -I $(SRCDIR) -f $(SRCDIR)/$*.mk + +clean:: + $(MAKE) -f $(SRCDIR)/One.mk clean + $(MAKE) -f $(SRCDIR)/Two.mk clean diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk new file mode 100644 index 00000000000..18f3725d22f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One.mk @@ -0,0 +1,8 @@ +DYLIB_NAME := One +DYLIB_C_SOURCES := One.c OneConstant.c +DYLIB_ONLY := YES + +include Makefile.rules + +OneConstant.o: OneConstant.c + $(CC) $(CFLAGS_NO_DEBUG) -c $< -o $@ diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c new file mode 100644 index 00000000000..6bd729f6570 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.c @@ -0,0 +1,6 @@ +#include "One.h" +#include <stdio.h> + +void one() { + printf("One\n"); // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h new file mode 100644 index 00000000000..aae27571bb9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/One.h @@ -0,0 +1,4 @@ +#ifndef ONE_H +#define ONE_H +LLDB_TEST_API void one(); +#endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c new file mode 100644 index 00000000000..8255c2fce99 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/One/OneConstant.c @@ -0,0 +1 @@ +int __attribute__ ((visibility("hidden"))) conflicting_symbol = 11111; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py new file mode 100644 index 00000000000..9d088e308ed --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py @@ -0,0 +1,122 @@ +"""Test that conflicting symbols in different shared libraries work correctly""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestConflictingSymbols(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + TestBase.setUp(self) + lldbutil.mkdir_p(self.getBuildArtifact("One")) + lldbutil.mkdir_p(self.getBuildArtifact("Two")) + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489") + @expectedFailureNetBSD + def test_conflicting_symbols(self): + self.build() + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Register our shared libraries for remote targets so they get + # automatically uploaded + environment = self.registerSharedLibrariesWithTarget( + target, ['One', 'Two']) + + lldbutil.run_break_set_by_source_regexp(self, '// break here', + extra_options='-f One.c', num_expected_locations=-2) + lldbutil.run_break_set_by_source_regexp(self, '// break here', + extra_options='-f Two.c', num_expected_locations=-2) + lldbutil.run_break_set_by_source_regexp(self, '// break here', + extra_options='-f main.c', num_expected_locations=1) + + process = target.LaunchSimple( + None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs=[' resolved, hit count = 1']) + + # This should display correctly. + self.expect( + "expr (unsigned long long)conflicting_symbol", + "Symbol from One should be found", + substrs=[ + "11111"]) + + self.runCmd("continue", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs=[' resolved, hit count = 1']) + + self.expect( + "expr (unsigned long long)conflicting_symbol", + "Symbol from Two should be found", + substrs=[ + "22222"]) + + self.runCmd("continue", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs=[' resolved, hit count = 1']) + + self.expect( + "expr (unsigned long long)conflicting_symbol", + "An error should be printed when symbols can't be ordered", + error=True, + substrs=[ + "Multiple internal symbols"]) + + @expectedFailureAll(bugnumber="llvm.org/pr35043") + @skipIfWindows # This test is "passing" on Windows, but it is a false positive. + def test_shadowed(self): + self.build() + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Register our shared libraries for remote targets so they get + # automatically uploaded + environment = self.registerSharedLibrariesWithTarget( + target, ['One', 'Two']) + + lldbutil.run_break_set_by_source_regexp(self, '// break here', + extra_options='-f main.c', num_expected_locations=1) + + process = target.LaunchSimple( + None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # As we are shadowing the conflicting symbol, there should be no + # ambiguity in this expression. + self.expect( + "expr int conflicting_symbol = 474747; conflicting_symbol", + substrs=[ "474747"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk new file mode 100644 index 00000000000..79b256a0e85 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two.mk @@ -0,0 +1,8 @@ +DYLIB_NAME := Two +DYLIB_C_SOURCES := Two.c TwoConstant.c +DYLIB_ONLY := YES + +include Makefile.rules + +TwoConstant.o: TwoConstant.c + $(CC) $(CFLAGS_NO_DEBUG) -c $< -o $@ diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c new file mode 100644 index 00000000000..8d8d668b8c3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.c @@ -0,0 +1,6 @@ +#include "Two.h" +#include <stdio.h> + +void two() { + printf("Two\n"); // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h new file mode 100644 index 00000000000..450fe5a3551 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/Two.h @@ -0,0 +1,4 @@ +#ifndef TWO_H +#define TWO_H +LLDB_TEST_API void two(); +#endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c new file mode 100644 index 00000000000..9fc7c4b7951 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/Two/TwoConstant.c @@ -0,0 +1 @@ +int __attribute__ ((visibility("hidden"))) conflicting_symbol = 22222; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c new file mode 100644 index 00000000000..4dcd443c049 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/main.c @@ -0,0 +1,11 @@ +#include "One/One.h" +#include "Two/Two.h" + +#include <stdio.h> + +int main() { + one(); + two(); + printf("main\n"); // break here + return(0); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/Makefile new file mode 100644 index 00000000000..325be90d17e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/Makefile @@ -0,0 +1,5 @@ +C_SOURCES := main.c functions.c + +CFLAGS_EXTRAS := -O3 + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py new file mode 100644 index 00000000000..59fa6bcb0a1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/TestConstVariables.py @@ -0,0 +1,68 @@ +"""Check that compiler-generated constant values work correctly""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ConstVariableTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll( + oslist=["freebsd", "linux"], + compiler="clang", compiler_version=["<", "3.5"]) + @expectedFailureAll( + oslist=["freebsd", "linux"], + compiler="clang", compiler_version=["=", "3.7"]) + @expectedFailureAll( + oslist=["freebsd", "linux"], + compiler="clang", compiler_version=["=", "3.8"]) + @expectedFailureAll(oslist=["freebsd", "linux"], compiler="icc") + @expectedFailureAll(archs=['mips', 'mipsel', 'mips64', 'mips64el']) + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows") + @expectedFailureNetBSD + def test_and_run_command(self): + """Test interpreted and JITted expressions on constant values.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_symbol( + self, "main", num_expected_locations=1) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + self.runCmd("next") + self.runCmd("next") + + # Try frame variable. + self.expect("frame variable index", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['(int32_t) index = 512']) + + # Try an interpreted expression. + self.expect("expr (index + 512)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['1024']) + + # Try a JITted expression. + self.expect( + "expr (int)getpid(); (index - 256)", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=['256']) + + self.runCmd("kill") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/functions.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/functions.c new file mode 100644 index 00000000000..c9ea63837c8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/functions.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +void foo() +{ + printf("foo()\n"); +} + +int bar() +{ + int ret = 3; + printf("bar()->%d\n", ret); + return ret; +} + +void baaz(int i) +{ + printf("baaz(%d)\n", i); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/main.c new file mode 100644 index 00000000000..50a924e01d9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/const_variables/main.c @@ -0,0 +1,23 @@ +#include <stdint.h> +#include <stdio.h> + +extern int foo(); +extern int bar(); +extern int baaz(int i); + +int main() +{ + int32_t index; + + foo(); + + index = 512; + + if (bar()) + { + printf("COMPILER PLEASE STOP HERE\n"); + index = 256; + } + + baaz(index); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py new file mode 100644 index 00000000000..af9b6fb8d46 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/TestEnumTypes.py @@ -0,0 +1,126 @@ +"""Look up enum type information and check for correct display.""" + + + +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * + + +class EnumTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + def test(self): + """Test 'image lookup -t days' and check for correct display and enum value printing.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_to_source_breakpoint( + self, '// Breakpoint for bitfield', lldb.SBFileSpec("main.c")) + + self.expect("fr var a", DATA_TYPES_DISPLAYED_CORRECTLY, + patterns=[' = A$']) + self.expect("fr var b", DATA_TYPES_DISPLAYED_CORRECTLY, + patterns=[' = B$']) + self.expect("fr var c", DATA_TYPES_DISPLAYED_CORRECTLY, + patterns=[' = C$']) + self.expect("fr var ab", DATA_TYPES_DISPLAYED_CORRECTLY, + patterns=[' = AB$']) + self.expect("fr var ac", DATA_TYPES_DISPLAYED_CORRECTLY, + patterns=[' = A | C$']) + self.expect("fr var all", DATA_TYPES_DISPLAYED_CORRECTLY, + patterns=[' = ALL$']) + # Test that an enum that doesn't match the heuristic we use in + # ClangASTContext::DumpEnumValue, gets printed as a raw integer. + self.expect("fr var omega", DATA_TYPES_DISPLAYED_CORRECTLY, + patterns=[' = 7$']) + # Test the behavior in case have a variable of a type considered + # 'bitfield' by the heuristic, but the value isn't actually fully + # covered by the enumerators. + self.expect("p (enum bitfield)nonsense", DATA_TYPES_DISPLAYED_CORRECTLY, + patterns=[' = B | C | 0x10$']) + + # Break inside the main. + bkpt_id = lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + self.runCmd("c", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # Look up information about the 'days' enum type. + # Check for correct display. + self.expect("image lookup -t days", DATA_TYPES_DISPLAYED_CORRECTLY, + substrs=['enum days {', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + 'kNumDays', + '}']) + + enum_values = ['-4', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + 'kNumDays', + '5'] + + # Make sure a pointer to an anonymous enum type does crash LLDB and displays correctly using + # frame variable and expression commands + self.expect( + 'frame variable f.op', + DATA_TYPES_DISPLAYED_CORRECTLY, + substrs=[ + 'ops *', + 'f.op'], + patterns=['0x0+$']) + self.expect( + 'frame variable *f.op', + DATA_TYPES_DISPLAYED_CORRECTLY, + substrs=[ + 'ops', + '*f.op', + '<parent is NULL>']) + self.expect( + 'expr f.op', + DATA_TYPES_DISPLAYED_CORRECTLY, + substrs=[ + 'ops *', + '$'], + patterns=['0x0+$']) + self.expect( + 'expr *f.op', + DATA_TYPES_DISPLAYED_CORRECTLY, + substrs=['error:'], + error=True) + + bkpt = self.target().FindBreakpointByID(bkpt_id) + for enum_value in enum_values: + self.expect( + "frame variable day", + 'check for valid enumeration value', + substrs=[enum_value]) + lldbutil.continue_to_breakpoint(self.process(), bkpt) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/main.c new file mode 100644 index 00000000000..675af5ecec5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/enum_types/main.c @@ -0,0 +1,58 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +#include <stdio.h> + +// Forward declare an enumeration (only works in C, not C++) +typedef enum ops ops; + +struct foo { + ops *op; +}; + +int main (int argc, char const *argv[]) +{ + enum bitfield { + None = 0, + A = 1 << 0, + B = 1 << 1, + C = 1 << 2, + AB = A | B, + ALL = A | B | C, + }; + + enum non_bitfield { + Alpha = 3, + Beta = 4 + }; + + enum days { + Monday = -3, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + Sunday, + kNumDays + }; + + enum bitfield a = A, b = B, c = C, ab = AB, ac = A | C, all = ALL; + int nonsense = a + b + c + ab + ac + all; + enum non_bitfield omega = Alpha | Beta; + + enum days day; + struct foo f; + f.op = NULL; // Breakpoint for bitfield + for (day = Monday - 1; day <= kNumDays + 1; day++) + { + printf("day as int is %i\n", (int)day); // Set break point at this line. + } + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/find_struct_type/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/find_struct_type/Makefile new file mode 100644 index 00000000000..c9319d6e688 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/find_struct_type/Makefile @@ -0,0 +1,2 @@ +C_SOURCES := main.c +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/find_struct_type/TestFindStructTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/find_struct_type/TestFindStructTypes.py new file mode 100644 index 00000000000..90d8530ff71 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/find_struct_type/TestFindStructTypes.py @@ -0,0 +1,59 @@ +""" +Make sure FindTypes finds struct types with the struct prefix. +""" + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + + +class TestFindTypesOnStructType(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # If your test case doesn't stress debug info, the + # set this to true. That way it won't be run once for + # each debug info format. + NO_DEBUG_INFO_TESTCASE = True + + def test_find_types_struct_type(self): + """Make sure FindTypes actually finds 'struct typename' not just 'typename'.""" + self.build() + self.do_test() + + def do_test(self): + """Make sure FindTypes actually finds 'struct typename' not just 'typename'.""" + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Make sure this works with struct + type_list = target.FindTypes("struct mytype") + self.assertEqual(type_list.GetSize(), 1, "Found one instance of the type with struct") + + # Make sure this works without the struct: + type_list = target.FindTypes("mytype") + self.assertEqual(type_list.GetSize(), 1, "Found one instance of the type without struct") + + # Make sure it works with union + type_list = target.FindTypes("union myunion") + self.assertEqual(type_list.GetSize(), 1, "Found one instance of the type with union") + + # Make sure this works without the union: + type_list = target.FindTypes("myunion") + self.assertEqual(type_list.GetSize(), 1, "Found one instance of the type without union") + + # Make sure it works with typedef + type_list = target.FindTypes("typedef MyType") + self.assertEqual(type_list.GetSize(), 1, "Found one instance of the type with typedef") + + # Make sure this works without the typedef: + type_list = target.FindTypes("MyType") + self.assertEqual(type_list.GetSize(), 1, "Found one instance of the type without typedef") + + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/find_struct_type/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/find_struct_type/main.c new file mode 100644 index 00000000000..fa009af27e1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/find_struct_type/main.c @@ -0,0 +1,25 @@ +#include <stdio.h> +#include <stdlib.h> +struct mytype { + int c; + int d; +}; + +union myunion { + int num; + char *str; +}; + +typedef struct mytype MyType; + +int main() +{ + struct mytype v; + MyType *v_ptr = &v; + + union myunion u = {5}; + v.c = u.num; + v.d = 10; + return v.c + v.d; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/Makefile new file mode 100644 index 00000000000..472e733aaad --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c foo.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/README.txt b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/README.txt new file mode 100644 index 00000000000..b7b66f75162 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/README.txt @@ -0,0 +1,5 @@ +This example has a function call in foo.c named "foo" that takes a forward +declaration to "struct bar" and uses it as a pointer argument. In main.c +we have a real declaration for "struct bar". We want to be able to find the +real definition of "struct bar" when we are stopped in foo in foo.c such that +when we stop in "foo" we see the contents of the "bar_ptr". diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/TestForwardDeclaration.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/TestForwardDeclaration.py new file mode 100644 index 00000000000..9ea13612c07 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/TestForwardDeclaration.py @@ -0,0 +1,65 @@ +"""Test that forward declaration of a data structure gets resolved correctly.""" + + + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + + +class ForwardDeclarationTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def do_test(self, dictionary=None): + """Display *bar_ptr when stopped on a function with forward declaration of struct bar.""" + self.build(dictionary=dictionary) + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_symbol( + self, "foo", num_expected_locations=1, sym_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # This should display correctly. + # Note that the member fields of a = 1 and b = 2 is by design. + self.expect( + "frame variable --show-types *bar_ptr", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(bar) *bar_ptr = ', + '(int) a = 1', + '(int) b = 2']) + + # And so should this. + self.expect( + "expression --show-types -- *bar_ptr", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(bar)', + '(int) a = 1', + '(int) b = 2']) + + def test(self): + self.do_test() + + @no_debug_info_test + @skipIfDarwin + @skipIf(compiler=no_match("clang")) + @skipIf(compiler_version=["<", "7.0"]) + def test_debug_names(self): + """Test that we are able to find complete types when using DWARF v5 + accelerator tables""" + self.do_test(dict(CFLAGS_EXTRAS="-mllvm -accel-tables=Dwarf")) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/foo.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/foo.c new file mode 100644 index 00000000000..2e050e77778 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/foo.c @@ -0,0 +1,8 @@ +#include <stdio.h> +#include "foo.h" + +int +foo (struct bar *bar_ptr) +{ + return printf ("bar_ptr = %p\n", bar_ptr); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/foo.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/foo.h new file mode 100644 index 00000000000..3040927cb47 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/foo.h @@ -0,0 +1,4 @@ + +struct bar; + +int foo (struct bar *bar_ptr); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/main.c new file mode 100644 index 00000000000..6f9787c30a3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/forward/main.c @@ -0,0 +1,18 @@ +#include <stdio.h> +#include "foo.h" + +struct bar +{ + int a; + int b; +}; + +int +main (int argc, char const *argv[]) +{ + struct bar b= { 1, 2 }; + + foo (&b); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/function_types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/function_types/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/function_types/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py new file mode 100644 index 00000000000..3753eab64ef --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/function_types/TestFunctionTypes.py @@ -0,0 +1,83 @@ +"""Test variable with function ptr type and that break on the function works.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class FunctionTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set break point at this line.') + + def test(self): + """Test 'callback' has function ptr type, then break on the function.""" + self.build() + self.runToBreakpoint() + + # Check that the 'callback' variable display properly. + self.expect( + "frame variable --show-types callback", + VARIABLES_DISPLAYED_CORRECTLY, + startstr='(int (*)(const char *)) callback =') + + # And that we can break on the callback function. + lldbutil.run_break_set_by_symbol( + self, + "string_not_empty", + num_expected_locations=1, + sym_exact=True) + self.runCmd("continue") + + # Check that we do indeed stop on the string_not_empty function. + self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, + substrs=['a.out`string_not_empty', + 'stop reason = breakpoint']) + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765") + @expectedFailureNetBSD + def test_pointers(self): + """Test that a function pointer to 'printf' works and can be called.""" + self.build() + self.runToBreakpoint() + + self.expect("expr string_not_empty", + substrs=['(int (*)(const char *)) $0 = ', '(a.out`']) + + if self.platformIsDarwin(): + regexps = ['lib.*\.dylib`printf'] + else: + regexps = ['printf'] + self.expect("expr (int (*)(const char*, ...))printf", + substrs=['(int (*)(const char *, ...)) $1 = '], + patterns=regexps) + + self.expect("expr $1(\"Hello world\\n\")", + startstr='(int) $2 = 12') + + def runToBreakpoint(self): + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/function_types/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/function_types/main.c new file mode 100644 index 00000000000..f8710f67720 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/function_types/main.c @@ -0,0 +1,21 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +int string_not_empty (const char *s) +{ + if (s && s[0]) + return 1; + return 0; +} + +int main (int argc, char const *argv[]) +{ + int (*callback)(const char *) = string_not_empty; + + return callback(0); // Set break point at this line. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/Makefile new file mode 100644 index 00000000000..7b94b6556f2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/Makefile @@ -0,0 +1,6 @@ +C_SOURCES := main.c + +DYLIB_NAME := a +DYLIB_C_SOURCES := a.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py new file mode 100644 index 00000000000..690d1abb3cf --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/TestGlobalVariables.py @@ -0,0 +1,123 @@ +"""Show global variables and check that they do indeed have global scopes.""" + + + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class GlobalVariablesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.c' + self.line = line_number( + self.source, '// Set break point at this line.') + self.shlib_names = ["a"] + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") + def test_without_process(self): + """Test that static initialized variables can be inspected without + process.""" + self.build() + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + + self.assertTrue(target, VALID_TARGET) + self.expect("target variable g_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['(int *)']) + self.expect("target variable *g_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['42']) + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") + @expectedFailureNetBSD + def test_c_global_variables(self): + """Test 'frame variable --scope --no-args' which omits args and shows scopes.""" + self.build() + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line( + self, self.source, self.line, num_expected_locations=1, loc_exact=True) + + # Register our shared libraries for remote targets so they get + # automatically uploaded + environment = self.registerSharedLibrariesWithTarget( + target, self.shlib_names) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # Test that the statically initialized variable can also be + # inspected *with* a process. + self.expect("target variable g_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['(int *)']) + self.expect("target variable *g_ptr", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['42']) + + # Check that GLOBAL scopes are indicated for the variables. + self.expect( + "frame variable --show-types --scope --show-globals --no-args", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + 'STATIC: (const int) g_file_static_int = 2', + 'STATIC: (const char *) g_func_static_cstr', + 'GLOBAL: (const char *) g_file_global_cstr', + '"g_file_global_cstr"', + 'GLOBAL: (int) g_file_global_int = 42', + 'GLOBAL: (int) g_common_1 = 21', + 'GLOBAL: (int *) g_ptr', + 'STATIC: (const char *) g_file_static_cstr', + '"g_file_static_cstr"' + ]) + + # 'frame variable' should support address-of operator. + self.runCmd("frame variable &g_file_global_int") + + # Exercise the 'target variable' command to display globals in a.c + # file. + self.expect("target variable g_a", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['g_a', '123']) + self.expect( + "target variable g_marked_spot.x", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + 'g_marked_spot.x', + '20']) + + # rdar://problem/9747668 + # runCmd: target variable g_marked_spot.y + # output: (int) g_marked_spot.y = <a.o[0x214] can't be resolved, in not currently loaded. + # > + self.expect( + "target variable g_marked_spot.y", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + 'g_marked_spot.y', + '21']) + self.expect( + "target variable g_marked_spot.y", + VARIABLES_DISPLAYED_CORRECTLY, + matching=False, + substrs=["can't be resolved"]) + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/a.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/a.c new file mode 100644 index 00000000000..ce3e6f9a2d4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/a.c @@ -0,0 +1,14 @@ +//===-- a.c -----------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +int g_a = 123; +struct Point { + int x; + int y; +}; +struct Point g_marked_spot = { 20, 21 }; + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/cmds.txt b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/cmds.txt new file mode 100644 index 00000000000..6906a0729ae --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/cmds.txt @@ -0,0 +1,3 @@ +break main.c:5 +continue +var -global g_a -global g_global_int diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/main.c new file mode 100644 index 00000000000..ea54eb927c0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/global_variables/main.c @@ -0,0 +1,24 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +int g_common_1; // Not initialized on purpose to cause it to be undefined external in .o file +int g_file_global_int = 42; +static const int g_file_static_int = 2; +const char *g_file_global_cstr = "g_file_global_cstr"; +static const char *g_file_static_cstr = "g_file_static_cstr"; +int *g_ptr = &g_file_global_int; + +extern int g_a; +int main (int argc, char const *argv[]) +{ + g_common_1 = g_file_global_int / g_file_static_int; + static const char *g_func_static_cstr = "g_func_static_cstr"; + printf ("%s %s\n", g_file_global_cstr, g_file_static_cstr); + return g_file_global_int + g_a + g_common_1 + *g_ptr; // Set break point at this line. //// break $source:$line; continue; var -global g_a -global g_global_int +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/inlines/TestRedefinitionsInInlines.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/inlines/TestRedefinitionsInInlines.py new file mode 100644 index 00000000000..311c5ec8e12 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/inlines/TestRedefinitionsInInlines.py @@ -0,0 +1,9 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, + globals(), + [decorators.expectedFailureAll(compiler="clang", + compiler_version=["<", + "3.5"], + bugnumber="llvm.org/pr27845")]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/inlines/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/inlines/main.c new file mode 100644 index 00000000000..8fe49180800 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/inlines/main.c @@ -0,0 +1,25 @@ +#include <stdio.h> + +inline void test1(int) __attribute__ ((always_inline)); +inline void test2(int) __attribute__ ((always_inline)); + +void test2(int b) { + printf("test2(%d)\n", b); //% self.expect("expression b", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["42"]) + { + int c = b * 2; + printf("c=%d\n", c); //% self.expect("expression b", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["42"]) + //% self.expect("expression c", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["84"]) + } +} + +void test1(int a) { + printf("test1(%d)\n", a); + test2(a+1);//% self.runCmd("step") + //% self.expect("expression b", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["24"]) +} + +int main() { + test2(42); + test1(23); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_types/TestUseClosestType.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_types/TestUseClosestType.py new file mode 100644 index 00000000000..2b8307ace0f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_types/TestUseClosestType.py @@ -0,0 +1,48 @@ +""" +If there is a definition of a type in the current +Execution Context's CU, then we should use that type +even if there are other definitions of the type in other +CU's. Assert that that is true. +""" + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * + + +class TestUseClosestType(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + NO_DEBUG_INFO_TESTCASE = True + + @expectedFailureAll(bugnumber="<rdar://problem/53262085>") + def test_use_in_expr(self): + """Use the shadowed type directly, see if we get a conflicting type definition.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.c") + self.expr_test() + + def run_and_check_expr(self, num_children, child_type): + frame = self.thread.GetFrameAtIndex(0) + result = frame.EvaluateExpression("struct Foo *$mine = (struct Foo *) malloc(sizeof(struct Foo)); $mine") + self.assertTrue(result.GetError().Success(), "Failed to parse an expression using a multiply defined type: %s"%(result.GetError().GetCString()), ) + self.assertEqual(result.GetTypeName(), "struct Foo *", "The result has the right typename.") + self.assertEqual(result.GetNumChildren(), num_children, "Got the right number of children") + self.assertEqual(result.GetChildAtIndex(0).GetTypeName(), child_type, "Got the right type.") + + def expr_test(self): + """ Run to a breakpoint in main.c, check that an expression referring to Foo gets the + local three int version. Then run to a breakpoint in other.c and check that an + expression referring to Foo gets the two char* version. """ + + (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint in main", self.main_source_file) + + self.run_and_check_expr(3, "int") + lldbutil.run_to_source_breakpoint(self, "Set a breakpoint in other", lldb.SBFileSpec("other.c")) + self.run_and_check_expr(2, "char *") + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_types/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_types/main.c new file mode 100644 index 00000000000..321facfee21 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_types/main.c @@ -0,0 +1,16 @@ +extern int callme(int input); + +struct Foo { + int a; + int b; + int c; +}; + +int +main(int argc, char **argv) +{ + // Set a breakpoint in main + struct Foo mine = {callme(argc), 10, 20}; + return mine.a; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_types/other.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_types/other.c new file mode 100644 index 00000000000..24b72d45ea8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_types/other.c @@ -0,0 +1,11 @@ +struct Foo { + char *ptr1; + char *ptr2; +}; + +int +callme(int input) +{ + struct Foo myFoo = { "string one", "Set a breakpoint in other"}; + return myFoo.ptr1[0] + myFoo.ptr2[0] + input; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_variables/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_variables/Makefile new file mode 100644 index 00000000000..d3998eeef99 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_variables/Makefile @@ -0,0 +1,5 @@ +C_SOURCES := main.c + +CFLAGS_EXTRAS := -O1 + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_variables/TestLocalVariables.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_variables/TestLocalVariables.py new file mode 100644 index 00000000000..381292a445b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_variables/TestLocalVariables.py @@ -0,0 +1,55 @@ +"""Show local variables and check that they can be inspected. + +This test was added after we made a change in clang to normalize +DW_OP_constu(X < 32) to DW_OP_litX which broke the debugger because +it didn't read the value as an unsigned. +""" + + + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class LocalVariablesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.c' + self.line = line_number( + self.source, '// Set break point at this line.') + + @skipIfWindows + def test_c_local_variables(self): + """Test local variable value.""" + self.build() + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line( + self, self.source, self.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()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + self.expect("frame variable i", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['(unsigned int) i = 10']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_variables/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_variables/main.c new file mode 100644 index 00000000000..2ab579a71a7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/local_variables/main.c @@ -0,0 +1,19 @@ +#include <stdio.h> + +void bar(unsigned i) +{ + printf("%d\n", i); +} + +void foo(unsigned j) +{ + unsigned i = j; + bar(i); + i = 10; + bar(i); // Set break point at this line. +} + +int main(int argc, char** argv) +{ + foo(argc); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/modules/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/modules/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/modules/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py new file mode 100644 index 00000000000..948e8bed786 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py @@ -0,0 +1,91 @@ +"""Test that importing modules in C works as expected.""" + + + +import os + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CModulesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfFreeBSD + @expectedFailureAll( + oslist=["linux"], + bugnumber="http://llvm.org/pr23456 'fopen' has unknown return type") + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows") + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureNetBSD + def test_expr(self): + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # Enable logging of the imported AST. + log_file = os.path.join(self.getBuildDir(), "lldb-ast-log.txt") + self.runCmd("log enable lldb ast -f '%s'" % log_file) + + self.expect( + "expr -l objc++ -- @import Darwin; 3", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "int", + "3"]) + + # This expr command imports __sFILE with definition + # (FILE is a typedef to __sFILE.) + self.expect( + "expr *fopen(\"/dev/zero\", \"w\")", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "FILE", + "_close"]) + + # Check that the AST log contains exactly one definition of __sFILE. + f = open(log_file) + log_lines = f.readlines() + f.close() + os.remove(log_file) + self.assertEqual(" ".join(log_lines).count("struct __sFILE definition"), + 1) + + self.expect("expr *myFile", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["a", "5", "b", "9"]) + + self.expect( + "expr MIN((uint64_t)2, (uint64_t)3)", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "uint64_t", + "2"]) + + self.expect("expr stdin", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["(FILE *)", "0x"]) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.c', '// Set breakpoint 0 here.') diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/modules/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/modules/main.c new file mode 100644 index 00000000000..df321a75faa --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/modules/main.c @@ -0,0 +1,20 @@ +#include <stdlib.h> + +int printf(const char * __restrict format, ...); + +typedef struct { + int a; + int b; +} MYFILE; + +int main() +{ + MYFILE *myFile = malloc(sizeof(MYFILE)); + + myFile->a = 5; + myFile->b = 9; + + printf("%d\n", myFile->a + myFile->b); // Set breakpoint 0 here. + + free(myFile); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/offsetof/TestOffsetof.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/offsetof/TestOffsetof.py new file mode 100644 index 00000000000..cdfbaae0ce3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/offsetof/TestOffsetof.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), [decorators.no_debug_info_test]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/offsetof/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/offsetof/main.c new file mode 100644 index 00000000000..cbb4a144418 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/offsetof/main.c @@ -0,0 +1,12 @@ +#include <stdint.h> + +struct Foo { + int8_t a; + int16_t b; +}; + +int main (int argc, char const *argv[]) { + struct Foo f; + return f.a; //% self.expect("expr offsetof(Foo, a)", substrs = ['= 0']) + //% self.expect("expr offsetof(Foo, b)", substrs = ['= 2']) +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/recurse/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/recurse/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/recurse/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/recurse/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/recurse/main.c new file mode 100644 index 00000000000..1159669ebf1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/recurse/main.c @@ -0,0 +1,28 @@ +#include <stdint.h> +#include <stdio.h> + +uint32_t +recurse_crash (uint32_t depth) +{ + if (depth > 0) + return recurse_crash (depth - 1); + return 0; +} + +int +main (int argc, char const *argv[]) +{ + // If we have more than one argument, then it should a depth to recurse to. + // If we have just the program name as an argument, use UINT32_MAX so we + // eventually crash the program by overflowing the stack + uint32_t depth = UINT32_MAX; + if (argc > 1) + { + char *end = NULL; + depth = strtoul (argv[1], &end, 0); + if (end == NULL || *end != '\0') + depth = UINT32_MAX; + } + recurse_crash (depth); + return 0; +}
\ No newline at end of file diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile new file mode 100644 index 00000000000..e4d42f6525d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/register_variables/Makefile @@ -0,0 +1,5 @@ +C_SOURCES := test.c + +CFLAGS_EXTRAS := -O1 -D_FORTIFY_SOURCE=0 + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py new file mode 100644 index 00000000000..af0ad2a0871 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py @@ -0,0 +1,204 @@ +"""Check that compiler-generated register values work correctly""" + +from __future__ import print_function + +import re +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +# This method attempts to figure out if a given variable +# is in a register. +# +# Return: +# True if the value has a readable value and is in a register +# False otherwise + + +def is_variable_in_register(frame, var_name): + # Ensure we can lookup the variable. + var = frame.FindVariable(var_name) + # print("\nchecking {}...".format(var_name)) + if var is None or not var.IsValid(): + # print("{} cannot be found".format(var_name)) + return False + + # Check that we can get its value. If not, this + # may be a variable that is just out of scope at this point. + value = var.GetValue() + # print("checking value...") + if value is None: + # print("value is invalid") + return False + # else: + # print("value is {}".format(value)) + + # We have a variable and we can get its value. The variable is in + # a register if we cannot get an address for it, assuming it is + # not a struct pointer. (This is an approximation - compilers can + # do other things with spitting up a value into multiple parts of + # multiple registers, but what we're verifying here is much more + # than it was doing before). + var_addr = var.GetAddress() + # print("checking address...") + if var_addr.IsValid(): + # We have an address, it must not be in a register. + # print("var {} is not in a register: has a valid address {}".format(var_name, var_addr)) + return False + else: + # We don't have an address but we can read the value. + # It is likely stored in a register. + # print("var {} is in a register (we don't have an address for it)".format(var_name)) + return True + + +def is_struct_pointer_in_register(frame, var_name, trace): + # Ensure we can lookup the variable. + var = frame.FindVariable(var_name) + if trace: + print("\nchecking {}...".format(var_name)) + + if var is None or not var.IsValid(): + # print("{} cannot be found".format(var_name)) + return False + + # Check that we can get its value. If not, this + # may be a variable that is just out of scope at this point. + value = var.GetValue() + # print("checking value...") + if value is None: + if trace: + print("value is invalid") + return False + else: + if trace: + print("value is {}".format(value)) + + var_loc = var.GetLocation() + if trace: + print("checking location: {}".format(var_loc)) + if var_loc is None or var_loc.startswith("0x"): + # The frame var is not in a register but rather a memory location. + # print("frame var {} is not in a register".format(var_name)) + return False + else: + # print("frame var {} is in a register".format(var_name)) + return True + + +def re_expr_equals(val_type, val): + # Match ({val_type}) ${sum_digits} = {val} + return re.compile(r'\(' + val_type + '\) \$\d+ = ' + str(val)) + + +class RegisterVariableTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(compiler="clang", compiler_version=['<', '3.5']) + @expectedFailureAll(compiler="gcc", compiler_version=[ + '>=', '4.8.2'], archs=["i386"]) + @expectedFailureAll(compiler="gcc", compiler_version=[ + '<', '4.9'], archs=["x86_64"]) + def test_and_run_command(self): + """Test expressions on register values.""" + + # This test now ensures that each probable + # register variable location is actually a register, and + # if so, whether we can print out the variable there. + # It only requires one of them to be handled in a non-error + # way. + register_variables_count = 0 + + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_source_regexp( + self, "break", num_expected_locations=3) + + #################### + # First breakpoint + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # Try some variables that should be visible + frame = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame() + if is_variable_in_register(frame, 'a'): + register_variables_count += 1 + self.expect("expr a", VARIABLES_DISPLAYED_CORRECTLY, + patterns=[re_expr_equals('int', 2)]) + + if is_struct_pointer_in_register(frame, 'b', self.TraceOn()): + register_variables_count += 1 + self.expect("expr b->m1", VARIABLES_DISPLAYED_CORRECTLY, + patterns=[re_expr_equals('int', 3)]) + + ##################### + # Second breakpoint + + self.runCmd("continue") + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # Try some variables that should be visible + frame = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame() + if is_struct_pointer_in_register(frame, 'b', self.TraceOn()): + register_variables_count += 1 + self.expect("expr b->m2", VARIABLES_DISPLAYED_CORRECTLY, + patterns=[re_expr_equals('int', 5)]) + + if is_variable_in_register(frame, 'c'): + register_variables_count += 1 + self.expect("expr c", VARIABLES_DISPLAYED_CORRECTLY, + patterns=[re_expr_equals('int', 5)]) + + ##################### + # Third breakpoint + + self.runCmd("continue") + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # Try some variables that should be visible + frame = self.dbg.GetSelectedTarget().GetProcess( + ).GetSelectedThread().GetSelectedFrame() + if is_variable_in_register(frame, 'f'): + register_variables_count += 1 + self.expect("expr f", VARIABLES_DISPLAYED_CORRECTLY, + patterns=[re_expr_equals('float', '3.1')]) + + # Validate that we verified at least one register variable + self.assertTrue( + register_variables_count > 0, + "expected to verify at least one variable in a register") + # print("executed {} expressions with values in registers".format(register_variables_count)) + + self.runCmd("kill") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/register_variables/test.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/register_variables/test.c new file mode 100644 index 00000000000..2c69039d40a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/register_variables/test.c @@ -0,0 +1,44 @@ +#include <stdio.h> + +#if defined(__arm__) || defined(__aarch64__) || defined (__mips__) || defined(__powerpc64__) +// Clang does not accept regparm attribute on these platforms. +// Fortunately, the default calling convention passes arguments in registers +// anyway. +#define REGPARM(N) +#else +#define REGPARM(N) __attribute__((regparm(N))) +#endif + +struct bar { + int m1; + int m2; +}; + +void f1(int a, struct bar *b) __attribute__((noinline)) REGPARM(2); +void f1(int a, struct bar *b) +{ + b->m2 = b->m1 + a; // set breakpoint here +} + +void f2(struct bar *b) __attribute__((noinline)) REGPARM(1); +void f2(struct bar *b) +{ + int c = b->m2; + printf("%d\n", c); // set breakpoint here +} + +float f3() __attribute__((noinline)); +float f3() { + return 3.14f; +} + +int main() +{ + struct bar myBar = { 3, 4 }; + f1(2, &myBar); + f2(&myBar); + + float f = f3(); + printf("%f\n", f); // set breakpoint here + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/set_values/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/set_values/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/set_values/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py new file mode 100644 index 00000000000..f16d554b815 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/set_values/TestSetValues.py @@ -0,0 +1,139 @@ +"""Test settings and readings of program variables.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SetValuesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.line1 = line_number('main.c', '// Set break point #1.') + self.line2 = line_number('main.c', '// Set break point #2.') + self.line3 = line_number('main.c', '// Set break point #3.') + self.line4 = line_number('main.c', '// Set break point #4.') + self.line5 = line_number('main.c', '// Set break point #5.') + + def test(self): + """Test settings and readings of program variables.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Set breakpoints on several places to set program variables. + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line1, num_expected_locations=1, loc_exact=True) + + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line2, num_expected_locations=1, loc_exact=True) + + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line3, num_expected_locations=1, loc_exact=True) + + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line4, num_expected_locations=1, loc_exact=True) + + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line5, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # main.c:15 + # Check that 'frame variable --show-types' displays the correct data + # type and value. + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(char) i = 'a'") + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 'b'") + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(char) i = 'b'") + + self.runCmd("continue") + + # main.c:36 + # Check that 'frame variable --show-types' displays the correct data + # type and value. + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + patterns=["\((short unsigned int|unsigned short)\) i = 33"]) + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 333") + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + patterns=["\((short unsigned int|unsigned short)\) i = 333"]) + + self.runCmd("continue") + + # main.c:57 + # Check that 'frame variable --show-types' displays the correct data + # type and value. + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(long) i = 33") + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 33333") + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(long) i = 33333") + + self.runCmd("continue") + + # main.c:78 + # Check that 'frame variable --show-types' displays the correct data + # type and value. + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(double) i = 2.25") + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 1.5") + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(double) i = 1.5") + + self.runCmd("continue") + + # main.c:85 + # Check that 'frame variable --show-types' displays the correct data + # type and value. + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(long double) i = 2.25") + + # Now set variable 'i' and check that it is correctly displayed. + self.runCmd("expression i = 1.5") + self.expect( + "frame variable --show-types", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(long double) i = 1.5") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/set_values/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/set_values/main.c new file mode 100644 index 00000000000..64bc95fb5a8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/set_values/main.c @@ -0,0 +1,115 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +void set_char(void) +{ + char i = 'a'; + printf("before (char) i = %c\n", i); + printf("after (char) i = %c\n", i); // Set break point #1. //// break $source:$line +} + +void set_uchar(void) +{ + unsigned char i = 'a'; + printf("before (unsigned char) i = %c\n", i); + printf("after (unsigned char) i = %c\n", i); //// break $source:$line +} + +void set_short(void) +{ + short i = 33; + printf("before (short) i = %i\n", i); + printf("after (short) i = %i\n", i); //// break $source:$line +} + +void set_ushort(void) +{ + unsigned short i = 33; + printf("before (unsigned short) i = %i\n", i); + printf("after (unsigned short) i = %i\n", i); // Set break point #2. //// break $source:$line +} + +void set_int(void) +{ + int i = 33; + printf("before (int) i = %i\n", i); + printf("after (int) i = %i\n", i); //// break $source:$line +} + +void set_uint(void) +{ + unsigned int i = 33; + printf("before (unsigned int) i = %u\n", i); + printf("after (unsigned int) i = %u\n", i); //// break $source:$line +} + +void set_long(void) +{ + long i = 33; + printf("before (long) i = %li\n", i); + printf("after (long) i = %li\n", i); // Set break point #3. //// break $source:$line +} + +void set_ulong(void) +{ + unsigned long i = 33; + printf("before (unsigned long) i = %lu\n", i); + printf("after (unsigned long) i = %lu\n", i); //// break $source:$line +} + +void set_float(void) +{ + float i = 2.25; + printf("before (float) i = %g\n", i); + printf("after (float) i = %g\n", i); //// break $source:$line +} + +void set_double(void) +{ + double i = 2.25; + printf("before (double) i = %g\n", i); + printf("after (double) i = %g\n", i); // Set break point #4. //// break $source:$line +} + +void set_long_double(void) +{ + long double i = 2.25; + printf("before (long double) i = %Lg\n", i); + printf("after (long double) i = %Lg\n", i); // Set break point #5. //// break $source:$line +} + +void set_point (void) +{ + struct point_tag { + int x; + int y; + }; + struct point_tag points_2[2] = { + {1,2}, + {3,4} + }; +} + +int main (int argc, char const *argv[]) +{ + // Continue to the breakpoint in set_char() + set_char(); //// continue; var i; val -set 99 1 + set_uchar(); //// continue; var i; val -set 99 2 + set_short(); //// continue; var i; val -set -42 3 + set_ushort(); //// continue; var i; val -set 42 4 + set_int(); //// continue; var i; val -set -42 5 + set_uint(); //// continue; var i; val -set 42 6 + set_long(); //// continue; var i; val -set -42 7 + set_ulong(); //// continue; var i; val -set 42 8 + set_float(); //// continue; var i; val -set 123.456 9 + set_double(); //// continue; var i; val -set 123.456 10 + set_long_double(); //// continue; var i; val -set 123.456 11 + set_point (); //// continue + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/Makefile new file mode 100644 index 00000000000..5e26f2748c0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/Makefile @@ -0,0 +1,5 @@ +DYLIB_NAME := foo +DYLIB_C_SOURCES := foo.c +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py new file mode 100644 index 00000000000..789939b29e7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py @@ -0,0 +1,101 @@ +"""Test that types defined in shared libraries work correctly.""" + + + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class SharedLibTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def common_test_expr(self, preload_symbols): + if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion(): + self.skipTest( + "llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef") + + self.build() + self.common_setup(preload_symbols) + + # This should display correctly. + self.expect( + "expression --show-types -- *my_foo_ptr", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "(foo)", + "(sub_foo)", + "other_element = 3"]) + + self.expect( + "expression GetMeASubFoo(my_foo_ptr)", + startstr="(sub_foo *) $") + + @expectedFailureNetBSD + def test_expr(self): + """Test that types work when defined in a shared library and forward-declared in the main executable""" + self.common_test_expr(True) + + @expectedFailureNetBSD + def test_expr_no_preload(self): + """Test that types work when defined in a shared library and forward-declared in the main executable, but with preloading disabled""" + self.common_test_expr(False) + + @unittest2.expectedFailure("llvm.org/PR36712") + def test_frame_variable(self): + """Test that types work when defined in a shared library and forward-declared in the main executable""" + self.build() + self.common_setup() + + # This should display correctly. + self.expect( + "frame variable --show-types -- *my_foo_ptr", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "(foo)", + "(sub_foo)", + "other_element = 3"]) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.c' + self.line = line_number(self.source, '// Set breakpoint 0 here.') + self.shlib_names = ["foo"] + + def common_setup(self, preload_symbols = True): + # Run in synchronous mode + self.dbg.SetAsync(False) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + self.runCmd("settings set target.preload-symbols " + str(preload_symbols).lower()) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line( + self, self.source, self.line, num_expected_locations=1, loc_exact=True) + + # Register our shared libraries for remote targets so they get + # automatically uploaded + environment = self.registerSharedLibrariesWithTarget( + target, self.shlib_names) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.c new file mode 100644 index 00000000000..6431bc496c3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.c @@ -0,0 +1,22 @@ +#include "foo.h" +#include <stdlib.h> + +struct foo +{ + struct sub_foo sub_element; + int other_element; +}; + +struct foo * +GetMeAFoo() +{ + struct foo *ret_val = (struct foo *) malloc (sizeof (struct foo)); + ret_val->other_element = 3; + return ret_val; +} + +struct sub_foo * +GetMeASubFoo (struct foo *in_foo) +{ + return &(in_foo->sub_element); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.h new file mode 100644 index 00000000000..78b9e3f9c0d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/foo.h @@ -0,0 +1,10 @@ +struct foo; + +struct sub_foo +{ + int sub_1; + char *sub_2; +}; + +LLDB_TEST_API struct foo *GetMeAFoo(); +LLDB_TEST_API struct sub_foo *GetMeASubFoo(struct foo *in_foo); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/main.c new file mode 100644 index 00000000000..b4377de18c1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib/main.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include "foo.h" + +int +main () +{ + struct foo *my_foo_ptr; + my_foo_ptr = GetMeAFoo(); + + printf ("My sub foo has: %d.\n", GetMeASubFoo(my_foo_ptr)->sub_1); // Set breakpoint 0 here. + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/Makefile new file mode 100644 index 00000000000..f3285de39e0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/Makefile @@ -0,0 +1,7 @@ +DYLIB_NAME := foo +DYLIB_C_SOURCES := foo.c +C_SOURCES := main.c + +SPLIT_DEBUG_SYMBOLS = YES + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py new file mode 100644 index 00000000000..8858f67cd18 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py @@ -0,0 +1,88 @@ +"""Test that types defined in shared libraries with stripped symbols work correctly.""" + + + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class SharedLibStrippedTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(oslist=["windows"]) + def test_expr(self): + """Test that types work when defined in a shared library and forwa/d-declared in the main executable""" + if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion(): + self.skipTest( + "llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef") + + self.build() + self.common_setup() + + # This should display correctly. + self.expect( + "expression --show-types -- *my_foo_ptr", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "(foo)", + "(sub_foo)", + "other_element = 3"]) + + @expectedFailureAll(oslist=["windows"]) + @unittest2.expectedFailure("llvm.org/PR36712") + def test_frame_variable(self): + """Test that types work when defined in a shared library and forward-declared in the main executable""" + self.build() + self.common_setup() + + # This should display correctly. + self.expect( + "frame variable --show-types -- *my_foo_ptr", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "(foo)", + "(sub_foo)", + "other_element = 3"]) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.c' + self.line = line_number(self.source, '// Set breakpoint 0 here.') + self.shlib_names = ["foo"] + + def common_setup(self): + # Run in synchronous mode + self.dbg.SetAsync(False) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line( + self, self.source, self.line, num_expected_locations=1, loc_exact=True) + + # Register our shared libraries for remote targets so they get + # automatically uploaded + environment = self.registerSharedLibrariesWithTarget( + target, self.shlib_names) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.c new file mode 100644 index 00000000000..6431bc496c3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.c @@ -0,0 +1,22 @@ +#include "foo.h" +#include <stdlib.h> + +struct foo +{ + struct sub_foo sub_element; + int other_element; +}; + +struct foo * +GetMeAFoo() +{ + struct foo *ret_val = (struct foo *) malloc (sizeof (struct foo)); + ret_val->other_element = 3; + return ret_val; +} + +struct sub_foo * +GetMeASubFoo (struct foo *in_foo) +{ + return &(in_foo->sub_element); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.h new file mode 100644 index 00000000000..78b3c124538 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/foo.h @@ -0,0 +1,12 @@ +struct foo; + +struct sub_foo +{ + int sub_1; + char *sub_2; +}; + +struct foo *GetMeAFoo(); +struct sub_foo *GetMeASubFoo (struct foo *in_foo); + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/main.c new file mode 100644 index 00000000000..b4377de18c1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/shared_lib_stripped_symbols/main.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include "foo.h" + +int +main () +{ + struct foo *my_foo_ptr; + my_foo_ptr = GetMeAFoo(); + + printf ("My sub foo has: %d.\n", GetMeASubFoo(my_foo_ptr)->sub_1); // Set breakpoint 0 here. + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/.categories new file mode 100644 index 00000000000..c00c25822e4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/.categories @@ -0,0 +1 @@ +basic_process diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py new file mode 100644 index 00000000000..7665b2f73b6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/TestStepTarget.py @@ -0,0 +1,122 @@ +"""Test the 'step target' feature.""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestStepTarget(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "main.c" + self.end_line = line_number(self.main_source, "All done") + + @add_test_categories(['pyapi']) + def get_to_start(self): + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + self.main_source_spec = lldb.SBFileSpec(self.main_source) + + break_in_main = target.BreakpointCreateBySourceRegex( + 'Break here to try targetted stepping', self.main_source_spec) + self.assertTrue(break_in_main, VALID_BREAKPOINT) + self.assertGreater(break_in_main.GetNumLocations(), 0, "Has locations.") + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, break_in_main) + + if len(threads) != 1: + self.fail("Failed to stop at first breakpoint in main.") + + thread = threads[0] + return thread + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr32343") + def test_with_end_line(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + error = lldb.SBError() + thread.StepInto("lotsOfArgs", self.end_line, error) + frame = thread.frames[0] + + self.assertEqual(frame.name, "lotsOfArgs", "Stepped to lotsOfArgs.") + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr32343") + def test_with_end_line_bad_name(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + error = lldb.SBError() + thread.StepInto("lotsOfArgssss", self.end_line, error) + frame = thread.frames[0] + self.assertEqual(frame.line_entry.line, self.end_line, + "Stepped to the block end.") + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr32343") + def test_with_end_line_deeper(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + error = lldb.SBError() + thread.StepInto("modifyInt", self.end_line, error) + frame = thread.frames[0] + self.assertEqual(frame.name, "modifyInt", "Stepped to modifyInt.") + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr32343") + def test_with_command_and_block(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + result = lldb.SBCommandReturnObject() + self.dbg.GetCommandInterpreter().HandleCommand( + 'thread step-in -t "lotsOfArgs" -e block', result) + self.assertTrue( + result.Succeeded(), + "thread step-in command succeeded.") + + frame = thread.frames[0] + self.assertEqual(frame.name, "lotsOfArgs", "Stepped to lotsOfArgs.") + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr32343") + def test_with_command_and_block_and_bad_name(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + thread = self.get_to_start() + + result = lldb.SBCommandReturnObject() + self.dbg.GetCommandInterpreter().HandleCommand( + 'thread step-in -t "lotsOfArgsssss" -e block', result) + self.assertTrue( + result.Succeeded(), + "thread step-in command succeeded.") + + frame = thread.frames[0] + + self.assertEqual(frame.name, "main", "Stepped back out to main.") + # end_line is set to the line after the containing block. Check that + # we got there: + self.assertEqual(frame.line_entry.line, self.end_line, + "Got out of the block") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/main.c new file mode 100644 index 00000000000..86a26c4d47a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step-target/main.c @@ -0,0 +1,40 @@ +#include <stdio.h> + +void +lotsOfArgs +( + int firstArg, + int secondArg, + int thirdArg, + int fourthArg +) +{ + printf ("First: %d Second: %d Third: %d Fourth: %d.\n", + firstArg, + secondArg, + thirdArg, + fourthArg); +} + +int +modifyInt(int incoming) +{ + return incoming % 2; +} + +int +main (int argc, char **argv) +{ + if (argc > 0) + { + int var_makes_block = argc + 1; + printf ("Break here to try targetted stepping.\n"); + lotsOfArgs(var_makes_block, + modifyInt(20), + 30, + modifyInt(40)); + printf ("Done calling lotsOfArgs."); + } + printf ("All done.\n"); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step_over_no_deadlock/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step_over_no_deadlock/Makefile new file mode 100644 index 00000000000..4b3467bc4e8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step_over_no_deadlock/Makefile @@ -0,0 +1,5 @@ +CXX_SOURCES := locking.cpp +CXXFLAGS_EXTRAS := -std=c++11 +ENABLE_THREADS := YES + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step_over_no_deadlock/TestStepOverDoesntBlock.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step_over_no_deadlock/TestStepOverDoesntBlock.py new file mode 100644 index 00000000000..988d90a7bb3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step_over_no_deadlock/TestStepOverDoesntBlock.py @@ -0,0 +1,30 @@ +""" +Test that step over will let other threads run when necessary +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class StepOverDoesntDeadlockTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_step_over(self): + """Test that when step over steps over a function it lets other threads run.""" + self.build() + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "without running the first thread at least somewhat", + lldb.SBFileSpec("locking.cpp")) + # This is just testing that the step over actually completes. + # If the test fails this step never return, so failure is really + # signaled by the test timing out. + + thread.StepOver() + state = process.GetState() + self.assertEqual(state, lldb.eStateStopped) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step_over_no_deadlock/locking.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step_over_no_deadlock/locking.cpp new file mode 100644 index 00000000000..8288a668fe8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/step_over_no_deadlock/locking.cpp @@ -0,0 +1,78 @@ +#include <stdio.h> +#include <thread> +#include <mutex> +#include <condition_variable> + +std::mutex contended_mutex; + +std::mutex control_mutex; +std::condition_variable control_condition; + +std::mutex thread_started_mutex; +std::condition_variable thread_started_condition; + +// This function runs in a thread. The locking dance is to make sure that +// by the time the main thread reaches the pthread_join below, this thread +// has for sure acquired the contended_mutex. So then the call_me_to_get_lock +// function will block trying to get the mutex, and only succeed once it +// signals this thread, then lets it run to wake up from the cond_wait and +// release the mutex. + +void +lock_acquirer_1 (void) +{ + std::unique_lock<std::mutex> contended_lock(contended_mutex); + + // Grab this mutex, that will ensure that the main thread + // is in its cond_wait for it (since that's when it drops the mutex. + + thread_started_mutex.lock(); + thread_started_mutex.unlock(); + + // Now signal the main thread that it can continue, we have the contended lock + // so the call to call_me_to_get_lock won't make any progress till this + // thread gets a chance to run. + + std::unique_lock<std::mutex> control_lock(control_mutex); + + thread_started_condition.notify_all(); + + control_condition.wait(control_lock); + +} + +int +call_me_to_get_lock (int ret_val) +{ + control_condition.notify_all(); + contended_mutex.lock(); + return ret_val; +} + +int +get_int() { + return 567; +} + +int main () +{ + std::unique_lock<std::mutex> thread_started_lock(thread_started_mutex); + + std::thread thread_1(lock_acquirer_1); + + thread_started_condition.wait(thread_started_lock); + + control_mutex.lock(); + control_mutex.unlock(); + + // Break here. At this point the other thread will have the contended_mutex, + // and be sitting in its cond_wait for the control condition. So there is + // no way that our by-hand calling of call_me_to_get_lock will proceed + // without running the first thread at least somewhat. + + int result = call_me_to_get_lock(get_int()); + thread_1.join(); + + return 0; + +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py new file mode 100644 index 00000000000..c20e443b683 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py @@ -0,0 +1,296 @@ +"""Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCStepping(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "main.c" + + @add_test_categories(['pyapi', 'basic_process']) + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr17932') + @expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr14437") + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24777") + @expectedFailureNetBSD + def test_and_python_api(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + self.main_source_spec = lldb.SBFileSpec(self.main_source) + + breakpoints_to_disable = [] + + break_1_in_main = target.BreakpointCreateBySourceRegex( + '// frame select 2, thread step-out while stopped at .c.1..', + self.main_source_spec) + self.assertTrue(break_1_in_main, VALID_BREAKPOINT) + breakpoints_to_disable.append(break_1_in_main) + + break_in_a = target.BreakpointCreateBySourceRegex( + '// break here to stop in a before calling b', self.main_source_spec) + self.assertTrue(break_in_a, VALID_BREAKPOINT) + breakpoints_to_disable.append(break_in_a) + + break_in_b = target.BreakpointCreateBySourceRegex( + '// thread step-out while stopped at .c.2..', self.main_source_spec) + self.assertTrue(break_in_b, VALID_BREAKPOINT) + breakpoints_to_disable.append(break_in_b) + + break_in_c = target.BreakpointCreateBySourceRegex( + '// Find the line number of function .c. here.', self.main_source_spec) + self.assertTrue(break_in_c, VALID_BREAKPOINT) + breakpoints_to_disable.append(break_in_c) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, break_1_in_main) + + if len(threads) != 1: + self.fail("Failed to stop at first breakpoint in main.") + + thread = threads[0] + + # Get the stop id and for fun make sure it increases: + old_stop_id = process.GetStopID() + + # Now step over, which should cause us to hit the breakpoint in "a" + thread.StepOver() + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, break_in_a) + if len(threads) != 1: + self.fail("Failed to stop at breakpoint in a.") + + # Check that the stop ID increases: + new_stop_id = process.GetStopID() + self.assertTrue( + new_stop_id > old_stop_id, + "Stop ID increases monotonically.") + + thread = threads[0] + + # Step over, and we should hit the breakpoint in b: + thread.StepOver() + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, break_in_b) + if len(threads) != 1: + self.fail("Failed to stop at breakpoint in b.") + thread = threads[0] + + # Now try running some function, and make sure that we still end up in the same place + # and with the same stop reason. + frame = thread.GetFrameAtIndex(0) + current_line = frame.GetLineEntry().GetLine() + current_file = frame.GetLineEntry().GetFileSpec() + current_bp = [] + current_bp.append(thread.GetStopReasonDataAtIndex(0)) + current_bp.append(thread.GetStopReasonDataAtIndex(1)) + + stop_id_before_expression = process.GetStopID() + stop_id_before_including_expressions = process.GetStopID(True) + + frame.EvaluateExpression("(int) printf (print_string)") + + frame = thread.GetFrameAtIndex(0) + self.assertTrue( + current_line == frame.GetLineEntry().GetLine(), + "The line stayed the same after expression.") + self.assertTrue( + current_file == frame.GetLineEntry().GetFileSpec(), + "The file stayed the same after expression.") + self.assertTrue( + thread.GetStopReason() == lldb.eStopReasonBreakpoint, + "We still say we stopped for a breakpoint.") + self.assertTrue(thread.GetStopReasonDataAtIndex(0) == current_bp[ + 0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") + + # Also make sure running the expression didn't change the public stop id + # but did change if we are asking for expression stops as well. + stop_id_after_expression = process.GetStopID() + stop_id_after_including_expressions = process.GetStopID(True) + + self.assertTrue( + stop_id_before_expression == stop_id_after_expression, + "Expression calling doesn't change stop ID") + + self.assertTrue( + stop_id_after_including_expressions > stop_id_before_including_expressions, + "Stop ID including expressions increments over expression call.") + + # Do the same thing with an expression that's going to crash, and make + # sure we are still unchanged. + + frame.EvaluateExpression("((char *) 0)[0] = 'a'") + + frame = thread.GetFrameAtIndex(0) + self.assertTrue( + current_line == frame.GetLineEntry().GetLine(), + "The line stayed the same after expression.") + self.assertTrue( + current_file == frame.GetLineEntry().GetFileSpec(), + "The file stayed the same after expression.") + self.assertTrue( + thread.GetStopReason() == lldb.eStopReasonBreakpoint, + "We still say we stopped for a breakpoint.") + self.assertTrue(thread.GetStopReasonDataAtIndex(0) == current_bp[ + 0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") + + # Now continue and make sure we just complete the step: + # Disable all our breakpoints first - sometimes the compiler puts two line table entries in for the + # breakpoint a "b" and we don't want to hit that. + for bkpt in breakpoints_to_disable: + bkpt.SetEnabled(False) + + process.Continue() + + self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "a") + self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) + + # And one more time should get us back to main: + process.Continue() + + self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main") + self.assertTrue(thread.GetStopReason() == lldb.eStopReasonPlanComplete) + + # Now make sure we can call a function, break in the called function, + # then have "continue" get us back out again: + frame = thread.GetFrameAtIndex(0) + frame = thread.GetFrameAtIndex(0) + current_line = frame.GetLineEntry().GetLine() + current_file = frame.GetLineEntry().GetFileSpec() + + break_in_b.SetEnabled(True) + options = lldb.SBExpressionOptions() + options.SetIgnoreBreakpoints(False) + options.SetFetchDynamicValue(False) + options.SetUnwindOnError(False) + frame.EvaluateExpression("b (4)", options) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, break_in_b) + + if len(threads) != 1: + self.fail("Failed to stop at breakpoint in b when calling b.") + thread = threads[0] + + # So do a step over here to make sure we can still do that: + + thread.StepOver() + + # See that we are still in b: + func_name = thread.GetFrameAtIndex(0).GetFunctionName() + self.assertTrue( + func_name == "b", + "Should be in 'b', were in %s" % + (func_name)) + + # Okay, now if we continue, we will finish off our function call and we + # should end up back in "a" as if nothing had happened: + process.Continue() + + self.assertTrue(thread.GetFrameAtIndex( + 0).GetLineEntry().GetLine() == current_line) + self.assertTrue(thread.GetFrameAtIndex( + 0).GetLineEntry().GetFileSpec() == current_file) + + # Now we are going to test step in targeting a function: + + break_in_b.SetEnabled(False) + + break_before_complex_1 = target.BreakpointCreateBySourceRegex( + '// Stop here to try step in targeting b.', self.main_source_spec) + self.assertTrue(break_before_complex_1, VALID_BREAKPOINT) + + break_before_complex_2 = target.BreakpointCreateBySourceRegex( + '// Stop here to try step in targeting complex.', self.main_source_spec) + self.assertTrue(break_before_complex_2, VALID_BREAKPOINT) + + break_before_complex_3 = target.BreakpointCreateBySourceRegex( + '// Stop here to step targeting b and hitting breakpoint.', self.main_source_spec) + self.assertTrue(break_before_complex_3, VALID_BREAKPOINT) + + break_before_complex_4 = target.BreakpointCreateBySourceRegex( + '// Stop here to make sure bogus target steps over.', self.main_source_spec) + self.assertTrue(break_before_complex_4, VALID_BREAKPOINT) + + threads = lldbutil.continue_to_breakpoint( + process, break_before_complex_1) + self.assertTrue(len(threads) == 1) + thread = threads[0] + break_before_complex_1.SetEnabled(False) + + thread.StepInto("b") + self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "b") + + # Now continue out and stop at the next call to complex. This time + # step all the way into complex: + threads = lldbutil.continue_to_breakpoint( + process, break_before_complex_2) + self.assertTrue(len(threads) == 1) + thread = threads[0] + break_before_complex_2.SetEnabled(False) + + thread.StepInto("complex") + self.assertTrue(thread.GetFrameAtIndex( + 0).GetFunctionName() == "complex") + + # Now continue out and stop at the next call to complex. This time + # enable breakpoints in a and c and then step targeting b: + threads = lldbutil.continue_to_breakpoint( + process, break_before_complex_3) + self.assertTrue(len(threads) == 1) + thread = threads[0] + break_before_complex_3.SetEnabled(False) + + break_at_start_of_a = target.BreakpointCreateByName('a') + break_at_start_of_c = target.BreakpointCreateByName('c') + + thread.StepInto("b") + threads = lldbutil.get_stopped_threads( + process, lldb.eStopReasonBreakpoint) + + self.assertTrue(len(threads) == 1) + thread = threads[0] + stop_break_id = thread.GetStopReasonDataAtIndex(0) + self.assertTrue(stop_break_id == break_at_start_of_a.GetID() + or stop_break_id == break_at_start_of_c.GetID()) + + break_at_start_of_a.SetEnabled(False) + break_at_start_of_c.SetEnabled(False) + + process.Continue() + self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "b") + + # Now continue out and stop at the next call to complex. This time + # enable breakpoints in a and c and then step targeting b: + threads = lldbutil.continue_to_breakpoint( + process, break_before_complex_4) + self.assertTrue(len(threads) == 1) + thread = threads[0] + break_before_complex_4.SetEnabled(False) + + thread.StepInto("NoSuchFunction") + self.assertTrue(thread.GetFrameAtIndex(0).GetFunctionName() == "main") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/TestThreadStepping.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/TestThreadStepping.py new file mode 100644 index 00000000000..43ed10d8b1a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/TestThreadStepping.py @@ -0,0 +1,83 @@ +""" +Test thread stepping features in combination with frame select. +""" + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class ThreadSteppingTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to of function 'c'. + self.line1 = line_number( + 'main.c', '// Find the line number of function "c" here.') + self.line2 = line_number( + 'main.c', '// frame select 2, thread step-out while stopped at "c(1)"') + self.line3 = line_number( + 'main.c', '// thread step-out while stopped at "c(2)"') + self.line4 = line_number( + 'main.c', '// frame select 1, thread step-out while stopped at "c(3)"') + + def test_step_out_with_run_command(self): + """Exercise thread step-out and frame select followed by thread step-out.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Create a breakpoint inside function 'c'. + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line1, num_expected_locations=1, loc_exact=True) + + # Now run the program. + self.runCmd("run", RUN_SUCCEEDED) + + # The process should be stopped at this point. + self.expect("process status", PROCESS_STOPPED, + patterns=['Process .* stopped']) + + # The frame #0 should correspond to main.c:32, the executable statement + # in function name 'c'. And frame #3 should point to main.c:37. + self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT, + substrs=["stop reason = breakpoint"], + patterns=["frame #0.*main.c:%d" % self.line1, + "frame #3.*main.c:%d" % self.line2]) + + # We want to move the pc to frame #3. This can be accomplished by + # 'frame select 2', followed by 'thread step-out'. + self.runCmd("frame select 2") + self.runCmd("thread step-out") + self.expect("thread backtrace", STEP_OUT_SUCCEEDED, + substrs=["stop reason = step out"], + patterns=["frame #0.*main.c:%d" % self.line2]) + + # Let's move on to a single step-out case. + self.runCmd("process continue") + + # The process should be stopped at this point. + self.expect("process status", PROCESS_STOPPED, + patterns=['Process .* stopped']) + self.runCmd("thread step-out") + self.expect("thread backtrace", STEP_OUT_SUCCEEDED, + substrs=["stop reason = step out"], + patterns=["frame #0.*main.c:%d" % self.line3]) + + # Do another frame selct, followed by thread step-out. + self.runCmd("process continue") + + # The process should be stopped at this point. + self.expect("process status", PROCESS_STOPPED, + patterns=['Process .* stopped']) + self.runCmd("frame select 1") + self.runCmd("thread step-out") + self.expect("thread backtrace", STEP_OUT_SUCCEEDED, + substrs=["stop reason = step out"], + patterns=["frame #0.*main.c:%d" % self.line4]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/main.c new file mode 100644 index 00000000000..fce61bfd93e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/stepping/main.c @@ -0,0 +1,68 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +int a(int); +int b(int); +int c(int); +const char *print_string = "aaaaaaaaaa\n"; + +int a(int val) +{ + int return_value = val; // basic break at the start of b + + if (val <= 1) + { + return_value = b(val); // break here to stop in a before calling b + } + else if (val >= 3) + { + return_value = c(val); + } + + return return_value; +} + +int b(int val) +{ + int rc = c(val); // thread step-out while stopped at "c(2)" + return rc; +} + +int c(int val) +{ + return val + 3; // Find the line number of function "c" here. +} + +int complex (int first, int second, int third) +{ + return first + second + third; // Step in targeting complex should stop here +} + +int main (int argc, char const *argv[]) +{ + int A1 = a(1); // frame select 2, thread step-out while stopped at "c(1)" + printf("a(1) returns %d\n", A1); + + int B2 = b(2); + printf("b(2) returns %d\n", B2); + + int A3 = a(3); // frame select 1, thread step-out while stopped at "c(3)" + printf("a(3) returns %d\n", A3); + + int A4 = complex (a(1), b(2), c(3)); // Stop here to try step in targeting b. + + int A5 = complex (a(2), b(3), c(4)); // Stop here to try step in targeting complex. + + int A6 = complex (a(4), b(5), c(6)); // Stop here to step targeting b and hitting breakpoint. + + int A7 = complex (a(5), b(6), c(7)); // Stop here to make sure bogus target steps over. + + printf ("I am using print_string: %s.\n", print_string); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/strings/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/strings/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/strings/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py new file mode 100644 index 00000000000..597a247178e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/strings/TestCStrings.py @@ -0,0 +1,56 @@ +""" +Tests that C strings work as expected in expressions +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CStringsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_with_run_command(self): + """Tests that C strings work as expected in expressions""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + line = line_number('main.c', '// breakpoint 1') + lldbutil.run_break_set_by_file_and_line( + self, "main.c", line, num_expected_locations=1, loc_exact=True) + + self.runCmd("process launch", RUN_SUCCEEDED) + + self.expect("expression -- a[2]", + patterns=["\((const )?char\) \$0 = 'c'"]) + + self.expect("expression -- z[2]", + startstr="(const char) $1 = 'x'") + + # On Linux, the expression below will test GNU indirect function calls. + self.expect("expression -- (int)strlen(\"hello\")", + startstr="(int) $2 = 5") + + self.expect("expression -- \"world\"[2]", + startstr="(const char) $3 = 'r'") + + self.expect("expression -- \"\"[0]", + startstr="(const char) $4 = '\\0'") + + self.expect("expr --raw -- \"hello\"", + substrs=['[0] = \'h\'', + '[5] = \'\\0\'']) + + self.expect("p \"hello\"", + substrs=['[6]) $', 'hello']) + + self.expect("p (char*)\"hello\"", + substrs=['(char *) $', ' = 0x', + 'hello']) + + self.expect("p (int)strlen(\"\")", + substrs=['(int) $', ' = 0']) + + self.expect("expression !z", + substrs=['false']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/strings/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/strings/main.c new file mode 100644 index 00000000000..3e7ead08478 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/strings/main.c @@ -0,0 +1,17 @@ +//===-- main.c ----------------------------------------------------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +int main() +{ + const char a[] = "abcde"; + const char *z = "vwxyz"; + + printf("%s %s", a, z); // breakpoint 1 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py new file mode 100644 index 00000000000..c8308c16011 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/struct_types/TestStructTypes.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/struct_types/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/struct_types/main.c new file mode 100644 index 00000000000..356f139c0b2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/struct_types/main.c @@ -0,0 +1,46 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +struct things_to_sum { + int a; + int b; + int c; +}; + +int sum_things(struct things_to_sum tts) +{ + return tts.a + tts.b + tts.c; +} + +int main (int argc, char const *argv[]) +{ + struct point_tag { + int x; + int y; + char padding[0]; + }; //% 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[]']) + + struct {} empty; + //% self.expect("frame variable empty", substrs = ["empty = {}"]) + //% self.expect("expression -- sizeof(empty)", substrs = ["= 0"]) + + struct rect_tag { + struct point_tag bottom_left; + struct point_tag top_right; + }; + struct point_tag pt = { 2, 3, {} }; + struct rect_tag rect = {{1, 2, {}}, {3, 4, {}}}; + struct things_to_sum tts = { 2, 3, 4 }; + + int sum = sum_things(tts); //% self.expect("expression -- &pt == (struct point_tag*)0", substrs = ['false']) + //% self.expect("expression -- sum_things(tts)", substrs = ['9']) + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/Makefile new file mode 100644 index 00000000000..b26ce5c8b14 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/Makefile @@ -0,0 +1,8 @@ +C_SOURCES := main.c + +DYLIB_NAME := a +DYLIB_C_SOURCES := a.c + +ENABLE_THREADS := YES + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py new file mode 100644 index 00000000000..b1fd2b8d031 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/TestTlsGlobals.py @@ -0,0 +1,95 @@ +"""Test that thread-local storage can be read correctly.""" + + + +import unittest2 +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TlsGlobalTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + + if self.getPlatform() == "freebsd" or self.getPlatform() == "linux": + # LD_LIBRARY_PATH must be set so the shared libraries are found on + # startup + if "LD_LIBRARY_PATH" in os.environ: + self.runCmd( + "settings set target.env-vars " + + self.dylibPath + + "=" + + os.environ["LD_LIBRARY_PATH"] + + ":" + + self.getBuildDir()) + else: + self.runCmd("settings set target.env-vars " + + self.dylibPath + "=" + self.getBuildDir()) + self.addTearDownHook( + lambda: self.runCmd( + "settings remove target.env-vars " + + self.dylibPath)) + + # TLS works differently on Windows, this would need to be implemented + # separately. + @skipIfWindows + @expectedFailureAll( + bugnumber="llvm.org/pr28392", + oslist=no_match( + lldbplatformutil.getDarwinOSTriples())) + def test(self): + """Test thread-local storage.""" + self.build() + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + if self.platformIsDarwin(): + self.registerSharedLibrariesWithTarget(target, ['liba.dylib']) + + line1 = line_number('main.c', '// thread breakpoint') + lldbutil.run_break_set_by_file_and_line( + self, "main.c", line1, num_expected_locations=1, loc_exact=True) + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.runCmd("process status", "Get process status") + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # BUG: sometimes lldb doesn't change threads to the stopped thread. + # (unrelated to this test). + self.runCmd("thread select 2", "Change thread") + + # Check that TLS evaluates correctly within the thread. + self.expect("expr var_static", VARIABLES_DISPLAYED_CORRECTLY, + patterns=["\(int\) \$.* = 88"]) + self.expect("expr var_shared", VARIABLES_DISPLAYED_CORRECTLY, + patterns=["\(int\) \$.* = 66"]) + + # Continue on the main thread + line2 = line_number('main.c', '// main breakpoint') + lldbutil.run_break_set_by_file_and_line( + self, "main.c", line2, num_expected_locations=1, loc_exact=True) + self.runCmd("continue", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.runCmd("process status", "Get process status") + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # BUG: sometimes lldb doesn't change threads to the stopped thread. + # (unrelated to this test). + self.runCmd("thread select 1", "Change thread") + + # Check that TLS evaluates correctly within the main thread. + self.expect("expr var_static", VARIABLES_DISPLAYED_CORRECTLY, + patterns=["\(int\) \$.* = 44"]) + self.expect("expr var_shared", VARIABLES_DISPLAYED_CORRECTLY, + patterns=["\(int\) \$.* = 33"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c new file mode 100644 index 00000000000..00803964e61 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/a.c @@ -0,0 +1,23 @@ +//===-- a.c -----------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <unistd.h> + +__thread int var_shared = 33; + +int +touch_shared() +{ + return var_shared; +} + +void shared_check() +{ + var_shared *= 2; + usleep(1); // shared thread breakpoint +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c new file mode 100644 index 00000000000..c9c1e681dc0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/tls_globals/main.c @@ -0,0 +1,41 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <pthread.h> +#include <unistd.h> + +void shared_check(); +// On some OS's (darwin) you must actually access a thread local variable +// before you can read it +int +touch_shared(); + +// Create some TLS storage within the static executable. +__thread int var_static = 44; + +void *fn_static(void *param) +{ + var_static *= 2; + shared_check(); + usleep(1); // thread breakpoint + for(;;) + usleep(1); +} + +int main (int argc, char const *argv[]) +{ + pthread_t handle; + pthread_create(&handle, NULL, &fn_static, NULL); + touch_shared(); + for (; var_static;) + { + usleep(1); // main breakpoint + } + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py new file mode 100644 index 00000000000..cbbb6362381 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/typedef/Testtypedef.py @@ -0,0 +1,52 @@ +"""Look up type information for typedefs of same name at different lexical scope and check for correct display.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TypedefTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(compiler="clang", bugnumber="llvm.org/pr19238") + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr25626 expectedFailureClang fails on FreeBSD") + def test_typedef(self): + """Test 'image lookup -t a' and check for correct display at different scopes.""" + self.build() + self.image_lookup_for_multiple_typedefs() + + def image_lookup_for_multiple_typedefs(self): + """Test 'image lookup -t a' at different scopes and check for correct display.""" + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + typearray = ( + "float", + "float", + "char", + "double *", + "float", + "int", + "double", + "float", + "float") + arraylen = len(typearray) + 1 + for i in range(1, arraylen): + loc_line = line_number( + 'main.c', '// Set break point ' + str(i) + '.') + lldbutil.run_break_set_by_file_and_line( + self, "main.c", loc_line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + for t in typearray: + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', 'stop reason = breakpoint']) + self.expect("image lookup -t a", DATA_TYPES_DISPLAYED_CORRECTLY, + substrs=['name = "' + t + '"']) + self.runCmd("continue") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/typedef/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/typedef/main.c new file mode 100644 index 00000000000..467612e9b37 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/typedef/main.c @@ -0,0 +1,45 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +void test() +{ + typedef double * a; + a b = 0; // Set break point 4. +} +int main (int argc, char const *argv[]) +{ + typedef float a; + int i = 0; // Set break point 1. + i++; + a floatvariable = 2.7; // Set break point 2. + { + typedef char a; + i++; + a charvariable = 'a'; // Set break point 3. + test(); + } + { + int c = 0; + c++; // Set break point 5. + for(i = 0 ; i < 1 ; i++) + { + typedef int a; + a b; + b = 7; // Set break point 6. + } + for(i = 0 ; i < 1 ; i++) + { + typedef double a; + a b; + b = 3.14; // Set break point 7. + } + c = 1; // Set break point 8. + } + floatvariable = 2.5; + floatvariable = 2.8; // Set break point 9. + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unicode/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unicode/Makefile new file mode 100644 index 00000000000..a40a666476c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unicode/Makefile @@ -0,0 +1,4 @@ +C_SOURCES := main.c +CFLAGS_EXTRAS := -finput-charset=UTF-8 -fextended-identifiers -std=c99 + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unicode/TestUnicodeSymbols.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unicode/TestUnicodeSymbols.py new file mode 100644 index 00000000000..9eb25e4d105 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unicode/TestUnicodeSymbols.py @@ -0,0 +1,21 @@ +# coding=utf8 +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * + + +class TestUnicodeSymbols(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(compiler="clang", compiler_version=['<', '7.0']) + def test_union_members(self): + self.build() + spec = lldb.SBModuleSpec() + spec.SetFileSpec(lldb.SBFileSpec(self.getBuildArtifact("a.out"))) + module = lldb.SBModule(spec) + self.assertTrue(module.IsValid()) + mytype = module.FindFirstType("foobár") + self.assertTrue(mytype.IsValid()) + self.assertTrue(mytype.IsPointerType()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unicode/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unicode/main.c new file mode 100644 index 00000000000..ae44dd0edfa --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unicode/main.c @@ -0,0 +1,5 @@ +typedef void *foob\u00E1r; +foob\u00E1r X = 0; +int main() { + return (long)X; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unions/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unions/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unions/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unions/TestUnionMembers.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unions/TestUnionMembers.py new file mode 100644 index 00000000000..4965df2d809 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unions/TestUnionMembers.py @@ -0,0 +1,52 @@ +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class TestUnionMembers(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_union_members(self): + self._load_exe() + + # Set breakpoints + bp = self.target.BreakpointCreateBySourceRegex( + "Break here", self.src_file_spec) + self.assertTrue( + bp.IsValid() and bp.GetNumLocations() >= 1, + VALID_BREAKPOINT) + + # Launch the process + self.process = self.target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) + self.assertTrue( + self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + thread = lldbutil.get_stopped_thread( + self.process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread.IsValid()) + frame = thread.GetSelectedFrame() + self.assertTrue(frame.IsValid()) + + val = frame.EvaluateExpression("u") + self.assertTrue(val.IsValid()) + val = frame.EvaluateExpression("u.s") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetNumChildren(), 2) + + def _load_exe(self): + self.build() + + src_file = os.path.join(self.getSourceDir(), "main.c") + self.src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(self.src_file_spec.IsValid(), "breakpoint file") + + # Get the path of the executable + exe_path = self.getBuildArtifact("a.out") + + # Load the executable + self.target = self.dbg.CreateTarget(exe_path) + self.assertTrue(self.target.IsValid(), VALID_TARGET) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unions/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unions/main.c new file mode 100644 index 00000000000..2c6a7d1e782 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/unions/main.c @@ -0,0 +1,18 @@ +#include <stdint.h> + +union S +{ + int32_t n; // occupies 4 bytes + uint16_t s[2]; // occupies 4 bytes + uint8_t c; // occupies 1 byte +}; // the whole union occupies 4 bytes + +int main() +{ + union S u; + + u.s[0] = 1234; + u.s[1] = 4321; + + return 0; // Break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/vla/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/vla/Makefile new file mode 100644 index 00000000000..10495940055 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/vla/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py new file mode 100644 index 00000000000..09439e2bc4b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py @@ -0,0 +1,45 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + + +class TestVLA(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(compiler="clang", compiler_version=['<', '8.0']) + def test_variable_list(self): + self.build() + _, process, _, _ = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec('main.c')) + + # Make sure no helper expressions show up in frame variable. + var_opts = lldb.SBVariablesOptions() + var_opts.SetIncludeArguments(False) + var_opts.SetIncludeLocals(True) + var_opts.SetInScopeOnly(True) + var_opts.SetIncludeStatics(False) + var_opts.SetIncludeRuntimeSupportValues(False) + var_opts.SetUseDynamic(lldb.eDynamicCanRunTarget) + all_locals = self.frame().GetVariables(var_opts) + for value in all_locals: + self.assertFalse("vla_expr" in value.name) + + @decorators.skipIf(compiler="clang", compiler_version=['<', '8.0']) + def test_vla(self): + self.build() + _, process, _, _ = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec('main.c')) + + def test(a, array): + for i in range(a): + self.expect("fr v vla[%d]"%i, substrs=["int", "%d"%(a-i)]) + self.expect("expr vla[%d]"%i, substrs=["int", "%d"%(a-i)]) + self.expect("fr v vla", substrs=array) + self.expect("expr vla", error=True, substrs=["incomplete"]) + + test(2, ["int []", "[0] = 2, [1] = 1"]) + process.Continue() + test(4, ["int []", "[0] = 4, [1] = 3, [2] = 2, [3] = 1"]) + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/vla/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/vla/main.c new file mode 100644 index 00000000000..ba9cc185560 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/c/vla/main.c @@ -0,0 +1,15 @@ +void pause() {} + +int foo(int a) { + int vla[a]; + + for (int i = 0; i < a; ++i) + vla[i] = a-i; + + pause(); // break here + return vla[a-1]; +} + +int main (void) { + return foo(2) + foo(4); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/Makefile new file mode 100644 index 00000000000..4c053a09c75 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/Makefile @@ -0,0 +1,7 @@ +# There is no guaranteed order in which the linker will order these +# files, so we just have a lot of them to make it unlikely that we hit +# the right one first by pure luck. + +CXX_SOURCES := main.cpp a.cpp b.cpp c.cpp d.cpp e.cpp f.cpp g.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/TestCPPAccelerator.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/TestCPPAccelerator.py new file mode 100644 index 00000000000..3705e95c600 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/TestCPPAccelerator.py @@ -0,0 +1,31 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CPPAcceleratorTableTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @skipIf(debug_info=no_match(["dwarf"])) + def test(self): + """Test that type lookups fail early (performance)""" + self.build() + logfile = self.getBuildArtifact('dwarf.log') + self.expect('log enable dwarf lookups -f' + logfile) + target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, 'break here', lldb.SBFileSpec('main.cpp')) + # Pick one from the middle of the list to have a high chance + # of it not being in the first file looked at. + self.expect('frame variable inner_d') + + log = open(logfile, 'r') + n = 0 + for line in log: + if re.findall(r'[abcdefg]\.o: FindByNameAndTag\(\)', line): + self.assertTrue("d.o" in line) + n += 1 + + self.assertEqual(n, 1, log) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/a.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/a.cpp new file mode 100644 index 00000000000..d9f758e1991 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/a.cpp @@ -0,0 +1,2 @@ +#include "source.h" +CLASS(A) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/b.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/b.cpp new file mode 100644 index 00000000000..a0cdffa14f1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/b.cpp @@ -0,0 +1,2 @@ +#include "source.h" +CLASS(B) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/c.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/c.cpp new file mode 100644 index 00000000000..1bd7172b771 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/c.cpp @@ -0,0 +1,2 @@ +#include "source.h" +CLASS(C) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/d.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/d.cpp new file mode 100644 index 00000000000..e43c2ad05aa --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/d.cpp @@ -0,0 +1,2 @@ +#include "source.h" +CLASS(D) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/e.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/e.cpp new file mode 100644 index 00000000000..a3008f71f65 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/e.cpp @@ -0,0 +1,2 @@ +#include "source.h" +CLASS(E) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/f.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/f.cpp new file mode 100644 index 00000000000..77df296183e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/f.cpp @@ -0,0 +1,2 @@ +#include "source.h" +CLASS(F) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/g.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/g.cpp new file mode 100644 index 00000000000..e1446918891 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/g.cpp @@ -0,0 +1,2 @@ +#include "source.h" +CLASS(G) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/main.cpp new file mode 100644 index 00000000000..b7eb252bad8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/main.cpp @@ -0,0 +1,28 @@ +#define CLASS(NAME) \ + class NAME { \ + public: \ + struct Inner; \ + Inner *i = nullptr; \ + }; \ +NAME::Inner &getInner##NAME(); + +CLASS(A) +CLASS(B) +CLASS(C) +CLASS(D) +CLASS(E) +CLASS(F) +CLASS(G) + +int main() +{ + A::Inner &inner_a = getInnerA(); + B::Inner &inner_b = getInnerB(); + C::Inner &inner_c = getInnerC(); + D::Inner &inner_d = getInnerD(); + E::Inner &inner_e = getInnerE(); + F::Inner &inner_f = getInnerF(); + G::Inner &inner_g = getInnerG(); + + return 0; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/source.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/source.h new file mode 100644 index 00000000000..214e7dada2e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/accelerator-table/source.h @@ -0,0 +1,12 @@ +#define CLASS(NAME) \ + class NAME { \ + public: \ + class Inner { \ + int j = #NAME[0]; \ + }; \ + Inner *i = nullptr; \ + }; \ + \ + static NAME::Inner inner; \ + static NAME obj; \ + NAME::Inner &getInner##NAME() { return inner; } diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/auto/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/auto/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/auto/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/auto/TestCPPAuto.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/auto/TestCPPAuto.py new file mode 100644 index 00000000000..fe3a8324348 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/auto/TestCPPAuto.py @@ -0,0 +1,41 @@ +""" +Tests that auto types work +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CPPAutoTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll( + compiler="gcc", + bugnumber="GCC generates incomplete debug info") + @expectedFailureAll(oslist=['windows'], bugnumber="llvm.org/pr26339") + @expectedFailureNetBSD + def test_with_run_command(self): + """Test that auto types work in the expression parser""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + line = line_number('main.cpp', '// break here') + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", line, num_expected_locations=-1, loc_exact=False) + + self.runCmd("process launch", RUN_SUCCEEDED) + + self.expect('expr auto f = 123456; f', substrs=['int', '123456']) + self.expect( + 'expr struct Test { int x; int y; Test() : x(123), y(456) {} }; auto t = Test(); t', + substrs=[ + 'Test', + '123', + '456']) + self.expect( + 'expr auto s = helloworld; s', + substrs=[ + 'string', + 'hello world']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/auto/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/auto/main.cpp new file mode 100644 index 00000000000..d411af67911 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/auto/main.cpp @@ -0,0 +1,20 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <string> + +int main() +{ + std::string helloworld("hello world"); + + // Ensure std::string copy constructor is present in the binary, as we will + // use it in an expression. + std::string other = helloworld; + + return 0; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bitfields/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bitfields/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bitfields/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bitfields/TestCppBitfields.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bitfields/TestCppBitfields.py new file mode 100644 index 00000000000..1b362e6b04f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bitfields/TestCppBitfields.py @@ -0,0 +1,105 @@ +"""Show bitfields and check that they display correctly.""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CppBitfieldsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.cpp', '// Set break point at this line.') + + # BitFields exhibit crashes in record layout on Windows + # (http://llvm.org/pr21800) + @skipIfWindows + def test_and_run_command(self): + """Test 'frame variable ...' on a variable with bitfields.""" + self.build() + + lldbutil.run_to_source_breakpoint(self, '// Set break point at this line.', + lldb.SBFileSpec("main.cpp", False)) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + self.expect("expr (lba.a)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['unsigned int', '2']) + self.expect("expr (lbb.b)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['unsigned int', '3']) + self.expect("expr (lbc.c)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['unsigned int', '4']) + self.expect("expr (lbd.a)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['unsigned int', '5']) + self.expect("expr (clang_example.f.a)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['uint64_t', '1']) + + self.expect( + "frame variable --show-types lba", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(int:32) = ', + '(unsigned int:20) a = 2', + ]) + + self.expect( + "frame variable --show-types lbb", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(unsigned int:1) a = 1', + '(int:31) =', + '(unsigned int:20) b = 3', + ]) + + self.expect( + "frame variable --show-types lbc", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(int:22) =', + '(unsigned int:1) a = 1', + '(unsigned int:1) b = 0', + '(unsigned int:5) c = 4', + '(unsigned int:1) d = 1', + '(int:2) =', + '(unsigned int:20) e = 20', + ]) + + self.expect( + "frame variable --show-types lbd", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(char [3]) arr = "ab"', + '(int:32) =', + '(unsigned int:20) a = 5', + ]) + + self.expect( + "frame variable --show-types clang_example", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(int:22) =', + '(uint64_t:1) a = 1', + '(uint64_t:1) b = 0', + '(uint64_t:1) c = 1', + '(uint64_t:1) d = 0', + '(uint64_t:1) e = 1', + '(uint64_t:1) f = 0', + '(uint64_t:1) g = 1', + '(uint64_t:1) h = 0', + '(uint64_t:1) i = 1', + '(uint64_t:1) j = 0', + '(uint64_t:1) k = 1', + ]) + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bitfields/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bitfields/main.cpp new file mode 100644 index 00000000000..e43bf8c138e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bitfields/main.cpp @@ -0,0 +1,81 @@ +#include <stdint.h> + +int main(int argc, char const *argv[]) { + struct LargeBitsA { + unsigned int : 30, a : 20; + } lba; + + struct LargeBitsB { + unsigned int a : 1, : 11, : 12, b : 20; + } lbb; + + struct LargeBitsC { + unsigned int : 13, : 9, a : 1, b : 1, c : 5, d : 1, e : 20; + } lbc; + + struct LargeBitsD { + char arr[3]; + unsigned int : 30, a : 20; + } lbd; + + // This case came up when debugging clang and models RecordDeclBits + struct BitExampleFromClangDeclContext { + class fields { + uint64_t : 13; + uint64_t : 9; + + uint64_t a: 1; + uint64_t b: 1; + uint64_t c: 1; + uint64_t d: 1; + uint64_t e: 1; + uint64_t f: 1; + uint64_t g: 1; + uint64_t h: 1; + uint64_t i: 1; + uint64_t j: 1; + uint64_t k: 1; + + // In order to reproduce the crash for this case we need the + // members of fields to stay private :-( + friend struct BitExampleFromClangDeclContext; + }; + + union { + struct fields f; + }; + + BitExampleFromClangDeclContext() { + f.a = 1; + f.b = 0; + f.c = 1; + f.d = 0; + f.e = 1; + f.f = 0; + f.g = 1; + f.h = 0; + f.i = 1; + f.j = 0; + f.k = 1; + } + } clang_example; + + lba.a = 2; + + lbb.a = 1; + lbb.b = 3; + + lbc.a = 1; + lbc.b = 0; + lbc.c = 4; + lbc.d = 1; + lbc.e = 20; + + lbd.arr[0] = 'a'; + lbd.arr[1] = 'b'; + lbd.arr[2] = '\0'; + lbd.a = 5; + + + return 0; // Set break point at this line. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bool/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bool/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bool/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bool/TestCPPBool.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bool/TestCPPBool.py new file mode 100644 index 00000000000..27ea773c5db --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bool/TestCPPBool.py @@ -0,0 +1,28 @@ +""" +Tests that bool types work +""" +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class CPPBoolTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_with_run_command(self): + """Test that bool types work in the expression parser""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + line = line_number('main.cpp', '// breakpoint 1') + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", line, num_expected_locations=-1, loc_exact=False) + + self.runCmd("process launch", RUN_SUCCEEDED) + + self.expect("expression -- bool second_bool = my_bool; second_bool", + startstr="(bool) $0 = false") + + self.expect("expression -- my_bool = true", + startstr="(bool) $1 = true") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bool/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bool/main.cpp new file mode 100644 index 00000000000..a14cc690da7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/bool/main.cpp @@ -0,0 +1,16 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +int main() +{ + bool my_bool = false; + + printf("%s\n", my_bool ? "true" : "false"); // breakpoint 1 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/Makefile new file mode 100644 index 00000000000..6afea39f81c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := nested.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py new file mode 100644 index 00000000000..32c974810f7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/TestCPPBreakpointCommands.py @@ -0,0 +1,83 @@ +""" +Test lldb breakpoint command for CPP methods & functions in a namespace. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CPPBreakpointCommandsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def make_breakpoint(self, name, type, expected_num_locations): + bkpt = self.target.BreakpointCreateByName(name, + type, + self.a_out_module, + self.nested_comp_unit) + num_locations = bkpt.GetNumLocations() + self.assertTrue( + num_locations == expected_num_locations, + "Wrong number of locations for '%s', expected: %d got: %d" % + (name, + expected_num_locations, + num_locations)) + return bkpt + + def test_cpp_breakpoint_cmds(self): + """Test a sequence of breakpoint command add, list, and delete.""" + self.build() + + exe = self.getBuildArtifact("a.out") + + # Create a target from the debugger. + + self.target = self.dbg.CreateTarget(exe) + self.assertTrue(self.target, VALID_TARGET) + + self.a_out_module = lldb.SBFileSpecList() + self.a_out_module.Append(lldb.SBFileSpec(exe)) + + self.nested_comp_unit = lldb.SBFileSpecList() + self.nested_comp_unit.Append(lldb.SBFileSpec("nested.cpp")) + + # First provide ONLY the method name. This should get everybody... + self.make_breakpoint("Function", + lldb.eFunctionNameTypeAuto, + 5) + + # Now add the Baz class specifier. This should get the version contained in Bar, + # AND the one contained in :: + self.make_breakpoint("Baz::Function", + lldb.eFunctionNameTypeAuto, + 2) + + # Then add the Bar::Baz specifier. This should get the version + # contained in Bar only + self.make_breakpoint("Bar::Baz::Function", + lldb.eFunctionNameTypeAuto, + 1) + + self.make_breakpoint("Function", + lldb.eFunctionNameTypeMethod, + 3) + + self.make_breakpoint("Baz::Function", + lldb.eFunctionNameTypeMethod, + 2) + + self.make_breakpoint("Bar::Baz::Function", + lldb.eFunctionNameTypeMethod, + 1) + + self.make_breakpoint("Function", + lldb.eFunctionNameTypeBase, + 2) + + self.make_breakpoint("Bar::Function", + lldb.eFunctionNameTypeBase, + 1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/nested.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/nested.cpp new file mode 100644 index 00000000000..740649622ca --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint-commands/nested.cpp @@ -0,0 +1,76 @@ +#include <stdio.h> + +namespace Foo +{ + namespace Bar + { + class Baz + { + public: + Baz (int value):m_value(value) {} + int Function () + { + printf ("%s returning: %d.\n", __FUNCTION__, m_value); + return m_value + 1; + } + private: + int m_value; + }; + + class Baz2 + { + public: + Baz2 (int value):m_value(value) {} + int Function () + { + printf ("%s returning: %d.\n", __FUNCTION__, m_value); + return m_value + 2; + } + private: + int m_value; + }; + + static int bar_value = 20; + int Function () + { + printf ("%s returning: %d.\n", __FUNCTION__, bar_value); + return bar_value + 3; + } + } +} + +class Baz +{ +public: + Baz (int value):m_value(value) {} + int Function () + { + printf ("%s returning: %d.\n", __FUNCTION__, m_value); + return m_value + 4; + } +private: + int m_value; +}; + +int +Function () +{ + printf ("I am a global function, I return 333.\n"); + return 333; +} + +int main () +{ + Foo::Bar::Baz mine(200); + Foo::Bar::Baz2 mine2(300); + ::Baz bare_baz (500); + + printf ("Yup, got %d from Baz.\n", mine.Function()); + printf ("Yup, got %d from Baz.\n", mine2.Function()); + printf ("Yup, got %d from Baz.\n", bare_baz.Function()); + printf ("And got %d from Bar.\n", Foo::Bar::Function()); + printf ("And got %d from ::.\n", ::Function()); + + return 0; + +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/Makefile new file mode 100644 index 00000000000..dc53622129f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES = main.cpp a.cpp +CFLAGS_EXTRAS = $(MANDATORY_CXXMODULE_BUILD_CFLAGS) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/TestBreakpointInMemberFuncWNonPrimitiveParams.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/TestBreakpointInMemberFuncWNonPrimitiveParams.py new file mode 100644 index 00000000000..1e46f73cb29 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/TestBreakpointInMemberFuncWNonPrimitiveParams.py @@ -0,0 +1,26 @@ +""" +This is a regression test for an assert that happens while setting a breakpoint. +The root cause of the assert was attempting to add a ParmVarDecl to a CXXRecordDecl +when it should have been added to a CXXMethodDecl. + +We can reproduce with a module build and setting a breakpoint in a member function +of a class with a non-primitive type as a parameter. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestBreakpointInMemberFuncWNonPrimitiveParams(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @add_test_categories(["gmodules"]) + def test_breakpint_in_member_func_w_non_primitie_params(self): + self.build() + + (self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here', + lldb.SBFileSpec("main.cpp", False)) + + self.runCmd("b a.cpp:11"); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/a.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/a.cpp new file mode 100644 index 00000000000..64e142c5379 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/a.cpp @@ -0,0 +1,14 @@ +#include "a.h" + +bool A::b(int x) { + if (x) + return true; + + return false; +} + +bool B::member_func_a(A a) { + return a.b(10); // We will try and add a breakpoint here which + // trigger an assert since we will attempt to + // to add ParamVarDecl a to CXXRecordDecl A +}; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/a.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/a.h new file mode 100644 index 00000000000..cb31d3efe8f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/a.h @@ -0,0 +1,7 @@ +struct A { + bool b(int x); +}; + +struct B { + bool member_func_a(A a); +}; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/main.cpp new file mode 100644 index 00000000000..779ef04072b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/main.cpp @@ -0,0 +1,15 @@ +#include "a.h" +#include <cstdio> + +bool foo() { + A a1; + B b1; + + return b1.member_func_a(a1); // break here +} + +int main() { + int x = 0; + + return foo(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/module.modulemap b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/module.modulemap new file mode 100644 index 00000000000..bbd9d674c94 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/breakpoint_in_member_func_w_non_primitive_params/module.modulemap @@ -0,0 +1,3 @@ +module A { + header "a.h" +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/call-function/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/call-function/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/call-function/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/call-function/TestCallCPPFunction.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/call-function/TestCallCPPFunction.py new file mode 100644 index 00000000000..b6274b3d266 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/call-function/TestCallCPPFunction.py @@ -0,0 +1,35 @@ +""" +Tests calling a function by basename +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CallCPPFunctionTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + self.line = line_number('main.cpp', '// breakpoint') + + def test_with_run_command(self): + """Test calling a function by basename""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("process launch", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", + STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', 'stop reason = breakpoint']) + + self.expect("expression -- a_function_to_call()", + startstr="(int) $0 = 0") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/call-function/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/call-function/main.cpp new file mode 100644 index 00000000000..61a5e9d21ab --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/call-function/main.cpp @@ -0,0 +1,11 @@ +#include <stdio.h> + +int a_function_to_call() +{ + return 0; +} + +int main() +{ + printf("%d\n", a_function_to_call()); // breakpoint +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/chained-calls/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/chained-calls/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/chained-calls/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/chained-calls/TestCppChainedCalls.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/chained-calls/TestCppChainedCalls.py new file mode 100644 index 00000000000..080c051de98 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/chained-calls/TestCppChainedCalls.py @@ -0,0 +1,99 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCppChainedCalls(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_with_run_command(self): + self.build() + + # Get main source file + src_file = "main.cpp" + src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(src_file_spec.IsValid(), "Main source file") + + # Get the path of the executable + exe_path = self.getBuildArtifact("a.out") + + # Load the executable + target = self.dbg.CreateTarget(exe_path) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Break on main function + main_breakpoint = target.BreakpointCreateBySourceRegex( + "break here", src_file_spec) + self.assertTrue( + main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, + VALID_BREAKPOINT) + + # Launch the process + args = None + env = None + process = target.LaunchSimple( + args, env, self.get_process_working_directory()) + self.assertTrue(process.IsValid(), PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue( + process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + + # Get frame for current thread + frame = thread.GetSelectedFrame() + + # Test chained calls + test_result = frame.EvaluateExpression("get(set(true))") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "true", + "get(set(true)) = true") + + test_result = frame.EvaluateExpression("get(set(false))") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "false", + "get(set(false)) = false") + + test_result = frame.EvaluateExpression("get(t & f)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "false", + "get(t & f) = false") + + test_result = frame.EvaluateExpression("get(f & t)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "false", + "get(f & t) = false") + + test_result = frame.EvaluateExpression("get(t & t)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "true", + "get(t & t) = true") + + test_result = frame.EvaluateExpression("get(f & f)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "false", + "get(f & f) = false") + + test_result = frame.EvaluateExpression("get(t & f)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "false", + "get(t & f) = false") + + test_result = frame.EvaluateExpression("get(f) && get(t)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "false", + "get(f) && get(t) = false") + + test_result = frame.EvaluateExpression("get(f) && get(f)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "false", + "get(f) && get(t) = false") + + test_result = frame.EvaluateExpression("get(t) && get(t)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "true", + "get(t) && get(t) = true") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/chained-calls/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/chained-calls/main.cpp new file mode 100644 index 00000000000..a888c3f6c55 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/chained-calls/main.cpp @@ -0,0 +1,33 @@ +class Bool { +public: + Bool operator&(const Bool other) + { + Bool result; + result.value = value && other.value; + return result; + } + + bool value; +}; + +bool get(Bool object) +{ + return object.value; +} + +Bool set(bool value) +{ + Bool result; + result.value = value; + return result; +} + +int main() +{ + Bool t = set(true); + Bool f = set(false); + get(t); + get(f); + get(t & f); + return 0; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/.categories new file mode 100644 index 00000000000..fe1da0247c6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/.categories @@ -0,0 +1 @@ +dataformatters diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/Makefile new file mode 100644 index 00000000000..64fd6effcee --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/Makefile @@ -0,0 +1,6 @@ +CXX_SOURCES := main.cpp +CFLAGS :=-g -O0 -std=c++11 + +clean: OBJECTS+=$(wildcard main.d.*) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/TestChar1632T.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/TestChar1632T.py new file mode 100644 index 00000000000..986d9e59cdf --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/TestChar1632T.py @@ -0,0 +1,119 @@ +# coding=utf8 +""" +Test that the C++11 support for char16_t and char32_t works correctly. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class Char1632TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.source = 'main.cpp' + self.lines = [line_number(self.source, '// breakpoint1'), + line_number(self.source, '// breakpoint2')] + + @expectedFailureAll( + compiler="icc", + bugnumber="ICC (13.1) does not emit the DW_TAG_base_type for char16_t and char32_t.") + def test(self): + """Test that the C++11 support for char16_t and char32_t works correctly.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set breakpoints + for line in self.lines: + lldbutil.run_break_set_by_file_and_line(self, "main.cpp", line) + + # Now launch the process, and do not stop at entry point and stop at + # breakpoint1 + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + if not process: + self.fail("SBTarget.Launch() failed") + + if self.TraceOn(): + self.runCmd("frame variable") + + # Check that we correctly report the const types + self.expect( + "frame variable cs16 cs32", + substrs=[ + '(const char16_t *) cs16 = ', + '(const char32_t *) cs32 = ', + 'u"hello world ྒྙྐ"', + 'U"hello world ྒྙྐ"']) + + # Check that we correctly report the non-const types + self.expect( + "frame variable s16 s32", + substrs=[ + '(char16_t *) s16 = ', + '(char32_t *) s32 = ', + 'u"ﺸﺵۻ"', + 'U"ЕЙРГЖО"']) + + # Check that we correctly report the array types + self.expect( + "frame variable as16 as32", + patterns=[ + '\(char16_t \[[0-9]+\]\) as16 = ', + '\(char32_t \[[0-9]+\]\) as32 = '], + substrs=[ + 'u"ﺸﺵۻ"', + 'U"ЕЙРГЖО"']) + + self.runCmd("next") # step to after the string is nullified + + # check that we don't crash on NULL + self.expect("frame variable s32", + substrs=['(char32_t *) s32 = 0x00000000']) + + # continue and hit breakpoint2 + self.runCmd("continue") + + # check that the new strings show + self.expect( + "frame variable s16 s32", + substrs=[ + '(char16_t *) s16 = 0x', + '(char32_t *) s32 = ', + '"色ハ匂ヘト散リヌルヲ"', + '"෴"']) + + # check the same as above for arrays + self.expect( + "frame variable as16 as32", + patterns=[ + '\(char16_t \[[0-9]+\]\) as16 = ', + '\(char32_t \[[0-9]+\]\) as32 = '], + substrs=[ + '"色ハ匂ヘト散リヌルヲ"', + '"෴"']) + + # check that zero values are properly handles + self.expect('frame variable cs16_zero', substrs=["U+0000 u'\\0'"]) + self.expect( + 'frame variable cs32_zero', + substrs=["U+0x00000000 U'\\0'"]) + self.expect('expression cs16_zero', substrs=["U+0000 u'\\0'"]) + self.expect('expression cs32_zero', substrs=["U+0x00000000 U'\\0'"]) + + # Check that we can run expressions that return charN_t + self.expect("expression u'a'", substrs=['(char16_t) $', "61 u'a'"]) + self.expect("expression U'a'", substrs=['(char32_t) $', "61 U'a'"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/main.cpp new file mode 100644 index 00000000000..8cd0cfc77c5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char1632_t/main.cpp @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <assert.h> +#include <string> + +#define UASZ 64 + +template<class T, int N> +void copy_char_seq (T (&arr)[N], const T* src) +{ + size_t src_len = std::char_traits<T>::length(src); + assert(src_len < N); + + std::char_traits<T>::copy(arr, src, src_len); + arr[src_len] = 0; +} + +int main (int argc, char const *argv[]) +{ + char16_t as16[UASZ]; + char32_t as32[UASZ]; + auto cs16_zero = (char16_t)0; + auto cs32_zero = (char32_t)0; + auto cs16 = u"hello world ྒྙྐ"; + auto cs32 = U"hello world ྒྙྐ"; + char16_t *s16 = (char16_t *)u"ﺸﺵۻ"; + char32_t *s32 = (char32_t *)U"ЕЙРГЖО"; + copy_char_seq(as16, s16); + copy_char_seq(as32, s32); + s32 = nullptr; // breakpoint1 + s32 = (char32_t *)U"෴"; + s16 = (char16_t *)u"色ハ匂ヘト散リヌルヲ"; + copy_char_seq(as16, s16); + copy_char_seq(as32, s32); + s32 = nullptr; // breakpoint2 + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char8_t/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char8_t/Makefile new file mode 100644 index 00000000000..e7c9938b5a8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char8_t/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp +CXXFLAGS_EXTRAS := -std=c++2a -fchar8_t + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char8_t/TestCxxChar8_t.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char8_t/TestCxxChar8_t.py new file mode 100644 index 00000000000..e7f2c1afbdd --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char8_t/TestCxxChar8_t.py @@ -0,0 +1,39 @@ +# coding=utf8 +""" +Test that C++ supports char8_t correctly. +""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class CxxChar8_tTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(compiler="clang", compiler_version=['<', '7.0']) + def test(self): + """Test that C++ supports char8_t correctly.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # FIXME: We should be able to test this with target variable, but the + # data formatter output is broken. + lldbutil.run_break_set_by_symbol(self, 'main') + self.runCmd("run", RUN_SUCCEEDED) + + self.expect( + "frame variable a", substrs=["(char8_t)", "0x61 u8'a'"]) + + self.expect( + "frame variable ab", substrs=['(const char8_t *)' , 'u8"你好"']) + + self.expect( + "frame variable abc", substrs=['(char8_t [9])', 'u8"你好"']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char8_t/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char8_t/main.cpp new file mode 100644 index 00000000000..b73ba0c4e61 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/char8_t/main.cpp @@ -0,0 +1,5 @@ +char8_t a = u8'a'; +const char8_t* ab = u8"你好"; +char8_t abc[9] = u8"你好"; + +int main (int argc, char const *argv[]) { return 0; } diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py new file mode 100644 index 00000000000..7e67f73b709 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/TestClassTemplateParameterPack.py @@ -0,0 +1,7 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.expectedFailureAll( + compiler="gcc")]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp new file mode 100644 index 00000000000..9278d01f8c5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class-template-parameter-pack/main.cpp @@ -0,0 +1,64 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +template <class T, int... Args> struct C { + T member; + bool isSixteenThirtyTwo() { return false; } +}; + +template <> struct C<int, 16> { + int member; + bool isSixteenThirtyTwo() { return false; } +}; + +template <> struct C<int, 16, 32> : C<int, 16> { + bool isSixteenThirtyTwo() { return true; } +}; + +template <class T, typename... Args> struct D { + T member; + bool isIntBool() { return false; } +}; + +template <> struct D<int, int> { + int member; + bool isIntBool() { return false; } +}; + +template <> struct D<int, int, bool> : D<int, int> { + bool isIntBool() { return true; } +}; + +int main (int argc, char const *argv[]) +{ + C<int,16,32> myC; + C<int,16> myLesserC; + myC.member = 64; + (void)C<int,16,32>().isSixteenThirtyTwo(); + (void)C<int,16>().isSixteenThirtyTwo(); + (void)(myC.member != 64); //% self.expect("expression -- myC", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["64"]) + //% self.expect("expression -- myLesserC.isSixteenThirtyTwo()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["false"]) + //% self.expect("expression -- myC.isSixteenThirtyTwo()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["true"]) + + // Disabling until we do template lookup correctly: http://lists.llvm.org/pipermail/lldb-commits/Week-of-Mon-20180507/040689.html + //#% self.expect("expression -- C<int, 16>().isSixteenThirtyTwo()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["false"]) + //#% self.expect("expression -- C<int, 16, 32>().isSixteenThirtyTwo()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["true"]) + + D<int,int,bool> myD; + D<int,int> myLesserD; + myD.member = 64; + (void)D<int,int,bool>().isIntBool(); + (void)D<int,int>().isIntBool(); + return myD.member != 64; //% self.expect("expression -- myD", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["64"]) + //% self.expect("expression -- myLesserD.isIntBool()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["false"]) + //% self.expect("expression -- myD.isIntBool()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["true"]) + + // See comment above. + //#% self.expect("expression -- D<int, int>().isIntBool()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["false"]) + //#% self.expect("expression -- D<int, int, bool>().isIntBool()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["true"]) +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_static/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_static/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_static/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py new file mode 100644 index 00000000000..7c019e0e7cf --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py @@ -0,0 +1,173 @@ +""" +Test display and Python APIs on file and class static variables. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class StaticVariableTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break at. + self.line = line_number('main.cpp', '// Set break point at this line.') + + def test_with_run_command(self): + """Test that file and class static variables display correctly.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Global variables are no longer displayed with the "frame variable" + # command. + self.expect( + 'target variable A::g_points', + VARIABLES_DISPLAYED_CORRECTLY, + patterns=['\(PointType \[[1-9]*\]\) A::g_points = {']) + self.expect('target variable g_points', VARIABLES_DISPLAYED_CORRECTLY, + substrs=['(PointType [2]) g_points']) + + # On Mac OS X, gcc 4.2 emits the wrong debug info for A::g_points. + # A::g_points is an array of two elements. + if self.platformIsDarwin() or self.getPlatform() == "linux": + self.expect( + "target variable A::g_points[1].x", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(int) A::g_points[1].x = 11") + + @expectedFailureAll( + compiler=["gcc"], + bugnumber="Compiler emits incomplete debug info") + @expectedFailureAll( + compiler=["clang"], + compiler_version=["<", "3.9"], + bugnumber='llvm.org/pr20550') + def test_with_run_command_complete(self): + """ + Test that file and class static variables display correctly with + complete debug information. + """ + self.build() + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Global variables are no longer displayed with the "frame variable" + # command. + self.expect( + 'target variable A::g_points', + VARIABLES_DISPLAYED_CORRECTLY, + patterns=[ + '\(PointType \[[1-9]*\]\) A::g_points = {', '(x = 1, y = 2)', + '(x = 11, y = 22)' + ]) + + # Ensure that we take the context into account and only print + # A::g_points. + self.expect( + 'target variable A::g_points', + VARIABLES_DISPLAYED_CORRECTLY, + matching=False, + patterns=['(x = 3, y = 4)', '(x = 33, y = 44)']) + + # Finally, ensure that we print both points when not specifying a + # context. + self.expect( + 'target variable g_points', + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + '(PointType [2]) g_points', '(x = 1, y = 2)', + '(x = 11, y = 22)', '(x = 3, y = 4)', '(x = 33, y = 44)' + ]) + + @expectedFailureAll( + compiler=["gcc"], + bugnumber="Compiler emits incomplete debug info") + @expectedFailureAll( + compiler=["clang"], + compiler_version=["<", "3.9"], + bugnumber='llvm.org/pr20550') + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test Python APIs on file and class static variables.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation("main.cpp", self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # Get the SBValue of 'A::g_points' and 'g_points'. + frame = thread.GetFrameAtIndex(0) + + # arguments => False + # locals => False + # statics => True + # in_scope_only => False + valList = frame.GetVariables(False, False, True, False) + + for val in valList: + self.DebugSBValue(val) + name = val.GetName() + self.assertTrue(name in ['g_points', 'A::g_points']) + if name == 'g_points': + self.assertTrue( + val.GetValueType() == lldb.eValueTypeVariableStatic) + self.assertEqual(val.GetNumChildren(), 2) + elif name == 'A::g_points': + self.assertTrue( + val.GetValueType() == lldb.eValueTypeVariableGlobal) + self.assertEqual(val.GetNumChildren(), 2) + child1 = val.GetChildAtIndex(1) + self.DebugSBValue(child1) + child1_x = child1.GetChildAtIndex(0) + self.DebugSBValue(child1_x) + self.assertTrue(child1_x.GetTypeName() == 'int' and + child1_x.GetValue() == '11') + + # SBFrame.FindValue() should also work. + val = frame.FindValue("A::g_points", lldb.eValueTypeVariableGlobal) + self.DebugSBValue(val) + self.assertTrue(val.GetName() == 'A::g_points') + + # Also exercise the "parameter" and "local" scopes while we are at it. + val = frame.FindValue("argc", lldb.eValueTypeVariableArgument) + self.DebugSBValue(val) + self.assertTrue(val.GetName() == 'argc') + + val = frame.FindValue("argv", lldb.eValueTypeVariableArgument) + self.DebugSBValue(val) + self.assertTrue(val.GetName() == 'argv') + + val = frame.FindValue("hello_world", lldb.eValueTypeVariableLocal) + self.DebugSBValue(val) + self.assertTrue(val.GetName() == 'hello_world') diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_static/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_static/main.cpp new file mode 100644 index 00000000000..319a05a7bee --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_static/main.cpp @@ -0,0 +1,52 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// I made this example after noting that I was unable to display an unsized +// static class array. It turns out that gcc 4.2 will emit DWARF that correctly +// describes the PointType, but it will incorrectly emit debug info for the +// "g_points" array where the following things are wrong: +// - the DW_TAG_array_type won't have a subrange info +// - the DW_TAG_variable for "g_points" won't have a valid byte size, so even +// though we know the size of PointType, we can't infer the actual size +// of the array by dividing the size of the variable by the number of +// elements. + +#include <stdio.h> + +typedef struct PointType +{ + int x, y; +} PointType; + +class A +{ +public: + static PointType g_points[]; +}; + +PointType A::g_points[] = +{ + { 1, 2 }, + { 11, 22 } +}; + +static PointType g_points[] = +{ + { 3, 4 }, + { 33, 44 } +}; + +int +main (int argc, char const *argv[]) +{ + const char *hello_world = "Hello, world!"; + printf ("A::g_points[1].x = %i\n", A::g_points[1].x); // Set break point at this line. + printf ("::g_points[1].x = %i\n", g_points[1].x); + printf ("%s\n", hello_world); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypes.py new file mode 100644 index 00000000000..45d64431ab3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypes.py @@ -0,0 +1,224 @@ +"""Test breakpoint on a class constructor; and variable list the this object.""" + + + +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ClassTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + 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 break point at this line.') + + def test_with_run_command(self): + """Test 'frame variable this' when stopped on a class constructor.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break on the ctor function of class C. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=-1) + + self.runCmd("run", RUN_SUCCEEDED) + + # The test suite sometimes shows that the process has exited without stopping. + # + # CC=clang ./dotest.py -v -t class_types + # ... + # Process 76604 exited with status = 0 (0x00000000) + self.runCmd("process status") + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # We should be stopped on the ctor function of class C. + self.expect( + "frame variable --show-types this", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + 'C *', + ' this = ']) + + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Use Python APIs to create a breakpoint by (filespec, line).""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + filespec = target.GetExecutable() + self.assertTrue(filespec, VALID_FILESPEC) + + fsDir = os.path.normpath(filespec.GetDirectory()) + fsFile = filespec.GetFilename() + + self.assertTrue(fsDir == os.path.dirname(self.getBuildArtifact()) + and fsFile == "a.out", + "FileSpec matches the executable") + + bpfilespec = lldb.SBFileSpec("main.cpp", False) + + breakpoint = target.BreakpointCreateByLocation(bpfilespec, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Verify the breakpoint just created. + self.expect(str(breakpoint), BREAKPOINT_CREATED, exe=False, + substrs=['main.cpp', + str(self.line)]) + + # 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") + + if process.GetState() != lldb.eStateStopped: + self.fail("Process should be in the 'stopped' state, " + "instead the actual state is: '%s'" % + lldbutil.state_type_to_str(process.GetState())) + + # The stop reason of the thread should be breakpoint. + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + # The filename of frame #0 should be 'main.cpp' and the line number + # should be 93. + self.expect("%s:%d" % (lldbutil.get_filenames(thread)[0], + lldbutil.get_line_numbers(thread)[0]), + "Break correctly at main.cpp:%d" % self.line, exe=False, + startstr="main.cpp:") + # clang compiled code reported main.cpp:94? + # startstr = "main.cpp:93") + + # We should be stopped on the breakpoint with a hit count of 1. + self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE) + + process.Continue() + + def test_with_expr_parser(self): + """Test 'frame variable this' and 'expr this' when stopped inside a constructor.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # rdar://problem/8516141 + # Is this a case of clang (116.1) generating bad debug info? + # + # Break on the ctor function of class C. + # self.expect("breakpoint set -M C", BREAKPOINT_CREATED, + # startstr = "Breakpoint created: 1: name = 'C'") + + # Make the test case more robust by using line number to break, + # instead. + lldbutil.run_break_set_by_file_and_line( + self, None, self.line, num_expected_locations=-1) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # Continue on inside the ctor() body... + self.runCmd("register read pc") + self.runCmd("thread step-over") + + # Verify that 'frame variable this' gets the data type correct. + self.expect("frame variable this", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['C *']) + + # Verify that frame variable --show-types this->m_c_int behaves + # correctly. + self.runCmd("register read pc") + self.runCmd("expr m_c_int") + self.expect( + "frame variable --show-types this->m_c_int", + VARIABLES_DISPLAYED_CORRECTLY, + startstr='(int) this->m_c_int = 66') + + # Verify that 'expression this' gets the data type correct. + self.expect("expression this", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['C *']) + + # rdar://problem/8430916 + # expr this->m_c_int returns an incorrect value + # + # Verify that expr this->m_c_int behaves correctly. + self.expect("expression this->m_c_int", VARIABLES_DISPLAYED_CORRECTLY, + patterns=['\(int\) \$[0-9]+ = 66']) + + def test_with_constructor_name(self): + """Test 'frame variable this' and 'expr this' when stopped inside a constructor.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + filespec = target.GetExecutable() + self.assertTrue(filespec, VALID_FILESPEC) + + fsDir = os.path.normpath(filespec.GetDirectory()) + fsFile = filespec.GetFilename() + + self.assertTrue(fsDir == os.path.dirname(self.getBuildArtifact()) + and fsFile == "a.out", + "FileSpec matches the executable") + + bpfilespec = lldb.SBFileSpec("main.cpp", False) + + breakpoint = target.BreakpointCreateByLocation(bpfilespec, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Verify the breakpoint just created. + self.expect(str(breakpoint), BREAKPOINT_CREATED, exe=False, + substrs=['main.cpp', + str(self.line)]) + + # 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") + + if process.GetState() != lldb.eStateStopped: + self.fail("Process should be in the 'stopped' state, " + "instead the actual state is: '%s'" % + lldbutil.state_type_to_str(process.GetState())) + + # The stop reason of the thread should be breakpoint. + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + + frame = thread.frames[0] + self.assertTrue(frame.IsValid(), "Got a valid frame.") + + self.assertTrue("C::C" in frame.name, + "Constructor name includes class name.") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypesDisassembly.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypesDisassembly.py new file mode 100644 index 00000000000..ad187d0394b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/TestClassTypesDisassembly.py @@ -0,0 +1,99 @@ +""" +Test the lldb disassemble command on each call frame when stopped on C's ctor. +""" + +from __future__ import print_function + + +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class IterateFrameAndDisassembleTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_and_run_command(self): + """Disassemble each call frame when stopped on C's constructor.""" + self.build() + self.breakOnCtor() + + raw_output = self.res.GetOutput() + frameRE = re.compile(r""" + ^\s\sframe # heading for the frame info, + .* # wildcard, and + 0x[0-9a-f]{16} # the frame pc, and + \sa.out`(.+) # module`function, and + \s\+\s # the rest ' + ....' + """, re.VERBOSE) + for line in raw_output.split(os.linesep): + match = frameRE.search(line) + if match: + function = match.group(1) + #print("line:", line) + #print("function:", function) + self.runCmd("disassemble -n '%s'" % function) + + @add_test_categories(['pyapi']) + def test_and_python_api(self): + """Disassemble each call frame when stopped on C's constructor.""" + self.build() + self.breakOnCtor() + + # Now use the Python API to get at each function on the call stack and + # disassemble it. + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + depth = thread.GetNumFrames() + for i in range(depth - 1): + frame = thread.GetFrameAtIndex(i) + function = frame.GetFunction() + # Print the function header. + if self.TraceOn(): + print() + print(function) + if function: + # Get all instructions for this function and print them out. + insts = function.GetInstructions(target) + for inst in insts: + # We could simply do 'print inst' to print out the disassembly. + # But we want to print to stdout only if self.TraceOn() is + # True. + disasm = str(inst) + if self.TraceOn(): + print(disasm) + + 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 break point at this line.') + + def breakOnCtor(self): + """Setup/run the program so it stops on C's constructor.""" + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break on the ctor function of class C. + bpno = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=-1) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint %d.' % (bpno)]) + + # This test was failing because we fail to put the C:: in front of constructore. + # We should maybe make another testcase to cover that specifically, but we shouldn't + # fail this whole testcase for an inessential issue. + # We should be stopped on the ctor function of class C. + # self.expect("thread backtrace", BACKTRACE_DISPLAYED_CORRECTLY, + # substrs = ['C::C']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/cmds.txt b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/cmds.txt new file mode 100644 index 00000000000..1c7ef9f1c8a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/cmds.txt @@ -0,0 +1,3 @@ +b main.cpp:97 +c +var diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/main.cpp new file mode 100644 index 00000000000..179f2177793 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/class_types/main.cpp @@ -0,0 +1,125 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +class Conversion +{ +public: + Conversion (int i) : + m_i (i) + {} + + operator bool() + { + return m_i != 0; + } + +private: + int m_i; +}; + +class A +{ +public: + A(int i=0): + m_a_int(i), + m_aa_int(i+1) + { + } + + //virtual + ~A() + { + } + + int + GetInteger() const + { + return m_a_int; + } + void + SetInteger(int i) + { + m_a_int = i; + } + +protected: + int m_a_int; + int m_aa_int; +}; + +class B : public A +{ +public: + B(int ai, int bi) : + A(ai), + m_b_int(bi) + { + } + + //virtual + ~B() + { + } + + int + GetIntegerB() const + { + return m_b_int; + } + void + SetIntegerB(int i) + { + m_b_int = i; + } + +protected: + int m_b_int; +}; + +#include <cstdio> +class C : public B +{ +public: + C(int ai, int bi, int ci) : + B(ai, bi), + m_c_int(ci) + { + std::printf("Within C::ctor() m_c_int=%d\n", m_c_int); // Set break point at this line. + } + + //virtual + ~C() + { + } + + int + GetIntegerC() const + { + return m_c_int; + } + void + SetIntegerC(int i) + { + m_c_int = i; + } + +protected: + int m_c_int; +}; + +int +main (int argc, char const *argv[]) +{ + A a(12); + B b(22,33); + C c(44,55,66); + Conversion conv(1); + if (conv) + return b.GetIntegerB() - a.GetInteger() + c.GetInteger(); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/const_this/TestConstThis.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/const_this/TestConstThis.py new file mode 100644 index 00000000000..f08c0dcbda9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/const_this/TestConstThis.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), []) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/const_this/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/const_this/main.cpp new file mode 100644 index 00000000000..c244e1bf44e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/const_this/main.cpp @@ -0,0 +1,22 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +class foo { +public: + template <class T> T func(T x) const { + return x+2; //% self.expect("expr 2+3", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["5"]) + } +}; + +int i; + +int main() { + return foo().func(i); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/diamond/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/diamond/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/diamond/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/diamond/TestDiamond.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/diamond/TestDiamond.py new file mode 100644 index 00000000000..c1d0d236268 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/diamond/TestDiamond.py @@ -0,0 +1,51 @@ +""" +Tests that bool types work +""" +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class CPPTestDiamondInheritance(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_with_run_command(self): + """Test that virtual base classes work in when SBValue objects are used to explore the variable value""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 1')) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 2')) + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + frame = thread.GetFrameAtIndex(0) + j1 = frame.FindVariable("j1") + j1_Derived1 = j1.GetChildAtIndex(0) + j1_Derived2 = j1.GetChildAtIndex(1) + j1_Derived1_VBase = j1_Derived1.GetChildAtIndex(0) + j1_Derived2_VBase = j1_Derived2.GetChildAtIndex(0) + j1_Derived1_VBase_m_value = j1_Derived1_VBase.GetChildAtIndex(0) + j1_Derived2_VBase_m_value = j1_Derived2_VBase.GetChildAtIndex(0) + self.assertTrue( + j1_Derived1_VBase.GetLoadAddress() == j1_Derived2_VBase.GetLoadAddress(), + "ensure virtual base class is the same between Derived1 and Derived2") + self.assertTrue(j1_Derived1_VBase_m_value.GetValueAsUnsigned( + 1) == j1_Derived2_VBase_m_value.GetValueAsUnsigned(2), "ensure m_value in VBase is the same") + self.assertTrue(frame.FindVariable("d").GetChildAtIndex(0).GetChildAtIndex( + 0).GetValueAsUnsigned(0) == 12345, "ensure Derived2 from j1 is correct") + thread.StepOver() + self.assertTrue(frame.FindVariable("d").GetChildAtIndex(0).GetChildAtIndex( + 0).GetValueAsUnsigned(0) == 12346, "ensure Derived2 from j2 is correct") + + def set_breakpoint(self, line): + # Some compilers (for example GCC 4.4.7 and 4.6.1) emit multiple locations for the statement with the ternary + # operator in the test program, while others emit only 1. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", line, num_expected_locations=-1, loc_exact=False) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/diamond/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/diamond/main.cpp new file mode 100644 index 00000000000..31329b271e2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/diamond/main.cpp @@ -0,0 +1,84 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +static int g_next_value = 12345; + +class VBase +{ +public: + VBase() : m_value(g_next_value++) {} + virtual ~VBase() {} + void Print() + { + printf("%p: %s\n%p: m_value = 0x%8.8x\n", this, __PRETTY_FUNCTION__, &m_value, m_value); + } + int m_value; +}; + +class Derived1 : public virtual VBase +{ +public: + Derived1() {}; + void Print () + { + printf("%p: %s\n", this, __PRETTY_FUNCTION__); + VBase::Print(); + } + +}; + +class Derived2 : public virtual VBase +{ +public: + Derived2() {}; + + void Print () + { + printf("%p: %s\n", this, __PRETTY_FUNCTION__); + VBase::Print(); + } +}; + +class Joiner1 : public Derived1, public Derived2 +{ +public: + Joiner1() : + m_joiner1(3456), + m_joiner2(6789) {} + void Print () + { + printf("%p: %s \n%p: m_joiner1 = 0x%8.8x\n%p: m_joiner2 = 0x%8.8x\n", + this, + __PRETTY_FUNCTION__, + &m_joiner1, + m_joiner1, + &m_joiner2, + m_joiner2); + Derived1::Print(); + Derived2::Print(); + } + int m_joiner1; + int m_joiner2; +}; + +class Joiner2 : public Derived2 +{ + int m_stuff[32]; +}; + +int main(int argc, const char * argv[]) +{ + Joiner1 j1; + Joiner2 j2; + j1.Print(); + j2.Print(); + Derived2 *d = &j1; + d = &j2; // breakpoint 1 + return 0; // breakpoint 2 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/TestDynamicValueSameBase.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/TestDynamicValueSameBase.py new file mode 100644 index 00000000000..546fd11a1b4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/TestDynamicValueSameBase.py @@ -0,0 +1,58 @@ +""" +Make sure if we have two classes with the same base name the +dynamic value calculator doesn't confuse them +""" + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + + +class DynamicValueSameBaseTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # If your test case doesn't stress debug info, the + # set this to true. That way it won't be run once for + # each debug info format. + NO_DEBUG_INFO_TESTCASE = True + + def test_same_basename_this(self): + """Test that the we use the full name to resolve dynamic types.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.cpp") + self.sample_test() + + def sample_test(self): + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Break here to get started", self.main_source_file) + + # Set breakpoints in the two class methods and run to them: + namesp_bkpt = target.BreakpointCreateBySourceRegex("namesp function did something.", self.main_source_file) + self.assertEqual(namesp_bkpt.GetNumLocations(), 1, "Namespace breakpoint invalid") + + virtual_bkpt = target.BreakpointCreateBySourceRegex("Virtual function did something.", self.main_source_file) + self.assertEqual(virtual_bkpt.GetNumLocations(), 1, "Virtual breakpoint invalid") + + threads = lldbutil.continue_to_breakpoint(process, namesp_bkpt) + self.assertEqual(len(threads), 1, "Didn't stop at namespace breakpoint") + + frame = threads[0].frame[0] + namesp_this = frame.FindVariable("this", lldb.eDynamicCanRunTarget) + # Clang specifies the type of this as "T *", gcc as "T * const". This + # erases the difference. + namesp_type = namesp_this.GetType().GetUnqualifiedType() + self.assertEqual(namesp_type.GetName(), "namesp::Virtual *", "Didn't get the right dynamic type") + + threads = lldbutil.continue_to_breakpoint(process, virtual_bkpt) + self.assertEqual(len(threads), 1, "Didn't stop at virtual breakpoint") + + frame = threads[0].frame[0] + virtual_this = frame.FindVariable("this", lldb.eDynamicCanRunTarget) + virtual_type = virtual_this.GetType().GetUnqualifiedType() + self.assertEqual(virtual_type.GetName(), "Virtual *", "Didn't get the right dynamic type") + + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/main.cpp new file mode 100644 index 00000000000..38e46c03f41 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value-same-basename/main.cpp @@ -0,0 +1,32 @@ +#include <stdio.h> + +namespace namesp +{ + class Virtual { + public: + virtual void doSomething() { + printf ("namesp function did something.\n"); + } + }; +} + +class Virtual { + public: + virtual void doSomething() { + printf("Virtual function did something.\n"); + } +}; + +int +main() +{ + namesp::Virtual my_outer; + Virtual my_virtual; + + // Break here to get started + my_outer.doSomething(); + my_virtual.doSomething(); + + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/Makefile new file mode 100644 index 00000000000..2bba8e757f7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := pass-to-base.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestCppValueCast.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestCppValueCast.py new file mode 100644 index 00000000000..609dd608aa4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestCppValueCast.py @@ -0,0 +1,135 @@ +""" +Test lldb Python API SBValue::Cast(SBType) for C++ types. +""" + +from __future__ import print_function + + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CppValueCastTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(bugnumber="llvm.org/PR36714") + @add_test_categories(['pyapi']) + def test_value_cast_with_virtual_inheritance(self): + """Test SBValue::Cast(SBType) API for C++ types with virtual inheritance.""" + self.build(dictionary=self.d_virtual) + self.setTearDownCleanup(dictionary=self.d_virtual) + self.do_sbvalue_cast(self.exe_name) + + @add_test_categories(['pyapi']) + def test_value_cast_with_regular_inheritance(self): + """Test SBValue::Cast(SBType) API for C++ types with regular inheritance.""" + self.build(dictionary=self.d_regular) + self.setTearDownCleanup(dictionary=self.d_regular) + self.do_sbvalue_cast(self.exe_name) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + # Find the line number to break for main.c. + self.source = 'sbvalue-cast.cpp' + self.line = line_number(self.source, '// Set breakpoint here.') + self.exe_name = self.testMethodName + self.d_virtual = { + 'CXX_SOURCES': self.source, + 'EXE': self.exe_name, + 'CFLAGS_EXTRAS': '-DDO_VIRTUAL_INHERITANCE'} + self.d_regular = {'CXX_SOURCES': self.source, 'EXE': self.exe_name} + + def do_sbvalue_cast(self, exe_name): + """Test SBValue::Cast(SBType) API for C++ types.""" + exe = self.getBuildArtifact(exe_name) + + # Create a target from the debugger. + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set up our breakpoints: + + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + # Find DerivedA and DerivedB types. + typeA = target.FindFirstType('DerivedA') + typeB = target.FindFirstType('DerivedB') + self.DebugSBType(typeA) + self.DebugSBType(typeB) + self.assertTrue(typeA) + self.assertTrue(typeB) + error = lldb.SBError() + + # First stop is for DerivedA instance. + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint) + self.assertTrue(len(threads) == 1) + thread = threads[0] + frame0 = thread.GetFrameAtIndex(0) + + tellerA = frame0.FindVariable('teller', lldb.eNoDynamicValues) + self.DebugSBValue(tellerA) + self.assertTrue(tellerA.GetChildMemberWithName( + 'm_base_val').GetValueAsUnsigned(error, 0) == 20) + + if self.TraceOn(): + for child in tellerA: + print("child name:", child.GetName()) + print(child) + + # Call SBValue.Cast() to obtain instanceA. + instanceA = tellerA.Cast(typeA.GetPointerType()) + self.DebugSBValue(instanceA) + + # Iterate through all the children and print their values. + if self.TraceOn(): + for child in instanceA: + print("child name:", child.GetName()) + print(child) + a_member_val = instanceA.GetChildMemberWithName('m_a_val') + self.DebugSBValue(a_member_val) + self.assertTrue(a_member_val.GetValueAsUnsigned(error, 0) == 10) + + # Second stop is for DerivedB instance. + threads = lldbutil.continue_to_breakpoint(process, breakpoint) + self.assertTrue(len(threads) == 1) + thread = threads[0] + frame0 = thread.GetFrameAtIndex(0) + + tellerB = frame0.FindVariable('teller', lldb.eNoDynamicValues) + self.DebugSBValue(tellerB) + self.assertTrue(tellerB.GetChildMemberWithName( + 'm_base_val').GetValueAsUnsigned(error, 0) == 12) + + if self.TraceOn(): + for child in tellerB: + print("child name:", child.GetName()) + print(child) + + # Call SBValue.Cast() to obtain instanceB. + instanceB = tellerB.Cast(typeB.GetPointerType()) + self.DebugSBValue(instanceB) + + # Iterate through all the children and print their values. + if self.TraceOn(): + for child in instanceB: + print("child name:", child.GetName()) + print(child) + b_member_val = instanceB.GetChildMemberWithName('m_b_val') + self.DebugSBValue(b_member_val) + self.assertTrue(b_member_val.GetValueAsUnsigned(error, 0) == 36) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestDynamicValue.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestDynamicValue.py new file mode 100644 index 00000000000..c3d7dfb328f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/TestDynamicValue.py @@ -0,0 +1,249 @@ +""" +Use lldb Python API to test dynamic values in C++ +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class DynamicValueTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + # Find the line number to break for main.c. + + self.do_something_line = line_number( + 'pass-to-base.cpp', '// Break here in doSomething.') + self.main_first_call_line = line_number( + 'pass-to-base.cpp', + '// Break here and get real addresses of myB and otherB.') + self.main_second_call_line = line_number( + 'pass-to-base.cpp', '// Break here and get real address of reallyA.') + + @add_test_categories(['pyapi']) + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24663") + def test_get_dynamic_vals(self): + """Test fetching C++ dynamic values from pointers & references.""" + self.build(dictionary=self.getBuildFlags()) + exe = self.getBuildArtifact("a.out") + + # Create a target from the debugger. + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set up our breakpoints: + + do_something_bpt = target.BreakpointCreateByLocation( + 'pass-to-base.cpp', self.do_something_line) + self.assertTrue(do_something_bpt, + VALID_BREAKPOINT) + + first_call_bpt = target.BreakpointCreateByLocation( + 'pass-to-base.cpp', self.main_first_call_line) + self.assertTrue(first_call_bpt, + VALID_BREAKPOINT) + + second_call_bpt = target.BreakpointCreateByLocation( + 'pass-to-base.cpp', self.main_second_call_line) + self.assertTrue(second_call_bpt, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, first_call_bpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + + frame = thread.GetFrameAtIndex(0) + + # Now find the dynamic addresses of myB and otherB so we can compare them + # with the dynamic values we get in doSomething: + + use_dynamic = lldb.eDynamicCanRunTarget + no_dynamic = lldb.eNoDynamicValues + + myB = frame.FindVariable('myB', no_dynamic) + self.assertTrue(myB) + myB_loc = int(myB.GetLocation(), 16) + + otherB = frame.FindVariable('otherB', no_dynamic) + self.assertTrue(otherB) + otherB_loc = int(otherB.GetLocation(), 16) + + # Okay now run to doSomething: + + threads = lldbutil.continue_to_breakpoint(process, do_something_bpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + + frame = thread.GetFrameAtIndex(0) + + # Get "this" using FindVariable: + + this_static = frame.FindVariable('this', no_dynamic) + this_dynamic = frame.FindVariable('this', use_dynamic) + self.examine_value_object_of_this_ptr( + this_static, this_dynamic, myB_loc) + + # Now make sure that the "GetDynamicValue" works: + # This doesn't work currently because we can't get dynamic values from + # ConstResult objects. + fetched_dynamic_value = this_static.GetDynamicValue(use_dynamic) + self.examine_value_object_of_this_ptr( + this_static, fetched_dynamic_value, myB_loc) + + # And conversely that the GetDynamicValue() interface also works: + fetched_static_value = this_dynamic.GetStaticValue() + self.examine_value_object_of_this_ptr( + fetched_static_value, this_dynamic, myB_loc) + + # Get "this" using FindValue, make sure that works too: + this_static = frame.FindValue( + 'this', lldb.eValueTypeVariableArgument, no_dynamic) + this_dynamic = frame.FindValue( + 'this', lldb.eValueTypeVariableArgument, use_dynamic) + self.examine_value_object_of_this_ptr( + this_static, this_dynamic, myB_loc) + + # Get "this" using the EvaluateExpression: + this_static = frame.EvaluateExpression('this', False) + this_dynamic = frame.EvaluateExpression('this', True) + self.examine_value_object_of_this_ptr( + this_static, this_dynamic, myB_loc) + + # The "frame var" code uses another path to get into children, so let's + # make sure that works as well: + + self.expect( + 'frame var -d run-target --ptr-depth=2 --show-types anotherA.m_client_A', + 'frame var finds its way into a child member', + patterns=['\(B \*\)']) + + # Now make sure we also get it right for a reference as well: + + anotherA_static = frame.FindVariable('anotherA', False) + self.assertTrue(anotherA_static) + anotherA_static_addr = int(anotherA_static.GetValue(), 16) + + anotherA_dynamic = frame.FindVariable('anotherA', True) + self.assertTrue(anotherA_dynamic) + anotherA_dynamic_addr = int(anotherA_dynamic.GetValue(), 16) + anotherA_dynamic_typename = anotherA_dynamic.GetTypeName() + self.assertTrue(anotherA_dynamic_typename.find('B') != -1) + + self.assertTrue(anotherA_dynamic_addr < anotherA_static_addr) + + anotherA_m_b_value_dynamic = anotherA_dynamic.GetChildMemberWithName( + 'm_b_value', True) + self.assertTrue(anotherA_m_b_value_dynamic) + anotherA_m_b_val = int(anotherA_m_b_value_dynamic.GetValue(), 10) + self.assertTrue(anotherA_m_b_val == 300) + + anotherA_m_b_value_static = anotherA_static.GetChildMemberWithName( + 'm_b_value', True) + self.assertFalse(anotherA_m_b_value_static) + + # Okay, now continue again, and when we hit the second breakpoint in + # main + + threads = lldbutil.continue_to_breakpoint(process, second_call_bpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + + frame = thread.GetFrameAtIndex(0) + reallyA_value = frame.FindVariable('reallyA', False) + self.assertTrue(reallyA_value) + reallyA_loc = int(reallyA_value.GetLocation(), 16) + + # Finally continue to doSomething again, and make sure we get the right value for anotherA, + # which this time around is just an "A". + + threads = lldbutil.continue_to_breakpoint(process, do_something_bpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + + frame = thread.GetFrameAtIndex(0) + anotherA_value = frame.FindVariable('anotherA', True) + self.assertTrue(anotherA_value) + anotherA_loc = int(anotherA_value.GetValue(), 16) + self.assertTrue(anotherA_loc == reallyA_loc) + self.assertTrue(anotherA_value.GetTypeName().find('B') == -1) + + def examine_value_object_of_this_ptr( + self, this_static, this_dynamic, dynamic_location): + # Get "this" as its static value + self.assertTrue(this_static) + this_static_loc = int(this_static.GetValue(), 16) + + # Get "this" as its dynamic value + + self.assertTrue(this_dynamic) + this_dynamic_typename = this_dynamic.GetTypeName() + self.assertTrue(this_dynamic_typename.find('B') != -1) + this_dynamic_loc = int(this_dynamic.GetValue(), 16) + + # Make sure we got the right address for "this" + + self.assertTrue(this_dynamic_loc == dynamic_location) + + # And that the static address is greater than the dynamic one + + self.assertTrue(this_static_loc > this_dynamic_loc) + + # Now read m_b_value which is only in the dynamic value: + + use_dynamic = lldb.eDynamicCanRunTarget + no_dynamic = lldb.eNoDynamicValues + + this_dynamic_m_b_value = this_dynamic.GetChildMemberWithName( + 'm_b_value', use_dynamic) + self.assertTrue(this_dynamic_m_b_value) + + m_b_value = int(this_dynamic_m_b_value.GetValue(), 0) + self.assertTrue(m_b_value == 10) + + # Make sure it is not in the static version + + this_static_m_b_value = this_static.GetChildMemberWithName( + 'm_b_value', no_dynamic) + self.assertFalse(this_static_m_b_value) + + # Okay, now let's make sure that we can get the dynamic type of a child + # element: + + contained_auto_ptr = this_dynamic.GetChildMemberWithName( + 'm_client_A', use_dynamic) + self.assertTrue(contained_auto_ptr) + contained_b = contained_auto_ptr.GetChildMemberWithName( + '_M_ptr', use_dynamic) + if not contained_b: + contained_b = contained_auto_ptr.GetChildMemberWithName( + '__ptr_', use_dynamic) + self.assertTrue(contained_b) + + contained_b_static = contained_auto_ptr.GetChildMemberWithName( + '_M_ptr', no_dynamic) + if not contained_b_static: + contained_b_static = contained_auto_ptr.GetChildMemberWithName( + '__ptr_', no_dynamic) + self.assertTrue(contained_b_static) + + contained_b_addr = int(contained_b.GetValue(), 16) + contained_b_static_addr = int(contained_b_static.GetValue(), 16) + + self.assertTrue(contained_b_addr < contained_b_static_addr) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/pass-to-base.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/pass-to-base.cpp new file mode 100644 index 00000000000..2bccf330382 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/pass-to-base.cpp @@ -0,0 +1,69 @@ +#include <stdio.h> +#include <memory> + +class Extra +{ +public: + Extra (int in_one, int in_two) : m_extra_one(in_one), m_extra_two(in_two) {} + +private: + int m_extra_one; + int m_extra_two; +}; + +class A +{ +public: + A(int value) : m_a_value (value) {} + A(int value, A* client_A) : m_a_value (value), m_client_A (client_A) {} + + virtual ~A() {} + + virtual void + doSomething (A &anotherA) + { + printf ("In A %p doing something with %d.\n", this, m_a_value); + int tmp_value = anotherA.Value(); + printf ("Also have another A at %p: %d.\n", &anotherA, tmp_value); // Break here in doSomething. + } + + int + Value() + { + return m_a_value; + } + +private: + int m_a_value; + std::auto_ptr<A> m_client_A; +}; + +class B : public Extra, public virtual A +{ +public: + B (int b_value, int a_value) : Extra(b_value, a_value), A(a_value), m_b_value(b_value) {} + B (int b_value, int a_value, A *client_A) : Extra(b_value, a_value), A(a_value, client_A), m_b_value(b_value) {} + + virtual ~B () {} + +private: + int m_b_value; +}; + +static A* my_global_A_ptr; + +int +main (int argc, char **argv) +{ + my_global_A_ptr = new B (100, 200); + B myB (10, 20, my_global_A_ptr); + B *second_fake_A_ptr = new B (150, 250); + B otherB (300, 400, second_fake_A_ptr); + + myB.doSomething(otherB); // Break here and get real addresses of myB and otherB. + + A reallyA (500); + myB.doSomething (reallyA); // Break here and get real address of reallyA. + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/sbvalue-cast.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/sbvalue-cast.cpp new file mode 100644 index 00000000000..9e03594a734 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/dynamic-value/sbvalue-cast.cpp @@ -0,0 +1,79 @@ +//===-- sbvalue-cast.cpp ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifdef DO_VIRTUAL_INHERITANCE +#define VIRTUAL virtual +#else +#define VIRTUAL +#endif + +#include <stdio.h> + +class Base +{ +public: + Base(int val) : m_base_val (val) {} + virtual ~Base() {} + + virtual void + forcast(int input) { + int future_val = m_base_val + input * 1; + printf("Forcasting %d\n", future_val); + } + +protected: + int m_base_val; +}; + +class DerivedA : public VIRTUAL Base +{ +public: + DerivedA(int val) : Base(val*2), m_a_val(val) { + printf("DerivedA::ctor()->\n"); + printf("m_base_val=%d\n", m_base_val); + printf("m_a_val=%d\n", m_a_val); + } + virtual ~DerivedA() {} + +private: + int m_a_val; +}; + +class DerivedB : public VIRTUAL Base +{ +public: + DerivedB(int val) : Base(val), m_b_val(val*3) { + printf("DerivedB::ctor()->\n"); + printf("m_base_val=%d\n", m_base_val); + printf("m_b_val=%d\n", m_b_val); + } + virtual ~DerivedB() {} + + virtual void + forcast(int input) { + int future_val = m_b_val + input * 2; + printf("Forcasting %d\n", future_val); + } + +private: + int m_b_val; +}; + +int +main(int argc, char **argv) +{ + DerivedA* dA = new DerivedA(10); + DerivedB* dB = new DerivedB(12); + Base *array[2] = {dA, dB}; + Base *teller = NULL; + for (int i = 0; i < 2; ++i) { + teller = array[i]; + teller->forcast(i); // Set breakpoint here. + } + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/enum_types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/enum_types/Makefile new file mode 100644 index 00000000000..a02c72adc20 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/enum_types/Makefile @@ -0,0 +1,9 @@ +CXX_SOURCES := main.cpp + +CXXFLAGS_EXTRAS := -std=c++11 + +clean: OBJECTS+=$(wildcard main.d.*) + + + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/enum_types/TestCPP11EnumTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/enum_types/TestCPP11EnumTypes.py new file mode 100644 index 00000000000..c58f700039e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/enum_types/TestCPP11EnumTypes.py @@ -0,0 +1,156 @@ +"""Look up enum type information and check for correct display.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class CPP11EnumTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527') + @skipIf(dwarf_version=['<', '4']) + def test_int8_t(self): + """Test C++11 enumeration class types as int8_t types.""" + self.build( + dictionary={ + 'CFLAGS_EXTRAS': '"-DSIGNED_ENUM_CLASS_TYPE=int8_t"'}) + self.image_lookup_for_enum_type(True) + + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527') + @skipIf(dwarf_version=['<', '4']) + def test_int16_t(self): + """Test C++11 enumeration class types as int16_t types.""" + self.build( + dictionary={ + 'CFLAGS_EXTRAS': '"-DSIGNED_ENUM_CLASS_TYPE=int16_t"'}) + self.image_lookup_for_enum_type(True) + + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527') + @skipIf(dwarf_version=['<', '4']) + def test_int32_t(self): + """Test C++11 enumeration class types as int32_t types.""" + self.build( + dictionary={ + 'CFLAGS_EXTRAS': '"-DSIGNED_ENUM_CLASS_TYPE=int32_t"'}) + self.image_lookup_for_enum_type(True) + + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527') + @skipIf(dwarf_version=['<', '4']) + def test_int64_t(self): + """Test C++11 enumeration class types as int64_t types.""" + self.build( + dictionary={ + 'CFLAGS_EXTRAS': '"-DSIGNED_ENUM_CLASS_TYPE=int64_t"'}) + self.image_lookup_for_enum_type(True) + + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527') + @skipIf(dwarf_version=['<', '4']) + def test_uint8_t(self): + """Test C++11 enumeration class types as uint8_t types.""" + self.build( + dictionary={ + 'CFLAGS_EXTRAS': '"-DUNSIGNED_ENUM_CLASS_TYPE=uint8_t"'}) + self.image_lookup_for_enum_type(False) + + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527') + @skipIf(dwarf_version=['<', '4']) + def test_uint16_t(self): + """Test C++11 enumeration class types as uint16_t types.""" + self.build( + dictionary={ + 'CFLAGS_EXTRAS': '"-DUNSIGNED_ENUM_CLASS_TYPE=uint16_t"'}) + self.image_lookup_for_enum_type(False) + + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527') + @skipIf(dwarf_version=['<', '4']) + def test_uint32_t(self): + """Test C++11 enumeration class types as uint32_t types.""" + self.build( + dictionary={ + 'CFLAGS_EXTRAS': '"-DUNSIGNED_ENUM_CLASS_TYPE=uint32_t"'}) + self.image_lookup_for_enum_type(False) + + @expectedFailureAll(oslist=['freebsd'], bugnumber='llvm.org/pr36527') + @skipIf(dwarf_version=['<', '4']) + def test_uint64_t(self): + """Test C++11 enumeration class types as uint64_t types.""" + self.build( + dictionary={ + 'CFLAGS_EXTRAS': '"-DUNSIGNED_ENUM_CLASS_TYPE=uint64_t"'}) + self.image_lookup_for_enum_type(False) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.cpp', '// Set break point at this line.') + + def image_lookup_for_enum_type(self, is_signed): + """Test C++11 enumeration class types.""" + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + bkpt_id = lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # Look up information about the 'DayType' enum type. + # Check for correct display. + self.expect("image lookup -t DayType", DATA_TYPES_DISPLAYED_CORRECTLY, + patterns=['enum( struct| class) DayType {'], + substrs=['Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + 'kNumDays', + '}']) + + if is_signed: + enum_values = ['-4', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + 'kNumDays', + '5'] + else: + enum_values = ['199', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + 'Sunday', + 'kNumDays', + '208'] + + bkpt = self.target().FindBreakpointByID(bkpt_id) + for enum_value in enum_values: + self.expect( + "frame variable day", + 'check for valid enumeration value', + substrs=[enum_value]) + lldbutil.continue_to_breakpoint(self.process(), bkpt) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/enum_types/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/enum_types/main.cpp new file mode 100644 index 00000000000..e00fc2df460 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/enum_types/main.cpp @@ -0,0 +1,48 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> +#include <stdint.h> + + +int main (int argc, char const *argv[]) +{ +#ifdef SIGNED_ENUM_CLASS_TYPE + typedef SIGNED_ENUM_CLASS_TYPE enum_integer_t; + enum class DayType : enum_integer_t { + Monday = -3, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + Sunday, + kNumDays + }; + enum_integer_t day_value; +#else + typedef UNSIGNED_ENUM_CLASS_TYPE enum_integer_t; + enum class DayType : enum_integer_t { + Monday = 200, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + Sunday, + kNumDays + }; + enum_integer_t day_value; +#endif + + for (day_value = (enum_integer_t)DayType::Monday - 1; day_value <= (enum_integer_t)DayType::kNumDays + 1; ++day_value) + { + DayType day = (DayType)day_value; + printf("day as int is %i\n", (int)day); // Set break point at this line. + } + return 0; // Break here for char tests +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/exceptions/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/exceptions/Makefile new file mode 100644 index 00000000000..edb53da7b8e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/exceptions/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := exceptions.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/exceptions/TestCPPExceptionBreakpoints.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/exceptions/TestCPPExceptionBreakpoints.py new file mode 100644 index 00000000000..e888958987a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/exceptions/TestCPPExceptionBreakpoints.py @@ -0,0 +1,82 @@ +""" +Test lldb exception breakpoint command for CPP. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CPPBreakpointTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + self.source = 'exceptions.cpp' + self.catch_line = line_number( + self.source, '// This is the line you should stop at for catch') + + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24538, clang-cl does not support throw or catch") + @expectedFailureNetBSD + def test(self): + """Test lldb exception breakpoint command for CPP.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target from the debugger. + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + exception_bkpt = target.BreakpointCreateForException( + lldb.eLanguageTypeC_plus_plus, True, True) + self.assertTrue(exception_bkpt, "Made an exception breakpoint") + + # Now run, and make sure we hit our breakpoint: + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, "Got a valid process") + + stopped_threads = [] + stopped_threads = lldbutil.get_threads_stopped_at_breakpoint( + process, exception_bkpt) + self.assertTrue( + len(stopped_threads) == 1, + "Stopped at our exception breakpoint.") + thread = stopped_threads[0] + # Make sure our throw function is still above us on the stack: + + frame_functions = lldbutil.get_function_names(thread) + self.assertTrue( + frame_functions.count("throws_exception_on_even(int)") == 1, + "Our throw function is still on the stack.") + + # Okay we hit our exception throw breakpoint, now make sure we get our catch breakpoint. + # One potential complication is that we might hit a couple of the exception breakpoints in getting out of the throw. + # so loop till we don't see the throws function on the stack. We should stop one more time for our exception breakpoint + # and that should be the catch... + + while frame_functions.count("throws_exception_on_even(int)") == 1: + stopped_threads = lldbutil.continue_to_breakpoint( + process, exception_bkpt) + self.assertTrue(len(stopped_threads) == 1) + + thread = stopped_threads[0] + frame_functions = lldbutil.get_function_names(thread) + + self.assertTrue( + frame_functions.count("throws_exception_on_even(int)") == 0, + "At catch our throw function is off the stack") + self.assertTrue( + frame_functions.count("intervening_function(int)") == 0, + "At catch our intervening function is off the stack") + self.assertTrue( + frame_functions.count("catches_exception(int)") == 1, + "At catch our catch function is on the stack") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/exceptions/exceptions.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/exceptions/exceptions.cpp new file mode 100644 index 00000000000..150d420b241 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/exceptions/exceptions.cpp @@ -0,0 +1,42 @@ +#include <exception> +#include <stdio.h> + +int throws_exception_on_even (int value); +int intervening_function (int value); +int catches_exception (int value); + +int +catches_exception (int value) +{ + try + { + return intervening_function(value); // This is the line you should stop at for catch + } + catch (int value) + { + return value; + } +} + +int +intervening_function (int value) +{ + return throws_exception_on_even (2 * value); +} + +int +throws_exception_on_even (int value) +{ + printf ("Mod two works: %d.\n", value%2); + if (value % 2 == 0) + throw 30; + else + return value; +} + +int +main () +{ + catches_exception (10); // Stop here + return 5; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py new file mode 100644 index 00000000000..b1b7e1744f1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/TestExternCSymbols.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), lldbinline.expectedFailureAll(oslist=["windows"])) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp new file mode 100644 index 00000000000..47769014d49 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/extern_c/main.cpp @@ -0,0 +1,28 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> +#include <stdint.h> + +extern "C" +{ + int foo(); +}; + +int foo() +{ + puts("foo"); + return 2; +} + +int main (int argc, char const *argv[], char const *envp[]) +{ + foo(); + return 0; //% self.expect("expression -- foo()", substrs = ['2']) +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/TestFrameVariableAnonymousUnions.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/TestFrameVariableAnonymousUnions.py new file mode 100644 index 00000000000..6352b68e7d7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/TestFrameVariableAnonymousUnions.py @@ -0,0 +1,35 @@ +""" +Tests that frame variable looks into anonymous unions +""" +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class FrameVariableAnonymousUnionsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_with_run_command(self): + """Tests that frame variable looks into anonymous unions""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + line = line_number('main.cpp', '// break here') + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", line, num_expected_locations=-1, loc_exact=False) + + self.runCmd("process launch", RUN_SUCCEEDED) + + process = self.dbg.GetSelectedTarget().GetProcess() + + if process.GetByteOrder() == lldb.eByteOrderLittle: + self.expect('frame variable -f x i', substrs=['ffffff41']) + else: + self.expect('frame variable -f x i', substrs=['41ffff00']) + + self.expect('frame variable c', substrs=["'A"]) + + self.expect('frame variable x', matching=False, substrs=['3']) + self.expect('frame variable y', matching=False, substrs=["'B'"]) + self.expect('frame variable z', matching=False, substrs=['14']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/main.cpp new file mode 100644 index 00000000000..2489506b280 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/frame-var-anon-unions/main.cpp @@ -0,0 +1,22 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +int main() { + union { + int i; + char c; + }; + struct { + int x; + char y; + short z; + } s{3,'B',14}; + i = 0xFFFFFF00; + c = 'A'; + return c; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py new file mode 100644 index 00000000000..b90f74656cd --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/TestFunctionTemplateParameterPack.py @@ -0,0 +1,12 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +# https://bugs.llvm.org/show_bug.cgi?id=35920 +# This test stresses expression evaluation support for template functions. +# Currently the support is rudimentary, and running this test causes assertion +# failures in clang. This test cannot be XFAIL'ed because the test harness +# treats assertion failures as unexpected events. For now, the test must be +# skipped. +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipIf]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp new file mode 100644 index 00000000000..eea2830aef8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function-template-parameter-pack/main.cpp @@ -0,0 +1,23 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +template <class T> int staticSizeof() { + return sizeof(T); +} + +template <class T1, class T2, class... Ts> int staticSizeof() { + return staticSizeof<T2, Ts...>() + sizeof(T1); +} + +int main (int argc, char const *argv[]) +{ + int sz = staticSizeof<long, int, char>(); + return staticSizeof<long, int, char>() != sz; //% self.expect("expression -- sz == staticSizeof<long, int, char>()", "staticSizeof<long, int, char> worked", substrs = ["true"]) + //% self.expect("expression -- sz == staticSizeof<long, int>() + sizeof(char)", "staticSizeof<long, int> worked", substrs = ["true"]) + //% self.expect("expression -- sz == staticSizeof<long>() + sizeof(int) + sizeof(char)", "staticSizeof<long> worked", substrs = ["true"]) +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function_refs/TestFunctionRefs.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function_refs/TestFunctionRefs.py new file mode 100644 index 00000000000..293e9139637 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function_refs/TestFunctionRefs.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), + lldbinline.expectedFailureAll(oslist=["windows"])) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function_refs/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function_refs/main.cpp new file mode 100644 index 00000000000..a57b0867fb8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/function_refs/main.cpp @@ -0,0 +1,32 @@ +// This is plagiarized from lit/SymbolFile/NativePDB/function-types-builtin.cpp. +void nullary() {} + +template<typename Arg> +void unary(Arg) { } + +template<typename A1, typename A2> +void binary(A1, A2) { } + +int varargs(int, int, ...) { return 0; } + +auto &ref = unary<bool>; +auto &ref2 = unary<volatile int*>; +auto &ref3 = varargs; +auto binp = &binary<int*, const int*>; +auto &binr = binary<int*, const int*>; +auto null = &nullary; +int main(int argc, char **argv) { +//% self.expect("target var ref", substrs=["(void (&)(bool))", "ref = 0x", +//% "&::ref = <no summary available>"]) +//% self.expect("target var ref2", +//% substrs=["(void (&)(volatile int *))", "ref2 = 0x"]) +//% self.expect("target var ref3", +//% substrs=["(int (&)(int, int, ...))", "ref3 = 0x"]) +//% self.expect("target var binp", +//% substrs=["(void (*)(int *, const int *))", "binp = 0x"]) +//% self.expect("target var binr", +//% substrs=["(void (&)(int *, const int *))", "binr = 0x"]) +//% self.expect("target var null", +//% substrs=["(void (*)())", "null = 0x"]) + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_operators/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_operators/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_operators/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py new file mode 100644 index 00000000000..4ead709cf56 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_operators/TestCppGlobalOperators.py @@ -0,0 +1,93 @@ +""" +Test that global operators are found and evaluated. +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCppGlobalOperators(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def prepare_executable_and_get_frame(self): + self.build() + + # Get main source file + src_file = "main.cpp" + src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(src_file_spec.IsValid(), "Main source file") + + # Get the path of the executable + exe_path = self.getBuildArtifact("a.out") + + # Load the executable + target = self.dbg.CreateTarget(exe_path) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Break on main function + main_breakpoint = target.BreakpointCreateBySourceRegex( + "// break here", src_file_spec) + self.assertTrue( + main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, + VALID_BREAKPOINT) + + # Launch the process + args = None + env = None + process = target.LaunchSimple( + args, env, self.get_process_working_directory()) + self.assertTrue(process.IsValid(), PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue( + process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + + return thread.GetSelectedFrame() + + def test_equals_operator(self): + frame = self.prepare_executable_and_get_frame() + + test_result = frame.EvaluateExpression("operator==(s1, s2)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "false", + "operator==(s1, s2) = false") + + test_result = frame.EvaluateExpression("operator==(s1, s3)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "true", + "operator==(s1, s3) = true") + + test_result = frame.EvaluateExpression("operator==(s2, s3)") + self.assertTrue( + test_result.IsValid() and test_result.GetValue() == "false", + "operator==(s2, s3) = false") + + def do_new_test(self, frame, expr, expected_value_name): + """Evaluate a new expression, and check its result""" + + expected_value = frame.FindValue( + expected_value_name, lldb.eValueTypeVariableGlobal) + self.assertTrue(expected_value.IsValid()) + + expected_value_addr = expected_value.AddressOf() + self.assertTrue(expected_value_addr.IsValid()) + + got = frame.EvaluateExpression(expr) + self.assertTrue(got.IsValid()) + self.assertEqual( + got.GetValueAsUnsigned(), + expected_value_addr.GetValueAsUnsigned()) + got_type = got.GetType() + self.assertTrue(got_type.IsPointerType()) + self.assertEqual(got_type.GetPointeeType().GetName(), "Struct") + + def test_operator_new(self): + frame = self.prepare_executable_and_get_frame() + + self.do_new_test(frame, "new Struct()", "global_new_buf") + self.do_new_test(frame, "new(new_tag) Struct()", "tagged_new_buf") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_operators/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_operators/main.cpp new file mode 100644 index 00000000000..c6dafd29586 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_operators/main.cpp @@ -0,0 +1,42 @@ +#include <new> + +struct new_tag_t +{ +}; +new_tag_t new_tag; + +struct Struct { + int value; +}; + +bool operator==(const Struct &a, const Struct &b) { + return a.value == b.value; +} + +typedef char buf_t[sizeof(Struct)]; +buf_t global_new_buf, tagged_new_buf; + +// This overrides global operator new +// This function and the following does not actually allocate memory. We are merely +// trying to make sure it is getting called. +void * +operator new(std::size_t count) +{ + return &global_new_buf; +} + +// A custom allocator +void * +operator new(std::size_t count, const new_tag_t &) +{ + return &tagged_new_buf; +} + +int main() { + Struct s1, s2, s3; + s1.value = 3; + s2.value = 5; + s3.value = 3; + return 0; // break here +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_variables/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_variables/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_variables/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_variables/TestCPPGlobalVariables.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_variables/TestCPPGlobalVariables.py new file mode 100644 index 00000000000..4870247995f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_variables/TestCPPGlobalVariables.py @@ -0,0 +1,40 @@ +"""Test that C++ global variables can be inspected by name and also their mangled name.""" + + + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class GlobalVariablesCppTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + self.source = lldb.SBFileSpec('main.cpp') + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") + def test(self): + self.build() + + (target, _, _, _) = lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", self.source) + + # Check that we can access g_file_global_int by its name + self.expect("target variable g_file_global_int", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['42']) + self.expect("target variable abc::g_file_global_int", VARIABLES_DISPLAYED_CORRECTLY, + substrs=['42']) + self.expect("target variable xyz::g_file_global_int", VARIABLES_DISPLAYED_CORRECTLY, + error=True, substrs=['can\'t find global variable']) + + # Check that we can access g_file_global_int by its mangled name + addr = target.EvaluateExpression("&abc::g_file_global_int").GetValueAsUnsigned() + self.assertTrue(addr != 0) + mangled = lldb.SBAddress(addr, target).GetSymbol().GetMangledName() + self.assertTrue(mangled != None) + gv = target.FindFirstGlobalVariable(mangled) + self.assertTrue(gv.IsValid()) + self.assertEqual(gv.GetName(), "abc::g_file_global_int") + self.assertEqual(gv.GetValueAsUnsigned(), 42) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_variables/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_variables/main.cpp new file mode 100644 index 00000000000..0a164186e71 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/global_variables/main.cpp @@ -0,0 +1,17 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +namespace abc { + int g_file_global_int = 42; +} + +int main (int argc, char const *argv[]) +{ + return abc::g_file_global_int; // Set break point at this line. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/TestGModules.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/TestGModules.py new file mode 100644 index 00000000000..69d04636d86 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/TestGModules.py @@ -0,0 +1,6 @@ +import lldbsuite.test.lldbinline as lldbinline +from lldbsuite.test.decorators import * + +lldbinline.MakeInlineTest(__file__, globals(), [ + expectedFailureAll(oslist=["linux"], bugnumber="llvm.org/pr36107", + debug_info="gmodules")]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/a.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/a.h new file mode 100644 index 00000000000..7384f230801 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/a.h @@ -0,0 +1,7 @@ +#include "memory.h" + +class MemoryBuffer { int buffer = 42; }; + +struct SrcBuffer { + my_std::unique_ptr<MemoryBuffer> Buffer; +}; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/b.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/b.h new file mode 100644 index 00000000000..b777e8e3473 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/b.h @@ -0,0 +1,6 @@ +#include "a.h" +#include "memory.h" + +class Module { + my_std::unique_ptr<MemoryBuffer> MBptr; +}; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/main.cpp new file mode 100644 index 00000000000..df752616570 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/main.cpp @@ -0,0 +1,9 @@ +#include "b.h" + +int main(int argc, const char * argv[]) +{ + Module m; + // Test that the type Module which contains a field that is a + // template instantiation can be fully resolved. + return 0; //% self.assertTrue(self.frame().FindVariable('m').GetChildAtIndex(0).GetChildAtIndex(0).GetChildAtIndex(0).GetName() == 'buffer', 'find template specializations in imported modules') +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/memory.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/memory.h new file mode 100644 index 00000000000..1d59dc0bbf0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/memory.h @@ -0,0 +1,8 @@ +#ifndef MEMORY_H +#define MEMORY_H +namespace my_std { + template<class T> class unique_ptr { + T t; + }; +} +#endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/module.modulemap b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/module.modulemap new file mode 100644 index 00000000000..2f05073a0b8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules-templates/module.modulemap @@ -0,0 +1,11 @@ +module A { + header "a.h" +} + +module B { + header "b.h" +} + +module std { + header "memory.h" +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/Makefile new file mode 100644 index 00000000000..a98dca64e8a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/Makefile @@ -0,0 +1,5 @@ +PCH_CXX_SOURCE = pch.h +CXX_SOURCES = main.cpp +CFLAGS_EXTRAS := $(MODULE_DEBUG_INFO_FLAGS) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py new file mode 100644 index 00000000000..20207c54db9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/TestWithModuleDebugging.py @@ -0,0 +1,94 @@ +import lldb +import os +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestWithGmodulesDebugInfo(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(bugnumber="llvm.org/pr36146", oslist=["linux"], archs=["i386"]) + @add_test_categories(["gmodules"]) + def test_specialized_typedef_from_pch(self): + self.build() + + src_file = os.path.join(self.getSourceDir(), "main.cpp") + src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(src_file_spec.IsValid(), "breakpoint file") + + # Get the path of the executable + exe_path = self.getBuildArtifact("a.out") + + # Load the executable + target = self.dbg.CreateTarget(exe_path) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Break on interesting line + breakpoint = target.BreakpointCreateBySourceRegex( + "break here", src_file_spec) + self.assertTrue( + breakpoint.IsValid() and breakpoint.GetNumLocations() >= 1, + VALID_BREAKPOINT) + + # Launch the process + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process.IsValid(), PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + + # Get frame for current thread + frame = thread.frames[0] + + testValue = frame.EvaluateExpression("test") + self.assertTrue( + testValue.GetError().Success(), + "Test expression value invalid: %s" % + (testValue.GetError().GetCString())) + self.assertTrue( + testValue.GetTypeName() == "IntContainer", + "Test expression type incorrect") + + memberValue = testValue.GetChildMemberWithName("storage") + self.assertTrue( + memberValue.GetError().Success(), + "Member value missing or invalid: %s" % + (testValue.GetError().GetCString())) + self.assertTrue( + memberValue.GetTypeName() == "int", + "Member type incorrect") + self.assertEqual( + 42, + memberValue.GetValueAsSigned(), + "Member value incorrect") + + testValue = frame.EvaluateExpression("bar") + self.assertTrue( + testValue.GetError().Success(), + "Test expression value invalid: %s" % + (testValue.GetError().GetCString())) + self.assertTrue( + testValue.GetTypeName() == "Foo::Bar", + "Test expression type incorrect") + + memberValue = testValue.GetChildMemberWithName("i") + self.assertTrue( + memberValue.GetError().Success(), + "Member value missing or invalid: %s" % + (testValue.GetError().GetCString())) + self.assertTrue( + memberValue.GetTypeName() == "int", + "Member type incorrect") + self.assertEqual( + 123, + memberValue.GetValueAsSigned(), + "Member value incorrect") + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp new file mode 100644 index 00000000000..588a3a8e01f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/main.cpp @@ -0,0 +1,8 @@ +class Foo::Bar { int i = 123; }; + +int main(int argc, const char * argv[]) +{ + IntContainer test(42); + Foo::Bar bar; + return 0; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h new file mode 100644 index 00000000000..dba4fee9a8c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/gmodules/pch.h @@ -0,0 +1,17 @@ +template<typename T> +class GenericContainer { + private: + T storage; + + public: + GenericContainer(T value) { + storage = value; + }; +}; + +typedef GenericContainer<int> IntContainer; + +struct Foo { + class Bar; + Bar *bar; +}; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/Makefile new file mode 100644 index 00000000000..769920c2833 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/Makefile @@ -0,0 +1,33 @@ +CXX_SOURCES = main.cpp length.cpp a.cpp + +CFLAGS_LIMIT = -c $(CXXFLAGS) +CFLAGS_NO_LIMIT = -c $(CXXFLAGS) + +ifneq (,$(findstring clang,$(CC))) + CFLAGS_LIMIT += -flimit-debug-info + CFLAGS_NO_LIMIT += -fno-limit-debug-info +endif + +all: limit nolimit + +limit: main.o length_limit.o a.o + $(CXX) main.o length_limit.o a.o -o limit $(LDFLAGS) + +nolimit: main.o length_nolimit.o a.o + $(CXX) main.o length_nolimit.o a.o -o nolimit $(LDFLAGS) + +main.o: main.cpp + $(CXX) $(CFLAGS_LIMIT) $(SRCDIR)/main.cpp -o main.o + +length_limit.o: length.cpp + $(CXX) $(CFLAGS_LIMIT) $(SRCDIR)/length.cpp -o length_limit.o + +length_nolimit.o: length.cpp + $(CXX) $(CFLAGS_NO_LIMIT) $(SRCDIR)/length.cpp -o length_nolimit.o + +a.o: a.cpp + $(CXX) $(CFLAGS_NO_DEBUG) -c $(SRCDIR)/a.cpp -o a.o + +clean: OBJECTS += limit nolimit length_limit.o length_nolimit.o length_limit.dwo length_nolimit.dwo + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py new file mode 100644 index 00000000000..7ce2e343b88 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/TestCppIncompleteTypes.py @@ -0,0 +1,55 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCppIncompleteTypes(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(compiler="gcc") + def test_limit_debug_info(self): + self.build() + frame = self.get_test_frame('limit') + + value_f = frame.EvaluateExpression("f") + self.assertTrue( + value_f.IsValid(), + "'expr f' results in a valid SBValue object") + self.assertTrue(value_f.GetError().Success(), "'expr f' is successful") + + value_a = frame.EvaluateExpression("a") + self.assertTrue( + value_a.IsValid(), + "'expr a' results in a valid SBValue object") + self.assertTrue(value_a.GetError().Success(), "'expr a' is successful") + + @skipIf(compiler="gcc") + # Clang on Windows asserts in external record layout in this case. + @skipIfWindows + def test_partial_limit_debug_info(self): + self.build() + frame = self.get_test_frame('nolimit') + + value_f = frame.EvaluateExpression("f") + self.assertTrue( + value_f.IsValid(), + "'expr f' results in a valid SBValue object") + self.assertTrue(value_f.GetError().Success(), "'expr f' is successful") + + value_a = frame.EvaluateExpression("a") + self.assertTrue( + value_a.IsValid(), + "'expr a' results in a valid SBValue object") + self.assertTrue(value_a.GetError().Success(), "'expr a' is successful") + + def get_test_frame(self, exe): + # Get main source file + src_file = "main.cpp" + src_file_spec = lldb.SBFileSpec(src_file) + + (target, process, thread, main_breakpoint) = lldbutil.run_to_source_breakpoint(self, + "break here", src_file_spec, exe_name = exe) + # Get frame for current thread + return thread.GetSelectedFrame() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/a.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/a.cpp new file mode 100644 index 00000000000..36b374be6f3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/a.cpp @@ -0,0 +1,10 @@ + +#include "a.h" + +A::A () { } + +int +A::length () +{ + return 123; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/a.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/a.h new file mode 100644 index 00000000000..13e9496e3fd --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/a.h @@ -0,0 +1,11 @@ +#ifndef __A_H__ +#define __A_H__ + +class A +{ +public: + A(); + virtual int length(); +}; + +#endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/length.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/length.cpp new file mode 100644 index 00000000000..90a3b640f73 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/length.cpp @@ -0,0 +1,8 @@ + +#include "length.h" + +int +length (A &a) +{ + return a.length(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/length.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/length.h new file mode 100644 index 00000000000..96df4f02180 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/length.h @@ -0,0 +1,8 @@ +#ifndef __LENGTH_H__ +#define __LENGTH_H__ + +#include "a.h" + +int length (A &a); + +#endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/main.cpp new file mode 100644 index 00000000000..ad324c90581 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/incomplete-types/main.cpp @@ -0,0 +1,18 @@ + +#include "length.h" + +class Foo { +public: + A a; +}; + +class MyA : public A { +}; + +int main() +{ + Foo f; + MyA a; + + return length(a); // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/Makefile new file mode 100644 index 00000000000..055e318e220 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := inlines.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/TestInlines.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/TestInlines.py new file mode 100644 index 00000000000..5f77d8f5963 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/TestInlines.py @@ -0,0 +1,59 @@ +"""Test variable lookup when stopped in inline functions.""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class InlinesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number( + 'inlines.cpp', + '// Set break point at this line.') + + @expectedFailureAll("llvm.org/pr26710", oslist=["linux"], compiler="gcc") + def test(self): + """Test that local variables are visible in expressions.""" + self.build() + self.runToBreakpoint() + + # Check that 'frame variable' finds a variable + self.expect( + "frame variable inner_input", + VARIABLES_DISPLAYED_CORRECTLY, + startstr='(int) inner_input =') + + # Check that 'expr' finds a variable + self.expect("expr inner_input", VARIABLES_DISPLAYED_CORRECTLY, + startstr='(int) $0 =') + + def runToBreakpoint(self): + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the main. + lldbutil.run_break_set_by_file_and_line( + self, + "inlines.cpp", + self.line, + num_expected_locations=2, + loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.cpp new file mode 100644 index 00000000000..822d88e22f9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.cpp @@ -0,0 +1,53 @@ +#include <stdio.h> +#include "inlines.h" + +#define INLINE_ME __inline__ __attribute__((always_inline)) + +int +not_inlined_2 (int input) +{ + printf ("Called in not_inlined_2 with : %d.\n", input); + return input; +} + +int +not_inlined_1 (int input) +{ + printf ("Called in not_inlined_1 with %d.\n", input); + return not_inlined_2(input); +} + +INLINE_ME int +inner_inline (int inner_input, int mod_value) +{ + int inner_result; + inner_result = inner_input % mod_value; + printf ("Returning: %d.\n", inner_result); + return not_inlined_1 (inner_result); // Set break point at this line. +} + +INLINE_ME int +outer_inline (int outer_input) +{ + int outer_result; + + outer_result = inner_inline (outer_input, outer_input % 3); + return outer_result; +} + +int +main (int argc, char **argv) +{ + printf ("Starting...\n"); + + int (*func_ptr) (int); + func_ptr = outer_inline; + + outer_inline (argc); + + func_ptr (argc); + + return 0; +} + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.h new file mode 100644 index 00000000000..265d7b4966e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/inlines/inlines.h @@ -0,0 +1,4 @@ +int inner_inline (int inner_input, int mod_value); +int outer_inline (int outer_input); +int not_inlined_2 (int input); +int not_inlined_1 (int input); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/lambdas/TestLambdas.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/lambdas/TestLambdas.py new file mode 100644 index 00000000000..c8308c16011 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/lambdas/TestLambdas.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp new file mode 100644 index 00000000000..5870c877f4a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp @@ -0,0 +1,16 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +int main (int argc, char const *argv[]) +{ + printf("Stop here\n"); //% self.runCmd("expression auto $add = [](int first, int second) { return first + second; }") + //% self.expect("expression $add(2,3)", substrs = ['= 5']) + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/Makefile new file mode 100644 index 00000000000..ba7e0153752 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/Makefile @@ -0,0 +1,5 @@ +CXX_SOURCES = main.cpp derived.cpp base.cpp + +CFLAGS_EXTRAS := $(LIMIT_DEBUG_INFO_FLAGS) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py new file mode 100644 index 00000000000..ae50d3d3966 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/TestWithLimitDebugInfo.py @@ -0,0 +1,63 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestWithLimitDebugInfo(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIf(debug_info=no_match(["dwarf"])) + def test_limit_debug_info(self): + self.build() + + src_file = os.path.join(self.getSourceDir(), "main.cpp") + src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(src_file_spec.IsValid(), "breakpoint file") + + # Get the path of the executable + exe_path = self.getBuildArtifact("a.out") + + # Load the executable + target = self.dbg.CreateTarget(exe_path) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Break on main function + breakpoint = target.BreakpointCreateBySourceRegex( + "break here", src_file_spec) + self.assertTrue( + breakpoint.IsValid() and breakpoint.GetNumLocations() >= 1, + VALID_BREAKPOINT) + + # Launch the process + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process.IsValid(), PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue( + process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + thread.StepInto() + + # Get frame for current thread + frame = thread.GetSelectedFrame() + + v1 = frame.EvaluateExpression("1") + self.assertTrue( + v1.IsValid(), + "'expr 1' results in a valid SBValue object") + self.assertTrue( + v1.GetError().Success(), + "'expr 1' succeeds without an error.") + + v2 = frame.EvaluateExpression("this") + self.assertTrue( + v2.IsValid(), + "'expr this' results in a valid SBValue object") + self.assertTrue( + v2.GetError().Success(), + "'expr this' succeeds without an error.") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/base.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/base.cpp new file mode 100644 index 00000000000..4023bdbc64a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/base.cpp @@ -0,0 +1,6 @@ +#include "base.h" + +void FooNS::bar() { + x = 54321; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/base.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/base.h new file mode 100644 index 00000000000..d3a09572bd2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/base.h @@ -0,0 +1,10 @@ +class FooNS +{ +public: + virtual void bar(); + virtual char baz() = 0; + +protected: + int x; +}; + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/derived.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/derived.cpp new file mode 100644 index 00000000000..9d773593eb5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/derived.cpp @@ -0,0 +1,6 @@ +#include "derived.h" + +char Foo::baz() { + return (char)(x&0xff); +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/derived.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/derived.h new file mode 100644 index 00000000000..46b3f83b9f7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/derived.h @@ -0,0 +1,13 @@ +#include "base.h" + +class Foo : public FooNS +{ +public: + Foo() { + a = 12345; + } + + char baz() override; + int a; +}; + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/main.cpp new file mode 100644 index 00000000000..64e0349b582 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/limit-debug-info/main.cpp @@ -0,0 +1,7 @@ +#include "derived.h" + +int main() { + Foo f; // break here + f.bar(); + return f.baz(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py new file mode 100644 index 00000000000..c8308c16011 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp new file mode 100644 index 00000000000..048eeb2d27b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp @@ -0,0 +1,35 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +namespace n { + struct D { + int i; + static int anInt() { return 2; } + int dump() { return i; } + }; + + class C { + public: + int foo(D *D); + }; +} + +using namespace n; + +int C::foo(D* D) { + return D->dump(); //% self.expect("expression -- D->dump()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "2"]) + //% self.expect("expression -- D::anInt()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "2"]) + +} + +int main (int argc, char const *argv[]) +{ + D myD { D::anInt() }; + C().foo(&myD); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/Makefile new file mode 100644 index 00000000000..82f96b62609 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES = main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/TestMembersAndLocalsWithSameName.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/TestMembersAndLocalsWithSameName.py new file mode 100644 index 00000000000..a0dcbf00266 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/TestMembersAndLocalsWithSameName.py @@ -0,0 +1,285 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class TestMembersAndLocalsWithSameName(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_when_stopped_in_method(self): + self._load_exe() + + # Set breakpoints + bp1 = self.target.BreakpointCreateBySourceRegex( + "Break 1", self.src_file_spec) + self.assertTrue( + bp1.IsValid() and bp1.GetNumLocations() >= 1, + VALID_BREAKPOINT) + bp2 = self.target.BreakpointCreateBySourceRegex( + "Break 2", self.src_file_spec) + self.assertTrue( + bp2.IsValid() and bp2.GetNumLocations() >= 1, + VALID_BREAKPOINT) + bp3 = self.target.BreakpointCreateBySourceRegex( + "Break 3", self.src_file_spec) + self.assertTrue( + bp3.IsValid() and bp3.GetNumLocations() >= 1, + VALID_BREAKPOINT) + bp4 = self.target.BreakpointCreateBySourceRegex( + "Break 4", self.src_file_spec) + self.assertTrue( + bp4.IsValid() and bp4.GetNumLocations() >= 1, + VALID_BREAKPOINT) + + # Launch the process + self.process = self.target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) + + self.assertTrue( + self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + self._test_globals() + + self.process.Continue() + self.assertTrue( + self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + self.process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread.IsValid()) + frame = thread.GetSelectedFrame() + self.assertTrue(frame.IsValid()) + + val = frame.EvaluateExpression("a") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 12345) + + val = frame.EvaluateExpression("b") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 54321) + + val = frame.EvaluateExpression("c") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 34567) + + self.process.Continue() + self.assertTrue( + self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + self.process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread.IsValid()) + frame = thread.GetSelectedFrame() + self.assertTrue(frame.IsValid()) + + val = frame.EvaluateExpression("a") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 10001) + + val = frame.EvaluateExpression("b") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 10002) + + val = frame.EvaluateExpression("c") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 10003) + + self.process.Continue() + self.assertTrue( + self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + self.process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread.IsValid()) + frame = thread.GetSelectedFrame() + self.assertTrue(frame.IsValid()) + + val = frame.EvaluateExpression("a") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 1) + + val = frame.EvaluateExpression("b") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 2) + + val = frame.EvaluateExpression("c") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 778899) + + def test_when_stopped_in_function(self): + self._load_exe() + + # Set breakpoints + bp1 = self.target.BreakpointCreateBySourceRegex( + "Break 1", self.src_file_spec) + self.assertTrue( + bp1.IsValid() and bp1.GetNumLocations() >= 1, + VALID_BREAKPOINT) + bp5 = self.target.BreakpointCreateBySourceRegex( + "Break 5", self.src_file_spec) + self.assertTrue( + bp5.IsValid() and bp5.GetNumLocations() >= 1, + VALID_BREAKPOINT) + bp6 = self.target.BreakpointCreateBySourceRegex( + "Break 6", self.src_file_spec) + self.assertTrue( + bp6.IsValid() and bp6.GetNumLocations() >= 1, + VALID_BREAKPOINT) + bp7 = self.target.BreakpointCreateBySourceRegex( + "Break 7", self.src_file_spec) + self.assertTrue( + bp7.IsValid() and bp7.GetNumLocations() >= 1, + VALID_BREAKPOINT) + + # Launch the process + self.process = self.target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(self.process.IsValid(), PROCESS_IS_VALID) + + self.assertTrue( + self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + self._test_globals() + + self.process.Continue() + self.assertTrue( + self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + self.process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread.IsValid()) + frame = thread.GetSelectedFrame() + self.assertTrue(frame.IsValid()) + + self.enable_expression_log() + val = frame.EvaluateExpression("a") + self.disable_expression_log_and_check_for_locals(['a']) + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 12345) + + val = frame.EvaluateExpression("b") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 54321) + + val = frame.EvaluateExpression("c") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 34567) + + self.process.Continue() + self.assertTrue( + self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + self.process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread.IsValid()) + frame = thread.GetSelectedFrame() + self.assertTrue(frame.IsValid()) + + val = frame.EvaluateExpression("a") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 10001) + + val = frame.EvaluateExpression("b") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 10002) + + val = frame.EvaluateExpression("c") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 10003) + + self.enable_expression_log() + val = frame.EvaluateExpression("c-b") + self.disable_expression_log_and_check_for_locals(['c','b']) + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 1) + + self.process.Continue() + self.assertTrue( + self.process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + self.process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread.IsValid()) + frame = thread.GetSelectedFrame() + self.assertTrue(frame.IsValid()) + + val = frame.EvaluateExpression("a") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 1) + + val = frame.EvaluateExpression("b") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 2) + + val = frame.EvaluateExpression("c") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 778899) + + self.enable_expression_log() + val = frame.EvaluateExpression("a+b") + self.disable_expression_log_and_check_for_locals(['a','b']) + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 3) + + + def _load_exe(self): + self.build() + + cwd = os.getcwd() + + src_file = os.path.join(cwd, "main.cpp") + self.src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(self.src_file_spec.IsValid(), "breakpoint file") + + # Get the path of the executable + exe_path = self.getBuildArtifact("a.out") + + # Load the executable + self.target = self.dbg.CreateTarget(exe_path) + self.assertTrue(self.target.IsValid(), VALID_TARGET) + + def _test_globals(self): + thread = lldbutil.get_stopped_thread( + self.process, lldb.eStopReasonBreakpoint) + self.assertTrue(thread.IsValid()) + frame = thread.GetSelectedFrame() + self.assertTrue(frame.IsValid()) + + self.enable_expression_log() + val = frame.EvaluateExpression("a") + self.disable_expression_log_and_check_for_locals([]) + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 112233) + + val = frame.EvaluateExpression("b") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 445566) + + val = frame.EvaluateExpression("c") + self.assertTrue(val.IsValid()) + self.assertEqual(val.GetValueAsUnsigned(), 778899) + + def enable_expression_log(self): + log_file = os.path.join(self.getBuildDir(), "expr.log") + self.runCmd("log enable -f '%s' lldb expr" % (log_file)) + + def disable_expression_log_and_check_for_locals(self, variables): + log_file = os.path.join(self.getBuildDir(), "expr.log") + self.runCmd("log disable lldb expr") + local_var_regex = re.compile(r".*__lldb_local_vars::(.*);") + matched = [] + with open(log_file, 'r') as log: + for line in log: + if line.find('LLDB_BODY_START') != -1: + break + m = re.match(local_var_regex, line) + if m: + self.assertIn(m.group(1), variables) + matched.append(m.group(1)) + self.assertEqual([item for item in variables if item not in matched], + []) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/main.cpp new file mode 100644 index 00000000000..baf08f6a983 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/member-and-local-vars-with-same-name/main.cpp @@ -0,0 +1,73 @@ +namespace NN +{ + int a = 778899; + int b = 665544; + int c = 445566; +} + +class A +{ +public: + A(); + int Method(int a, int b); + +private: + int a, b; +}; + +A::A() : a(10), b(100) { } + +int a = 112233; +int b = 445566; +int c = 778899; + +int +A::Method(int a, int b) +{ + { + int a = 12345; + int b = 54321; + int c = 34567; + this->a = a + b + this->b; // Break 2 + } + + { + using namespace NN; + int a = 10001; + int b = 10002; + int c = 10003; + this->a = a + b + this->b; // Break 3 + } + + return this->a + this->b + a + b; // Break 4 +} + +int +Function(int a, int b) +{ + int A; + + { + int a = 12345; + int b = 54321; + int c = 34567; + A = a + b + c; // Break 5 + } + + { + using namespace NN; + int a = 10001; + int b = 10002; + int c = 10003; + A = a + b + c; // Break 6 + } + + return A + a + b; // Break 7 +} + +int +main() +{ + A obj; + return obj.Method(1, 2) + Function(1, 2); // Break 1 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Inputs/Bar.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Inputs/Bar.h new file mode 100644 index 00000000000..3d9a88c024d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Inputs/Bar.h @@ -0,0 +1 @@ +struct Bar { int success; }; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Inputs/Foo.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Inputs/Foo.h new file mode 100644 index 00000000000..1fe02e89786 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Inputs/Foo.h @@ -0,0 +1 @@ +struct Foo {}; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Inputs/module.modulemap b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Inputs/module.modulemap new file mode 100644 index 00000000000..4221d0f9134 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Inputs/module.modulemap @@ -0,0 +1,7 @@ +module Foo { + header "Foo.h" +} + +module Bar { + header "Bar.h" +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Makefile new file mode 100644 index 00000000000..3dff43b34c7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES := main.cpp +CXXFLAGS_EXTRAS = $(MANDATORY_MODULE_BUILD_CFLAGS) -I$(BUILDDIR)/include + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/TestCXXModulesImport.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/TestCXXModulesImport.py new file mode 100644 index 00000000000..e7f98c63b5e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/TestCXXModulesImport.py @@ -0,0 +1,45 @@ +"""Test that importing modules in C++ works as expected.""" + + +import unittest2 +import lldb +import shutil + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CXXModulesImportTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def build(self): + include = self.getBuildArtifact('include') + lldbutil.mkdir_p(include) + for f in ['Foo.h', 'Bar.h', 'module.modulemap']: + shutil.copyfile(self.getSourcePath(os.path.join('Inputs', f)), + os.path.join(include, f)) + super(CXXModulesImportTestCase, self).build() + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + def test_expr(self): + self.build() + target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, 'break here', lldb.SBFileSpec('main.cpp')) + + self.expect("expr -l Objective-C++ -- @import Bar") + self.expect("expr -- Bar()", substrs = ["success"]) + self.expect("expr -l Objective-C++ -- @import THIS_MODULE_DOES_NOT_EXIST", + error=True) + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + def test_expr_failing_import(self): + self.build() + shutil.rmtree(self.getBuildArtifact('include')) + target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, 'break here', lldb.SBFileSpec('main.cpp')) + + self.expect("expr -l Objective-C++ -- @import Bar", error=True) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/main.cpp new file mode 100644 index 00000000000..a6acf9a1a69 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/modules-import/main.cpp @@ -0,0 +1,7 @@ +#include "Foo.h" + +int main(int argc, char **argv) { + Foo foo; + // break here. + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/Makefile new file mode 100644 index 00000000000..638974fafd6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp ns.cpp ns2.cpp ns3.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespace.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespace.py new file mode 100644 index 00000000000..2221755fad3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespace.py @@ -0,0 +1,236 @@ +""" +Test the printing of anonymous and named namespace variables. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class NamespaceBreakpointTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(bugnumber="llvm.org/pr28548", compiler="gcc") + @expectedFailureAll(oslist=["windows"]) + def test_breakpoints_func_auto(self): + """Test that we can set breakpoints correctly by basename to find all functions whose basename is "func".""" + self.build() + + names = [ + "func()", + "func(int)", + "A::B::func()", + "A::func()", + "A::func(int)"] + + # Create a target by the debugger. + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + module_list = lldb.SBFileSpecList() + module_list.Append(lldb.SBFileSpec(exe, False)) + cu_list = lldb.SBFileSpecList() + # Set a breakpoint by name "func" which should pick up all functions + # whose basename is "func" + bp = target.BreakpointCreateByName( + "func", lldb.eFunctionNameTypeAuto, module_list, cu_list) + for bp_loc in bp: + name = bp_loc.GetAddress().GetFunction().GetName() + self.assertTrue( + name in names, + "make sure breakpoint locations are correct for 'func' with eFunctionNameTypeAuto") + + @expectedFailureAll(bugnumber="llvm.org/pr28548", compiler="gcc") + def test_breakpoints_func_full(self): + """Test that we can set breakpoints correctly by fullname to find all functions whose fully qualified name is "func" + (no namespaces).""" + self.build() + + names = ["func()", "func(int)"] + + # Create a target by the debugger. + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + module_list = lldb.SBFileSpecList() + module_list.Append(lldb.SBFileSpec(exe, False)) + cu_list = lldb.SBFileSpecList() + + # Set a breakpoint by name "func" whose fullly qualified named matches "func" which + # should pick up only functions whose basename is "func" and has no + # containing context + bp = target.BreakpointCreateByName( + "func", lldb.eFunctionNameTypeFull, module_list, cu_list) + for bp_loc in bp: + name = bp_loc.GetAddress().GetFunction().GetName() + self.assertTrue( + name in names, + "make sure breakpoint locations are correct for 'func' with eFunctionNameTypeFull") + + def test_breakpoints_a_func_full(self): + """Test that we can set breakpoints correctly by fullname to find all functions whose fully qualified name is "A::func".""" + self.build() + + names = ["A::func()", "A::func(int)"] + + # Create a target by the debugger. + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + module_list = lldb.SBFileSpecList() + module_list.Append(lldb.SBFileSpec(exe, False)) + cu_list = lldb.SBFileSpecList() + + # Set a breakpoint by name "A::func" whose fullly qualified named matches "A::func" which + # should pick up only functions whose basename is "func" and is + # contained in the "A" namespace + bp = target.BreakpointCreateByName( + "A::func", lldb.eFunctionNameTypeFull, module_list, cu_list) + for bp_loc in bp: + name = bp_loc.GetAddress().GetFunction().GetName() + self.assertTrue( + name in names, + "make sure breakpoint locations are correct for 'A::func' with eFunctionNameTypeFull") + + +class NamespaceTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers for declarations of namespace variables i and + # j. + self.line_var_i = line_number( + 'main.cpp', '// Find the line number for anonymous namespace variable i.') + self.line_var_j = line_number( + 'main.cpp', '// Find the line number for named namespace variable j.') + # And the line number to break at. + self.line_break = line_number('main.cpp', + '// Set break point at this line.') + # Break inside do {} while and evaluate value + self.line_break_ns1 = line_number('main.cpp', '// Evaluate ns1::value') + self.line_break_ns2 = line_number('main.cpp', '// Evaluate ns2::value') + + def runToBkpt(self, command): + self.runCmd(command, RUN_SUCCEEDED) + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # rdar://problem/8668674 + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") + def test_with_run_command(self): + """Test that anonymous and named namespace variables display correctly.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + "main.cpp", + self.line_break_ns1, + num_expected_locations=1, + loc_exact=True) + lldbutil.run_break_set_by_file_and_line( + self, + "main.cpp", + self.line_break_ns2, + num_expected_locations=1, + loc_exact=True) + lldbutil.run_break_set_by_file_and_line( + self, + "main.cpp", + self.line_break, + num_expected_locations=1, + loc_exact=True) + + self.runToBkpt("run") + # Evaluate ns1::value + self.expect("expression -- value", startstr="(int) $0 = 100") + + self.runToBkpt("continue") + # Evaluate ns2::value + self.expect("expression -- value", startstr="(int) $1 = 200") + + self.runToBkpt("continue") + # On Mac OS X, gcc 4.2 emits the wrong debug info with respect to + # types. + slist = ['(int) a = 12', 'anon_uint', 'a_uint', 'b_uint', 'y_uint'] + if self.platformIsDarwin() and self.getCompiler() in [ + 'clang', 'llvm-gcc']: + slist = ['(int) a = 12', + '::my_uint_t', 'anon_uint = 0', + '(A::uint_t) a_uint = 1', + '(A::B::uint_t) b_uint = 2', + '(Y::uint_t) y_uint = 3'] + + # 'frame variable' displays the local variables with type information. + self.expect('frame variable', VARIABLES_DISPLAYED_CORRECTLY, + substrs=slist) + + # 'frame variable' with basename 'i' should work. + self.expect( + "frame variable --show-declaration --show-globals i", + startstr="main.cpp:%d: (int) (anonymous namespace)::i = 3" % + self.line_var_i) + # main.cpp:12: (int) (anonymous namespace)::i = 3 + + # 'frame variable' with basename 'j' should work, too. + self.expect( + "frame variable --show-declaration --show-globals j", + startstr="main.cpp:%d: (int) A::B::j = 4" % + self.line_var_j) + # main.cpp:19: (int) A::B::j = 4 + + # 'frame variable' should support address-of operator. + self.runCmd("frame variable &i") + + # 'frame variable' with fully qualified name 'A::B::j' should work. + self.expect("frame variable A::B::j", VARIABLES_DISPLAYED_CORRECTLY, + startstr='(int) A::B::j = 4', + patterns=[' = 4']) + + # So should the anonymous namespace case. + self.expect( + "frame variable '(anonymous namespace)::i'", + VARIABLES_DISPLAYED_CORRECTLY, + startstr='(int) (anonymous namespace)::i = 3', + patterns=[' = 3']) + + # rdar://problem/8660275 + # test/namespace: 'expression -- i+j' not working + # This has been fixed. + self.expect("expression -- i + j", + startstr="(int) $2 = 7") + # (int) $2 = 7 + + self.runCmd("expression -- i") + self.runCmd("expression -- j") + + # rdar://problem/8668674 + # expression command with fully qualified namespace for a variable does + # not work + self.expect("expression -- ::i", VARIABLES_DISPLAYED_CORRECTLY, + patterns=[' = 3']) + self.expect("expression -- A::B::j", VARIABLES_DISPLAYED_CORRECTLY, + patterns=[' = 4']) + + # expression command with function in anonymous namespace + self.expect("expression -- myanonfunc(3)", + patterns=[' = 6']) + + # global namespace qualification with function in anonymous namespace + self.expect("expression -- ::myanonfunc(4)", + patterns=[' = 8']) + + self.expect("p myanonfunc", + patterns=['\(anonymous namespace\)::myanonfunc\(int\)']) + + self.expect("p variadic_sum", patterns=[ + '\(anonymous namespace\)::variadic_sum\(int, ...\)']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespaceLookup.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespaceLookup.py new file mode 100644 index 00000000000..5526a14f530 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/TestNamespaceLookup.py @@ -0,0 +1,314 @@ +""" +Test the printing of anonymous and named namespace variables. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class NamespaceLookupTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Break inside different scopes and evaluate value + self.line_break_global_scope = line_number( + 'ns.cpp', '// BP_global_scope') + self.line_break_file_scope = line_number('ns2.cpp', '// BP_file_scope') + self.line_break_ns_scope = line_number('ns2.cpp', '// BP_ns_scope') + self.line_break_nested_ns_scope = line_number( + 'ns2.cpp', '// BP_nested_ns_scope') + self.line_break_nested_ns_scope_after_using = line_number( + 'ns2.cpp', '// BP_nested_ns_scope_after_using') + self.line_break_before_using_directive = line_number( + 'ns3.cpp', '// BP_before_using_directive') + self.line_break_after_using_directive = line_number( + 'ns3.cpp', '// BP_after_using_directive') + + def runToBkpt(self, command): + self.runCmd(command, RUN_SUCCEEDED) + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr25819") + @skipIfWindows # This is flakey on Windows: llvm.org/pr38373 + def test_scope_lookup_with_run_command(self): + """Test scope lookup of functions in lldb.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + "ns.cpp", + self.line_break_global_scope, + num_expected_locations=1, + loc_exact=False) + lldbutil.run_break_set_by_file_and_line( + self, + "ns2.cpp", + self.line_break_ns_scope, + num_expected_locations=1, + loc_exact=False) + lldbutil.run_break_set_by_file_and_line( + self, + "ns2.cpp", + self.line_break_nested_ns_scope, + num_expected_locations=1, + loc_exact=False) + lldbutil.run_break_set_by_file_and_line( + self, + "ns2.cpp", + self.line_break_nested_ns_scope_after_using, + num_expected_locations=1, + loc_exact=False) + lldbutil.run_break_set_by_file_and_line( + self, + "ns3.cpp", + self.line_break_before_using_directive, + num_expected_locations=1, + loc_exact=False) + lldbutil.run_break_set_by_file_and_line( + self, + "ns3.cpp", + self.line_break_after_using_directive, + num_expected_locations=1, + loc_exact=False) + + # Run to BP_global_scope at global scope + self.runToBkpt("run") + # Evaluate func() - should call ::func() + self.expect("expr -- func()", startstr="(int) $0 = 1") + # Evaluate A::B::func() - should call A::B::func() + self.expect("expr -- A::B::func()", startstr="(int) $1 = 4") + # Evaluate func(10) - should call ::func(int) + self.expect("expr -- func(10)", startstr="(int) $2 = 11") + # Evaluate ::func() - should call A::func() + self.expect("expr -- ::func()", startstr="(int) $3 = 1") + # Evaluate A::foo() - should call A::foo() + self.expect("expr -- A::foo()", startstr="(int) $4 = 42") + + # Continue to BP_ns_scope at ns scope + self.runToBkpt("continue") + # Evaluate func(10) - should call A::func(int) + self.expect("expr -- func(10)", startstr="(int) $5 = 13") + # Evaluate B::func() - should call B::func() + self.expect("expr -- B::func()", startstr="(int) $6 = 4") + # Evaluate func() - should call A::func() + self.expect("expr -- func()", startstr="(int) $7 = 3") + + # Continue to BP_nested_ns_scope at nested ns scope + self.runToBkpt("continue") + # Evaluate func() - should call A::B::func() + self.expect("expr -- func()", startstr="(int) $8 = 4") + # Evaluate A::func() - should call A::func() + self.expect("expr -- A::func()", startstr="(int) $9 = 3") + + # Evaluate func(10) - should call A::func(10) + # NOTE: Under the rules of C++, this test would normally get an error + # because A::B::func() hides A::func(), but lldb intentionally + # disobeys these rules so that the intended overload can be found + # by only removing duplicates if they have the same type. + self.expect("expr -- func(10)", startstr="(int) $10 = 13") + + # Continue to BP_nested_ns_scope_after_using at nested ns scope after + # using declaration + self.runToBkpt("continue") + # Evaluate A::func(10) - should call A::func(int) + self.expect("expr -- A::func(10)", startstr="(int) $11 = 13") + + # Continue to BP_before_using_directive at global scope before using + # declaration + self.runToBkpt("continue") + # Evaluate ::func() - should call ::func() + self.expect("expr -- ::func()", startstr="(int) $12 = 1") + # Evaluate B::func() - should call B::func() + self.expect("expr -- B::func()", startstr="(int) $13 = 4") + + # Continue to BP_after_using_directive at global scope after using + # declaration + self.runToBkpt("continue") + # Evaluate ::func() - should call ::func() + self.expect("expr -- ::func()", startstr="(int) $14 = 1") + # Evaluate B::func() - should call B::func() + self.expect("expr -- B::func()", startstr="(int) $15 = 4") + + @unittest2.expectedFailure("lldb scope lookup of functions bugs") + def test_function_scope_lookup_with_run_command(self): + """Test scope lookup of functions in lldb.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + "ns.cpp", + self.line_break_global_scope, + num_expected_locations=1, + loc_exact=False) + lldbutil.run_break_set_by_file_and_line( + self, + "ns2.cpp", + self.line_break_ns_scope, + num_expected_locations=1, + loc_exact=False) + + # Run to BP_global_scope at global scope + self.runToBkpt("run") + # Evaluate foo() - should call ::foo() + # FIXME: lldb finds Y::foo because lookup for variables is done + # before functions. + self.expect("expr -- foo()", startstr="(int) $0 = 42") + # Evaluate ::foo() - should call ::foo() + # FIXME: lldb finds Y::foo because lookup for variables is done + # before functions and :: is ignored. + self.expect("expr -- ::foo()", startstr="(int) $1 = 42") + + # Continue to BP_ns_scope at ns scope + self.runToBkpt("continue") + # Evaluate foo() - should call A::foo() + # FIXME: lldb finds Y::foo because lookup for variables is done + # before functions. + self.expect("expr -- foo()", startstr="(int) $2 = 42") + + @unittest2.expectedFailure("lldb file scope lookup bugs") + @skipIfWindows # This is flakey on Windows: llvm.org/pr38373 + def test_file_scope_lookup_with_run_command(self): + """Test file scope lookup in lldb.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + "ns2.cpp", + self.line_break_file_scope, + num_expected_locations=1, + loc_exact=False) + + # Run to BP_file_scope at file scope + self.runToBkpt("run") + # Evaluate func() - should call static ns2.cpp:func() + # FIXME: This test fails because lldb doesn't know about file scopes so + # finds the global ::func(). + self.expect("expr -- func()", startstr="(int) $0 = 2") + + @skipIfWindows # This is flakey on Windows: llvm.org/pr38373 + def test_scope_lookup_before_using_with_run_command(self): + """Test scope lookup before using in lldb.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + "ns3.cpp", + self.line_break_before_using_directive, + num_expected_locations=1, + loc_exact=False) + + # Run to BP_before_using_directive at global scope before using + # declaration + self.runToBkpt("run") + # Evaluate func() - should call ::func() + self.expect("expr -- func()", startstr="(int) $0 = 1") + + # NOTE: this test may fail on older systems that don't emit import + # entries in DWARF - may need to add checks for compiler versions here. + @skipIf( + compiler="gcc", + oslist=["linux"], + debug_info=["dwo"]) # Skip to avoid crash + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr25819") + def test_scope_after_using_directive_lookup_with_run_command(self): + """Test scope lookup after using directive in lldb.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + "ns3.cpp", + self.line_break_after_using_directive, + num_expected_locations=1, + loc_exact=False) + + # Run to BP_after_using_directive at global scope after using + # declaration + self.runToBkpt("run") + # Evaluate func2() - should call A::func2() + self.expect("expr -- func2()", startstr="(int) $0 = 3") + + @unittest2.expectedFailure( + "lldb scope lookup after using declaration bugs") + # NOTE: this test may fail on older systems that don't emit import + # emtries in DWARF - may need to add checks for compiler versions here. + def test_scope_after_using_declaration_lookup_with_run_command(self): + """Test scope lookup after using declaration in lldb.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + "ns2.cpp", + self.line_break_nested_ns_scope_after_using, + num_expected_locations=1, + loc_exact=False) + + # Run to BP_nested_ns_scope_after_using at nested ns scope after using + # declaration + self.runToBkpt("run") + # Evaluate func() - should call A::func() + self.expect("expr -- func()", startstr="(int) $0 = 3") + + @unittest2.expectedFailure("lldb scope lookup ambiguity after using bugs") + def test_scope_ambiguity_after_using_lookup_with_run_command(self): + """Test scope lookup ambiguity after using in lldb.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + "ns3.cpp", + self.line_break_after_using_directive, + num_expected_locations=1, + loc_exact=False) + + # Run to BP_after_using_directive at global scope after using + # declaration + self.runToBkpt("run") + # Evaluate func() - should get error: ambiguous + # FIXME: This test fails because lldb removes duplicates if they have + # the same type. + self.expect("expr -- func()", startstr="error") + + @expectedFailureAll( + oslist=["freebsd"], + bugnumber="llvm.org/pr25819") + def test_scope_lookup_shadowed_by_using_with_run_command(self): + """Test scope lookup shadowed by using in lldb.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + "ns2.cpp", + self.line_break_nested_ns_scope, + num_expected_locations=1, + loc_exact=False) + + # Run to BP_nested_ns_scope at nested ns scope + self.runToBkpt("run") + # Evaluate func(10) - should call A::func(10) + # NOTE: Under the rules of C++, this test would normally get an error + # because A::B::func() shadows A::func(), but lldb intentionally + # disobeys these rules so that the intended overload can be found + # by only removing duplicates if they have the same type. + self.expect("expr -- func(10)", startstr="(int) $0 = 13") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/cmds.txt b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/cmds.txt new file mode 100644 index 00000000000..76bb1bcba75 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/cmds.txt @@ -0,0 +1,3 @@ +b main.cpp:54 +c +var diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/main.cpp new file mode 100644 index 00000000000..22c0309695c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/main.cpp @@ -0,0 +1,124 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <cstdarg> +#include <cstdlib> +#include "ns.h" + +namespace { + typedef unsigned int my_uint_t; + int i; // Find the line number for anonymous namespace variable i. + + int myanonfunc (int a) + { + return a + a; + } + + int + variadic_sum (int arg_count...) + { + int sum = 0; + std::va_list args; + va_start(args, arg_count); + + for (int i = 0; i < arg_count; i++) + sum += va_arg(args, int); + + va_end(args); + return sum; + } +} + +namespace A { + typedef unsigned int uint_t; + namespace B { + typedef unsigned int uint_t; + int j; // Find the line number for named namespace variable j. + int myfunc (int a); + int myfunc2(int a) + { + return a + 2; + } + float myfunc (float f) + { + return f - 2.0; + } + } +} + +namespace Y +{ + typedef unsigned int uint_t; + using A::B::j; + int foo; +} + +using A::B::j; // using declaration + +namespace Foo = A::B; // namespace alias + +using Foo::myfunc; // using declaration + +using namespace Foo; // using directive + +namespace A { + namespace B { + using namespace Y; + int k; + } +} + +namespace ns1 { + int value = 100; +} + +namespace ns2 { + int value = 200; +} + +void test_namespace_scopes() { + do { + using namespace ns1; + printf("ns1::value = %d\n", value); // Evaluate ns1::value + } while(0); + + do { + using namespace ns2; + printf("ns2::value = %d\n", value); // Evaluate ns2::value + } while(0); +} + +int Foo::myfunc(int a) +{ + test_namespace_scopes(); + + ::my_uint_t anon_uint = 0; + A::uint_t a_uint = 1; + B::uint_t b_uint = 2; + Y::uint_t y_uint = 3; + i = 3; + j = 4; + printf("::i=%d\n", ::i); + printf("A::B::j=%d\n", A::B::j); + printf("variadic_sum=%d\n", variadic_sum(3, 1, 2, 3)); + myanonfunc(3); + return myfunc2(3) + j + i + a + 2 + anon_uint + a_uint + b_uint + y_uint; // Set break point at this line. +} + +int +main (int argc, char const *argv[]) +{ + test_lookup_at_global_scope(); + test_lookup_at_file_scope(); + A::test_lookup_at_ns_scope(); + A::B::test_lookup_at_nested_ns_scope(); + A::B::test_lookup_at_nested_ns_scope_after_using(); + test_lookup_before_using_directive(); + test_lookup_after_using_directive(); + return Foo::myfunc(12); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns.cpp new file mode 100644 index 00000000000..481a9866fcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns.cpp @@ -0,0 +1,31 @@ +//===-- ns.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ns.h" + +int foo() +{ + std::printf("global foo()\n"); + return 42; +} +int func() +{ + std::printf("global func()\n"); + return 1; +} +int func(int a) +{ + std::printf("global func(int)\n"); + return a + 1; +} +void test_lookup_at_global_scope() +{ + // BP_global_scope + std::printf("at global scope: foo() = %d\n", foo()); // eval foo(), exp: 42 + std::printf("at global scope: func() = %d\n", func()); // eval func(), exp: 1 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns.h new file mode 100644 index 00000000000..d04b45a7d7a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns.h @@ -0,0 +1,33 @@ +//===-- ns.h ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <cstdio> + +void test_lookup_at_global_scope(); +void test_lookup_at_file_scope(); +void test_lookup_before_using_directive(); +void test_lookup_after_using_directive(); +int func(int a); +namespace A { +int foo(); +int func(int a); +inline int func() { + std::printf("A::func()\n"); + return 3; +} +inline int func2() { + std::printf("A::func2()\n"); + return 3; +} +void test_lookup_at_ns_scope(); +namespace B { +int func(); +void test_lookup_at_nested_ns_scope(); +void test_lookup_at_nested_ns_scope_after_using(); +} // namespace B +} // namespace A diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns2.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns2.cpp new file mode 100644 index 00000000000..9aae5d0a495 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns2.cpp @@ -0,0 +1,64 @@ +//===-- ns2.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ns.h" + +static int func() +{ + std::printf("static m2.cpp func()\n"); + return 2; +} +void test_lookup_at_file_scope() +{ + // BP_file_scope + std::printf("at file scope: func() = %d\n", func()); // eval func(), exp: 2 + std::printf("at file scope: func(10) = %d\n", func(10)); // eval func(10), exp: 11 +} +namespace A { + namespace B { + int func() + { + std::printf("A::B::func()\n"); + return 4; + } + void test_lookup_at_nested_ns_scope() + { + // BP_nested_ns_scope + std::printf("at nested ns scope: func() = %d\n", func()); // eval func(), exp: 4 + + //printf("func(10) = %d\n", func(10)); // eval func(10), exp: 13 + // NOTE: Under the rules of C++, this test would normally get an error + // because A::B::func() hides A::func(), but lldb intentionally + // disobeys these rules so that the intended overload can be found + // by only removing duplicates if they have the same type. + } + void test_lookup_at_nested_ns_scope_after_using() + { + // BP_nested_ns_scope_after_using + using A::func; + std::printf("at nested ns scope after using: func() = %d\n", func()); // eval func(), exp: 3 + } + } +} +int A::foo() +{ + std::printf("A::foo()\n"); + return 42; +} +int A::func(int a) +{ + std::printf("A::func(int)\n"); + return a + 3; +} +void A::test_lookup_at_ns_scope() +{ + // BP_ns_scope + std::printf("at nested ns scope: func() = %d\n", func()); // eval func(), exp: 3 + std::printf("at nested ns scope: func(10) = %d\n", func(10)); // eval func(10), exp: 13 + std::printf("at nested ns scope: foo() = %d\n", foo()); // eval foo(), exp: 42 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns3.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns3.cpp new file mode 100644 index 00000000000..0f7a5050fde --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace/ns3.cpp @@ -0,0 +1,26 @@ +//===-- ns3.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ns.h" +extern int func(); + +// Note: the following function must be before the using. +void test_lookup_before_using_directive() +{ + // BP_before_using_directive + std::printf("before using directive: func() = %d\n", func()); // eval func(), exp: 1 +} +using namespace A; +void test_lookup_after_using_directive() +{ + // BP_after_using_directive + //printf("func() = %d\n", func()); // eval func(), exp: error, amiguous + std::printf("after using directive: func2() = %d\n", func2()); // eval func2(), exp: 3 + std::printf("after using directive: ::func() = %d\n", ::func()); // eval ::func(), exp: 1 + std::printf("after using directive: B::func() = %d\n", B::func()); // eval B::func(), exp: 4 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_conflicts/TestNamespaceConflicts.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_conflicts/TestNamespaceConflicts.py new file mode 100644 index 00000000000..c8308c16011 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_conflicts/TestNamespaceConflicts.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_conflicts/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_conflicts/main.cpp new file mode 100644 index 00000000000..0349365d843 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_conflicts/main.cpp @@ -0,0 +1,28 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +namespace n { + struct D { + int i; + static int anInt() { return 2; } + int dump() { return i; } + }; +} + +using namespace n; + +int foo(D* D) { + return D->dump(); //% self.expect("expression -- D->dump()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "2"]) +} + +int main (int argc, char const *argv[]) +{ + D myD { D::anInt() }; + foo(&myD); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/Makefile new file mode 100644 index 00000000000..fc9165f67f4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/Makefile @@ -0,0 +1,15 @@ +LD_EXTRAS := -L. -la -lb +CXX_SOURCES := main.cpp + +a.out: liba libb + +include Makefile.rules + +liba: + $(MAKE) -f $(MAKEFILE_RULES) \ + DYLIB_ONLY=YES DYLIB_NAME=a DYLIB_CXX_SOURCES=a.cpp + +libb: + $(MAKE) -f $(MAKEFILE_RULES) \ + DYLIB_ONLY=YES DYLIB_NAME=b DYLIB_CXX_SOURCES=b.cpp + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py new file mode 100644 index 00000000000..e96a9fb93b7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/TestNamespaceDefinitions.py @@ -0,0 +1,73 @@ +"""Test that forward declarations don't cause bogus conflicts in namespaced types""" + + + +import unittest2 +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + + +class NamespaceDefinitionsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll( + bugnumber="llvm.org/pr28948", + compiler="gcc", + compiler_version=[ + "<", + "4.9"]) + @expectedFailureAll( + bugnumber="llvm.org/pr28948", + oslist=['linux'], compiler="gcc", archs=['arm','aarch64']) + @expectedFailureAll(oslist=["windows"]) + @expectedFailureNetBSD + def test_expr(self): + self.build() + self.common_setup() + + self.expect( + "expression -- Foo::MyClass()", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=['thing = ']) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.cpp' + self.line = line_number(self.source, '// Set breakpoint here') + self.shlib_names = ["a", "b"] + + def common_setup(self): + # Run in synchronous mode + self.dbg.SetAsync(False) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line( + self, self.source, self.line, num_expected_locations=1, loc_exact=True) + + # Register our shared libraries for remote targets so they get + # automatically uploaded + environment = self.registerSharedLibrariesWithTarget( + target, self.shlib_names) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.cpp new file mode 100644 index 00000000000..2795b206e8e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/a.cpp @@ -0,0 +1,15 @@ +//===-- a.cpp ---------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "foo.h" + +class ThingInside { + int a; +}; + +Foo::MyClass a_class; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.cpp new file mode 100644 index 00000000000..b676865c4d2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/b.cpp @@ -0,0 +1,11 @@ +//===-- b.cpp ---------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "foo.h" + +Foo::MyClass b_class; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/foo.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/foo.h new file mode 100644 index 00000000000..a2c64ab5928 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/foo.h @@ -0,0 +1,17 @@ +//===-- foo.h ---------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +class ThingInside; + +namespace Foo { + class MyClass { + ThingInside *thing; + public: + MyClass() { } + }; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/main.cpp new file mode 100644 index 00000000000..8703cd99246 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/namespace_definitions/main.cpp @@ -0,0 +1,15 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +int +main (int argc, char const *argv[]) +{ + return 0; // Set breakpoint here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/Makefile new file mode 100644 index 00000000000..020dce7c31d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp other.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/TestNestedClassWithParentInAnotherCU.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/TestNestedClassWithParentInAnotherCU.py new file mode 100644 index 00000000000..5b590d6363a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/TestNestedClassWithParentInAnotherCU.py @@ -0,0 +1,29 @@ +""" +Test that the expression evaluator can access members of nested classes even if +the parents of the nested classes were imported from another compilation unit. +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestNestedClassWithParentInAnotherCU(TestBase): + mydir = TestBase.compute_mydir(__file__) + + def test_nested_class_with_parent_in_another_cu(self): + self.main_source_file = lldb.SBFileSpec("main.cpp") + self.build() + (_, _, thread, _) = lldbutil.run_to_source_breakpoint(self, "// break here", self.main_source_file) + frame = thread.GetSelectedFrame() + # Parse the DIEs of the parent classes and the nested classes from + # other.cpp's CU. + warmup_result = frame.EvaluateExpression("b") + self.assertTrue(warmup_result.IsValid()) + # Inspect fields of the nested classes. This will reuse the types that + # were parsed during the evaluation above. By accessing a chain of + # fields, we try to verify that all the DIEs, reused types and + # declaration contexts were wired properly into lldb's parser's state. + expr_result = frame.EvaluateExpression("a.y.oY_inner.oX_inner") + self.assertTrue(expr_result.IsValid()) + self.assertEqual(expr_result.GetValue(), "42") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/main.cpp new file mode 100644 index 00000000000..8a6e6ff81d2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/main.cpp @@ -0,0 +1,22 @@ +#include "shared.h" + +struct WrapperA { + OuterY::Inner<unsigned int> y; +}; + +int main() { + // WrapperA refers to the Inner and Outer class DIEs from this CU. + WrapperA a; + // WrapperB refers to the Inner and Outer DIEs from the other.cpp CU. + // It is important that WrapperB is only forward-declared in shared.h. + WrapperB* b = foo(); + + // Evaluating 'b' here will parse other.cpp's DIEs for all + // the Inner and Outer classes from shared.h. + // + // Evaluating 'a' here will find and reuse the already-parsed + // versions of the Inner and Outer classes. In the associated test + // we make sure that we can still resolve all the types properly + // by evaluating 'a.y.oY_inner.oX_inner'. + return 0; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/other.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/other.cpp new file mode 100644 index 00000000000..71a9579c4e8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/other.cpp @@ -0,0 +1,10 @@ +#include "shared.h" + +struct WrapperB { + OuterY y; + OuterX x; +}; + +WrapperB* foo() { + return new WrapperB(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/shared.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/shared.h new file mode 100644 index 00000000000..627f49ab79c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nested-class-other-compilation-unit/shared.h @@ -0,0 +1,17 @@ +struct OuterX { + template<typename T> + struct Inner { + int oX_inner = 42; + }; +}; + +struct OuterY { + template<typename T> + struct Inner { + typename OuterX::Inner<T> oY_inner; + }; +}; + +struct WrapperB; + +WrapperB* foo(); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nsimport/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nsimport/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nsimport/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py new file mode 100644 index 00000000000..f42d194cd62 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py @@ -0,0 +1,136 @@ +""" +Tests imported namespaces in C++. +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCppNsImport(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_with_run_command(self): + """Tests imported namespaces in C++.""" + self.build() + + # Get main source file + src_file = os.path.join(self.getSourceDir(), "main.cpp") + src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(src_file_spec.IsValid(), "Main source file") + + # Get the path of the executable + exe_path = self.getBuildArtifact("a.out") + + # Load the executable + target = self.dbg.CreateTarget(exe_path) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Break on main function + break_0 = target.BreakpointCreateBySourceRegex( + "// break 0", src_file_spec) + self.assertTrue( + break_0.IsValid() and break_0.GetNumLocations() >= 1, + VALID_BREAKPOINT) + break_1 = target.BreakpointCreateBySourceRegex( + "// break 1", src_file_spec) + self.assertTrue( + break_1.IsValid() and break_1.GetNumLocations() >= 1, + VALID_BREAKPOINT) + + # Launch the process + args = None + env = None + process = target.LaunchSimple( + args, env, self.get_process_working_directory()) + self.assertTrue(process.IsValid(), PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue( + process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + + # Get current fream of the thread at the breakpoint + frame = thread.GetSelectedFrame() + + # Test imported namespaces + test_result = frame.EvaluateExpression("n") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 1, + "n = 1") + + test_result = frame.EvaluateExpression("N::n") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 1, + "N::n = 1") + + test_result = frame.EvaluateExpression("nested") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 3, + "nested = 3") + + test_result = frame.EvaluateExpression("anon") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 2, + "anon = 2") + + test_result = frame.EvaluateExpression("global") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 4, + "global = 4") + + test_result = frame.EvaluateExpression("fun_var") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 9, + "fun_var = 9") + + test_result = frame.EvaluateExpression("Fun::fun_var") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 0, + "Fun::fun_var = 0") + + test_result = frame.EvaluateExpression("not_imported") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 35, + "not_imported = 35") + + # Currently there is no way to distinguish between "::imported" and "imported" in ClangExpressionDeclMap so this fails + #test_result = frame.EvaluateExpression("::imported") + #self.assertTrue(test_result.IsValid() and test_result.GetValueAsSigned() == 89, "::imported = 89") + + test_result = frame.EvaluateExpression("Imported::imported") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 99, + "Imported::imported = 99") + + test_result = frame.EvaluateExpression("imported") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 99, + "imported = 99") + + test_result = frame.EvaluateExpression("single") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 3, + "single = 3") + + # Continue to second breakpoint + process.Continue() + + # Get the thread of the process + self.assertTrue( + process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + + # Get current fream of the thread at the breakpoint + frame = thread.GetSelectedFrame() + + # Test function inside namespace + test_result = frame.EvaluateExpression("fun_var") + self.assertTrue( + test_result.IsValid() and test_result.GetValueAsSigned() == 5, + "fun_var = 5") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nsimport/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nsimport/main.cpp new file mode 100644 index 00000000000..e125ebaa243 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/nsimport/main.cpp @@ -0,0 +1,72 @@ +namespace N +{ + int n; +} + +namespace +{ + int anon; +} + +namespace Nested +{ + namespace + { + int nested; + } +} + +namespace Global +{ + int global; +} + +namespace Fun +{ + int fun_var; + int fun() + { + fun_var = 5; + return 0; // break 1 + } +} + +namespace Single +{ + int single = 3; +} + +namespace NotImportedBefore +{ + int not_imported = 45; +} + +using namespace Global; + +int not_imported = 35; +int fun_var = 9; + +namespace NotImportedAfter +{ + int not_imported = 55; +} + +namespace Imported +{ + int imported = 99; +} + +int imported = 89; + +int main() +{ + using namespace N; + using namespace Nested; + using namespace Imported; + using Single::single; + n = 1; + anon = 2; + nested = 3; + global = 4; + return Fun::fun(); // break 0 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/offsetof/TestOffsetofCpp.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/offsetof/TestOffsetofCpp.py new file mode 100644 index 00000000000..cdfbaae0ce3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/offsetof/TestOffsetofCpp.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), [decorators.no_debug_info_test]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/offsetof/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/offsetof/main.cpp new file mode 100644 index 00000000000..ab379f839c8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/offsetof/main.cpp @@ -0,0 +1,25 @@ +#include <cstdint> + +class Base { + int32_t a; +}; +class Class1 : Base { +public: + int32_t b; +}; + +class EmptyBase { +}; +class Class2 : EmptyBase { +public: + int32_t b; +}; + +int main(int argc, char **argv) { + Class1 c1; + Class2 c2; + //% self.expect("expr offsetof(Base, a)", substrs=["= 0"]) + //% self.expect("expr offsetof(Class1, b)", substrs=["= 4"]) + //% self.expect("expr offsetof(Class2, b)", substrs=["= 0"]) + return c1.b + c2.b; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/Makefile new file mode 100644 index 00000000000..80b3ee02c3e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/Makefile @@ -0,0 +1,6 @@ +CXX_SOURCES = a.cpp b.cpp + +include Makefile.rules + +a.o: a.cpp + $(CC) $(CFLAGS_NO_DEBUG) -c $< -o $@ diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/TestOperatorOverload.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/TestOperatorOverload.py new file mode 100644 index 00000000000..f541a6617e3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/TestOperatorOverload.py @@ -0,0 +1,22 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestOperatorOverload(TestBase): + mydir = TestBase.compute_mydir(__file__) + + def test_overload(self): + self.build() + (target, process, thread, + main_breakpoint) = lldbutil.run_to_source_breakpoint(self, + "break here", lldb.SBFileSpec("b.cpp")) + frame = thread.GetSelectedFrame() + value = frame.EvaluateExpression("x == nil") + self.assertTrue(str(value.GetError()) + .find("comparison between NULL and non-pointer ('Tinky' and NULL)") + != -1) + self.assertTrue(str(value.GetError()) + .find("invalid operands to binary expression ('Tinky' and") + != -1) + self.assertFalse(value.GetError().Success()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/a.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/a.cpp new file mode 100644 index 00000000000..77b2f6ace82 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/a.cpp @@ -0,0 +1,9 @@ +class Patatino { +public: + double _blah; + Patatino(int blah) : _blah(blah) {} +}; + +bool operator==(const Patatino& a, const Patatino& b) { + return a._blah < b._blah; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/b.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/b.cpp new file mode 100644 index 00000000000..c0eb29bb79f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operator-overload/b.cpp @@ -0,0 +1,10 @@ +class Tinky { +public: + int _meh; + Tinky(int meh) : _meh(meh) {} +}; + +int main(void) { + Tinky x(12); + return 0; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/TestCppOperators.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/TestCppOperators.py new file mode 100644 index 00000000000..c8308c16011 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/TestCppOperators.py @@ -0,0 +1,4 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/main.cpp new file mode 100644 index 00000000000..892d0bae42a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/operators/main.cpp @@ -0,0 +1,181 @@ +#include <cstdlib> + +int side_effect = 0; + +struct B { int dummy = 2324; }; +struct C { + void *operator new(size_t size) { C* r = ::new C; r->custom_new = true; return r; } + void *operator new[](size_t size) { C* r = static_cast<C*>(std::malloc(size)); r->custom_new = true; return r; } + void operator delete(void *p) { std::free(p); side_effect = 1; } + void operator delete[](void *p) { std::free(p); side_effect = 2; } + + bool custom_new = false; + B b; + B* operator->() { return &b; } + int operator->*(int) { return 2; } + int operator+(int) { return 44; } + int operator+=(int) { return 42; } + int operator++(int) { return 123; } + int operator++() { return 1234; } + int operator-(int) { return 34; } + int operator-=(int) { return 32; } + int operator--() { return 321; } + int operator--(int) { return 4321; } + + int operator*(int) { return 51; } + int operator*=(int) { return 52; } + int operator%(int) { return 53; } + int operator%=(int) { return 54; } + int operator/(int) { return 55; } + int operator/=(int) { return 56; } + int operator^(int) { return 57; } + int operator^=(int) { return 58; } + + int operator|(int) { return 61; } + int operator|=(int) { return 62; } + int operator||(int) { return 63; } + int operator&(int) { return 64; } + int operator&=(int) { return 65; } + int operator&&(int) { return 66; } + + int operator~() { return 71; } + int operator!() { return 72; } + int operator!=(int) { return 73; } + int operator=(int) { return 74; } + int operator==(int) { return 75; } + + int operator<(int) { return 81; } + int operator<<(int) { return 82; } + int operator<=(int) { return 83; } + int operator<<=(int) { return 84; } + int operator>(int) { return 85; } + int operator>>(int) { return 86; } + int operator>=(int) { return 87; } + int operator>>=(int) { return 88; } + + int operator,(int) { return 2012; } + int operator&() { return 2013; } + + int operator()(int) { return 91; } + int operator[](int) { return 92; } + + operator int() { return 11; } + operator long() { return 12; } + + // Make sure this doesn't collide with + // the real operator int. + int operatorint() { return 13; } + int operatornew() { return 14; } +}; + +int main(int argc, char **argv) { + C c; + int result = c->dummy; + result = c->*4; + result += c+1; + result += c+=1; + result += c++; + result += ++c; + result += c-1; + result += c-=1; + result += c--; + result += --c; + + result += c * 4; + result += c *= 4; + result += c % 4; + result += c %= 4; + result += c / 4; + result += c /= 4; + result += c ^ 4; + result += c ^= 4; + + result += c | 4; + result += c |= 4; + result += c || 4; + result += c & 4; + result += c &= 4; + result += c && 4; + + result += ~c; + result += !c; + result += c!=1; + result += c=2; + result += c==2; + + result += c<2; + result += c<<2; + result += c<=2; + result += c<<=2; + result += c>2; + result += c>>2; + result += c>=2; + result += c>>=2; + + result += (c , 2); + result += &c; + + result += c(1); + result += c[1]; + + result += static_cast<int>(c); + result += static_cast<long>(c); + result += c.operatorint(); + result += c.operatornew(); + + C *c2 = new C(); + C *c3 = new C[3]; + + //% self.expect("expr c->dummy", endstr=" 2324\n") + //% self.expect("expr c->*2", endstr=" 2\n") + //% self.expect("expr c + 44", endstr=" 44\n") + //% self.expect("expr c += 42", endstr=" 42\n") + //% self.expect("expr c++", endstr=" 123\n") + //% self.expect("expr ++c", endstr=" 1234\n") + //% self.expect("expr c - 34", endstr=" 34\n") + //% self.expect("expr c -= 32", endstr=" 32\n") + //% self.expect("expr c--", endstr=" 4321\n") + //% self.expect("expr --c", endstr=" 321\n") + //% self.expect("expr c * 3", endstr=" 51\n") + //% self.expect("expr c *= 3", endstr=" 52\n") + //% self.expect("expr c % 3", endstr=" 53\n") + //% self.expect("expr c %= 3", endstr=" 54\n") + //% self.expect("expr c / 3", endstr=" 55\n") + //% self.expect("expr c /= 3", endstr=" 56\n") + //% self.expect("expr c ^ 3", endstr=" 57\n") + //% self.expect("expr c ^= 3", endstr=" 58\n") + //% self.expect("expr c | 3", endstr=" 61\n") + //% self.expect("expr c |= 3", endstr=" 62\n") + //% self.expect("expr c || 3", endstr=" 63\n") + //% self.expect("expr c & 3", endstr=" 64\n") + //% self.expect("expr c &= 3", endstr=" 65\n") + //% self.expect("expr c && 3", endstr=" 66\n") + //% self.expect("expr ~c", endstr=" 71\n") + //% self.expect("expr !c", endstr=" 72\n") + //% self.expect("expr c!=1", endstr=" 73\n") + //% self.expect("expr c=1", endstr=" 74\n") + //% self.expect("expr c==1", endstr=" 75\n") + //% self.expect("expr c<1", endstr=" 81\n") + //% self.expect("expr c<<1", endstr=" 82\n") + //% self.expect("expr c<=1", endstr=" 83\n") + //% self.expect("expr c<<=1", endstr=" 84\n") + //% self.expect("expr c>1", endstr=" 85\n") + //% self.expect("expr c>>1", endstr=" 86\n") + //% self.expect("expr c>=1", endstr=" 87\n") + //% self.expect("expr c>>=1", endstr=" 88\n") + //% self.expect("expr c,1", endstr=" 2012\n") + //% self.expect("expr &c", endstr=" 2013\n") + //% self.expect("expr c(1)", endstr=" 91\n") + //% self.expect("expr c[1]", endstr=" 92\n") + //% self.expect("expr static_cast<int>(c)", endstr=" 11\n") + //% self.expect("expr static_cast<long>(c)", endstr=" 12\n") + //% self.expect("expr c.operatorint()", endstr=" 13\n") + //% self.expect("expr c.operatornew()", endstr=" 14\n") + //% self.expect("expr (new C)->custom_new", endstr=" true\n") + //% self.expect("expr (new struct C[1])->custom_new", endstr=" true\n") + //% self.expect("expr delete c2; side_effect", endstr=" = 1\n") + //% self.expect("expr delete[] c3; side_effect", endstr=" = 2\n") + delete c2; + delete[] c3; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/Makefile new file mode 100644 index 00000000000..1185ed0c1e8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp static-a.cpp static-b.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/TestOverloadedFunctions.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/TestOverloadedFunctions.py new file mode 100644 index 00000000000..ad969ef3d08 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/TestOverloadedFunctions.py @@ -0,0 +1,38 @@ +""" +Tests that functions with the same name are resolved correctly. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class OverloadedFunctionsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + self.line = line_number('main.cpp', '// breakpoint') + + def test_with_run_command(self): + """Test that functions with the same name are resolved correctly""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("process launch", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", + STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', 'stop reason = breakpoint']) + + self.expect("expression -- Dump(myB)", + startstr="(int) $0 = 2") + + self.expect("expression -- Static()", + startstr="(int) $1 = 1") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/main.cpp new file mode 100644 index 00000000000..250e2cd1d96 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/main.cpp @@ -0,0 +1,43 @@ +#include <stdio.h> + +struct A { + int aa; + char ab; +}; + +struct B { + int ba; + int bb; +}; + +struct C { + int ca; + int cb; +}; + +int Dump (A &a) +{ + return 1; +} + +int Dump (B &b) +{ + return 2; +} + +int Dump (C &c) +{ + return 3; +} + +extern int CallStaticA(); +extern int CallStaticB(); + +int main() +{ + A myA; + B myB; + C myC; + + printf("%d\n", CallStaticA() + CallStaticB()); // breakpoint +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/static-a.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/static-a.cpp new file mode 100644 index 00000000000..7250fa4bed5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/static-a.cpp @@ -0,0 +1,9 @@ +static int Static() +{ + return 1; +} + +int CallStaticA() +{ + return Static(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/static-b.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/static-b.cpp new file mode 100644 index 00000000000..90a20f69e6d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/overloaded-functions/static-b.cpp @@ -0,0 +1,9 @@ +static int Static() +{ + return 1; +} + +int CallStaticB() +{ + return Static(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/printf/TestPrintf.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/printf/TestPrintf.py new file mode 100644 index 00000000000..10e400f4e72 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/printf/TestPrintf.py @@ -0,0 +1,8 @@ +from lldbsuite.test import lldbinline, lldbplatformutil +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.expectedFailureAll( + bugnumber="llvm.org/PR36715", + oslist=lldbplatformutil.getDarwinOSTriples()+['windows'])]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/printf/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/printf/main.cpp new file mode 100644 index 00000000000..27395eb6f41 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/printf/main.cpp @@ -0,0 +1,20 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +class PrintfContainer { +public: + int printf() { + return 0; + } +}; + +int main() { + PrintfContainer().printf(); //% self.expect("expression -- printf(\"Hello\\n\")", substrs = ['6']) + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/Makefile new file mode 100644 index 00000000000..e891bb25dd9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/Makefile @@ -0,0 +1,5 @@ +CXX_SOURCES := main.cpp + +CXXFLAGS_EXTRAS := -std=c++11 + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/TestRvalueReferences.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/TestRvalueReferences.py new file mode 100644 index 00000000000..5e31d93eb16 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/TestRvalueReferences.py @@ -0,0 +1,53 @@ +""" +Tests that rvalue references are supported in C++ +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class RvalueReferencesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # rdar://problem/11479676 + @expectedFailureAll( + compiler="icc", + bugnumber="ICC (13.1, 14-beta) do not emit DW_TAG_rvalue_reference_type.") + def test_with_run_command(self): + """Test that rvalues are supported in the C++ expression parser""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + self.set_breakpoint(line_number('main.cpp', '// breakpoint 1')) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 2')) + + self.runCmd("process launch", RUN_SUCCEEDED) + + # Note that clang as of r187480 doesn't emit DW_TAG_const_type, unlike gcc 4.8.1 + # With gcc 4.8.1, lldb reports the type as (int &&const) + self.expect("frame variable i", + startstr="(int &&", + substrs=["i = 0x", "&i = 3"]) + + self.expect("expression -- i", + startstr="(int) ", + substrs=["3"]) + + self.expect("breakpoint delete 1") + + self.runCmd("process continue") + + self.expect("expression -- foo(2)") + + self.expect("expression -- int &&j = 3; foo(j)", + error=True) + + self.expect("expression -- int &&k = 6; k", + startstr="(int) $1 = 6") + + def set_breakpoint(self, line): + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", line, num_expected_locations=1, loc_exact=True) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/main.cpp new file mode 100644 index 00000000000..6da34c73f10 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/rvalue-references/main.cpp @@ -0,0 +1,12 @@ +#include <stdio.h> + +void foo (int &&i) +{ + printf("%d\n", i); // breakpoint 1 +} + +int main() +{ + foo(3); + return 0; // breakpoint 2 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/scope/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/scope/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/scope/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py new file mode 100644 index 00000000000..213e7fbe902 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/scope/TestCppScope.py @@ -0,0 +1,91 @@ +""" +Test scopes in C++. +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCppScopes(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") + def test_all_but_c(self): + self.do_test(False) + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24764") + def test_c(self): + self.do_test(True) + + def do_test(self, test_c): + self.build() + + # Get main source file + src_file = os.path.join(self.getSourceDir(), "main.cpp") + src_file_spec = lldb.SBFileSpec(src_file) + self.assertTrue(src_file_spec.IsValid(), "Main source file") + + # Get the path of the executable + exe_path = self.getBuildArtifact("a.out") + + # Load the executable + target = self.dbg.CreateTarget(exe_path) + self.assertTrue(target.IsValid(), VALID_TARGET) + + # Break on main function + main_breakpoint = target.BreakpointCreateBySourceRegex( + "// break here", src_file_spec) + self.assertTrue( + main_breakpoint.IsValid() and main_breakpoint.GetNumLocations() >= 1, + VALID_BREAKPOINT) + + # Launch the process + args = None + env = None + process = target.LaunchSimple( + args, env, self.get_process_working_directory()) + self.assertTrue(process.IsValid(), PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue( + process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + + # Get current fream of the thread at the breakpoint + frame = thread.GetSelectedFrame() + + # Test result for scopes of variables + + global_variables = frame.GetVariables(True, True, True, False) + global_variables_assert = { + 'A::a': 1111, + 'B::a': 2222, + 'C::a': 3333, + '::a': 4444, + 'a': 4444 + } + + self.assertTrue( + global_variables.GetSize() == 4, + "target variable returns all variables") + for variable in global_variables: + name = variable.GetName() + self.assertTrue( + name in global_variables_assert, + "target variable returns wrong variable " + name) + + for name in global_variables_assert: + if name is "C::a" and not test_c: + continue + if name is not "C::a" and test_c: + continue + + value = frame.EvaluateExpression(name) + assert_value = global_variables_assert[name] + self.assertTrue( + value.IsValid() and value.GetValueAsSigned() == assert_value, + name + " = " + str(assert_value)) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/scope/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/scope/main.cpp new file mode 100644 index 00000000000..da5d7ed529d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/scope/main.cpp @@ -0,0 +1,25 @@ +class A { +public: + static int a; + int b; +}; + +class B { +public: + static int a; + int b; +}; + +struct C { + static int a; +}; + +int A::a = 1111; +int B::a = 2222; +int C::a = 3333; +int a = 4444; + +int main() // break here +{ + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/signed_types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/signed_types/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/signed_types/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/signed_types/TestSignedTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/signed_types/TestSignedTypes.py new file mode 100644 index 00000000000..f61cd64130d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/signed_types/TestSignedTypes.py @@ -0,0 +1,66 @@ +""" +Test that variables with signed types display correctly. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class SignedTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.cpp' + self.line = line_number( + self.source, '// Set break point at this line.') + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489") + def test(self): + """Test that variables with signed types display correctly.""" + self.build() + + # Run in synchronous mode + self.dbg.SetAsync(False) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + lldbutil.run_break_set_by_file_and_line( + self, self.source, self.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()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', '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']) + + # Execute the puts(). + self.runCmd("thread step-over") + + # Test that signed types display correctly. + self.expect( + "frame variable --show-types --no-args", + VARIABLES_DISPLAYED_CORRECTLY, + patterns=[ + "\((short int|short)\) the_signed_short = 99", + "\((signed char|char)\) the_signed_char = 'c'"], + substrs=[ + "(int) the_signed_int = 99", + "(long) the_signed_long = 99", + "(long long) the_signed_long_long = 99"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/signed_types/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/signed_types/main.cpp new file mode 100644 index 00000000000..4f180bbbd13 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/signed_types/main.cpp @@ -0,0 +1,32 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <stdio.h> + +int main (int argc, char const *argv[]) +{ + char the_char = 'c'; + short the_short = 'c'; + wchar_t the_wchar_t = 'c'; + int the_int = 'c'; + long the_long = 'c'; + long long the_long_long = 'c'; + + signed char the_signed_char = 'c'; + signed short the_signed_short = 'c'; + signed int the_signed_int = 'c'; + signed long the_signed_long = 'c'; + signed long long the_signed_long_long = 'c'; + puts(""); // Set break point at this line. + return the_char - the_signed_char + + the_short - the_signed_short + + the_int - the_signed_int + + the_long - the_signed_long + + the_long_long - the_signed_long_long; //// break $source:$line; c + //// var the_int + //// val -set 22 1 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_members/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_members/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_members/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_members/TestCPPStaticMembers.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_members/TestCPPStaticMembers.py new file mode 100644 index 00000000000..4e02ebe8965 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_members/TestCPPStaticMembers.py @@ -0,0 +1,61 @@ +""" +Tests that C++ member and static variables have correct layout and scope. +""" + + + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CPPStaticMembersTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @unittest2.expectedFailure # llvm.org/pr15401 + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr21765") + def test_with_run_command(self): + """Test that member variables have the correct layout, scope and qualifiers when stopped inside and outside C++ methods""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + self.set_breakpoint(line_number('main.cpp', '// breakpoint 1')) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 2')) + + self.runCmd("process launch", RUN_SUCCEEDED) + self.expect("expression my_a.access()", + startstr="(long) $0 = 10") + + self.expect("expression my_a.m_a", + startstr="(short) $1 = 1") + + # Note: SymbolFileDWARF::ParseChildMembers doesn't call + # AddFieldToRecordType, consistent with clang's AST layout. + self.expect("expression my_a.s_d", + startstr="(int) $2 = 4") + + self.expect("expression my_a.s_b", + startstr="(long) $3 = 2") + + self.expect("expression A::s_b", + startstr="(long) $4 = 2") + + # should not be available in global scope + self.expect("expression s_d", + startstr="error: use of undeclared identifier 's_d'") + + self.runCmd("process continue") + self.expect("expression m_c", + startstr="(char) $5 = \'\\x03\'") + + self.expect("expression s_b", + startstr="(long) $6 = 2") + + self.runCmd("process continue") + + def set_breakpoint(self, line): + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", line, num_expected_locations=1, loc_exact=False) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_members/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_members/main.cpp new file mode 100644 index 00000000000..ab8ae1b645f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_members/main.cpp @@ -0,0 +1,35 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +struct A +{ + short m_a; + static long s_b; + char m_c; + static int s_d; + + long access() { + return m_a + s_b + m_c + s_d; // breakpoint 2 + } +}; + +long A::s_b = 2; +int A::s_d = 4; + +int main() +{ + A my_a; + my_a.m_a = 1; + my_a.m_c = 3; + + my_a.access(); // breakpoint 1 + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_methods/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_methods/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_methods/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_methods/TestCPPStaticMethods.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_methods/TestCPPStaticMethods.py new file mode 100644 index 00000000000..4b422674134 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_methods/TestCPPStaticMethods.py @@ -0,0 +1,38 @@ +""" +Tests expressions that distinguish between static and non-static methods. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CPPStaticMethodsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + TestBase.setUp(self) + self.line = line_number('main.cpp', '// Break at this line') + + def test_with_run_command(self): + """Test that static methods are properly distinguished from regular methods""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("process launch", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", + STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', 'stop reason = breakpoint']) + + self.expect("expression -- A::getStaticValue()", + startstr="(int) $0 = 5") + + self.expect("expression -- my_a.getMemberValue()", + startstr="(int) $1 = 3") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_methods/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_methods/main.cpp new file mode 100644 index 00000000000..4c57e09296c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/static_methods/main.cpp @@ -0,0 +1,37 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +class A +{ +public: + static int getStaticValue(); + int getMemberValue(); + int a; +}; + +int A::getStaticValue() +{ + return 5; +} + +int A::getMemberValue() +{ + return a; +} + +int main() +{ + A my_a; + + my_a.a = 3; + + printf("%d\n", A::getStaticValue()); // Break at this line + printf("%d\n", my_a.getMemberValue()); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/std-function-step-into-callable/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/std-function-step-into-callable/Makefile new file mode 100644 index 00000000000..b016f006747 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/std-function-step-into-callable/Makefile @@ -0,0 +1,5 @@ +CXX_SOURCES := main.cpp +CXXFLAGS_EXTRAS := -std=c++11 +USE_LIBCPP := 1 + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/std-function-step-into-callable/TestStdFunctionStepIntoCallable.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/std-function-step-into-callable/TestStdFunctionStepIntoCallable.py new file mode 100644 index 00000000000..d667321493e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/std-function-step-into-callable/TestStdFunctionStepIntoCallable.py @@ -0,0 +1,71 @@ +""" +Test stepping into std::function +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class LibCxxFunctionSteppingIntoCallableTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + NO_DEBUG_INFO_TESTCASE = True + + @add_test_categories(["libc++"]) + def test(self): + """Test that std::function as defined by libc++ is correctly printed by LLDB""" + self.build() + + self.main_source = "main.cpp" + self.main_source_spec = lldb.SBFileSpec(self.main_source) + self.source_foo_line = line_number( + self.main_source, '// Source foo start line') + self.source_lambda_f2_line = line_number( + self.main_source, '// Source lambda used by f2 start line') + self.source_lambda_f3_line = line_number( + self.main_source, '// Source lambda used by f3 start line') + self.source_bar_operator_line = line_number( + self.main_source, '// Source Bar::operator()() start line') + self.source_bar_add_num_line = line_number( + self.main_source, '// Source Bar::add_num start line') + self.source_main_invoking_f1 = line_number( + self.main_source, '// Source main invoking f1') + + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "// Set break point at this line.", self.main_source_spec) + + thread.StepInto() + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetLine(), self.source_main_invoking_f1 ) ; + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec().GetFilename(), self.main_source) ; + + thread.StepInto() + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetLine(), self.source_foo_line ) ; + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec().GetFilename(), self.main_source) ; + process.Continue() + + thread.StepInto() + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetLine(), self.source_lambda_f2_line ) ; + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec().GetFilename(), self.main_source) ; + process.Continue() + + thread.StepInto() + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetLine(), self.source_lambda_f3_line ) ; + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec().GetFilename(), self.main_source) ; + process.Continue() + + # TODO reenable this case when std::function formatter supports + # general callable object case. + #thread.StepInto() + #self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetLine(), self.source_bar_operator_line ) ; + #self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec().GetFilename(), self.main_source) ; + #process.Continue() + + thread.StepInto() + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetLine(), self.source_bar_add_num_line ) ; + self.assertEqual( thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec().GetFilename(), self.main_source) ; + process.Continue() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/std-function-step-into-callable/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/std-function-step-into-callable/main.cpp new file mode 100644 index 00000000000..ebbb05e6d13 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/std-function-step-into-callable/main.cpp @@ -0,0 +1,40 @@ +#include <functional> + +int foo(int x, int y) { + return x + y - 1; // Source foo start line +} + +struct Bar { + int operator()() { + return 66 ; // Source Bar::operator()() start line + } + int add_num(int i) const { return i + 3 ; } // Source Bar::add_num start line + int num_ = 0 ; +} ; + +int main (int argc, char *argv[]) +{ + int acc = 42; + std::function<int (int,int)> f1 = foo; + std::function<int (int)> f2 = [acc,f1] (int x) -> int { + return x+f1(acc,x); // Source lambda used by f2 start line + }; + + auto f = [](int x, int y) { return x + y; }; // Source lambda used by f3 start line + auto g = [](int x, int y) { return x * y; } ; + std::function<int (int,int)> f3 = argc %2 ? f : g ; + + Bar bar1 ; + std::function<int ()> f4( bar1 ) ; + std::function<int (const Bar&, int)> f5 = &Bar::add_num; + std::function<int(Bar const&)> f_mem = &Bar::num_; + + return f_mem(bar1) + // Set break point at this line. + f1(acc,acc) + // Source main invoking f1 + f2(acc) + // Set break point at this line. + f3(acc+1,acc+2) + // Set break point at this line. + // TODO reenable this case when std::function formatter supports + // general callable object case. + //f4() + // Set break point at this line. + f5(bar1, 10); // Set break point at this line. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/Makefile new file mode 100644 index 00000000000..a4b03ae0aab --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/Makefile @@ -0,0 +1,6 @@ +CXX_SOURCES := main.cpp +CFLAGS := -g -O0 + +clean: OBJECTS+=$(wildcard main.d.*) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py new file mode 100644 index 00000000000..341b205389f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/TestSTL.py @@ -0,0 +1,122 @@ +""" +Test some expressions involving STL data types. +""" + + + +import unittest2 +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class STLTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.cpp' + self.line = line_number( + self.source, '// Set break point at this line.') + + @skipIf + @expectedFailureAll(bugnumber="llvm.org/PR36713") + def test(self): + """Test some expressions involving STL data types.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # The following two lines, if uncommented, will enable loggings. + #self.ci.HandleCommand("log enable -f /tmp/lldb.log lldb default", res) + # self.assertTrue(res.Succeeded()) + + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # Stop at 'std::string hello_world ("Hello World!");'. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['main.cpp:%d' % self.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']) + + # Now try some expressions.... + + self.runCmd( + 'expr for (int i = 0; i < hello_world.length(); ++i) { (void)printf("%c\\n", hello_world[i]); }') + + self.expect('expr associative_array.size()', + substrs=[' = 3']) + self.expect('expr associative_array.count(hello_world)', + substrs=[' = 1']) + self.expect('expr associative_array[hello_world]', + substrs=[' = 1']) + self.expect('expr associative_array["hello"]', + substrs=[' = 2']) + + @expectedFailureAll( + compiler="icc", + bugnumber="ICC (13.1, 14-beta) do not emit DW_TAG_template_type_parameter.") + @add_test_categories(['pyapi']) + def test_SBType_template_aspects(self): + """Test APIs for getting template arguments from an SBType.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # Get Frame #0. + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + + # Get the type for variable 'associative_array'. + associative_array = frame0.FindVariable('associative_array') + self.DebugSBValue(associative_array) + self.assertTrue(associative_array, VALID_VARIABLE) + map_type = associative_array.GetType() + self.DebugSBType(map_type) + self.assertTrue(map_type, VALID_TYPE) + num_template_args = map_type.GetNumberOfTemplateArguments() + self.assertTrue(num_template_args > 0) + + # We expect the template arguments to contain at least 'string' and + # 'int'. + expected_types = {'string': False, 'int': False} + for i in range(num_template_args): + t = map_type.GetTemplateArgumentType(i) + self.DebugSBType(t) + self.assertTrue(t, VALID_TYPE) + name = t.GetName() + if 'string' in name: + expected_types['string'] = True + elif 'int' == name: + expected_types['int'] = True + + # Check that both entries of the dictionary have 'True' as the value. + self.assertTrue(all(expected_types.values())) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/TestStdCXXDisassembly.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/TestStdCXXDisassembly.py new file mode 100644 index 00000000000..49aa16ce106 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/TestStdCXXDisassembly.py @@ -0,0 +1,114 @@ +""" +Test the lldb disassemble command on lib stdc++. +""" + +from __future__ import print_function + + +import unittest2 +import os +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * + +class StdCXXDisassembleTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.cpp', '// Set break point at this line.') + + @skipIfWindows + @expectedFailureNetBSD + def test_stdcxx_disasm(self): + """Do 'disassemble' on each and every 'Code' symbol entry from the std c++ lib.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # rdar://problem/8543077 + # test/stl: clang built binaries results in the breakpoint locations = 3, + # is this a problem with clang generated debug info? + # + # Break on line 13 of main.cpp. + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # Now let's get the target as well as the process objects. + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + + # The process should be in a 'stopped' state. + self.expect(str(process), STOPPED_DUE_TO_BREAKPOINT, exe=False, + substrs=["a.out", + "stopped"]) + + # Disassemble the functions on the call stack. + self.runCmd("thread backtrace") + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertIsNotNone(thread) + depth = thread.GetNumFrames() + for i in range(depth - 1): + frame = thread.GetFrameAtIndex(i) + function = frame.GetFunction() + if function.GetName(): + self.runCmd("disassemble -n '%s'" % function.GetName()) + + lib_stdcxx = "FAILHORRIBLYHERE" + # Iterate through the available modules, looking for stdc++ library... + for i in range(target.GetNumModules()): + module = target.GetModuleAtIndex(i) + fs = module.GetFileSpec() + if (fs.GetFilename().startswith("libstdc++") + or fs.GetFilename().startswith("libc++")): + lib_stdcxx = str(fs) + break + + # At this point, lib_stdcxx is the full path to the stdc++ library and + # module is the corresponding SBModule. + + self.expect(lib_stdcxx, "Libraray StdC++ is located", exe=False, + substrs=["lib"]) + + self.runCmd("image dump symtab '%s'" % lib_stdcxx) + raw_output = self.res.GetOutput() + # Now, look for every 'Code' symbol and feed its load address into the + # command: 'disassemble -s load_address -e end_address', where the + # end_address is taken from the next consecutive 'Code' symbol entry's + # load address. + # + # The load address column comes after the file address column, with both + # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits. + codeRE = re.compile(r""" + \ Code\ {9} # ' Code' followed by 9 SPCs, + 0x[0-9a-f]{16} # the file address column, and + \ # a SPC, and + (0x[0-9a-f]{16}) # the load address column, and + .* # the rest. + """, re.VERBOSE) + # Maintain a start address variable; if we arrive at a consecutive Code + # entry, then the load address of the that entry is fed as the end + # address to the 'disassemble -s SA -e LA' command. + SA = None + for line in raw_output.split(os.linesep): + match = codeRE.search(line) + if match: + LA = match.group(1) + if self.TraceOn(): + print("line:", line) + print("load address:", LA) + print("SA:", SA) + if SA and LA: + if int(LA, 16) > int(SA, 16): + self.runCmd("disassemble -s %s -e %s" % (SA, LA)) + SA = LA + else: + # This entry is not a Code entry. Reset SA = None. + SA = None diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/cmds.txt b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/cmds.txt new file mode 100644 index 00000000000..9c9c2e3db57 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/cmds.txt @@ -0,0 +1,3 @@ +b main.cpp:6 +continue +var diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/main.cpp new file mode 100644 index 00000000000..89895196b15 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/stl/main.cpp @@ -0,0 +1,29 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <cstdio> +#include <iostream> +#include <string> +#include <map> +int main (int argc, char const *argv[]) +{ + std::string hello_world ("Hello World!"); + std::cout << hello_world << std::endl; + std::cout << hello_world.length() << std::endl; + std::cout << hello_world[11] << std::endl; + + std::map<std::string, int> associative_array; + std::cout << "size of upon construction associative_array: " << associative_array.size() << std::endl; + associative_array[hello_world] = 1; + associative_array["hello"] = 2; + associative_array["world"] = 3; + + std::cout << "size of associative_array: " << associative_array.size() << std::endl; + printf("associative_array[\"hello\"]=%d\n", associative_array["hello"]); + + printf("before returning....\n"); // Set break point at this line. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py new file mode 100644 index 00000000000..af362f5be5d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py @@ -0,0 +1,7 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.expectedFailureAll( + oslist=["windows"], bugnumber="llvm.org/pr24764")]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp new file mode 100644 index 00000000000..cbd3ab253d6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp @@ -0,0 +1,39 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +void *D = 0; + +class D { + static int i; +}; + +int D::i = 3; + +namespace errno { + int j = 4; +}; + +int twice(int n) +{ + return n * 2; //% self.expect("expression -- D::i", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "3"]) + //% self.expect("expression -- D", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["void"]) + //% self.expect("expression -- errno::j", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "4"]) +} + +const char getAChar() +{ + const char D[] = "Hello world"; + return D[0]; //% self.expect("expression -- D::i", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "3"]) + //% self.expect("expression -- D", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["char", "Hello"]) +} + +int main (int argc, char const *argv[]) +{ + int six = twice(3); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template-function/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template-function/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template-function/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template-function/TestTemplateFunctions.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template-function/TestTemplateFunctions.py new file mode 100644 index 00000000000..6c9a0ac35f4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template-function/TestTemplateFunctions.py @@ -0,0 +1,32 @@ +""" +Test that we can call C++ template fucntions. +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TemplateFunctionsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def do_test_template_function(self, add_cast): + self.build() + (_, _, thread, _) = lldbutil.run_to_name_breakpoint(self, "main") + frame = thread.GetSelectedFrame() + expr = "foo(42)" + if add_cast: + expr = "(int)" + expr + expr_result = frame.EvaluateExpression(expr) + self.assertTrue(expr_result.IsValid()) + self.assertEqual(expr_result.GetValue(), "42") + + @skipIfWindows + def test_template_function_with_cast(self): + self.do_test_template_function(True) + + @skipIfWindows + @expectedFailureAll(debug_info=["dwarf", "gmodules", "dwo"]) + def test_template_function_without_cast(self): + self.do_test_template_function(False) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template-function/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template-function/main.cpp new file mode 100644 index 00000000000..035e6450cd3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template-function/main.cpp @@ -0,0 +1,16 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +template<typename T> +int foo(T t1) { + return int(t1); +} + +int main() { + return foo(42); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py new file mode 100644 index 00000000000..08132702b8d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template/TestTemplateArgs.py @@ -0,0 +1,158 @@ +""" +Test that C++ template classes that have integer parameters work correctly. + +We must reconstruct the types correctly so the template types are correct +and display correctly, and also make sure the expression parser works and +is able the find all needed functions when evaluating expressions +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TemplateArgsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def prepareProcess(self): + self.build() + + # Create a target by the debugger. + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set breakpoints inside and outside methods that take pointers to the + # containing struct. + line = line_number('main.cpp', '// Breakpoint 1') + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", line, num_expected_locations=1, loc_exact=True) + + arguments = None + environment = None + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + arguments, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # Get the thread of the process + self.assertTrue( + process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + + # Get frame for current thread + return thread.GetSelectedFrame() + + def test_integer_args(self): + frame = self.prepareProcess() + + testpos = frame.FindVariable('testpos') + self.assertTrue( + testpos.IsValid(), + 'make sure we find a local variabble named "testpos"') + self.assertTrue(testpos.GetType().GetName() == 'TestObj<1>') + + expr_result = frame.EvaluateExpression("testpos.getArg()") + self.assertTrue( + expr_result.IsValid(), + 'got a valid expression result from expression "testpos.getArg()"') + self.assertTrue(expr_result.GetValue() == "1", "testpos.getArg() == 1") + self.assertTrue( + expr_result.GetType().GetName() == "int", + 'expr_result.GetType().GetName() == "int"') + + testneg = frame.FindVariable('testneg') + self.assertTrue( + testneg.IsValid(), + 'make sure we find a local variabble named "testneg"') + self.assertTrue(testneg.GetType().GetName() == 'TestObj<-1>') + + expr_result = frame.EvaluateExpression("testneg.getArg()") + self.assertTrue( + expr_result.IsValid(), + 'got a valid expression result from expression "testneg.getArg()"') + self.assertTrue( + expr_result.GetValue() == "-1", + "testneg.getArg() == -1") + self.assertTrue( + expr_result.GetType().GetName() == "int", + 'expr_result.GetType().GetName() == "int"') + + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489") + def test_template_template_args(self): + frame = self.prepareProcess() + + c1 = frame.FindVariable('c1') + self.assertTrue( + c1.IsValid(), + 'make sure we find a local variabble named "c1"') + self.assertTrue(c1.GetType().GetName() == 'C<float, T1>') + f1 = c1.GetChildMemberWithName("V").GetChildAtIndex(0).GetChildMemberWithName("f") + self.assertTrue(f1.GetType().GetName() == 'float') + self.assertTrue(f1.GetValue() == '1.5') + + c2 = frame.FindVariable('c2') + self.assertTrue( + c2.IsValid(), + 'make sure we find a local variabble named "c2"') + self.assertTrue(c2.GetType().GetName() == 'C<double, T1, T2>') + f2 = c2.GetChildMemberWithName("V").GetChildAtIndex(0).GetChildMemberWithName("f") + self.assertTrue(f2.GetType().GetName() == 'double') + self.assertTrue(f2.GetValue() == '1.5') + f3 = c2.GetChildMemberWithName("V").GetChildAtIndex(1).GetChildMemberWithName("f") + self.assertTrue(f3.GetType().GetName() == 'double') + self.assertTrue(f3.GetValue() == '2.5') + f4 = c2.GetChildMemberWithName("V").GetChildAtIndex(1).GetChildMemberWithName("i") + self.assertTrue(f4.GetType().GetName() == 'int') + self.assertTrue(f4.GetValue() == '42') + + # Gcc does not generate the necessary DWARF attribute for enum template + # parameters. + @expectedFailureAll(bugnumber="llvm.org/pr28354", compiler="gcc") + @skipIf(dwarf_version=['<', '4']) + def test_enum_args(self): + frame = self.prepareProcess() + + # Make sure "member" can be displayed and also used in an expression + # correctly + member = frame.FindVariable('member') + self.assertTrue( + member.IsValid(), + 'make sure we find a local variabble named "member"') + self.assertTrue(member.GetType().GetName() == + 'EnumTemplate<EnumType::Member>') + + expr_result = frame.EvaluateExpression("member.getMember()") + self.assertTrue( + expr_result.IsValid(), + 'got a valid expression result from expression "member.getMember()"') + self.assertTrue( + expr_result.GetValue() == "123", + "member.getMember() == 123") + self.assertTrue( + expr_result.GetType().GetName() == "int", + 'expr_result.GetType().GetName() == "int"') + + # Make sure "subclass" can be displayed and also used in an expression + # correctly + subclass = frame.FindVariable('subclass') + self.assertTrue( + subclass.IsValid(), + 'make sure we find a local variabble named "subclass"') + self.assertTrue(subclass.GetType().GetName() == + 'EnumTemplate<EnumType::Subclass>') + + expr_result = frame.EvaluateExpression("subclass.getMember()") + self.assertTrue( + expr_result.IsValid(), + 'got a valid expression result from expression "subclass.getMember()"') + self.assertTrue( + expr_result.GetValue() == "246", + "subclass.getMember() == 246") + self.assertTrue( + expr_result.GetType().GetName() == "int", + 'expr_result.GetType().GetName() == "int"') diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp new file mode 100644 index 00000000000..445a34fe067 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/template/main.cpp @@ -0,0 +1,78 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <tuple> + +template <int Arg> +class TestObj +{ +public: + int getArg() + { + return Arg; + } +}; + +//---------------------------------------------------------------------- +// Define a template class that we can specialize with an enumeration +//---------------------------------------------------------------------- +enum class EnumType +{ + Member, + Subclass +}; + +template <EnumType Arg> class EnumTemplate; + +//---------------------------------------------------------------------- +// Specialization for use when "Arg" is "EnumType::Member" +//---------------------------------------------------------------------- +template <> +class EnumTemplate<EnumType::Member> +{ +public: + EnumTemplate(int m) : + m_member(m) + { + } + + int getMember() const + { + return m_member; + } + +protected: + int m_member; +}; + +//---------------------------------------------------------------------- +// Specialization for use when "Arg" is "EnumType::Subclass" +//---------------------------------------------------------------------- +template <> +class EnumTemplate<EnumType::Subclass> : + public EnumTemplate<EnumType::Member> +{ +public: + EnumTemplate(int m) : EnumTemplate<EnumType::Member>(m) + { + } +}; + +template <typename FLOAT> struct T1 { FLOAT f = 1.5; }; +template <typename FLOAT> struct T2 { FLOAT f = 2.5; int i = 42; }; +template <typename FLOAT, template <typename> class ...Args> class C { std::tuple<Args<FLOAT>...> V; }; + +int main(int argc, char **argv) +{ + TestObj<1> testpos; + TestObj<-1> testneg; + EnumTemplate<EnumType::Member> member(123); + EnumTemplate<EnumType::Subclass> subclass(123*2); + C<float, T1> c1; + C<double, T1, T2> c2; + return testpos.getArg() - testneg.getArg() + member.getMember()*2 - subclass.getMember(); // Breakpoint 1 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/this/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/this/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/this/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/this/TestCPPThis.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/this/TestCPPThis.py new file mode 100644 index 00000000000..ab95627729d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/this/TestCPPThis.py @@ -0,0 +1,61 @@ +""" +Tests that C++ member and static variables are available where they should be. +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class CPPThisTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # rdar://problem/9962849 + @expectedFailureAll( + compiler="gcc", + bugnumber="llvm.org/pr15439 The 'this' pointer isn't available during expression evaluation when stopped in an inlined member function") + @expectedFailureAll( + compiler="icc", + bugnumber="ICC doesn't emit correct DWARF inline debug info for inlined member functions.") + @expectedFailureAll( + oslist=["windows"], + bugnumber="llvm.org/pr24489: Name lookup not working correctly on Windows") + @expectedFailureNetBSD + def test_with_run_command(self): + """Test that the appropriate member variables are available when stopped in C++ static, inline, and const methods""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + self.set_breakpoint(line_number('main.cpp', '// breakpoint 1')) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 2')) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 3')) + self.set_breakpoint(line_number('main.cpp', '// breakpoint 4')) + + self.runCmd("process launch", RUN_SUCCEEDED) + + self.expect("expression -- m_a = 2", + startstr="(int) $0 = 2") + + self.runCmd("process continue") + + # This would be disallowed if we enforced const. But we don't. + self.expect("expression -- m_a = 2", + startstr="(int) $1 = 2") + + self.expect("expression -- (int)getpid(); m_a", + startstr="(int) $2 = 2") + + self.runCmd("process continue") + + self.expect("expression -- s_a", + startstr="(int) $3 = 5") + + self.runCmd("process continue") + + self.expect("expression -- m_a", + startstr="(int) $4 = 2") + + def set_breakpoint(self, line): + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", line, num_expected_locations=1, loc_exact=False) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/this/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/this/main.cpp new file mode 100644 index 00000000000..4026de0222f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/this/main.cpp @@ -0,0 +1,52 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +template <class T> class A +{ +public: + void accessMember(T a); + T accessMemberConst() const; + static int accessStaticMember(); + + void accessMemberInline(T a) __attribute__ ((always_inline)) + { + m_a = a; // breakpoint 4 + } + + T m_a; + static int s_a; +}; + +template <class T> int A<T>::s_a = 5; + +template <class T> void A<T>::accessMember(T a) +{ + m_a = a; // breakpoint 1 +} + +template <class T> T A<T>::accessMemberConst() const +{ + return m_a; // breakpoint 2 +} + +template <class T> int A<T>::accessStaticMember() +{ + return s_a; // breakpoint 3 +} + +int main() +{ + A<int> my_a; + + my_a.accessMember(3); + my_a.accessMemberConst(); + A<int>::accessStaticMember(); + my_a.accessMemberInline(5); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/thread_local/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/thread_local/Makefile new file mode 100644 index 00000000000..3d0b98f13f3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/thread_local/Makefile @@ -0,0 +1,2 @@ +CXX_SOURCES := main.cpp +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/thread_local/TestThreadLocal.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/thread_local/TestThreadLocal.py new file mode 100644 index 00000000000..5152c0010d1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/thread_local/TestThreadLocal.py @@ -0,0 +1,6 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest(__file__, globals(), + lldbinline.expectedFailureAll(oslist=[ + "windows", "linux", "netbsd"])) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/thread_local/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/thread_local/main.cpp new file mode 100644 index 00000000000..1855b7c5f34 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/thread_local/main.cpp @@ -0,0 +1,17 @@ +int storage = 45; +thread_local int tl_global_int = 123; +thread_local int *tl_global_ptr = &storage; + +int main(int argc, char **argv) { + //% self.expect("expr tl_local_int", error=True, substrs=["couldn't get the value of variable tl_local_int"]) + //% self.expect("expr *tl_local_ptr", error=True, substrs=["couldn't get the value of variable tl_local_ptr"]) + thread_local int tl_local_int = 321; + thread_local int *tl_local_ptr = nullptr; + tl_local_ptr = &tl_local_int; + tl_local_int++; + //% self.expect("expr tl_local_int + 1", substrs=["int", "= 323"]) + //% self.expect("expr *tl_local_ptr + 2", substrs=["int", "= 324"]) + //% self.expect("expr tl_global_int", substrs=["int", "= 123"]) + //% self.expect("expr *tl_global_ptr", substrs=["int", "= 45"]) + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py new file mode 100644 index 00000000000..2a8a78a45ff --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/TestTrivialABI.py @@ -0,0 +1,72 @@ +""" +Test that we work properly with classes with the trivial_abi attribute +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestTrivialABI(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + @skipUnlessSupportedTypeAttribute("trivial_abi") + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr37995") + @expectedFailureAll(archs=["aarch64"], oslist=["linux"], + bugnumber="llvm.org/pr44161") + def test_call_trivial(self): + """Test that we can print a variable & call a function with a trivial ABI class.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.cpp") + self.expr_test(True) + + @skipUnlessSupportedTypeAttribute("trivial_abi") + # fixed for SysV-x86_64 ABI, but not Windows-x86_64 + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr36870") + @expectedFailureAll(archs=["aarch64"], oslist=["linux"], + bugnumber="llvm.org/pr44161") + @expectedFailureAll(archs=["arm64", "arm64e"], bugnumber="<rdar://problem/57844240>") + def test_call_nontrivial(self): + """Test that we can print a variable & call a function on the same class w/o the trivial ABI marker.""" + self.build() + self.main_source_file = lldb.SBFileSpec("main.cpp") + self.expr_test(False) + + def check_value(self, test_var, ivar_value): + self.assertTrue(test_var.GetError().Success(), "Invalid valobj: %s"%(test_var.GetError().GetCString())) + ivar = test_var.GetChildMemberWithName("ivar") + self.assertTrue(test_var.GetError().Success(), "Failed to fetch ivar") + self.assertEqual(ivar_value, ivar.GetValueAsSigned(), "Got the right value for ivar") + + def check_frame(self, thread): + frame = thread.frames[0] + inVal_var = frame.FindVariable("inVal") + self.check_value(inVal_var, 10) + + options = lldb.SBExpressionOptions() + inVal_expr = frame.EvaluateExpression("inVal", options) + self.check_value(inVal_expr, 10) + + thread.StepOut() + outVal_ret = thread.GetStopReturnValue() + self.check_value(outVal_ret, 30) + + def expr_test(self, trivial): + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, + "Set a breakpoint here", self.main_source_file) + + # Stop in a function that takes a trivial value, and try both frame var & expr to get its value: + if trivial: + self.check_frame(thread) + return + + # Now continue to the same thing without the trivial_abi and see if we get that right: + threads = lldbutil.continue_to_breakpoint(process, bkpt) + self.assertEqual(len(threads), 1, "Hit my breakpoint the second time.") + + self.check_frame(threads[0]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/main.cpp new file mode 100644 index 00000000000..b1f50159692 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/trivial_abi/main.cpp @@ -0,0 +1,35 @@ +struct __attribute__((trivial_abi)) S_Trivial { + ~S_Trivial() {} + int ivar = 10; +}; + +S_Trivial takeTrivial(S_Trivial inVal) +{ + S_Trivial ret_val = inVal; + ret_val.ivar = 30; + return ret_val; // Set a breakpoint here +} + +struct S_NotTrivial { + ~S_NotTrivial() {} + int ivar = 10; +}; + +S_NotTrivial takeNotTrivial(S_NotTrivial inVal) +{ + S_NotTrivial ret_val = inVal; + ret_val.ivar = 30; + return ret_val; // Set a breakpoint here +} + +int +main() +{ + S_Trivial inVal, outVal; + outVal = takeTrivial(inVal); + + S_NotTrivial inNotVal, outNotVal; + outNotVal = takeNotTrivial(inNotVal); + + return 0; // Set another for return value +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/type_lookup/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/type_lookup/Makefile new file mode 100644 index 00000000000..3d0b98f13f3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/type_lookup/Makefile @@ -0,0 +1,2 @@ +CXX_SOURCES := main.cpp +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/type_lookup/TestCppTypeLookup.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/type_lookup/TestCppTypeLookup.py new file mode 100644 index 00000000000..45be73118f8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/type_lookup/TestCppTypeLookup.py @@ -0,0 +1,93 @@ +""" +Test that we can lookup types correctly in the expression parser +""" + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * +from lldbsuite.test import decorators + +class TestCppTypeLookup(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def check_value(self, value, ivar_name, ivar_value): + self.assertTrue(value.GetError().Success(), + "Invalid valobj: %s" % ( + value.GetError().GetCString())) + ivar = value.GetChildMemberWithName(ivar_name) + self.assertTrue(ivar.GetError().Success(), + "Failed to fetch ivar named '%s'" % (ivar_name)) + self.assertEqual(ivar_value, + ivar.GetValueAsSigned(), + "Got the right value for ivar") + + def test_namespace_only(self): + """ + Test that we fail to lookup a struct type that exists only in a + namespace. + """ + self.build() + self.main_source_file = lldb.SBFileSpec("main.cpp") + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "Set a breakpoint here", self.main_source_file) + + # Get frame for current thread + frame = thread.GetSelectedFrame() + + # We are testing LLDB's type lookup machinery, but if we inject local + # variables, the types for those will be found because they have been + # imported through the variable, not because the type lookup worked. + self.runCmd("settings set target.experimental.inject-local-vars false") + + # Make sure we don't accidentally accept structures that exist only + # in namespaces when evaluating expressions with top level types. + # Prior to the revision that added this test, we would accidentally + # accept types from namespaces, so this will ensure we don't regress + # to that behavior again + expr_result = frame.EvaluateExpression("*((namespace_only *)&i)") + self.assertTrue(expr_result.GetError().Fail(), + "'namespace_only' exists in namespace only") + + # Make sure we can find the correct type in a namespace "nsp_a" + expr_result = frame.EvaluateExpression("*((nsp_a::namespace_only *)&i)") + self.check_value(expr_result, "a", 123) + # Make sure we can find the correct type in a namespace "nsp_b" + expr_result = frame.EvaluateExpression("*((nsp_b::namespace_only *)&i)") + self.check_value(expr_result, "b", 123) + + # Make sure we can find the correct type in the root namespace + expr_result = frame.EvaluateExpression("*((namespace_and_file *)&i)") + self.check_value(expr_result, "ff", 123) + # Make sure we can find the correct type in a namespace "nsp_a" + expr_result = frame.EvaluateExpression( + "*((nsp_a::namespace_and_file *)&i)") + self.check_value(expr_result, "aa", 123) + # Make sure we can find the correct type in a namespace "nsp_b" + expr_result = frame.EvaluateExpression( + "*((nsp_b::namespace_and_file *)&i)") + self.check_value(expr_result, "bb", 123) + + # Make sure we don't accidentally accept structures that exist only + # in namespaces when evaluating expressions with top level types. + # Prior to the revision that added this test, we would accidentally + # accept types from namespaces, so this will ensure we don't regress + # to that behavior again + expr_result = frame.EvaluateExpression("*((in_contains_type *)&i)") + self.assertTrue(expr_result.GetError().Fail(), + "'in_contains_type' exists in struct only") + + # Make sure we can find the correct type in the root namespace + expr_result = frame.EvaluateExpression( + "*((contains_type::in_contains_type *)&i)") + self.check_value(expr_result, "fff", 123) + # Make sure we can find the correct type in a namespace "nsp_a" + expr_result = frame.EvaluateExpression( + "*((nsp_a::contains_type::in_contains_type *)&i)") + self.check_value(expr_result, "aaa", 123) + # Make sure we can find the correct type in a namespace "nsp_b" + expr_result = frame.EvaluateExpression( + "*((nsp_b::contains_type::in_contains_type *)&i)") + self.check_value(expr_result, "bbb", 123) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/type_lookup/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/type_lookup/main.cpp new file mode 100644 index 00000000000..f2803e36152 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/type_lookup/main.cpp @@ -0,0 +1,66 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// In this test, we define struct that exist might exist at the different +// levels in the code and test that we can properly locate these types with +// a varienty of different expressions. + +namespace nsp_a { + struct namespace_only { + int a; + }; + struct namespace_and_file { + int aa; + }; + struct contains_type { + struct in_contains_type { + int aaa; + }; + }; +}; +namespace nsp_b { + struct namespace_only { + int b; + }; + struct namespace_and_file { + int bb; + }; + struct contains_type { + struct in_contains_type { + int bbb; + }; + }; +}; + +struct namespace_and_file { + int ff; +}; + +struct contains_type { + struct in_contains_type { + int fff; + }; +}; + + +int main (int argc, char const *argv[]) { + nsp_a::namespace_only a_namespace_only = { 1 }; + nsp_a::namespace_and_file a_namespace_and_file = { 2 }; + nsp_a::contains_type::in_contains_type a_in_contains_type = { 3 }; + nsp_b::namespace_only b_namespace_only = { 11 }; + nsp_b::namespace_and_file b_namespace_and_file = { 22 }; + nsp_b::contains_type::in_contains_type b_in_contains_type = { 33 }; + namespace_and_file file_namespace_and_file = { 44 }; + contains_type::in_contains_type file_in_contains_type = { 55 }; + int i = 123; // Provide an integer that can be used for casting + // Take address of "i" to ensure it is in memory + if (&i == &argc) { + i = -1; + } + return i == -1; // Set a breakpoint here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/Makefile new file mode 100644 index 00000000000..bf443d855ce --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/Makefile @@ -0,0 +1,6 @@ +CXX_SOURCES := main.cpp +CFLAGS := -g -O0 -std=c++11 + +clean: OBJECTS+=$(wildcard main.d.*) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/TestUnicodeLiterals.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/TestUnicodeLiterals.py new file mode 100644 index 00000000000..c1bd892447a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/TestUnicodeLiterals.py @@ -0,0 +1,83 @@ +# coding=utf8 +""" +Test that the expression parser returns proper Unicode strings. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +# this test case fails because of rdar://12991846 +# the expression parser does not deal correctly with Unicode expressions +# e.g. +#(lldb) expr L"Hello" +#(const wchar_t [6]) $0 = { +# [0] = \0\0\0\0 +# [1] = \0\0\0\0 +# [2] = \0\0\0\0 +# [3] = \0\0\0\0 +# [4] = H\0\0\0 +# [5] = e\0\0\0 +#} + + +class UnicodeLiteralsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_expr1(self): + """Test that the expression parser returns proper Unicode strings.""" + self.build() + self.rdar12991846(expr=1) + + def test_expr2(self): + """Test that the expression parser returns proper Unicode strings.""" + self.build() + self.rdar12991846(expr=2) + + def test_expr3(self): + """Test that the expression parser returns proper Unicode strings.""" + self.build() + self.rdar12991846(expr=3) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.source = 'main.cpp' + self.line = line_number( + self.source, '// Set break point at this line.') + + def rdar12991846(self, expr=None): + """Test that the expression parser returns proper Unicode strings.""" + if self.getArchitecture() in ['i386']: + self.skipTest( + "Skipping because this test is known to crash on i386") + + exe = self.getBuildArtifact("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.cpp. + lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line) + + # 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") + + if expr == 1: + self.expect('expression L"hello"', substrs=['hello']) + + if expr == 2: + self.expect('expression u"hello"', substrs=['hello']) + + if expr == 3: + self.expect('expression U"hello"', substrs=['hello']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/main.cpp new file mode 100644 index 00000000000..a98fb44e5f4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unicode-literals/main.cpp @@ -0,0 +1,20 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + + +int main (int argc, char const *argv[]) +{ + auto cs16 = u"hello world ྒྙྐ"; + auto cs32 = U"hello world ྒྙྐ"; + char16_t *s16 = (char16_t *)u"ﺸﺵۻ"; + char32_t *s32 = (char32_t *)U"ЕЙРГЖО"; + s32 = nullptr; // Set break point at this line. + s32 = (char32_t *)U"෴"; + s16 = (char16_t *)u"色ハ匂ヘト散リヌルヲ"; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unique-types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unique-types/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unique-types/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unique-types/TestUniqueTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unique-types/TestUniqueTypes.py new file mode 100644 index 00000000000..78121c14970 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unique-types/TestUniqueTypes.py @@ -0,0 +1,65 @@ +""" +Test that template instaniations of std::vector<long> and <short> in the same module have the correct types. +""" + + + +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + + +class UniqueTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number inside main.cpp. + self.line = line_number( + "main.cpp", + "// Set breakpoint here to verify that std::vector 'longs' and 'shorts' have unique types.") + + def test(self): + """Test for unique types of std::vector<long> and std::vector<short>.""" + self.build() + + compiler = self.getCompiler() + compiler_basename = os.path.basename(compiler) + + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=-1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Do a "frame variable --show-types longs" and verify "long" is in each + # line of output. + self.runCmd("frame variable --show-types longs") + output = self.res.GetOutput() + for x in [line.strip() for line in output.split(os.linesep)]: + # Skip empty line, closing brace, and messages about more variables + # than can be displayed. + if not x or x == '}' or x == '...' or "Some of your variables have more members than the debugger will show by default" in x: + continue + self.expect(x, "Expect type 'long'", exe=False, + substrs=['long']) + + # Do a "frame variable --show-types shorts" and verify "short" is in + # each line of output. + self.runCmd("frame variable --show-types shorts") + output = self.res.GetOutput() + for x in [line.strip() for line in output.split(os.linesep)]: + # Skip empty line, closing brace, and messages about more variables + # than can be displayed. + if not x or x == '}' or x == '...' or "Some of your variables have more members than the debugger will show by default" in x: + continue + self.expect(x, "Expect type 'short'", exe=False, + substrs=['short']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unique-types/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unique-types/main.cpp new file mode 100644 index 00000000000..839fd93f764 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unique-types/main.cpp @@ -0,0 +1,23 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include <vector> + +#include <stdio.h> +#include <stdint.h> + +int main (int argc, char const *argv[], char const *envp[]) +{ + std::vector<long> longs; + std::vector<short> shorts; + for (int i=0; i<12; i++) + { + longs.push_back(i); + shorts.push_back(i); + } + return 0; // Set breakpoint here to verify that std::vector 'longs' and 'shorts' have unique types. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/TestUnsignedTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/TestUnsignedTypes.py new file mode 100644 index 00000000000..ca754f470da --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/TestUnsignedTypes.py @@ -0,0 +1,60 @@ +""" +Test that variables with unsigned types display correctly. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class UnsignedTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.cpp', '// Set break point at this line.') + + def test(self): + """Test that variables with unsigned types display correctly.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # GCC puts a breakpoint on the last line of a multi-line expression, so + # if GCC is the target compiler, we cannot rely on an exact line match. + need_exact = "gcc" not in self.getCompiler() + # Break on line 19 in main() after the variables are assigned values. + lldbutil.run_break_set_by_file_and_line( + self, + "main.cpp", + self.line, + num_expected_locations=-1, + loc_exact=need_exact) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', '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']) + + # Test that unsigned types display correctly. + self.expect( + "frame variable --show-types --no-args", + VARIABLES_DISPLAYED_CORRECTLY, + patterns=["\((short unsigned int|unsigned short)\) the_unsigned_short = 99"], + substrs=[ + "(unsigned char) the_unsigned_char = 'c'", + "(unsigned int) the_unsigned_int = 99", + "(unsigned long) the_unsigned_long = 99", + "(unsigned long long) the_unsigned_long_long = 99", + "(uint32_t) the_uint32 = 99"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/main.cpp new file mode 100644 index 00000000000..8d0a0c386e3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/unsigned_types/main.cpp @@ -0,0 +1,21 @@ +//===-- main.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +int main (int argc, char const *argv[]) +{ + typedef unsigned int uint32_t; + unsigned char the_unsigned_char = 'c'; + unsigned short the_unsigned_short = 'c'; + unsigned int the_unsigned_int = 'c'; + unsigned long the_unsigned_long = 'c'; + unsigned long long the_unsigned_long_long = 'c'; + uint32_t the_uint32 = 'c'; + + return the_unsigned_char - the_unsigned_short + // Set break point at this line. + the_unsigned_int - the_unsigned_long + + the_unsigned_long_long - the_uint32; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual-overload/TestVirtualOverload.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual-overload/TestVirtualOverload.py new file mode 100644 index 00000000000..1311a149326 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual-overload/TestVirtualOverload.py @@ -0,0 +1,3 @@ +from lldbsuite.test import lldbinline + +lldbinline.MakeInlineTest(__file__, globals()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual-overload/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual-overload/main.cpp new file mode 100644 index 00000000000..79c482352f9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual-overload/main.cpp @@ -0,0 +1,17 @@ +// Test that lldb doesn't get confused by an overload of a virtual +// function of the same name. +struct Base { + virtual void f(int i) {} + virtual ~Base() {} +}; + +struct Derived : Base { + virtual void f(int i, int j) {} +}; + +int main(int argc, char **argv) { + Derived obj; + obj.f(1, 2); //% self.expect("fr var", "not crashing", substrs = ["obj"]) + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py new file mode 100644 index 00000000000..22fe96b96d2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual/TestVirtual.py @@ -0,0 +1,101 @@ +""" +Test C++ virtual function and virtual inheritance. +""" + +import os +import re +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +def Msg(expr, val): + return "'expression %s' matches the output (from compiled code): %s" % ( + expr, val) + + +class CppVirtualMadness(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + # This is the pattern by design to match the "my_expr = 'value'" output from + # printf() stmts (see main.cpp). + pattern = re.compile("^([^=]*) = '([^=]*)'$") + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.source = 'main.cpp' + self.line = line_number(self.source, '// Set first breakpoint here.') + + @expectedFailureAll( + compiler="icc", + bugnumber="llvm.org/pr16808 lldb does not call the correct virtual function with icc.") + @skipIfWindows # This test will hang on windows llvm.org/pr21753 + @expectedFlakeyNetBSD + def test_virtual_madness(self): + """Test that expression works correctly with virtual inheritance as well as virtual function.""" + self.build() + + # Bring the program to the point where we can issue a series of + # 'expression' command to compare against the golden output. + self.dbg.SetAsync(False) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + self.assertTrue(process.GetState() == lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + + # First, capture the golden output from the program itself. + golden = thread.GetFrameAtIndex(0).FindVariable("golden") + self.assertTrue( + golden.IsValid(), + "Encountered an error reading the process's golden variable") + error = lldb.SBError() + golden_str = process.ReadCStringFromMemory( + golden.AddressOf().GetValueAsUnsigned(), 4096, error) + self.assertTrue(error.Success()) + self.assertTrue("c_as_C" in golden_str) + + # 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 golden_str.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) + + # Now iterate through the golden list, comparing against the output from + # 'expression var'. + for my_expr, val in gl: + + 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]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual/main.cpp new file mode 100644 index 00000000000..0adf4157731 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/virtual/main.cpp @@ -0,0 +1,116 @@ +#include <stdio.h> +#include <stdint.h> + +class A +{ +public: + A () : m_pad ('c') {} + + virtual ~A () {} + + virtual const char * a() + { + return __PRETTY_FUNCTION__; + } + + virtual const char * b() + { + return __PRETTY_FUNCTION__; + } + + virtual const char * c() + { + return __PRETTY_FUNCTION__; + } +protected: + char m_pad; +}; + +class AA +{ +public: + AA () : m_pad('A') {} + virtual ~AA () {} + + virtual const char * aa() + { + return __PRETTY_FUNCTION__; + } + +protected: + char m_pad; +}; + +class B : virtual public A, public AA +{ +public: + B () : m_pad ('c') {} + + virtual ~B () {} + + virtual const char * a() + { + return __PRETTY_FUNCTION__; + } + + virtual const char * b() + { + return __PRETTY_FUNCTION__; + } +protected: + char m_pad; +}; + +class C : public B, virtual public A +{ +public: + C () : m_pad ('c') {} + + virtual ~C () {} + + virtual const char * a() + { + return __PRETTY_FUNCTION__; + } +protected: + char m_pad; +}; + +int main (int argc, char const *argv[], char const *envp[]) +{ + A *a_as_A = new A(); + B *b_as_B = new B(); + A *b_as_A = b_as_B; + C *c_as_C = new C(); + A *c_as_A = c_as_C; + + char golden[4096]; + char *p = golden; + char *end = p + sizeof golden; + p += snprintf(p, end-p, "a_as_A->a() = '%s'\n", a_as_A->a()); + p += snprintf(p, end-p, "a_as_A->b() = '%s'\n", a_as_A->b()); + p += snprintf(p, end-p, "a_as_A->c() = '%s'\n", a_as_A->c()); + p += snprintf(p, end-p, "b_as_A->a() = '%s'\n", b_as_A->a()); + p += snprintf(p, end-p, "b_as_A->b() = '%s'\n", b_as_A->b()); + p += snprintf(p, end-p, "b_as_A->c() = '%s'\n", b_as_A->c()); + p += snprintf(p, end-p, "b_as_B->aa() = '%s'\n", b_as_B->aa()); + p += snprintf(p, end-p, "c_as_A->a() = '%s'\n", c_as_A->a()); + p += snprintf(p, end-p, "c_as_A->b() = '%s'\n", c_as_A->b()); + p += snprintf(p, end-p, "c_as_A->c() = '%s'\n", c_as_A->c()); + p += snprintf(p, end-p, "c_as_C->aa() = '%s'\n", c_as_C->aa()); + puts("");// Set first breakpoint here. + // then evaluate: + // expression a_as_A->a() + // expression a_as_A->b() + // expression a_as_A->c() + // expression b_as_A->a() + // expression b_as_A->b() + // expression b_as_A->c() + // expression b_as_B->aa() + // expression c_as_A->a() + // expression c_as_A->b() + // expression c_as_A->c() + // expression c_as_C->aa() + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/.categories new file mode 100644 index 00000000000..fe1da0247c6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/.categories @@ -0,0 +1 @@ +dataformatters diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/Makefile new file mode 100644 index 00000000000..a4b03ae0aab --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/Makefile @@ -0,0 +1,6 @@ +CXX_SOURCES := main.cpp +CFLAGS := -g -O0 + +clean: OBJECTS+=$(wildcard main.d.*) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/TestCxxWCharT.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/TestCxxWCharT.py new file mode 100644 index 00000000000..b59d71e8e8e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/TestCxxWCharT.py @@ -0,0 +1,77 @@ +# coding=utf8 +""" +Test that C++ supports wchar_t correctly. +""" + + + +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class CxxWCharTTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.cpp. + self.source = 'main.cpp' + self.line = line_number( + self.source, '// Set break point at this line.') + + def test(self): + """Test that C++ supports wchar_t correctly.""" + self.build() + exe = self.getBuildArtifact("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.cpp. + lldbutil.run_break_set_by_file_and_line(self, "main.cpp", self.line) + + # 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") + + # Check that we correctly report templates on wchar_t + self.expect("frame variable foo_y", + substrs=['(Foo<wchar_t>) foo_y = ']) + + # Check that we correctly report templates on int + self.expect("frame variable foo_x", + substrs=['(Foo<int>) foo_x = ']) + + # Check that we correctly report wchar_t + self.expect("frame variable foo_y.object", + substrs=['(wchar_t) foo_y.object = ']) + + # Check that we correctly report int + self.expect("frame variable foo_x.object", + substrs=['(int) foo_x.object = ']) + + # Check that we can run expressions that return wchar_t + self.expect("expression L'a'", substrs=['(wchar_t) $', "L'a'"]) + + # Mazel Tov if this works! + self.expect("frame variable mazeltov", + substrs=['(const wchar_t *) mazeltov = ', 'L"מזל טוב"']) + + self.expect( + "frame variable ws_NULL", + substrs=['(wchar_t *) ws_NULL = 0x0']) + self.expect("frame variable ws_empty", substrs=[' L""']) + + self.expect("frame variable array", substrs=[ + 'L"Hey, I\'m a super wchar_t string']) + self.expect("frame variable array", substrs=['[0]'], matching=False) + + self.expect('frame variable wchar_zero', substrs=["L'\\0'"]) + self.expect('expression wchar_zero', substrs=["L'\\0'"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/main.cpp new file mode 100644 index 00000000000..4d6a1072d69 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/cpp/wchar_t/main.cpp @@ -0,0 +1,34 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <cstring> + +template <typename T> +class Foo +{ +public: + Foo () : object() {} + Foo (T x) : object(x) {} + T getObject() { return object; } +private: + T object; +}; + + +int main (int argc, char const *argv[]) +{ + Foo<int> foo_x('a'); + Foo<wchar_t> foo_y(L'a'); + const wchar_t *mazeltov = L"מזל טוב"; + wchar_t *ws_NULL = nullptr; + wchar_t *ws_empty = L""; + wchar_t array[200], * array_source = L"Hey, I'm a super wchar_t string, éõñž"; + wchar_t wchar_zero = (wchar_t)0; + memcpy(array, array_source, 39 * sizeof(wchar_t)); + return 0; // Set break point at this line. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/Makefile new file mode 100644 index 00000000000..12db32c506f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/Makefile @@ -0,0 +1,4 @@ +CXX_SOURCES := foo.cpp +C_SOURCES := main.c + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/TestMixedLanguages.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/TestMixedLanguages.py new file mode 100644 index 00000000000..b4fe5396291 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/TestMixedLanguages.py @@ -0,0 +1,57 @@ +"""Test that lldb works correctly on compile units form different languages.""" + + + +import re +import lldb +from lldbsuite.test.lldbtest import * + + +class MixedLanguagesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_language_of_frame(self): + """Test that the language defaults to the language of the current frame.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Execute the cleanup function during test case tear down + # to restore the frame format. + def cleanup(): + self.runCmd( + "settings set frame-format %s" % + self.format_string, check=False) + self.addTearDownHook(cleanup) + self.runCmd("settings show frame-format") + m = re.match( + '^frame-format \(format-string\) = "(.*)\"$', + self.res.GetOutput()) + self.assertTrue(m, "Bad settings string") + self.format_string = m.group(1) + + # Change the default format to print the language. + format_string = "frame #${frame.index}: ${frame.pc}{ ${module.file.basename}\`${function.name}{${function.pc-offset}}}{, lang=${language}}\n" + self.runCmd("settings set frame-format %s" % format_string) + self.expect("settings show frame-format", SETTING_MSG("frame-format"), + substrs=[format_string]) + + # Run to BP at main (in main.c) and test that the language is C. + self.runCmd("breakpoint set -n main") + self.runCmd("run") + self.expect("thread backtrace", + substrs=["`main", "lang=c"]) + # Make sure evaluation of C++11 fails. + self.expect("expr foo != nullptr", error=True, + startstr="error") + + # Run to BP at foo (in foo.cpp) and test that the language is C++. + self.runCmd("breakpoint set -n foo") + self.runCmd("continue") + self.expect("thread backtrace", + substrs=["`::foo()", "lang=c++"]) + # Make sure we can evaluate an expression requiring C++11 + # (note: C++11 is enabled by default for C++). + self.expect("expr foo != nullptr", + patterns=["true"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/foo.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/foo.cpp new file mode 100644 index 00000000000..8a5a6a2b541 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/foo.cpp @@ -0,0 +1,11 @@ +namespace ns { + int func(void) + { + return 0; + } +} + +extern "C" int foo(void) +{ + return ns::func(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/main.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/main.c new file mode 100644 index 00000000000..f5c5d19f2c8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/mixed/main.c @@ -0,0 +1,15 @@ +int foo(void); +static int static_value = 0; + +int +bar() +{ + static_value++; + return static_value; +} + +int main (int argc, char const *argv[]) +{ + bar(); // breakpoint_in_main + return foo(); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/.categories new file mode 100644 index 00000000000..72cf07c1efe --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/.categories @@ -0,0 +1 @@ +objc diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/TestBitfieldIvars.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/TestBitfieldIvars.py new file mode 100644 index 00000000000..c0d006ee53a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/TestBitfieldIvars.py @@ -0,0 +1,12 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, + globals(), + [ + # This is a Darwin-only failure related to incorrect expression- + # evaluation for single-bit ObjC bitfields. + decorators.skipUnlessDarwin, + decorators.expectedFailureAll( + bugnumber="rdar://problem/17990991")]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/main.m new file mode 100644 index 00000000000..e19f291ecf9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/bitfield_ivars/main.m @@ -0,0 +1,51 @@ +//===-- main.m -------------------------------------------*- Objective-C-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +@interface HasBitfield : NSObject { +@public + unsigned field1 : 1; + unsigned field2 : 1; +}; + +-(id)init; +@end + +@implementation HasBitfield +-(id)init { + self = [super init]; + field1 = 0; + field2 = 1; + return self; +} +@end + +@interface ContainsAHasBitfield : NSObject { +@public + HasBitfield *hb; +}; +-(id)init; +@end + +@implementation ContainsAHasBitfield +-(id)init { + self = [super init]; + hb = [[HasBitfield alloc] init]; + return self; +} + +@end + +int main(int argc, const char * argv[]) { + ContainsAHasBitfield *chb = [[ContainsAHasBitfield alloc] init]; + printf("%d\n", chb->hb->field2); //% self.expect("expression -- chb->hb->field1", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["= 0"]) + //% self.expect("expression -- chb->hb->field2", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["= 1"]) # this must happen second + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/Makefile new file mode 100644 index 00000000000..df76ed3069f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := ivars-in-blocks.m main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/TestObjCIvarsInBlocks.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/TestObjCIvarsInBlocks.py new file mode 100644 index 00000000000..e790e6e9d96 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/TestObjCIvarsInBlocks.py @@ -0,0 +1,131 @@ +"""Test printing ivars and ObjC objects captured in blocks that are made in methods of an ObjC class.""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCIvarsInBlocks(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "main.m" + self.class_source = "ivars-in-blocks.m" + self.class_source_file_spec = lldb.SBFileSpec(self.class_source) + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + @skipIf(dwarf_version=['<', '4']) + @expectedFailureAll( + archs=["i[3-6]86"], + bugnumber="This test requires the 2.0 runtime, so it will fail on i386") + def test_with_python_api(self): + """Test printing the ivars of the self when captured in blocks""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateBySourceRegex( + '// Break here inside the block.', self.class_source_file_spec) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + breakpoint_two = target.BreakpointCreateBySourceRegex( + '// Break here inside the class method block.', self.class_source_file_spec) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, "Created a process.") + self.assertTrue( + process.GetState() == lldb.eStateStopped, + "Stopped it too.") + + thread_list = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint) + self.assertTrue(len(thread_list) == 1) + thread = thread_list[0] + + frame = thread.GetFrameAtIndex(0) + self.assertTrue(frame, "frame 0 is valid") + + # First use the FindVariable API to see if we can find the ivar by + # undecorated name: + direct_blocky = frame.GetValueForVariablePath("blocky_ivar") + self.assertTrue(direct_blocky, "Found direct access to blocky_ivar.") + + # Now get it as a member of "self" and make sure the two values are + # equal: + self_var = frame.GetValueForVariablePath("self") + self.assertTrue(self_var, "Found self in block.") + indirect_blocky = self_var.GetChildMemberWithName("blocky_ivar") + self.assertTrue(indirect_blocky, "Found blocky_ivar through self") + + error = lldb.SBError() + direct_value = direct_blocky.GetValueAsSigned(error) + self.assertTrue(error.Success(), "Got direct value for blocky_ivar") + + indirect_value = indirect_blocky.GetValueAsSigned(error) + self.assertTrue(error.Success(), "Got indirect value for blocky_ivar") + + self.assertTrue( + direct_value == indirect_value, + "Direct and indirect values are equal.") + + # Now make sure that we can get at the captured ivar through the expression parser. + # Doing a little trivial math will force this into the real expression + # parser: + direct_expr = frame.EvaluateExpression("blocky_ivar + 10") + self.assertTrue( + direct_expr, + "Got blocky_ivar through the expression parser") + + # Again, get the value through self directly and make sure they are the + # same: + indirect_expr = frame.EvaluateExpression("self->blocky_ivar + 10") + self.assertTrue( + indirect_expr, + "Got blocky ivar through expression parser using self.") + + direct_value = direct_expr.GetValueAsSigned(error) + self.assertTrue( + error.Success(), + "Got value from direct use of expression parser") + + indirect_value = indirect_expr.GetValueAsSigned(error) + self.assertTrue( + error.Success(), + "Got value from indirect access using the expression parser") + + self.assertTrue( + direct_value == indirect_value, + "Direct ivar access and indirect through expression parser produce same value.") + + process.Continue() + self.assertTrue( + process.GetState() == lldb.eStateStopped, + "Stopped at the second breakpoint.") + + thread_list = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint_two) + self.assertTrue(len(thread_list) == 1) + thread = thread_list[0] + + frame = thread.GetFrameAtIndex(0) + self.assertTrue(frame, "frame 0 is valid") + + expr = frame.EvaluateExpression("(ret)") + self.assertTrue( + expr, "Successfully got a local variable in a block in a class method.") + + ret_value_signed = expr.GetValueAsSigned(error) + # print('ret_value_signed = %i' % (ret_value_signed)) + self.assertTrue( + ret_value_signed == 5, + "The local variable in the block was what we expected.") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/ivars-in-blocks.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/ivars-in-blocks.h new file mode 100644 index 00000000000..1ceac3361ac --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/ivars-in-blocks.h @@ -0,0 +1,11 @@ +#import <Foundation/Foundation.h> + +@interface IAmBlocky : NSObject +{ + @public + int blocky_ivar; +} ++ (void) classMethod; +- (IAmBlocky *) init; +- (int) callABlock: (int) block_value; +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/ivars-in-blocks.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/ivars-in-blocks.m new file mode 100644 index 00000000000..1098a9136ae --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/ivars-in-blocks.m @@ -0,0 +1,57 @@ +#import "ivars-in-blocks.h" + +typedef int (^my_block_ptr_type) (int); + +@interface IAmBlocky() +{ + int _hidden_ivar; + my_block_ptr_type _block_ptr; +} + +@end + +@implementation IAmBlocky + ++ (int) addend +{ + return 3; +} + ++ (void) classMethod +{ + int (^my_block)(int) = ^(int foo) + { + int ret = foo + [self addend]; + return ret; // Break here inside the class method block. + }; + printf("%d\n", my_block(2)); +} + +- (void) makeBlockPtr; +{ + _block_ptr = ^(int inval) + { + _hidden_ivar += inval; + return blocky_ivar * inval; // Break here inside the block. + }; +} + +- (IAmBlocky *) init +{ + blocky_ivar = 10; + _hidden_ivar = 20; + // Interesting... Apparently you can't make a block in your init method. This crashes... + // [self makeBlockPtr]; + return self; +} + +- (int) callABlock: (int) block_value +{ + if (_block_ptr == NULL) + [self makeBlockPtr]; + int ret = _block_ptr (block_value); + [IAmBlocky classMethod]; + return ret; +} +@end + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/main.m new file mode 100644 index 00000000000..0c56f45da46 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/blocks/main.m @@ -0,0 +1,10 @@ +#import "ivars-in-blocks.h" + +int +main (int argc, char **argv) +{ + IAmBlocky *my_blocky = [[IAmBlocky alloc] init]; + int blocky_value; + blocky_value = [my_blocky callABlock: 33]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Makefile new file mode 100644 index 00000000000..00a0769a086 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Makefile @@ -0,0 +1,23 @@ +LD_EXTRAS := -lobjc -framework Foundation -L. -lTest -lTestExt +OBJC_SOURCES := main.m + +all: a.out + +a.out: libTest.dylib libTestExt.dylib + +include Makefile.rules + +libTest.dylib: Test/Test.m + mkdir -p Test + $(MAKE) MAKE_DSYM=YES -f $(MAKEFILE_RULES) \ + DYLIB_ONLY=YES DYLIB_NAME=Test DYLIB_OBJC_SOURCES=Test/Test.m \ + LD_EXTRAS="-lobjc -framework Foundation" \ + CFLAGS_EXTRAS=-I$(SRCDIR) + +libTestExt.dylib: TestExt/TestExt.m + mkdir -p TestExt + $(MAKE) MAKE_DSYM=YES -f $(MAKEFILE_RULES) \ + DYLIB_ONLY=YES DYLIB_NAME=TestExt DYLIB_OBJC_SOURCES=TestExt/TestExt.m \ + LD_EXTRAS="-lobjc -framework Foundation -lTest -L." \ + CFLAGS_EXTRAS=-I$(SRCDIR) + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Test/Foo.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Test/Foo.h new file mode 100644 index 00000000000..db07f50d5d6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Test/Foo.h @@ -0,0 +1,9 @@ +#ifndef __Foo_h__ +#define __Foo_h__ + +typedef struct { + float start; + float duration; +} CMTimeRange; + +#endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Test/Test.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Test/Test.h new file mode 100644 index 00000000000..73928c5fb0d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Test/Test.h @@ -0,0 +1,10 @@ +#import <Foundation/Foundation.h> +#import <Test/Foo.h> + +@interface Test : NSObject { +@public + CMTimeRange _range; +} +- (void) doTest; +@end + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Test/Test.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Test/Test.m new file mode 100644 index 00000000000..6b2cb3af808 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/Test/Test.m @@ -0,0 +1,8 @@ +#import "Test.h" + +@implementation Test +- (void) doTest { + NSLog(@"-[Test doTest]"); +} +@end + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestConflictingDefinition.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestConflictingDefinition.py new file mode 100644 index 00000000000..f49858ca4f3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestConflictingDefinition.py @@ -0,0 +1,50 @@ +"""Test that types defined in shared libraries work correctly.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestRealDefinition(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test_frame_var_after_stop_at_implementation(self): + """Test that we can find the implementation for an objective C type""" + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + self.build() + self.shlib_names = ["libTestExt.dylib", "libTest.dylib"] + self.common_setup() + + line = line_number('TestExt/TestExt.m', '// break here') + lldbutil.run_break_set_by_file_and_line( + self, 'TestExt.m', line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs=[' resolved, hit count = 1']) + + # This should display correctly. + self.expect( + "expr 42", + "A simple expression should execute correctly", + substrs=[ + "42"]) + + def common_setup(self): + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.registerSharedLibrariesWithTarget(target, self.shlib_names) + + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestExt/Foo.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestExt/Foo.h new file mode 100644 index 00000000000..7c90e6ca8e3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestExt/Foo.h @@ -0,0 +1,9 @@ +#ifndef __Foo_h__ +#define __Foo_h__ + +typedef struct { + float s; + float d; +} CMTimeRange; + +#endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestExt/TestExt.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestExt/TestExt.h new file mode 100644 index 00000000000..243443c647b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestExt/TestExt.h @@ -0,0 +1,7 @@ +#import <TestExt/Foo.h> +#import <Test/Test.h> +struct CMTimeRange; + +@interface Test (Stuff) +- (void)doSomethingElse: (CMTimeRange *)range_ptr; +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestExt/TestExt.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestExt/TestExt.m new file mode 100644 index 00000000000..a14c702787d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/TestExt/TestExt.m @@ -0,0 +1,8 @@ +#import "TestExt.h" +#import "Foo.h" + +@implementation Test (Stuff) +- (void)doSomethingElse: (CMTimeRange *)range_ptr { + NSLog(@"doSomethingElse: %p", range_ptr); // break here +} +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/main.m new file mode 100644 index 00000000000..6a714577a35 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/conflicting-definition/main.m @@ -0,0 +1,10 @@ +#import <Test/Test.h> +#import <TestExt/TestExt.h> + +int main() { + @autoreleasepool { + Test *test = [[Test alloc] init]; + [test doSomethingElse:&test->_range]; + } +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/Makefile new file mode 100644 index 00000000000..876340159d9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/Makefile @@ -0,0 +1,8 @@ +OBJCXX_SOURCES := main.mm + +CFLAGS_EXTRAS := -w + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py new file mode 100644 index 00000000000..ce9ee8e027f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/TestObjCExceptions.py @@ -0,0 +1,206 @@ +# encoding: utf-8 +""" +Test lldb Obj-C exception support. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCExceptionsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test_objc_exceptions_at_throw(self): + self.build() + + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + launch_info = lldb.SBLaunchInfo(["a.out", "0"]) + lldbutil.run_to_name_breakpoint(self, "objc_exception_throw", launch_info=launch_info) + + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', 'stop reason = breakpoint']) + + self.expect('thread exception', substrs=[ + '(NSException *) exception = ', + '"SomeReason"', + ]) + + target = self.dbg.GetSelectedTarget() + thread = target.GetProcess().GetSelectedThread() + frame = thread.GetSelectedFrame() + + opts = lldb.SBVariablesOptions() + opts.SetIncludeRecognizedArguments(True) + variables = frame.GetVariables(opts) + + self.assertEqual(variables.GetSize(), 1) + self.assertEqual(variables.GetValueAtIndex(0).name, "exception") + self.assertEqual(variables.GetValueAtIndex(0).GetValueType(), lldb.eValueTypeVariableArgument) + + lldbutil.run_to_source_breakpoint(self, "// Set break point at this line.", lldb.SBFileSpec("main.mm"), launch_info=launch_info) + + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', 'stop reason = breakpoint']) + + target = self.dbg.GetSelectedTarget() + thread = target.GetProcess().GetSelectedThread() + frame = thread.GetSelectedFrame() + + # No exception being currently thrown/caught at this point + self.assertFalse(thread.GetCurrentException().IsValid()) + self.assertFalse(thread.GetCurrentExceptionBacktrace().IsValid()) + + self.expect( + 'frame variable e1', + substrs=[ + '(NSException *) e1 = ', + '"SomeReason"' + ]) + + self.expect( + 'frame variable --dynamic-type no-run-target *e1', + substrs=[ + '(NSException) *e1 = ', + 'name = ', '"ExceptionName"', + 'reason = ', '"SomeReason"', + 'userInfo = ', '1 key/value pair', + 'reserved = ', 'nil', + ]) + + e1 = frame.FindVariable("e1") + self.assertTrue(e1) + self.assertEqual(e1.type.name, "NSException *") + self.assertEqual(e1.GetSummary(), '"SomeReason"') + self.assertEqual(e1.GetChildMemberWithName("name").description, "ExceptionName") + self.assertEqual(e1.GetChildMemberWithName("reason").description, "SomeReason") + userInfo = e1.GetChildMemberWithName("userInfo").dynamic + self.assertEqual(userInfo.summary, "1 key/value pair") + self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key") + self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value") + self.assertEqual(e1.GetChildMemberWithName("reserved").description, "<nil>") + + self.expect( + 'frame variable e2', + substrs=[ + '(NSException *) e2 = ', + '"SomeReason"' + ]) + + self.expect( + 'frame variable --dynamic-type no-run-target *e2', + substrs=[ + '(NSException) *e2 = ', + 'name = ', '"ThrownException"', + 'reason = ', '"SomeReason"', + 'userInfo = ', '1 key/value pair', + 'reserved = ', + ]) + + e2 = frame.FindVariable("e2") + self.assertTrue(e2) + self.assertEqual(e2.type.name, "NSException *") + self.assertEqual(e2.GetSummary(), '"SomeReason"') + self.assertEqual(e2.GetChildMemberWithName("name").description, "ThrownException") + self.assertEqual(e2.GetChildMemberWithName("reason").description, "SomeReason") + userInfo = e2.GetChildMemberWithName("userInfo").dynamic + self.assertEqual(userInfo.summary, "1 key/value pair") + self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(0).description, "some_key") + self.assertEqual(userInfo.GetChildAtIndex(0).GetChildAtIndex(1).description, "some_value") + reserved = e2.GetChildMemberWithName("reserved").dynamic + self.assertGreater(reserved.num_children, 0) + callStackReturnAddresses = [reserved.GetChildAtIndex(i).GetChildAtIndex(1) for i in range(0, reserved.GetNumChildren()) + if reserved.GetChildAtIndex(i).GetChildAtIndex(0).description == "callStackReturnAddresses"][0].dynamic + children = [callStackReturnAddresses.GetChildAtIndex(i) for i in range(0, callStackReturnAddresses.num_children)] + + pcs = [i.unsigned for i in children] + names = [target.ResolveSymbolContextForAddress(lldb.SBAddress(pc, target), lldb.eSymbolContextSymbol).GetSymbol().name for pc in pcs] + for n in ["objc_exception_throw", "foo(int)", "main"]: + self.assertTrue(n in names, "%s is in the exception backtrace (%s)" % (n, names)) + + @skipUnlessDarwin + def test_objc_exceptions_at_abort(self): + self.build() + + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + self.runCmd("run 0") + + # We should be stopped at pthread_kill because of an unhandled exception + self.expect("thread list", + substrs=['stopped', 'stop reason = signal SIGABRT']) + + self.expect('thread exception', substrs=[ + '(NSException *) exception = ', + '"SomeReason"', + 'libobjc.A.dylib`objc_exception_throw', + 'a.out`foo', 'at main.mm:24', + 'a.out`rethrow', 'at main.mm:35', + 'a.out`main', + ]) + + process = self.dbg.GetSelectedTarget().process + thread = process.GetSelectedThread() + + # There is an exception being currently processed at this point + self.assertTrue(thread.GetCurrentException().IsValid()) + self.assertTrue(thread.GetCurrentExceptionBacktrace().IsValid()) + + history_thread = thread.GetCurrentExceptionBacktrace() + self.assertGreaterEqual(history_thread.num_frames, 4) + for n in ["objc_exception_throw", "foo(int)", "rethrow(int)", "main"]: + self.assertEqual(len([f for f in history_thread.frames if f.GetFunctionName() == n]), 1) + + self.runCmd("kill") + + self.runCmd("run 1") + # We should be stopped at pthread_kill because of an unhandled exception + self.expect("thread list", + substrs=['stopped', 'stop reason = signal SIGABRT']) + + self.expect('thread exception', substrs=[ + '(MyCustomException *) exception = ', + 'libobjc.A.dylib`objc_exception_throw', + 'a.out`foo', 'at main.mm:26', + 'a.out`rethrow', 'at main.mm:35', + 'a.out`main', + ]) + + process = self.dbg.GetSelectedTarget().process + thread = process.GetSelectedThread() + + history_thread = thread.GetCurrentExceptionBacktrace() + self.assertGreaterEqual(history_thread.num_frames, 4) + for n in ["objc_exception_throw", "foo(int)", "rethrow(int)", "main"]: + self.assertEqual(len([f for f in history_thread.frames if f.GetFunctionName() == n]), 1) + + @skipUnlessDarwin + def test_cxx_exceptions_at_abort(self): + self.build() + + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + self.runCmd("run 2") + + # We should be stopped at pthread_kill because of an unhandled exception + self.expect("thread list", + substrs=['stopped', 'stop reason = signal SIGABRT']) + + self.expect('thread exception', substrs=['exception =']) + + process = self.dbg.GetSelectedTarget().process + thread = process.GetSelectedThread() + + self.assertTrue(thread.GetCurrentException().IsValid()) + + # C++ exception backtraces are not exposed in the API (yet). + self.assertFalse(thread.GetCurrentExceptionBacktrace().IsValid()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/main.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/main.mm new file mode 100644 index 00000000000..b5c71f9fcf9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/exceptions/main.mm @@ -0,0 +1,62 @@ +//===-- main.m ------------------------------------------------*- ObjC -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +#import <exception> +#import <stdexcept> + +@interface MyCustomException: NSException +@end +@implementation MyCustomException +@end + +void foo(int n) +{ + NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:@"some_value", @"some_key", nil]; + switch (n) { + case 0: + @throw [[NSException alloc] initWithName:@"ThrownException" reason:@"SomeReason" userInfo:info]; + case 1: + @throw [[MyCustomException alloc] initWithName:@"ThrownException" reason:@"SomeReason" userInfo:info]; + case 2: + throw std::runtime_error("C++ exception"); + } +} + +void rethrow(int n) +{ + @try { + foo(n); + } @catch(NSException *e) { + @throw; + } +} + +int main(int argc, const char * argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:@"some_value", @"some_key", nil]; + NSException *e1 = [[NSException alloc] initWithName:@"ExceptionName" reason:@"SomeReason" userInfo:info]; + NSException *e2; + + @try { + foo(atoi(argv[1])); + } @catch(NSException *e) { + e2 = e; + } + + NSLog(@"1"); // Set break point at this line. + + rethrow(atoi(argv[1])); + + [pool drain]; + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/Container.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/Container.h new file mode 100644 index 00000000000..85bbd06b161 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/Container.h @@ -0,0 +1,13 @@ +#import <Foundation/Foundation.h> + +@class ForwardDeclaredClass; + +@interface Container : NSObject { +@public + ForwardDeclaredClass *member; +} + +-(id)init; +-(ForwardDeclaredClass*)getMember; + +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/Container.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/Container.m new file mode 100644 index 00000000000..4d2139ff5fc --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/Container.m @@ -0,0 +1,27 @@ +#import "Container.h" + +@interface ForwardDeclaredClass : NSObject +{ + int a; + int b; +} +@end + +@implementation ForwardDeclaredClass + +@end + +@implementation Container + +-(id)init +{ + member = [ForwardDeclaredClass alloc]; + return [super init]; +} + +-(ForwardDeclaredClass *)getMember +{ + return member; +} + +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/Makefile new file mode 100644 index 00000000000..cfae251ead4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/Makefile @@ -0,0 +1,8 @@ +DYLIB_NAME := Container +DYLIB_OBJC_SOURCES := Container.m +OBJC_SOURCES := main.m + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py new file mode 100644 index 00000000000..fd35d64c191 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/TestForwardDecl.py @@ -0,0 +1,69 @@ +"""Test that a forward-declared class works when its complete definition is in a library""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ForwardDeclTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.m' + self.line = line_number(self.source, '// Set breakpoint 0 here.') + self.shlib_names = ["Container"] + + def do_test(self, dictionary=None): + self.build(dictionary=dictionary) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Register our shared libraries for remote targets so they get + # automatically uploaded + environment = self.registerSharedLibrariesWithTarget( + target, self.shlib_names) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + # This should display correctly. + self.expect("expression [j getMember]", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 0x"]) + + @skipUnlessDarwin + def test_expr(self): + self.do_test() + + @no_debug_info_test + @skipUnlessDarwin + @skipIf(compiler=no_match("clang")) + @skipIf(compiler_version=["<", "7.0"]) + def test_debug_names(self): + """Test that we are able to find complete types when using DWARF v5 + accelerator tables""" + self.do_test( + dict(CFLAGS_EXTRAS="-dwarf-version=5 -mllvm -accel-tables=Dwarf")) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/main.m new file mode 100644 index 00000000000..8e5256e9523 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/forward-decl/main.m @@ -0,0 +1,14 @@ +#import <Foundation/Foundation.h> +#import "Container.h" + +int main(int argc, const char * argv[]) +{ + + @autoreleasepool { + Container *j = [[Container alloc] init]; + + printf("member value = %p", [j getMember]); // Set breakpoint 0 here. + } + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/Makefile new file mode 100644 index 00000000000..e95ebd94a94 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/Makefile @@ -0,0 +1,7 @@ +OBJC_SOURCES := main.m my-base.m +#OBJC_SOURCES := const-strings.m + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestConstStrings.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestConstStrings.py new file mode 100644 index 00000000000..6e8e9898e19 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestConstStrings.py @@ -0,0 +1,57 @@ +""" +Test that objective-c constant strings are generated correctly by the expression +parser. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ConstStringTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + d = {'OBJC_SOURCES': 'const-strings.m'} + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.main_source = "const-strings.m" + self.line = line_number(self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + def test_break(self): + """Test constant string generation amd comparison by the expression parser.""" + self.build(dictionary=self.d) + self.setTearDownCleanup(self.d) + + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + self.main_source, + self.line, + num_expected_locations=1, + loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, + substrs=[" at %s:%d" % (self.main_source, self.line), + "stop reason = breakpoint"]) + + self.expect('expression (int)[str compare:@"hello"]', + startstr="(int) $0 = 0") + self.expect('expression (int)[str compare:@"world"]', + startstr="(int) $1 = -1") + + # Test empty strings, too. + self.expect('expression (int)[@"" length]', + startstr="(int) $2 = 0") + + self.expect('expression (int)[@"123" length]', + startstr="(int) $3 = 3") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestFoundationDisassembly.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestFoundationDisassembly.py new file mode 100644 index 00000000000..9e39a735f8b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestFoundationDisassembly.py @@ -0,0 +1,151 @@ +""" +Test the lldb disassemble command on foundation framework. +""" + +import unittest2 +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class FoundationDisassembleTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + NO_DEBUG_INFO_TESTCASE = True + + @skipIfAsan + def test_foundation_disasm(self): + """Do 'disassemble -n func' on each and every 'Code' symbol entry from the Foundation.framework.""" + self.build() + + # Enable synchronous mode + self.dbg.SetAsync(False) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + foundation_framework = None + for module in target.modules: + if module.file.basename == "Foundation": + foundation_framework = module.file.fullpath + break + + self.assertTrue( + foundation_framework is not None, + "Foundation.framework path located") + self.runCmd("image dump symtab '%s'" % foundation_framework) + raw_output = self.res.GetOutput() + # Now, grab every 'Code' symbol and feed it into the command: + # 'disassemble -n func'. + # + # The symbol name is on the last column and trails the flag column which + # looks like '0xhhhhhhhh', i.e., 8 hexadecimal digits. + codeRE = re.compile(r""" + \ Code\ {9} # ' Code' followed by 9 SPCs, + .* # the wildcard chars, + 0x[0-9a-f]{8} # the flag column, and + \ (.+)$ # finally the function symbol. + """, re.VERBOSE) + for line in raw_output.split(os.linesep): + match = codeRE.search(line) + if match: + func = match.group(1) + self.runCmd('image lookup -s "%s"' % func) + self.runCmd('disassemble -n "%s"' % func) + + @skipIfAsan + def test_simple_disasm(self): + """Test the lldb 'disassemble' command""" + self.build() + + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Stop at +[NSString stringWithFormat:]. + symbol_name = "+[NSString stringWithFormat:]" + break_results = lldbutil.run_break_set_command( + self, "_regexp-break %s" % (symbol_name)) + + lldbutil.check_breakpoint_result( + self, + break_results, + symbol_name=symbol_name, + num_locations=1) + + # Stop at -[MyString initWithNSString:]. + lldbutil.run_break_set_by_symbol( + self, + '-[MyString initWithNSString:]', + num_expected_locations=1, + sym_exact=True) + + # Stop at the "description" selector. + lldbutil.run_break_set_by_selector( + self, + 'description', + num_expected_locations=1, + module_name='a.out') + + # Stop at -[NSAutoreleasePool release]. + break_results = lldbutil.run_break_set_command( + self, "_regexp-break -[NSAutoreleasePool release]") + lldbutil.check_breakpoint_result( + self, + break_results, + symbol_name='-[NSAutoreleasePool release]', + num_locations=1) + + self.runCmd("run", RUN_SUCCEEDED) + + # First stop is +[NSString stringWithFormat:]. + self.expect( + "thread backtrace", + "Stop at +[NSString stringWithFormat:]", + substrs=["Foundation`+[NSString stringWithFormat:]"]) + + # Do the disassemble for the currently stopped function. + self.runCmd("disassemble -f") + + self.runCmd("process continue") + # Skip another breakpoint for +[NSString stringWithFormat:]. + self.runCmd("process continue") + + # Followed by a.out`-[MyString initWithNSString:]. + self.expect( + "thread backtrace", + "Stop at a.out`-[MyString initWithNSString:]", + substrs=["a.out`-[MyString initWithNSString:]"]) + + # Do the disassemble for the currently stopped function. + self.runCmd("disassemble -f") + + self.runCmd("process continue") + + # Followed by -[MyString description]. + self.expect("thread backtrace", "Stop at -[MyString description]", + substrs=["a.out`-[MyString description]"]) + + # Do the disassemble for the currently stopped function. + self.runCmd("disassemble -f") + + self.runCmd("process continue") + # Skip another breakpoint for -[MyString description]. + self.runCmd("process continue") + + # Followed by -[NSAutoreleasePool release]. + self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]", + substrs=["Foundation`-[NSAutoreleasePool release]"]) + + # Do the disassemble for the currently stopped function. + self.runCmd("disassemble -f") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods.py new file mode 100644 index 00000000000..7d4990c4f38 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods.py @@ -0,0 +1,325 @@ +""" +Set breakpoints on objective-c class and instance methods in foundation. +Also lookup objective-c data types and evaluate expressions. +""" + +from __future__ import print_function + + +import os +import os.path +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +file_index = 0 + + +@skipUnlessDarwin +class FoundationTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.main_source = "main.m" + self.line = line_number( + self.main_source, + '// Set break point at this line.') + + def test_break(self): + """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Stop at +[NSString stringWithFormat:]. + break_results = lldbutil.run_break_set_command( + self, "_regexp-break +[NSString stringWithFormat:]") + lldbutil.check_breakpoint_result( + self, + break_results, + symbol_name='+[NSString stringWithFormat:]', + num_locations=1) + + # Stop at -[MyString initWithNSString:]. + lldbutil.run_break_set_by_symbol( + self, + '-[MyString initWithNSString:]', + num_expected_locations=1, + sym_exact=True) + + # Stop at the "description" selector. + lldbutil.run_break_set_by_selector( + self, + 'description', + num_expected_locations=1, + module_name='a.out') + + # Stop at -[NSAutoreleasePool release]. + break_results = lldbutil.run_break_set_command( + self, "_regexp-break -[NSAutoreleasePool release]") + lldbutil.check_breakpoint_result( + self, + break_results, + symbol_name='-[NSAutoreleasePool release]', + num_locations=1) + + self.runCmd("run", RUN_SUCCEEDED) + + # First stop is +[NSString stringWithFormat:]. + self.expect( + "thread backtrace", + "Stop at +[NSString stringWithFormat:]", + substrs=["Foundation`+[NSString stringWithFormat:]"]) + + self.runCmd("process continue") + + # Second stop is still +[NSString stringWithFormat:]. + self.expect( + "thread backtrace", + "Stop at +[NSString stringWithFormat:]", + substrs=["Foundation`+[NSString stringWithFormat:]"]) + + self.runCmd("process continue") + + # Followed by a.out`-[MyString initWithNSString:]. + self.expect( + "thread backtrace", + "Stop at a.out`-[MyString initWithNSString:]", + substrs=["a.out`-[MyString initWithNSString:]"]) + + self.runCmd("process continue") + + # Followed by -[MyString description]. + self.expect("thread backtrace", "Stop at -[MyString description]", + substrs=["a.out`-[MyString description]"]) + + self.runCmd("process continue") + + # Followed by the same -[MyString description]. + self.expect("thread backtrace", "Stop at -[MyString description]", + substrs=["a.out`-[MyString description]"]) + + self.runCmd("process continue") + + # Followed by -[NSAutoreleasePool release]. + self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]", + substrs=["Foundation`-[NSAutoreleasePool release]"]) + + # rdar://problem/8542091 + # rdar://problem/8492646 + def test_data_type_and_expr(self): + """Lookup objective-c data types and evaluate expressions.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Stop at -[MyString description]. + lldbutil.run_break_set_by_symbol( + self, + '-[MyString description]', + num_expected_locations=1, + sym_exact=True) +# self.expect("breakpoint set -n '-[MyString description]", BREAKPOINT_CREATED, +# startstr = "Breakpoint created: 1: name = '-[MyString description]', +# locations = 1") + + self.runCmd("run", RUN_SUCCEEDED) + + # The backtrace should show we stop at -[MyString description]. + self.expect("thread backtrace", "Stop at -[MyString description]", + substrs=["a.out`-[MyString description]"]) + + # Lookup objc data type MyString and evaluate some expressions. + + self.expect("image lookup -t NSString", DATA_TYPES_DISPLAYED_CORRECTLY, + substrs=['name = "NSString"', + 'compiler_type = "@interface NSString']) + + self.expect("image lookup -t MyString", DATA_TYPES_DISPLAYED_CORRECTLY, + substrs=['name = "MyString"', + 'compiler_type = "@interface MyString', + 'NSString * str;', + 'NSDate * date;']) + + self.expect( + "frame variable --show-types --scope", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["ARG: (MyString *) self"], + patterns=[ + "ARG: \(.*\) _cmd", + "(objc_selector *)|(SEL)"]) + + # rdar://problem/8651752 + # don't crash trying to ask clang how many children an empty record has + self.runCmd("frame variable *_cmd") + + # rdar://problem/8492646 + # test/foundation fails after updating to tot r115023 + # self->str displays nothing as output + self.expect( + "frame variable --show-types self->str", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(NSString *) self->str") + + # rdar://problem/8447030 + # 'frame variable self->date' displays the wrong data member + self.expect( + "frame variable --show-types self->date", + VARIABLES_DISPLAYED_CORRECTLY, + startstr="(NSDate *) self->date") + + # This should display the str and date member fields as well. + self.expect( + "frame variable --show-types *self", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "(MyString) *self", + "(NSString *) str", + "(NSDate *) date"]) + + # isa should be accessible. + self.expect("expression self->isa", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["(Class)"]) + + # This should fail expectedly. + self.expect( + "expression self->non_existent_member", + COMMAND_FAILED_AS_EXPECTED, + error=True, + substrs=["error:", "'MyString' does not have a member named 'non_existent_member'"]) + + # Use expression parser. + self.runCmd("expression self->str") + self.runCmd("expression self->date") + + # (lldb) expression self->str + # error: instance variable 'str' is protected + # error: 1 errors parsing expression + # + # (lldb) expression self->date + # error: instance variable 'date' is protected + # error: 1 errors parsing expression + # + + self.runCmd("breakpoint delete 1") + lldbutil.run_break_set_by_file_and_line( + self, "main.m", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("process continue") + + # rdar://problem/8542091 + # test/foundation: expr -o -- my not working? + # + # Test new feature with r115115: + # Add "-o" option to "expression" which prints the object description + # if available. + self.expect( + "expression --object-description -- my", + "Object description displayed correctly", + patterns=["Hello from.*a.out.*with timestamp: "]) + + @add_test_categories(['pyapi']) + def test_print_ivars_correctly(self): + self.build() + # See: <rdar://problem/8717050> lldb needs to use the ObjC runtime symbols for ivar offsets + # Only fails for the ObjC 2.0 runtime. + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + break1 = target.BreakpointCreateByLocation(self.main_source, self.line) + self.assertTrue(break1, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread = process.GetThreadAtIndex(0) + if thread.GetStopReason() != lldb.eStopReasonBreakpoint: + from lldbsuite.test.lldbutil import stop_reason_to_str + self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS % + stop_reason_to_str(thread.GetStopReason())) + + # Make sure we stopped at the first breakpoint. + + cur_frame = thread.GetFrameAtIndex(0) + + line_number = cur_frame.GetLineEntry().GetLine() + self.assertTrue(line_number == self.line, "Hit the first breakpoint.") + + my_var = cur_frame.FindVariable("my") + self.assertTrue(my_var, "Made a variable object for my") + + str_var = cur_frame.FindVariable("str") + self.assertTrue(str_var, "Made a variable object for str") + + # Now make sure that the my->str == str: + + my_str_var = my_var.GetChildMemberWithName("str") + self.assertTrue(my_str_var, "Found a str ivar in my") + + str_value = int(str_var.GetValue(), 0) + + my_str_value = int(my_str_var.GetValue(), 0) + + self.assertTrue( + str_value == my_str_value, + "Got the correct value for my->str") + + def test_expression_lookups_objc(self): + """Test running an expression detect spurious debug info lookups (DWARF).""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Stop at -[MyString initWithNSString:]. + lldbutil.run_break_set_by_symbol( + self, + '-[MyString initWithNSString:]', + num_expected_locations=1, + sym_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + global file_index + # Log any DWARF lookups + ++file_index + logfile = os.path.join( + self.getBuildDir(), + "dwarf-lookups-" + + self.getArchitecture() + + "-" + + str(file_index) + + ".txt") + self.runCmd("log enable -f %s dwarf lookups" % (logfile)) + self.runCmd("expr self") + self.runCmd("log disable dwarf lookups") + + def cleanup(): + if os.path.exists(logfile): + os.unlink(logfile) + + self.addTearDownHook(cleanup) + + if os.path.exists(logfile): + f = open(logfile) + lines = f.readlines() + num_errors = 0 + for line in lines: + if "$__lldb" in line: + if num_errors == 0: + print( + "error: found spurious name lookups when evaluating an expression:") + num_errors += 1 + print(line, end='') + self.assertTrue(num_errors == 0, "Spurious lookups detected") + f.close() diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods2.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods2.py new file mode 100644 index 00000000000..b2d0d190eb0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethods2.py @@ -0,0 +1,40 @@ +""" +Test more expression command sequences with objective-c. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class FoundationTestCase2(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + NO_DEBUG_INFO_TESTCASE = True + + def test_expr_commands(self): + """More expression commands for objective-c.""" + self.build() + main_spec = lldb.SBFileSpec("main.m") + + (target, process, thread, bp) = lldbutil.run_to_source_breakpoint( + self, "Break here for selector: tests", main_spec) + + # Test_Selector: + self.expect("expression (char *)sel_getName(sel)", + substrs=["(char *)", + "length"]) + + desc_bkpt = target.BreakpointCreateBySourceRegex("Break here for description test", + main_spec) + self.assertEqual(desc_bkpt.GetNumLocations(), 1, "description breakpoint has a location") + lldbutil.continue_to_breakpoint(process, desc_bkpt) + + self.expect("expression (char *)sel_getName(_cmd)", + substrs=["(char *)", + "description"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethodsNSArray.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethodsNSArray.py new file mode 100644 index 00000000000..8080029ef02 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethodsNSArray.py @@ -0,0 +1,36 @@ +""" +Test more expression command sequences with objective-c. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class FoundationTestCaseNSArray(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_NSArray_expr_commands(self): + """Test expression commands for NSArray.""" + self.build() + self.target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, '// Break here for NSArray tests', + lldb.SBFileSpec('main.m', False)) + + self.runCmd("thread backtrace") + self.expect("expression (int)[nil_mutable_array count]", + patterns=["\(int\) \$.* = 0"]) + self.expect("expression (int)[array1 count]", + patterns=["\(int\) \$.* = 3"]) + self.expect("expression (int)[array2 count]", + patterns=["\(int\) \$.* = 3"]) + self.expect("expression (int)array1.count", + patterns=["\(int\) \$.* = 3"]) + self.expect("expression (int)array2.count", + patterns=["\(int\) \$.* = 3"]) + self.runCmd("process continue") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethodsNSError.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethodsNSError.py new file mode 100644 index 00000000000..07717926b5e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethodsNSError.py @@ -0,0 +1,49 @@ +""" +Test more expression command sequences with objective-c. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class FoundationTestCaseNSError(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(archs=["i[3-6]86"], bugnumber="<rdar://problem/28814052>") + def test_runtime_types(self): + """Test commands that require runtime types""" + self.build() + self.target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, '// Break here for NSString tests', + lldb.SBFileSpec('main.m', False)) + + # Test_NSString: + self.runCmd("thread backtrace") + self.expect("expression [str length]", + patterns=["\(NSUInteger\) \$.* ="]) + self.expect("expression str.length") + self.expect('expression str = [NSString stringWithCString: "new"]') + self.expect( + 'po [NSError errorWithDomain:@"Hello" code:35 userInfo:@{@"NSDescription" : @"be completed."}]', + substrs=[ + "Error Domain=Hello", + "Code=35", + "be completed."]) + self.runCmd("process continue") + + @expectedFailureAll(archs=["i[3-6]86"], bugnumber="<rdar://problem/28814052>") + def test_NSError_p(self): + """Test that p of the result of an unknown method does require a cast.""" + self.build() + self.target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, '// Set break point at this line', + lldb.SBFileSpec('main.m', False)) + self.expect("p [NSError thisMethodIsntImplemented:0]", error=True, patterns=[ + "no known method", "cast the message send to the method's return type"]) + self.runCmd("process continue") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethodsString.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethodsString.py new file mode 100644 index 00000000000..65ccb0c19b5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjCMethodsString.py @@ -0,0 +1,53 @@ +""" +Test more expression command sequences with objective-c. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class FoundationTestCaseString(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def test_NSString_expr_commands(self): + """Test expression commands for NSString.""" + self.build() + self.target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, '// Break here for NSString tests', + lldb.SBFileSpec('main.m', False)) + + # Test_NSString: + self.runCmd("thread backtrace") + self.expect("expression (int)[str length]", + patterns=["\(int\) \$.* ="]) + self.expect("expression (int)[str_id length]", + patterns=["\(int\) \$.* ="]) + self.expect("expression (id)[str description]", + patterns=["\(id\) \$.* = 0x"]) + self.expect("expression (id)[str_id description]", + patterns=["\(id\) \$.* = 0x"]) + self.expect("expression str.length") + self.expect('expression str = @"new"') + self.runCmd("image lookup -t NSString") + self.expect('expression str = (id)[NSString stringWithCString: "new"]') + self.runCmd("process continue") + + @expectedFailureAll(archs=["i[3-6]86"], bugnumber="<rdar://problem/28814052>") + def test_MyString_dump_with_runtime(self): + """Test dump of a known Objective-C object by dereferencing it.""" + self.build() + self.target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, '// Set break point at this line', + lldb.SBFileSpec('main.m', False)) + self.expect( + "expression --show-types -- *my", + patterns=[ + "\(MyString\) \$.* = ", + "\(MyBase\)"]) + self.runCmd("process continue") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjectDescriptionAPI.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjectDescriptionAPI.py new file mode 100644 index 00000000000..803cbfe1218 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestObjectDescriptionAPI.py @@ -0,0 +1,75 @@ +""" +Test SBValue.GetObjectDescription() with the value from SBTarget.FindGlobalVariables(). +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjectDescriptionAPITestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break at. + self.source = 'main.m' + self.line = line_number( + self.source, '// Set break point at this line.') + + # rdar://problem/10857337 + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_find_global_variables_then_object_description(self): + """Exercise SBTarget.FindGlobalVariables() API.""" + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + exe = self.getBuildArtifact('b.out') + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + # Make sure we hit our breakpoint: + thread_list = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint) + self.assertTrue(len(thread_list) == 1) + + thread = thread_list[0] + frame0 = thread.GetFrameAtIndex(0) + + # Note my_global_str's object description prints fine here. + value_list1 = frame0.GetVariables(True, True, True, True) + for v in value_list1: + self.DebugSBValue(v) + if self.TraceOn(): + print("val:", v) + print("object description:", v.GetObjectDescription()) + if v.GetName() == 'my_global_str': + self.assertTrue(v.GetObjectDescription() == + 'This is a global string') + + # But not here! + value_list2 = target.FindGlobalVariables('my_global_str', 3) + for v in value_list2: + self.DebugSBValue(v) + if self.TraceOn(): + print("val:", v) + print("object description:", v.GetObjectDescription()) + if v.GetName() == 'my_global_str': + self.assertTrue(v.GetObjectDescription() == + 'This is a global string') diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestRuntimeTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestRuntimeTypes.py new file mode 100644 index 00000000000..f5cb75b4a6d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestRuntimeTypes.py @@ -0,0 +1,59 @@ +""" +Test that Objective-C methods from the runtime work correctly. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class RuntimeTypesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll( + oslist=["macosx"], + debug_info="gmodules", + bugnumber="llvm.org/pr27862") + def test_break(self): + """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'.""" + if self.getArchitecture() != 'x86_64': + self.skipTest("This only applies to the v2 runtime") + + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Stop at -[MyString description]. + lldbutil.run_break_set_by_symbol( + self, + '-[MyString description]', + num_expected_locations=1, + sym_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The backtrace should show we stop at -[MyString description]. + self.expect("thread backtrace", "Stop at -[MyString description]", + substrs=["a.out`-[MyString description]"]) + + # Use runtime information about NSString. + + # The length property should be usable. + self.expect("expression str.length", VARIABLES_DISPLAYED_CORRECTLY, + patterns=[r"(\(unsigned long long\))|\(NSUInteger\)"]) + + # Static methods on NSString should work. + self.expect( + "expr [NSString stringWithCString:\"foo\" encoding:1]", + VALID_TYPE, + substrs=[ + "(id)", + "$1"]) + + self.expect("po $1", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["foo"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestSymbolTable.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestSymbolTable.py new file mode 100644 index 00000000000..abfc7621e2e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/TestSymbolTable.py @@ -0,0 +1,68 @@ +""" +Test symbol table access for main.m. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class FoundationSymtabTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + symbols_list = ['-[MyString initWithNSString:]', + '-[MyString dealloc]', + '-[MyString description]', + '-[MyString descriptionPauses]', # synthesized property + # synthesized property + '-[MyString setDescriptionPauses:]', + 'Test_Selector', + 'Test_NSString', + 'Test_MyString', + 'Test_NSArray', + 'main' + ] + + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test symbol table access with Python APIs.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + # + # Exercise Python APIs to access the symbol table entries. + # + + # Create the filespec by which to locate our a.out module. + filespec = lldb.SBFileSpec(exe, False) + + module = target.FindModule(filespec) + self.assertTrue(module, VALID_MODULE) + + # Create the set of known symbols. As we iterate through the symbol + # table, remove the symbol from the set if it is a known symbol. + expected_symbols = set(self.symbols_list) + for symbol in module: + self.assertTrue(symbol, VALID_SYMBOL) + #print("symbol:", symbol) + name = symbol.GetName() + if name in expected_symbols: + #print("Removing %s from known_symbols %s" % (name, expected_symbols)) + expected_symbols.remove(name) + + # At this point, the known_symbols set should have become an empty set. + # If not, raise an error. + #print("symbols unaccounted for:", expected_symbols) + self.assertTrue(len(expected_symbols) == 0, + "All the known symbols are accounted for") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/const-strings.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/const-strings.m new file mode 100644 index 00000000000..8a43abee7b8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/const-strings.m @@ -0,0 +1,24 @@ +#import <Foundation/Foundation.h> + +// Tests to run: + +// Breakpoint 1 +// -- +// (lldb) expr (int)[str compare:@"hello"] +// (int) $0 = 0 +// (lldb) expr (int)[str compare:@"world"] +// (int) $1 = -1 +// (lldb) expr (int)[@"" length] +// (int) $2 = 0 + +int main () +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSString *str = [NSString stringWithCString:"hello" encoding:NSASCIIStringEncoding]; + + NSLog(@"String \"%@\" has length %lu", str, [str length]); // Set breakpoint here. + + [pool drain]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/main.m new file mode 100644 index 00000000000..519bec5a3e6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/main.m @@ -0,0 +1,141 @@ +#import <Foundation/Foundation.h> +#include <unistd.h> +#import "my-base.h" + +@interface MyString : MyBase { + NSString *str; + NSDate *date; + BOOL _desc_pauses; +} + +@property(retain) NSString * str_property; +@property BOOL descriptionPauses; + +- (id)initWithNSString:(NSString *)string; +@end + +@implementation MyString +@synthesize descriptionPauses = _desc_pauses; +@synthesize str_property = str; + +- (id)initWithNSString:(NSString *)string +{ + if (self = [super init]) + { + str = [NSString stringWithString:string]; + date = [NSDate date]; + } + self.descriptionPauses = NO; + return self; +} + +- (void)dealloc +{ + [date release]; + [str release]; + [super dealloc]; +} + +- (NSString *)description +{ + // Set a breakpoint on '-[MyString description]' and test expressions: + // expression (char *)sel_getName(_cmd) + if (self.descriptionPauses) // Break here for description test + { + printf ("\nAbout to sleep.\n"); + usleep(100000); + } + + return [str stringByAppendingFormat:@" with timestamp: %@", date]; +} +@end + +int +Test_Selector () +{ + SEL sel = @selector(length); + printf("sel = %p\n", sel); + // Expressions to test here for selector: + // expression (char *)sel_getName(sel) + // The expression above should return "sel" as it should be just + // a uniqued C string pointer. We were seeing the result pointer being + // truncated with recent LLDBs. + return 0; // Break here for selector: tests +} + +int +Test_NSString (const char *program) +{ + NSString *str = [NSString stringWithFormat:@"Hello from '%s'", program]; + NSLog(@"NSString instance: %@", str); + printf("str = '%s'\n", [str cStringUsingEncoding: [NSString defaultCStringEncoding]]); + printf("[str length] = %zu\n", (size_t)[str length]); + printf("[str description] = %s\n", [[str description] UTF8String]); + id str_id = str; + // Expressions to test here for NSString: + // expression (char *)sel_getName(sel) + // expression [str length] + // expression [str_id length] + // expression [str description] + // expression [str_id description] + // expression str.length + // expression str.description + // expression str = @"new" + // expression str = [NSString stringWithFormat: @"%cew", 'N'] + return 0; // Break here for NSString tests +} + +NSString *my_global_str = NULL; + +void +Test_MyString (const char *program) +{ + my_global_str = @"This is a global string"; + NSString *str = [NSString stringWithFormat:@"Hello from '%s'", program]; + MyString *my = [[MyString alloc] initWithNSString:str]; + NSLog(@"MyString instance: %@", [my description]); + my.descriptionPauses = YES; // Set break point at this line. Test 'expression -o -- my'. + NSLog(@"MyString instance: %@", [my description]); +} + +int +Test_NSArray () +{ + NSMutableArray *nil_mutable_array = nil; + NSArray *array1 = [NSArray arrayWithObjects: @"array1 object1", @"array1 object2", @"array1 object3", nil]; + NSArray *array2 = [NSArray arrayWithObjects: array1, @"array2 object2", @"array2 object3", nil]; + // Expressions to test here for NSArray: + // expression [nil_mutable_array count] + // expression [array1 count] + // expression array1.count + // expression [array2 count] + // expression array2.count + id obj; + // After each object at index call, use expression and validate object + obj = [array1 objectAtIndex: 0]; // Break here for NSArray tests + obj = [array1 objectAtIndex: 1]; + obj = [array1 objectAtIndex: 2]; + + obj = [array2 objectAtIndex: 0]; + obj = [array2 objectAtIndex: 1]; + obj = [array2 objectAtIndex: 2]; + NSUInteger count = [nil_mutable_array count]; + return 0; +} + + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + Test_Selector(); + Test_NSArray (); + Test_NSString (argv[0]); + Test_MyString (argv[0]); + + printf("sizeof(id) = %zu\n", sizeof(id)); + printf("sizeof(Class) = %zu\n", sizeof(Class)); + printf("sizeof(SEL) = %zu\n", sizeof(SEL)); + + [pool release]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/my-base.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/my-base.h new file mode 100644 index 00000000000..53202aa0de3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/my-base.h @@ -0,0 +1,8 @@ +@interface MyBase : NSObject +{ +#if !__OBJC2__ + int maybe_used; // The 1.0 runtime needs to have backed properties... +#endif +} +@property int propertyMovesThings; +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/my-base.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/my-base.m new file mode 100644 index 00000000000..0c316b244f2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/foundation/my-base.m @@ -0,0 +1,10 @@ +#import <Foundation/Foundation.h> +#import "my-base.h" +@implementation MyBase +#if __OBJC2__ +@synthesize propertyMovesThings; +#else +@synthesize propertyMovesThings = maybe_used; +#endif +@end + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/global_ptrs/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/global_ptrs/Makefile new file mode 100644 index 00000000000..afecbf96948 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/global_ptrs/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/global_ptrs/TestGlobalObjects.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/global_ptrs/TestGlobalObjects.py new file mode 100644 index 00000000000..5cc6f4e7ba9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/global_ptrs/TestGlobalObjects.py @@ -0,0 +1,57 @@ +"""Test that a global ObjC object found before the process is started updates correctly.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCGlobalVar(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + self.main_source = lldb.SBFileSpec("main.m") + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test that a global ObjC object found before the process is started updates correctly.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + bkpt = target.BreakpointCreateBySourceRegex('NSLog', self.main_source) + self.assertTrue(bkpt, VALID_BREAKPOINT) + + # Before we launch, make an SBValue for our global object pointer: + g_obj_ptr = target.FindFirstGlobalVariable("g_obj_ptr") + self.assertTrue(g_obj_ptr.GetError().Success(), "Made the g_obj_ptr") + self.assertTrue( + g_obj_ptr.GetValueAsUnsigned(10) == 0, + "g_obj_ptr is initially null") + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint(process, bkpt) + if len(threads) != 1: + self.fail("Failed to stop at breakpoint 1.") + + thread = threads[0] + + dyn_value = g_obj_ptr.GetDynamicValue(lldb.eDynamicCanRunTarget) + self.assertTrue( + dyn_value.GetError().Success(), + "Dynamic value is valid") + self.assertTrue(dyn_value.GetObjectDescription() == "Some NSString") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/global_ptrs/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/global_ptrs/main.m new file mode 100644 index 00000000000..977a984e06e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/global_ptrs/main.m @@ -0,0 +1,11 @@ +#import <Foundation/Foundation.h> + +id g_obj_ptr = nil; + +int +main() +{ + g_obj_ptr = @"Some NSString"; + NSLog(@"My string was %@.", g_obj_ptr); + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/InternalDefiner.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/InternalDefiner.h new file mode 100644 index 00000000000..59652d4b09c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/InternalDefiner.h @@ -0,0 +1,11 @@ +#import <Foundation/Foundation.h> +#import <stdint.h> + +@interface InternalDefiner : NSObject { +@public + uintptr_t foo; +} + +-(id)initWithFoo:(uintptr_t)f andBar:(uintptr_t)b; + +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/InternalDefiner.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/InternalDefiner.m new file mode 100644 index 00000000000..1a10ce021ce --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/InternalDefiner.m @@ -0,0 +1,31 @@ +#import "InternalDefiner.h" + +@interface InternalDefiner () { + uintptr_t bar; +} + +@end + +@implementation InternalDefiner + +-(id)init +{ + if (self = [super init]) + { + foo = 2; + bar = 3; + } + return self; +} + +-(id)initWithFoo:(uintptr_t)f andBar:(uintptr_t)b +{ + if (self = [super init]) + { + foo = f; + bar = b; + } + return self; +} + +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/Makefile new file mode 100644 index 00000000000..0664769456e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/Makefile @@ -0,0 +1,7 @@ +DYLIB_NAME := InternalDefiner +DYLIB_OBJC_SOURCES := InternalDefiner.m +OBJC_SOURCES := main.m + +LD_EXTRAS = -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/TestHiddenIvars.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/TestHiddenIvars.py new file mode 100644 index 00000000000..03a325ac49c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/TestHiddenIvars.py @@ -0,0 +1,238 @@ +"""Test that hidden ivars in a shared library are visible from the main executable.""" + + + +import unittest2 +import subprocess + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class HiddenIvarsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.source = 'main.m' + self.line = line_number(self.source, '// breakpoint1') + # The makefile names of the shared libraries as they appear in DYLIB_NAME. + # The names should have no loading "lib" or extension as they will be + # localized + self.shlib_names = ["InternalDefiner"] + + @skipUnlessDarwin + @skipIf( + debug_info=no_match("dsym"), + bugnumber="This test requires a stripped binary and a dSYM") + def test_expr_stripped(self): + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + else: + self.build() + self.expr(True) + + @skipUnlessDarwin + def test_expr(self): + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + else: + self.build() + self.expr(False) + + @skipUnlessDarwin + @skipIf( + debug_info=no_match("dsym"), + bugnumber="This test requires a stripped binary and a dSYM") + def test_frame_variable_stripped(self): + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + else: + self.build() + self.frame_var(True) + + @skipUnlessDarwin + def test_frame_variable(self): + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + else: + self.build() + self.frame_var(False) + + @unittest2.expectedFailure("rdar://18683637") + @skipUnlessDarwin + def test_frame_variable_across_modules(self): + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + else: + self.build() + self.common_setup(False) + self.expect( + "frame variable k->bar", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 3"]) + + def common_setup(self, strip): + + if strip: + self.assertTrue(subprocess.call( + ['/usr/bin/strip', '-Sx', + self.getBuildArtifact('libInternalDefiner.dylib')]) == 0, + 'stripping dylib succeeded') + self.assertTrue(subprocess.call( + ['/bin/rm', '-rf', + self.getBuildArtifact('libInternalDefiner.dylib.dSYM')]) == 0, + 'remove dylib dSYM file succeeded') + self.assertTrue(subprocess.call(['/usr/bin/strip', '-Sx', + self.getBuildArtifact("a.out") + ]) == 0, + 'stripping a.out succeeded') + # Create a target by the debugger. + target = self.dbg.CreateTarget(self.getBuildArtifact("a.out")) + self.assertTrue(target, VALID_TARGET) + + # Create the breakpoint inside function 'main'. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + # Register our shared libraries for remote targets so they get + # automatically uploaded + environment = self.registerSharedLibrariesWithTarget( + target, self.shlib_names) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line( + self, "main.m", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + def expr(self, strip): + self.common_setup(strip) + + # This should display correctly. + self.expect( + "expression (j->_definer->foo)", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 4"]) + + self.expect( + "expression (j->_definer->bar)", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 5"]) + + if strip: + self.expect( + "expression *(j->_definer)", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["foo = 4"]) + else: + self.expect( + "expression *(j->_definer)", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "foo = 4", + "bar = 5"]) + + self.expect("expression (k->foo)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 2"]) + + self.expect("expression (k->bar)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 3"]) + + self.expect( + "expression k.filteredDataSource", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + ' = 0x', + '"2 elements"']) + + if strip: + self.expect("expression *(k)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["foo = 2", ' = 0x', '"2 elements"']) + else: + self.expect( + "expression *(k)", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "foo = 2", + "bar = 3", + '_filteredDataSource = 0x', + '"2 elements"']) + + def frame_var(self, strip): + self.common_setup(strip) + + # This should display correctly. + self.expect( + "frame variable j->_definer->foo", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 4"]) + + if not strip: + self.expect( + "frame variable j->_definer->bar", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 5"]) + + if strip: + self.expect( + "frame variable *j->_definer", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["foo = 4"]) + else: + self.expect( + "frame variable *j->_definer", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "foo = 4", + "bar = 5"]) + + self.expect("frame variable k->foo", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["= 2"]) + + self.expect( + "frame variable k->_filteredDataSource", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + ' = 0x', + '"2 elements"']) + + if strip: + self.expect( + "frame variable *k", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "foo = 2", + '_filteredDataSource = 0x', + '"2 elements"']) + else: + self.expect( + "frame variable *k", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "foo = 2", + "bar = 3", + '_filteredDataSource = 0x', + '"2 elements"']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/main.m new file mode 100644 index 00000000000..1795d56e7d8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/hidden-ivars/main.m @@ -0,0 +1,54 @@ +#import <Foundation/Foundation.h> +#import "InternalDefiner.h" + +@interface Container : NSObject { +@public + InternalDefiner *_definer; +} + +-(id)init; +@end + +@implementation Container + +-(id)init +{ + if (self = [super init]) + { + _definer = [[InternalDefiner alloc] initWithFoo:4 andBar:5]; + } + return self; +} + +@end + +@interface InheritContainer : InternalDefiner +@property (nonatomic, strong) NSMutableArray *filteredDataSource; +-(id)init; +@end + +@implementation InheritContainer + +-(id)init +{ + if (self = [super initWithFoo:2 andBar:3]) + { + self.filteredDataSource = [NSMutableArray arrayWithObjects:@"hello", @"world", nil]; + } + return self; +} + +@end + +int main(int argc, const char * argv[]) +{ + @autoreleasepool { + Container *j = [[Container alloc] init]; + InheritContainer *k = [[InheritContainer alloc] init]; + + printf("ivar value = %u\n", (unsigned)j->_definer->foo); // breakpoint1 + printf("ivar value = %u\n", (unsigned)k->foo); + } + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/Makefile new file mode 100644 index 00000000000..ba7e23acaba --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/Makefile @@ -0,0 +1,13 @@ +CFLAGS := -g -O0 +CFLAGS_NO_DEBUG = + +all: aout + +aout: + $(CC) $(CFLAGS_NO_DEBUG) $(SRCDIR)/myclass.m -c -o myclass.o + $(CC) $(CFLAGS) myclass.o $(SRCDIR)/repro.m -framework Foundation + +clean:: + rm -f myclass.o + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/TestObjCiVarIMP.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/TestObjCiVarIMP.py new file mode 100644 index 00000000000..3019bcfc5cf --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/TestObjCiVarIMP.py @@ -0,0 +1,48 @@ +""" +Test that dynamically discovered ivars of type IMP do not crash LLDB +""" + + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCiVarIMPTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @skipIf(archs=['i386']) # objc file does not build for i386 + @no_debug_info_test + def test_imp_ivar_type(self): + """Test that dynamically discovered ivars of type IMP do not crash LLDB""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target from the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set up our breakpoint + + bkpt = lldbutil.run_break_set_by_source_regexp(self, "break here") + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + self.expect( + 'frame variable --ptr-depth=1 --show-types -d run -- object', + substrs=[ + '(MyClass *) object = 0x', + '(void *) myImp = 0x']) + self.expect( + 'disassemble --start-address `((MyClass*)object)->myImp`', + substrs=['-[MyClass init]']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/myclass.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/myclass.h new file mode 100644 index 00000000000..da28d1e0518 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/myclass.h @@ -0,0 +1,6 @@ +#import <Foundation/Foundation.h> + +@interface MyClass : NSObject +{} +- (id)init; +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/myclass.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/myclass.m new file mode 100644 index 00000000000..85b2fcfe9b3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/myclass.m @@ -0,0 +1,16 @@ +#import <Foundation/Foundation.h> +#import "myclass.h" + +@implementation MyClass +{ + IMP myImp; +} +- (id)init { + if (self = [super init]) + { + SEL theSelector = @selector(init); + self->myImp = [self methodForSelector:theSelector]; + } + return self; +} +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/repro.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/repro.m new file mode 100644 index 00000000000..14f911f07dd --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ivar-IMP/repro.m @@ -0,0 +1,7 @@ +#import <Foundation/Foundation.h> +#import "myclass.h" + +int main() { + id object = [MyClass new]; + return 0; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/Makefile new file mode 100644 index 00000000000..0d8068b3085 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/Makefile @@ -0,0 +1,5 @@ +CFLAGS_EXTRAS = -I$(BUILDDIR) +USE_PRIVATE_MODULE_CACHE := YES +OBJC_SOURCES := main.m foo.m + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/TestClangModulesAppUpdate.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/TestClangModulesAppUpdate.py new file mode 100644 index 00000000000..4bd136b7285 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/TestClangModulesAppUpdate.py @@ -0,0 +1,57 @@ + +import unittest2 +import os +import shutil + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestClangModuleAppUpdate(TestBase): + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @skipIf(debug_info=no_match(["gmodules"])) + def test_rebuild_app_modules_untouched(self): + with open(self.getBuildArtifact("module.modulemap"), "w") as f: + f.write(""" + module Foo { header "f.h" } + """) + with open(self.getBuildArtifact("f.h"), "w") as f: + f.write(""" + @import Foundation; + @interface Foo : NSObject { + int i; + } + +(instancetype)init; + @end + """) + + mod_cache = self.getBuildArtifact("private-module-cache") + import os + if os.path.isdir(mod_cache): + shutil.rmtree(mod_cache) + self.build() + self.assertTrue(os.path.isdir(mod_cache), "module cache exists") + + target, process, _, bkpt = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.m")) + bar = target.FindTypes('Bar').GetTypeAtIndex(0) + foo = bar.GetDirectBaseClassAtIndex(0).GetType() + self.assertEqual(foo.GetNumberOfFields(), 1) + self.assertEqual(foo.GetFieldAtIndex(0).GetName(), "i") + + # Rebuild. + process.Kill() + os.remove(self.getBuildArtifact('main.o')) + os.remove(self.getBuildArtifact('a.out')) + self.build() + + # Reattach. + target, process, _, _ = lldbutil.run_to_breakpoint_do_run(self, target, bkpt) + bar = target.FindTypes('Bar').GetTypeAtIndex(0) + foo = bar.GetDirectBaseClassAtIndex(0).GetType() + self.assertEqual(foo.GetNumberOfFields(), 1) + self.assertEqual(foo.GetFieldAtIndex(0).GetName(), "i") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/foo.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/foo.m new file mode 100644 index 00000000000..83a5abc04e2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/foo.m @@ -0,0 +1,7 @@ +@import Foundation; +@import Foo; +@implementation Foo ++(instancetype)init { + return [super init]; +} +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/main.m new file mode 100644 index 00000000000..37ec1f37b57 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/main.m @@ -0,0 +1,17 @@ +@import Umbrella; + +@interface Bar : Foo ++(instancetype)init; +@end + +@implementation Bar ++(instancetype)init { + return [super init]; +} +@end + +int main(int argc, char **argv) { + id bar = [Bar new]; + [bar i]; // break here + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/module.modulemap b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/module.modulemap new file mode 100644 index 00000000000..c142410cd07 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/module.modulemap @@ -0,0 +1,4 @@ +module Umbrella { + header "umbrella.h" + export * +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/umbrella.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/umbrella.h new file mode 100644 index 00000000000..375d3ea2a04 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-app-update/umbrella.h @@ -0,0 +1 @@ +@import Foo; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/Makefile new file mode 100644 index 00000000000..3b2bd504c89 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/Makefile @@ -0,0 +1,5 @@ +OBJC_SOURCES := main.m + +CFLAGS_EXTRAS = $(MANDATORY_MODULE_BUILD_CFLAGS) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/TestModulesAutoImport.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/TestModulesAutoImport.py new file mode 100644 index 00000000000..449e5b50d05 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/TestModulesAutoImport.py @@ -0,0 +1,48 @@ +"""Test that importing modules in Objective-C works as expected.""" + + + +import unittest2 +import lldb + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCModulesAutoImportTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.m', '// Set breakpoint 0 here.') + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + def test_expr(self): + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line( + self, "main.m", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + self.runCmd("settings set target.auto-import-clang-modules true") + + self.expect("p getpid()", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["pid_t"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/main.m new file mode 100644 index 00000000000..5452ffd9bd1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-auto-import/main.m @@ -0,0 +1,7 @@ +@import Darwin; + +int main() +{ + size_t ret = printf("Stop here\n"); // Set breakpoint 0 here. + return ret; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/Makefile new file mode 100644 index 00000000000..d0aadc1af9e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/Makefile @@ -0,0 +1,2 @@ +OBJC_SOURCES := main.m +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/TestClangModulesCache.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/TestClangModulesCache.py new file mode 100644 index 00000000000..3a12b23a79c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/TestClangModulesCache.py @@ -0,0 +1,35 @@ +"""Test that the clang modules cache directory can be controlled.""" + + + +import unittest2 +import os +import shutil + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCModulesTestCase(TestBase): + NO_DEBUG_INFO_TESTCASE = True + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test_expr(self): + self.build() + self.main_source_file = lldb.SBFileSpec("main.m") + self.runCmd("settings set target.auto-import-clang-modules true") + mod_cache = self.getBuildArtifact("my-clang-modules-cache") + if os.path.isdir(mod_cache): + shutil.rmtree(mod_cache) + self.assertFalse(os.path.isdir(mod_cache), + "module cache should not exist") + self.runCmd('settings set symbols.clang-modules-cache-path "%s"' % mod_cache) + self.runCmd('settings set target.clang-module-search-paths "%s"' + % self.getSourceDir()) + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, "Set breakpoint here", self.main_source_file) + self.runCmd("expr @import Foo") + self.assertTrue(os.path.isdir(mod_cache), "module cache exists") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/f.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/f.h new file mode 100644 index 00000000000..56757a701bf --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/f.h @@ -0,0 +1 @@ +void f() {} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/main.m new file mode 100644 index 00000000000..6009d28d81b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/main.m @@ -0,0 +1,5 @@ +#include "f.h" +int main() { + f(); // Set breakpoint here. + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/module.modulemap b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/module.modulemap new file mode 100644 index 00000000000..f54534a1c07 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-cache/module.modulemap @@ -0,0 +1,3 @@ +module Foo { + header "f.h" +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/Makefile new file mode 100644 index 00000000000..59bf009f686 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/Makefile @@ -0,0 +1,16 @@ +OBJC_SOURCES := main.m +CFLAGS_EXTRAS = -I$(BUILDDIR) +USE_PRIVATE_MODULE_CACHE = YES + +.PHONY: update-module + +all: $(EXE) + $(MAKE) -f $(SRCDIR)/Makefile update-module + +include Makefile.rules + +update-module: + echo "forcing an update of f.pcm" + echo "typedef int something_other;" > $(BUILDDIR)/f.h + $(CC) $(CFLAGS) $(MANDATORY_MODULE_BUILD_CFLAGS) \ + -c $(SRCDIR)/other.m -o $(BUILDDIR)/other.o diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/TestClangModulesHashMismatch.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/TestClangModulesHashMismatch.py new file mode 100644 index 00000000000..606bd300c24 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/TestClangModulesHashMismatch.py @@ -0,0 +1,45 @@ + +import unittest2 +import os +import shutil + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestClangModuleHashMismatch(TestBase): + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @skipIf(debug_info=no_match(["gmodules"])) + def test_expr(self): + with open(self.getBuildArtifact("module.modulemap"), "w") as f: + f.write(""" + module Foo { header "f.h" } + """) + with open(self.getBuildArtifact("f.h"), "w") as f: + f.write(""" + typedef int my_int; + void f() {} + """) + + mod_cache = self.getBuildArtifact("private-module-cache") + if os.path.isdir(mod_cache): + shutil.rmtree(mod_cache) + self.build() + self.assertTrue(os.path.isdir(mod_cache), "module cache exists") + + logfile = self.getBuildArtifact("host.log") + self.runCmd("log enable -v -f %s lldb host" % logfile) + target, _, _, _ = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.m")) + target.GetModuleAtIndex(0).FindTypes('my_int') + + found = False + with open(logfile, 'r') as f: + for line in f: + if "hash mismatch" in line and "Foo" in line: + found = True + self.assertTrue(found) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/main.m new file mode 100644 index 00000000000..5065222731e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/main.m @@ -0,0 +1,6 @@ +#include "f.h" +int main(int argc, char **argv) { + my_int i = argc; + f(); // break here + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/other.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/other.m new file mode 100644 index 00000000000..0afd3eb078d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-hash-mismatch/other.m @@ -0,0 +1,4 @@ +#include "f.h" +something_other f() { + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/Makefile new file mode 100644 index 00000000000..abb36e281b2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/Makefile @@ -0,0 +1,5 @@ +OBJC_SOURCES := main.m myModule.m + +CFLAGS_EXTRAS = $(MANDATORY_MODULE_BUILD_CFLAGS) +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/TestIncompleteModules.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/TestIncompleteModules.py new file mode 100644 index 00000000000..8fed6133f7d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/TestIncompleteModules.py @@ -0,0 +1,61 @@ +"""Test that DWARF types are trusted over module types""" + + + +import unittest2 + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class IncompleteModulesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.m', '// Set breakpoint 0 here.') + + @skipUnlessDarwin + @skipIf(debug_info=no_match(["gmodules"])) + def test_expr(self): + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + lldbutil.run_break_set_by_file_and_line( + self, "main.m", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + self.runCmd( + "settings set target.clang-module-search-paths \"" + + self.getSourceDir() + + "\"") + + self.expect("expr @import myModule; 3", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["int", "3"]) + + self.expect( + "expr private_func()", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "int", + "5"]) + + self.expect("expr MY_MIN(2,3)", "#defined macro was found", + substrs=["int", "2"]) + + self.expect("expr MY_MAX(2,3)", "#undefd macro was correctly not found", + error=True) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/main.m new file mode 100644 index 00000000000..bfa0b06f1a1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/main.m @@ -0,0 +1,7 @@ +@import myModule; +@import minmax; + +int main(int argc, char **argv) { + public_func(); // Set breakpoint 0 here. + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/minmax.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/minmax.h new file mode 100644 index 00000000000..efad1201695 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/minmax.h @@ -0,0 +1,2 @@ +#define MY_MIN(A, B) (((A) < (B)) ? (A) : (B)) +#define MY_MAX(A, B) (((A) < (B)) ? (B) : (A)) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/module.map b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/module.map new file mode 100644 index 00000000000..0dd9fadb262 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/module.map @@ -0,0 +1,9 @@ +module myModule { + header "myModule.h" + export * +} + +module minmax { + header "minmax.h" + export * +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/myModule.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/myModule.h new file mode 100644 index 00000000000..04ec3885c83 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/myModule.h @@ -0,0 +1,5 @@ +@import minmax; + +#undef MY_MAX + +extern void public_func(); diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/myModule.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/myModule.m new file mode 100644 index 00000000000..372a3288932 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-incomplete/myModule.m @@ -0,0 +1,8 @@ +#include "myModule.h" + +void public_func() {} + +int private_func() { + return 5; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/Makefile new file mode 100644 index 00000000000..b4afe2cb3e8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/Makefile @@ -0,0 +1,7 @@ +C_SOURCES := myModule.c + +OBJC_SOURCES := main.m + +CFLAGS_EXTRAS = $(MANDATORY_MODULE_BUILD_CFLAGS) -I$(BUILDDIR) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/TestModulesInlineFunctions.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/TestModulesInlineFunctions.py new file mode 100644 index 00000000000..e2e335a1c43 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/TestModulesInlineFunctions.py @@ -0,0 +1,38 @@ +"""Test that inline functions from modules are imported correctly""" + + + + +import unittest2 + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ModulesInlineFunctionsTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"], debug_info=no_match(["gmodules"])) + def test_expr(self): + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_to_source_breakpoint( + self, '// Set breakpoint here.', lldb.SBFileSpec('main.m')) + + self.runCmd( + "settings set target.clang-module-search-paths \"" + + self.getSourceDir() + + "\"") + + self.expect("expr @import myModule; 3", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["int", "3"]) + + self.expect("expr isInline(2)", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["4"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/main.m new file mode 100644 index 00000000000..13a5bf316ee --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/main.m @@ -0,0 +1,9 @@ +@import Darwin; +@import myModule; + +int main() +{ + int a = isInline(2); + int b = notInline(); + printf("%d %d\n", a, b); // Set breakpoint here. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/module.map b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/module.map new file mode 100644 index 00000000000..2ef8064d15b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/module.map @@ -0,0 +1,4 @@ +module myModule { + header "myModule.h" + export * +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/myModule.c b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/myModule.c new file mode 100644 index 00000000000..ad3c85d155e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/myModule.c @@ -0,0 +1,7 @@ +#include "myModule.h" + +int notInline() +{ + return 3; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/myModule.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/myModule.h new file mode 100644 index 00000000000..d50d0101f64 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-inline-functions/myModule.h @@ -0,0 +1,7 @@ +int notInline(); + +static __inline__ __attribute__ ((always_inline)) int isInline(int a) +{ + int b = a + a; + return b; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/Makefile new file mode 100644 index 00000000000..5d0a2209ef7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/Makefile @@ -0,0 +1,3 @@ +CFLAGS_EXTRAS = -I$(BUILDDIR) +USE_PRIVATE_MODULE_CACHE = YES +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/TestClangModulesUpdate.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/TestClangModulesUpdate.py new file mode 100644 index 00000000000..e36a2278daa --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/TestClangModulesUpdate.py @@ -0,0 +1,65 @@ + +import unittest2 +import os +import shutil + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestClangModuleUpdate(TestBase): + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + @skipIf(debug_info=no_match(["gmodules"])) + def test_expr(self): + with open(self.getBuildArtifact("module.modulemap"), "w") as f: + f.write(""" + module Foo { header "f.h" } + """) + with open(self.getBuildArtifact("f.h"), "w") as f: + f.write(""" + struct Q { int i; }; + void f() {} + """) + + mod_cache = self.getBuildArtifact("private-module-cache") + if os.path.isdir(mod_cache): + shutil.rmtree(mod_cache) + d = {'OBJC_SOURCES': 'first.m'} + self.build(dictionary=d) + self.assertTrue(os.path.isdir(mod_cache), "module cache exists") + + logfile = self.getBuildArtifact("modules.log") + self.runCmd("log enable -f %s lldb module" % logfile) + target, process, _, bkpt = lldbutil.run_to_name_breakpoint(self, "main") + self.assertIn("int i", str(target.FindTypes('Q').GetTypeAtIndex(0))) + self.expect("image list -g", patterns=[r'first\.o', r'Foo.*\.pcm']) + + # Update the module. + with open(self.getBuildArtifact("f.h"), "w") as f: + f.write(""" + struct S { int i; }; + struct S getS() { struct S r = {1}; return r; } + void f() {} + """) + + # Rebuild. + d = {'OBJC_SOURCES': 'second.m'} + self.build(dictionary=d) + + # Reattach. + process.Kill() + target, process, _, _ = lldbutil.run_to_breakpoint_do_run(self, target, bkpt) + self.assertIn("int i", str(target.FindTypes('S').GetTypeAtIndex(0))) + self.expect("image list -g", patterns=[r'second\.o', r'Foo.*\.pcm']) + + # Check log file. + found = False + with open(logfile, 'r') as f: + for line in f: + if "module changed" in line and "Foo" in line: + found = True + self.assertTrue(found) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/first.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/first.m new file mode 100644 index 00000000000..bcc458ffb8e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/first.m @@ -0,0 +1,5 @@ +@import Umbrella; +int main(int argc, char **argv) { + f(); // break here + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/module.modulemap b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/module.modulemap new file mode 100644 index 00000000000..c142410cd07 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/module.modulemap @@ -0,0 +1,4 @@ +module Umbrella { + header "umbrella.h" + export * +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/second.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/second.m new file mode 100644 index 00000000000..bce925cb057 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/second.m @@ -0,0 +1,5 @@ +@import Umbrella; +int main() { + struct S s = getS(); // break here + return s.i; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/umbrella.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/umbrella.h new file mode 100644 index 00000000000..375d3ea2a04 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules-update/umbrella.h @@ -0,0 +1 @@ +@import Foo; diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules/Makefile new file mode 100644 index 00000000000..37dd8f40a9d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules/Makefile @@ -0,0 +1,6 @@ +OBJC_SOURCES := main.m + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules/TestObjCModules.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules/TestObjCModules.py new file mode 100644 index 00000000000..695eac9ee85 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules/TestObjCModules.py @@ -0,0 +1,79 @@ +"""Test that importing modules in Objective-C works as expected.""" + + + +import unittest2 + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCModulesTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.m', '// Set breakpoint 0 here.') + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + def test_expr(self): + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line( + self, "main.m", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + self.expect("expr @import Darwin; 3", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["int", "3"]) + + self.expect("expr getpid()", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["pid_t"]) + + self.expect( + "expr @import Foundation; 4", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "int", + "4"]) + + # Type lookup should still work and print something reasonable + # for types from the module. + self.expect("type lookup NSObject", substrs=["instanceMethod"]) + + self.expect("expr string.length", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["NSUInteger", "5"]) + + self.expect("expr array.count", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["NSUInteger", "3"]) + + self.expect( + "p *[NSURL URLWithString:@\"http://lldb.llvm.org\"]", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "NSURL", + "isa", + "_urlString"]) + + self.expect( + "p [NSURL URLWithString:@\"http://lldb.llvm.org\"].scheme", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["http"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules/main.m new file mode 100644 index 00000000000..99b50f9620d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/modules/main.m @@ -0,0 +1,12 @@ +#import <Foundation/Foundation.h> + +int main() +{ + @autoreleasepool + { + NSString *string = @"Hello"; + NSArray *array = @[ @1, @2, @3 ]; + + NSLog(@"Stop here"); // Set breakpoint 0 here. + } +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc++/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc++/Makefile new file mode 100644 index 00000000000..e8a4b0cc29c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc++/Makefile @@ -0,0 +1,4 @@ +OBJCXX_SOURCES := main.mm +LD_EXTRAS = -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc++/TestObjCXX.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc++/TestObjCXX.py new file mode 100644 index 00000000000..344af99f589 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc++/TestObjCXX.py @@ -0,0 +1,33 @@ +""" +Make sure that ivars of Objective-C++ classes are visible in LLDB. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCXXTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test_break(self): + """Test ivars of Objective-C++ classes""" + if self.getArchitecture() == 'i386': + self.skipTest("requires Objective-C 2.0 runtime") + + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_source_regexp( + self, 'breakpoint 1', num_expected_locations=1) + + self.runCmd("run", RUN_SUCCEEDED) + + self.expect("expr f->f", "Found ivar in class", + substrs=["= 3"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc++/main.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc++/main.mm new file mode 100644 index 00000000000..50d2f0a8df3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc++/main.mm @@ -0,0 +1,19 @@ +#include <Foundation/NSObject.h> + +@interface F : NSObject +@end + +@implementation F +{ +@public + int f; +} + +@end + +int main(int argc, char* argv[]) +{ + F* f = [F new]; + f->f = 3; + return 0; // breakpoint 1 +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/Makefile new file mode 100644 index 00000000000..ad28ecfeb5d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS = -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/TestObjCBaseClassSBType.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/TestObjCBaseClassSBType.py new file mode 100644 index 00000000000..8f974f03838 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/TestObjCBaseClassSBType.py @@ -0,0 +1,64 @@ +""" +Use lldb Python API to test base class resolution for ObjC classes +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCDynamicValueTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + self.line = line_number('main.m', '// Set breakpoint here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_get_baseclass(self): + """Test fetching ObjC dynamic values.""" + if self.getArchitecture() == 'i386': + # rdar://problem/9946499 + self.skipTest("Dynamic types for ObjC V1 runtime not implemented") + + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target from the debugger. + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set up our breakpoints: + + target.BreakpointCreateByLocation('main.m', self.line) + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + var = self.frame().FindVariable("foo") + var_ptr_type = var.GetType() + var_pte_type = var_ptr_type.GetPointeeType() + self.assertTrue( + var_ptr_type.GetNumberOfDirectBaseClasses() == 1, + "Foo * has one base class") + self.assertTrue( + var_pte_type.GetNumberOfDirectBaseClasses() == 1, + "Foo has one base class") + + self.assertTrue(var_ptr_type.GetDirectBaseClassAtIndex( + 0).IsValid(), "Foo * has a valid base class") + self.assertTrue(var_pte_type.GetDirectBaseClassAtIndex( + 0).IsValid(), "Foo * has a valid base class") + + self.assertTrue(var_ptr_type.GetDirectBaseClassAtIndex(0).GetName() == var_pte_type.GetDirectBaseClassAtIndex( + 0).GetName(), "Foo and its pointer type don't agree on their base class") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/main.m new file mode 100644 index 00000000000..3ec78fd0bd6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-baseclass-sbtype/main.m @@ -0,0 +1,22 @@ +#import <Foundation/Foundation.h> + +@interface Foo : NSObject {} + +-(id) init; + +@end + +@implementation Foo + +-(id) init +{ + return self = [super init]; +} +@end +int main () +{ + Foo *foo = [Foo new]; + NSLog(@"a"); // Set breakpoint here. + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/Makefile new file mode 100644 index 00000000000..99998b20bcb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py new file mode 100644 index 00000000000..d07b827e771 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py @@ -0,0 +1,61 @@ +"""Test that the expression parser doesn't get confused by 'id' and 'Class'""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCBuiltinTypes(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "main.cpp" + self.break_line = line_number( + self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + #<rdar://problem/10591460> [regression] Can't print ivar value: error: reference to 'id' is ambiguous + def test_with_python_api(self): + """Test expression parser respect for ObjC built-in types.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + bpt = target.BreakpointCreateByLocation( + self.main_source, self.break_line) + self.assertTrue(bpt, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread_list = lldbutil.get_threads_stopped_at_breakpoint(process, bpt) + + # Make sure we stopped at the first breakpoint. + self.assertTrue( + len(thread_list) != 0, + "No thread stopped at our breakpoint.") + self.assertTrue(len(thread_list) == 1, + "More than one thread stopped at our breakpoint.") + + # Now make sure we can call a function in the class method we've + # stopped in. + frame = thread_list[0].GetFrameAtIndex(0) + self.assertTrue(frame, "Got a valid frame 0 frame.") + + self.expect("expr (foo)", patterns=["\(ns::id\) \$.* = 0"]) + + self.expect("expr id my_id = 0; my_id", patterns=["\(id\) \$.* = nil"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/main.cpp b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/main.cpp new file mode 100644 index 00000000000..6dd8cbc6e9f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-builtin-types/main.cpp @@ -0,0 +1,9 @@ +namespace ns { + typedef int id; +}; + +int main() +{ + ns::id foo = 0; + return foo; // Set breakpoint here. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-checker/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-checker/Makefile new file mode 100644 index 00000000000..afecbf96948 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-checker/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-checker/TestObjCCheckers.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-checker/TestObjCCheckers.py new file mode 100644 index 00000000000..ac2dc2a3899 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-checker/TestObjCCheckers.py @@ -0,0 +1,90 @@ +""" +Use lldb Python API to make sure the dynamic checkers are doing their jobs. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCCheckerTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + NO_DEBUG_INFO_TESTCASE = True + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + # Find the line number to break for main.c. + self.source_name = 'main.m' + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_objc_checker(self): + """Test that checkers catch unrecognized selectors""" + if self.getArchitecture() == 'i386': + self.skipTest("requires Objective-C 2.0 runtime") + + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target from the debugger. + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set up our breakpoints: + + main_bkpt = target.BreakpointCreateBySourceRegex( + "Set a breakpoint here.", lldb.SBFileSpec(self.source_name)) + self.assertTrue(main_bkpt and + main_bkpt.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, main_bkpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + + # + # The class Simple doesn't have a count method. Make sure that we don't + # actually try to send count but catch it as an unrecognized selector. + + frame = thread.GetFrameAtIndex(0) + expr_value = frame.EvaluateExpression("(int) [my_simple count]", False) + expr_error = expr_value.GetError() + + self.assertTrue(expr_error.Fail()) + + # Make sure the call produced no NSLog stdout. + stdout = process.GetSTDOUT(100) + self.assertTrue(stdout is None or (len(stdout) == 0)) + + # Make sure the error is helpful: + err_string = expr_error.GetCString() + self.assertTrue("selector" in err_string) + + # + # Check that we correctly insert the checker for an + # ObjC method with the struct return convention. + # Getting this wrong would cause us to call the checker + # with the wrong arguments, and the checker would crash + # So I'm just checking "expression runs successfully" here: + # + expr_value = frame.EvaluateExpression("[my_simple getBigStruct]", False) + expr_error = expr_value.GetError() + + self.assertTrue(expr_error.Success()) + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-checker/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-checker/main.m new file mode 100644 index 00000000000..de73e688f25 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-checker/main.m @@ -0,0 +1,47 @@ +#import <Foundation/Foundation.h> + +// This should be a big enough struct that it will force +// the struct return convention: +typedef struct BigStruct { + float a, b, c, d, e, f, g, h, i, j, k, l; +} BigStruct; + + +@interface Simple : NSObject +{ + int _value; +} +- (int) value; +- (void) setValue: (int) newValue; +- (BigStruct) getBigStruct; +@end + +@implementation Simple +- (int) value +{ + return _value; +} + +- (void) setValue: (int) newValue +{ + _value = newValue; +} + +- (BigStruct) getBigStruct +{ + BigStruct big_struct = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, + 7.0, 8.0, 9.0, 10.0, 11.0, 12.0}; + return big_struct; +} +@end + +int main () +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + Simple *my_simple = [[Simple alloc] init]; + my_simple.value = 20; + // Set a breakpoint here. + NSLog (@"Object has value: %d.", my_simple.value); + [pool drain]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-class-method/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-class-method/Makefile new file mode 100644 index 00000000000..e6db3dee37b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-class-method/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := class.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-class-method/TestObjCClassMethod.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-class-method/TestObjCClassMethod.py new file mode 100644 index 00000000000..46cddd635c0 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-class-method/TestObjCClassMethod.py @@ -0,0 +1,66 @@ +"""Test calling functions in class methods.""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCClassMethod(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "class.m" + self.break_line = line_number( + self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test calling functions in class methods.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + bpt = target.BreakpointCreateByLocation( + self.main_source, self.break_line) + self.assertTrue(bpt, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread_list = lldbutil.get_threads_stopped_at_breakpoint(process, bpt) + + # Make sure we stopped at the first breakpoint. + self.assertTrue( + len(thread_list) != 0, + "No thread stopped at our breakpoint.") + self.assertTrue(len(thread_list) == 1, + "More than one thread stopped at our breakpoint.") + + # Now make sure we can call a function in the class method we've + # stopped in. + frame = thread_list[0].GetFrameAtIndex(0) + self.assertTrue(frame, "Got a valid frame 0 frame.") + + cmd_value = frame.EvaluateExpression( + "(int)[Foo doSomethingWithString:@\"Hello\"]") + if self.TraceOn(): + if cmd_value.IsValid(): + print("cmd_value is valid") + print("cmd_value has the value %d" % cmd_value.GetValueAsUnsigned()) + self.assertTrue(cmd_value.IsValid()) + self.assertTrue(cmd_value.GetValueAsUnsigned() == 5) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-class-method/class.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-class-method/class.m new file mode 100644 index 00000000000..18a2c2729be --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-class-method/class.m @@ -0,0 +1,24 @@ +#import <Foundation/Foundation.h> + +@interface Foo : NSObject ++(int) doSomethingWithString: (NSString *) string; +-(int) doSomethingInstance: (NSString *) string; +@end + +@implementation Foo ++(int) doSomethingWithString: (NSString *) string +{ + NSLog (@"String is: %@.", string); + return [string length]; +} + +-(int) doSomethingInstance: (NSString *)string +{ + return [Foo doSomethingWithString:string]; +} +@end + +int main() +{ + return 0; // Set breakpoint here. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/.categories b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/.categories new file mode 100644 index 00000000000..9526bab96fb --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/.categories @@ -0,0 +1 @@ +dyntype diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/Makefile new file mode 100644 index 00000000000..9ff3ce6e4a5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/Makefile @@ -0,0 +1,5 @@ +OBJC_SOURCES := main.m + +include Makefile.rules + +LD_EXTRAS = -framework Foundation diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py new file mode 100644 index 00000000000..1851bc33264 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/TestObjCDynamicSBType.py @@ -0,0 +1,90 @@ +""" +Test that we are able to properly report a usable dynamic type +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class ObjCDynamicSBTypeTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to break inside main(). + self.main_source = "main.m" + self.line = line_number(self.main_source, '// Set breakpoint here.') + + @skipIf(archs="i[3-6]86") + def test_dyn(self): + """Test that we are able to properly report a usable dynamic type.""" + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + + exe = self.getBuildArtifact(self.exe_name) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + self.main_source, + self.line, + num_expected_locations=1, + loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + v_object = self.frame().FindVariable( + "object").GetDynamicValue(lldb.eDynamicCanRunTarget) + v_base = self.frame().FindVariable( + "base").GetDynamicValue(lldb.eDynamicCanRunTarget) + self.assertTrue( + v_object.GetTypeName() == "MyDerivedClass *", + "The NSObject is properly type-named") + self.assertTrue( + v_base.GetTypeName() == "MyDerivedClass *", + "The Base is properly type-named") + object_type = v_object.GetType() + base_type = v_base.GetType() + self.assertTrue( + object_type.GetName() == "MyDerivedClass *", + "The dynamic SBType for NSObject is for the correct type") + self.assertTrue( + base_type.GetName() == "MyDerivedClass *", + "The dynamic SBType for Base is for the correct type") + object_pointee_type = object_type.GetPointeeType() + base_pointee_type = base_type.GetPointeeType() + self.assertTrue( + object_pointee_type.GetName() == "MyDerivedClass", + "The dynamic type for NSObject figures out its pointee type just fine") + self.assertTrue( + base_pointee_type.GetName() == "MyDerivedClass", + "The dynamic type for Base figures out its pointee type just fine") + + self.assertTrue( + object_pointee_type.GetDirectBaseClassAtIndex(0).GetName() == "MyBaseClass", + "The dynamic type for NSObject can go back to its base class") + self.assertTrue( + base_pointee_type.GetDirectBaseClassAtIndex(0).GetName() == "MyBaseClass", + "The dynamic type for Base can go back to its base class") + + self.assertTrue(object_pointee_type.GetDirectBaseClassAtIndex(0).GetType().GetDirectBaseClassAtIndex( + 0).GetName() == "NSObject", "The dynamic type for NSObject can go up the hierarchy") + self.assertTrue(base_pointee_type.GetDirectBaseClassAtIndex(0).GetType().GetDirectBaseClassAtIndex( + 0).GetName() == "NSObject", "The dynamic type for Base can go up the hierarchy") + + self.assertTrue( + object_pointee_type.GetNumberOfFields() == 2, + "The dynamic type for NSObject has 2 fields") + self.assertTrue( + base_pointee_type.GetNumberOfFields() == 2, + "The dynamic type for Base has 2 fields") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/main.m new file mode 100644 index 00000000000..f3587b52cd5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dyn-sbtype/main.m @@ -0,0 +1,53 @@ +#import <Foundation/Foundation.h> + +@interface MyBaseClass : NSObject +{} +-(id) init; +-(int) getInt; +@end + +@implementation MyBaseClass +- (id) init { + return (self = [super init]); +} + +- (int) getInt { + return 1; +} +@end + +@interface MyDerivedClass : MyBaseClass +{ + int x; + int y; +} +-(id) init; +-(int) getInt; +@end + +@implementation MyDerivedClass +- (id) init { + self = [super init]; + if (self) { + self-> x = 0; + self->y = 1; + } + return self; +} + +- (int) getInt { + y = x++; + return x; +} +@end + + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + NSObject* object = [[MyDerivedClass alloc] init]; + MyBaseClass* base = [[MyDerivedClass alloc] init]; + [pool release]; // Set breakpoint here. + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/Makefile new file mode 100644 index 00000000000..a34977712c3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := dynamic-value.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py new file mode 100644 index 00000000000..5a6ec4ed39d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py @@ -0,0 +1,207 @@ +""" +Use lldb Python API to test dynamic values in ObjC +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCDynamicValueTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + # Find the line number to break for main.c. + + self.source_name = 'dynamic-value.m' + self.set_property_line = line_number( + self.source_name, + '// This is the line in setProperty, make sure we step to here.') + self.handle_SourceBase = line_number( + self.source_name, '// Break here to check dynamic values.') + self.main_before_setProperty_line = line_number( + self.source_name, '// Break here to see if we can step into real method.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + @expectedFailureDarwin("llvm.org/pr20271 rdar://18684107") + def test_get_objc_dynamic_vals(self): + """Test fetching ObjC dynamic values.""" + if self.getArchitecture() == 'i386': + # rdar://problem/9946499 + self.skipTest("Dynamic types for ObjC V1 runtime not implemented") + + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target from the debugger. + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set up our breakpoints: + + handle_SourceBase_bkpt = target.BreakpointCreateByLocation( + self.source_name, self.handle_SourceBase) + self.assertTrue(handle_SourceBase_bkpt and + handle_SourceBase_bkpt.GetNumLocations() == 1, + VALID_BREAKPOINT) + + main_before_setProperty_bkpt = target.BreakpointCreateByLocation( + self.source_name, self.main_before_setProperty_line) + self.assertTrue(main_before_setProperty_bkpt and + main_before_setProperty_bkpt.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, main_before_setProperty_bkpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + + # + # At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived + # make sure we can get that properly: + + frame = thread.GetFrameAtIndex(0) + myObserver = frame.FindVariable( + 'myObserver', lldb.eDynamicCanRunTarget) + self.assertTrue(myObserver) + myObserver_source = myObserver.GetChildMemberWithName( + '_source', lldb.eDynamicCanRunTarget) + self.examine_SourceDerived_ptr(myObserver_source) + + # + # Make sure a static value can be correctly turned into a dynamic + # value. + + frame = thread.GetFrameAtIndex(0) + myObserver_static = frame.FindVariable( + 'myObserver', lldb.eNoDynamicValues) + self.assertTrue(myObserver_static) + myObserver = myObserver_static.GetDynamicValue( + lldb.eDynamicCanRunTarget) + myObserver_source = myObserver.GetChildMemberWithName( + '_source', lldb.eDynamicCanRunTarget) + self.examine_SourceDerived_ptr(myObserver_source) + + # The "frame var" code uses another path to get into children, so let's + # make sure that works as well: + + result = lldb.SBCommandReturnObject() + + self.expect( + 'frame var -d run-target myObserver->_source', + 'frame var finds its way into a child member', + patterns=['\(SourceDerived \*\)']) + + # check that our ObjC GetISA() does a good job at hiding KVO swizzled + # classes + + self.expect( + 'frame var -d run-target myObserver->_source -T', + 'the KVO-ed class is hidden', + substrs=['SourceDerived']) + + self.expect( + 'frame var -d run-target myObserver->_source -T', + 'the KVO-ed class is hidden', + matching=False, + substrs=['NSKVONotify']) + + # This test is not entirely related to the main thrust of this test case, but since we're here, + # try stepping into setProperty, and make sure we get into the version + # in Source: + + thread.StepInto() + + threads = lldbutil.get_stopped_threads( + process, lldb.eStopReasonPlanComplete) + self.assertTrue(len(threads) == 1) + line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry() + + self.assertEqual(line_entry.GetLine(), self.set_property_line) + self.assertEqual( + line_entry.GetFileSpec().GetFilename(), + self.source_name) + + # Okay, back to the main business. Continue to the handle_SourceBase + # and make sure we get the correct dynamic value. + + threads = lldbutil.continue_to_breakpoint( + process, handle_SourceBase_bkpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + + frame = thread.GetFrameAtIndex(0) + + # Get "object" using FindVariable: + + noDynamic = lldb.eNoDynamicValues + useDynamic = lldb.eDynamicCanRunTarget + + object_static = frame.FindVariable('object', noDynamic) + object_dynamic = frame.FindVariable('object', useDynamic) + + # Delete this object to make sure that this doesn't cause havoc with + # the dynamic object that depends on it. + del (object_static) + + self.examine_SourceDerived_ptr(object_dynamic) + + # Get "this" using FindValue, make sure that works too: + object_static = frame.FindValue( + 'object', lldb.eValueTypeVariableArgument, noDynamic) + object_dynamic = frame.FindValue( + 'object', lldb.eValueTypeVariableArgument, useDynamic) + del (object_static) + self.examine_SourceDerived_ptr(object_dynamic) + + # Get "this" using the EvaluateExpression: + object_static = frame.EvaluateExpression('object', noDynamic) + object_dynamic = frame.EvaluateExpression('object', useDynamic) + del (object_static) + self.examine_SourceDerived_ptr(object_dynamic) + + # Continue again to the handle_SourceBase and make sure we get the correct dynamic value. + # This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so + # its isa pointer points to SourceBase not NSKVOSourceBase or + # whatever... + + threads = lldbutil.continue_to_breakpoint( + process, handle_SourceBase_bkpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + + frame = thread.GetFrameAtIndex(0) + + # Get "object" using FindVariable: + + object_static = frame.FindVariable('object', noDynamic) + object_dynamic = frame.FindVariable('object', useDynamic) + + # Delete this object to make sure that this doesn't cause havoc with + # the dynamic object that depends on it. + del (object_static) + + self.examine_SourceDerived_ptr(object_dynamic) + + def examine_SourceDerived_ptr(self, object): + self.assertTrue(object) + self.assertTrue(object.GetTypeName().find('SourceDerived') != -1) + derivedValue = object.GetChildMemberWithName('_derivedValue') + self.assertTrue(derivedValue) + self.assertTrue(int(derivedValue.GetValue(), 0) == 30) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/dynamic-value.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/dynamic-value.m new file mode 100644 index 00000000000..2bcb76b1d9d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-dynamic-value/dynamic-value.m @@ -0,0 +1,147 @@ +#import <Foundation/Foundation.h> + +// SourceBase will be the base class of Source. We'll pass a Source object into a +// function as a SourceBase, and then see if the dynamic typing can get us through the KVO +// goo and all the way back to Source. + +@interface SourceBase: NSObject +{ + uint32_t _value; +} +- (SourceBase *) init; +- (uint32_t) getValue; +@end + +@implementation SourceBase +- (SourceBase *) init +{ + [super init]; + _value = 10; + return self; +} +- (uint32_t) getValue +{ + return _value; +} +@end + +// Source is a class that will be observed by the Observer class below. +// When Observer sets itself up to observe this property (in initWithASource) +// the KVO system will overwrite the "isa" pointer of the object with the "kvo'ed" +// one. + +@interface Source : SourceBase +{ + int _property; +} +- (Source *) init; +- (void) setProperty: (int) newValue; +@end + +@implementation Source +- (Source *) init +{ + [super init]; + _property = 20; + return self; +} +- (void) setProperty: (int) newValue +{ + _property = newValue; // This is the line in setProperty, make sure we step to here. +} +@end + +@interface SourceDerived : Source +{ + int _derivedValue; +} +- (SourceDerived *) init; +- (uint32_t) getValue; +@end + +@implementation SourceDerived +- (SourceDerived *) init +{ + [super init]; + _derivedValue = 30; + return self; +} +- (uint32_t) getValue +{ + return _derivedValue; +} +@end + +// Observer is the object that will watch Source and cause KVO to swizzle it... + +@interface Observer : NSObject +{ + Source *_source; +} ++ (Observer *) observerWithSource: (Source *) source; +- (Observer *) initWithASource: (Source *) source; +- (void) observeValueForKeyPath: (NSString *) path + ofObject: (id) object + change: (NSDictionary *) change + context: (void *) context; +@end + +@implementation Observer + ++ (Observer *) observerWithSource: (Source *) inSource; +{ + Observer *retval; + + retval = [[Observer alloc] initWithASource: inSource]; + return retval; +} + +- (Observer *) initWithASource: (Source *) source +{ + [super init]; + _source = source; + [_source addObserver: self + forKeyPath: @"property" + options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) + context: NULL]; + return self; +} + +- (void) observeValueForKeyPath: (NSString *) path + ofObject: (id) object + change: (NSDictionary *) change + context: (void *) context +{ + printf ("Observer function called.\n"); + return; +} +@end + +uint32_t +handle_SourceBase (SourceBase *object) +{ + return [object getValue]; // Break here to check dynamic values. +} + +int main () +{ + Source *mySource; + Observer *myObserver; + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + mySource = [[SourceDerived alloc] init]; + myObserver = [Observer observerWithSource: mySource]; + + [mySource setProperty: 5]; // Break here to see if we can step into real method. + + uint32_t return_value = handle_SourceBase (mySource); + + SourceDerived *unwatchedSource = [[SourceDerived alloc] init]; + + return_value = handle_SourceBase (unwatchedSource); + + [pool release]; + return 0; + +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-foundation-dictionary-empty/TestNSDictionary0.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-foundation-dictionary-empty/TestNSDictionary0.py new file mode 100644 index 00000000000..562d9ae01e2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-foundation-dictionary-empty/TestNSDictionary0.py @@ -0,0 +1,7 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipIfFreeBSD, decorators.skipIfLinux, + decorators.skipIfWindows, decorators.skipIfNetBSD]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-foundation-dictionary-empty/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-foundation-dictionary-empty/main.m new file mode 100644 index 00000000000..14a792b3776 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-foundation-dictionary-empty/main.m @@ -0,0 +1,7 @@ +#import <Foundation/Foundation.h> + +int main(void) +{ + NSDictionary *emptyDictionary = [[NSDictionary alloc] init]; + return 0; //% self.expect("frame var emptyDictionary", substrs = ["0 key/value pairs"]); +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/Makefile new file mode 100644 index 00000000000..5408f4199f2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := objc-ivar-offsets.m main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py new file mode 100644 index 00000000000..749c7137dc9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py @@ -0,0 +1,83 @@ +"""Test printing ObjC objects that use unbacked properties - so that the static ivar offsets are incorrect.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCIvarOffsets(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "main.m" + self.stop_line = line_number( + self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test printing ObjC objects that use unbacked properties""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation( + self.main_source, self.stop_line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, "Created a process.") + self.assertTrue( + process.GetState() == lldb.eStateStopped, + "Stopped it too.") + + thread_list = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint) + self.assertTrue(len(thread_list) == 1) + thread = thread_list[0] + + frame = thread.GetFrameAtIndex(0) + self.assertTrue(frame, "frame 0 is valid") + + mine = thread.GetFrameAtIndex(0).FindVariable("mine") + self.assertTrue(mine, "Found local variable mine.") + + # Test the value object value for BaseClass->_backed_int + + error = lldb.SBError() + + mine_backed_int = mine.GetChildMemberWithName("_backed_int") + self.assertTrue( + mine_backed_int, + "Found mine->backed_int local variable.") + backed_value = mine_backed_int.GetValueAsSigned(error) + self.assertTrue(error.Success()) + self.assertTrue(backed_value == 1111) + + # Test the value object value for DerivedClass->_derived_backed_int + + mine_derived_backed_int = mine.GetChildMemberWithName( + "_derived_backed_int") + self.assertTrue(mine_derived_backed_int, + "Found mine->derived_backed_int local variable.") + derived_backed_value = mine_derived_backed_int.GetValueAsSigned(error) + self.assertTrue(error.Success()) + self.assertTrue(derived_backed_value == 3333) + + # Make sure we also get bit-field offsets correct: + + mine_flag2 = mine.GetChildMemberWithName("flag2") + self.assertTrue(mine_flag2, "Found mine->flag2 local variable.") + flag2_value = mine_flag2.GetValueAsUnsigned(error) + self.assertTrue(error.Success()) + self.assertTrue(flag2_value == 7) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/main.m new file mode 100644 index 00000000000..41943f48aef --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/main.m @@ -0,0 +1,15 @@ +#include "objc-ivar-offsets.h" + +int +main () +{ + DerivedClass *mine = [[DerivedClass alloc] init]; + mine.backed_int = 1111; + mine.unbacked_int = 2222; + mine.derived_backed_int = 3333; + mine.derived_unbacked_int = 4444; + mine->flag1 = 1; + mine->flag2 = 7; + + return 0; // Set breakpoint here. +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/objc-ivar-offsets.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/objc-ivar-offsets.h new file mode 100644 index 00000000000..99bbd427b06 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/objc-ivar-offsets.h @@ -0,0 +1,27 @@ +#import <Foundation/Foundation.h> + +@interface BaseClass : NSObject +{ + int _backed_int; +#if !__OBJC2__ + int _unbacked_int; +#endif +} +@property int backed_int; +@property int unbacked_int; +@end + +@interface DerivedClass : BaseClass +{ + int _derived_backed_int; +#if !__OBJC2__ + int _derived_unbacked_int; +#endif + @public + uint32_t flag1 : 1; + uint32_t flag2 : 3; +} + +@property int derived_backed_int; +@property int derived_unbacked_int; +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/objc-ivar-offsets.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/objc-ivar-offsets.m new file mode 100644 index 00000000000..db87adea3d1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-offsets/objc-ivar-offsets.m @@ -0,0 +1,19 @@ +#import "objc-ivar-offsets.h" + +@implementation BaseClass +@synthesize backed_int = _backed_int; +#if __OBJC2__ +@synthesize unbacked_int; +#else +@synthesize unbacked_int = _unbacked_int; +#endif +@end + +@implementation DerivedClass +@synthesize derived_backed_int = _derived_backed_int; +#if __OBJC2__ +@synthesize derived_unbacked_int; +#else +@synthesize derived_unbacked_int = _derived_unbacked_int; +#endif +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/TestIvarProtocols.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/TestIvarProtocols.py new file mode 100644 index 00000000000..562d9ae01e2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/TestIvarProtocols.py @@ -0,0 +1,7 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipIfFreeBSD, decorators.skipIfLinux, + decorators.skipIfWindows, decorators.skipIfNetBSD]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/main.m new file mode 100644 index 00000000000..aa6c4715c33 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-protocols/main.m @@ -0,0 +1,33 @@ +#import <Foundation/Foundation.h> + +@protocol MyProtocol +-(void)aMethod; +@end + +@interface MyClass : NSObject { + id <MyProtocol> myId; + NSObject <MyProtocol> *myObject; +}; + +-(void)doSomething; + +@end + +@implementation MyClass + +-(void)doSomething +{ + NSLog(@"Hello"); //% self.expect("expression -- myId", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["id"]); + //% self.expect("expression -- myObject", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["NSObject"]); +} + +@end + +int main () +{ + @autoreleasepool + { + MyClass *c = [MyClass alloc]; + [c doSomething]; + } +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/Makefile new file mode 100644 index 00000000000..a218ce37e61 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/Makefile @@ -0,0 +1,13 @@ +OBJC_SOURCES := main.m +LD_EXTRAS := -lobjc -framework Foundation + +all: a.out.stripped + +a.out.stripped: a.out.dSYM + strip -o a.out.stripped a.out + +clean:: + rm -f a.out.stripped + rm -rf a.out.stripped.dSYM + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py new file mode 100644 index 00000000000..12a22f6b903 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py @@ -0,0 +1,67 @@ +"""Test printing ObjC objects that use unbacked properties - so that the static ivar offsets are incorrect.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCIvarStripped(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "main.m" + self.stop_line = line_number( + self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + @skipIf( + debug_info=no_match("dsym"), + bugnumber="This test requires a stripped binary and a dSYM") + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test that we can find stripped Objective-C ivars in the runtime""" + self.build() + exe = self.getBuildArtifact("a.out.stripped") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + self.dbg.HandleCommand("add-dsym "+self.getBuildArtifact("a.out.dSYM")) + + breakpoint = target.BreakpointCreateByLocation( + self.main_source, self.stop_line) + self.assertTrue( + breakpoint.IsValid() and breakpoint.GetNumLocations() > 0, + VALID_BREAKPOINT) + + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, "Created a process.") + self.assertTrue( + process.GetState() == lldb.eStateStopped, + "Stopped it too.") + + thread_list = lldbutil.get_threads_stopped_at_breakpoint( + process, breakpoint) + self.assertTrue(len(thread_list) == 1) + thread = thread_list[0] + + frame = thread.GetFrameAtIndex(0) + self.assertTrue(frame, "frame 0 is valid") + + # Test the expression for mc->_foo + + error = lldb.SBError() + + ivar = frame.EvaluateExpression("(mc->_foo)") + self.assertTrue(ivar, "Got result for mc->_foo") + ivar_value = ivar.GetValueAsSigned(error) + self.assertTrue(error.Success()) + self.assertTrue(ivar_value == 3) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/main.m new file mode 100644 index 00000000000..ed9c1d9ec42 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-ivar-stripped/main.m @@ -0,0 +1,33 @@ +#import <Foundation/Foundation.h> + +@interface MyClass : NSObject { +@public + int _foo; +}; + +-(id)init; +@end + +@implementation MyClass + +-(id)init +{ + if ([super init]) + { + _foo = 3; + } + + return self; +} + +@end + +int main () +{ + @autoreleasepool + { + MyClass *mc = [[MyClass alloc] init]; + + NSLog(@"%d", mc->_foo); // Set breakpoint here. + } +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/Makefile new file mode 100644 index 00000000000..37dd8f40a9d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/Makefile @@ -0,0 +1,6 @@ +OBJC_SOURCES := main.m + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/ObjCNewSyntaxTest.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/ObjCNewSyntaxTest.py new file mode 100644 index 00000000000..5fa9336b731 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/ObjCNewSyntaxTest.py @@ -0,0 +1,29 @@ +"""Test that the Objective-C syntax for dictionary/array literals and indexing works""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCNewSyntaxTest(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def runToBreakpoint(self): + self.build() + self.target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, '// Set breakpoint 0 here.', lldb.SBFileSpec( + 'main.m', False)) + + # The stop reason of the thread should be breakpoint. + self.expect( + "thread list", + STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', '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']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntaxArray.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntaxArray.py new file mode 100644 index 00000000000..cf638c7a108 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntaxArray.py @@ -0,0 +1,58 @@ +"""Test that the Objective-C syntax for dictionary/array literals and indexing works""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +from ObjCNewSyntaxTest import ObjCNewSyntaxTest + + +class ObjCNewSyntaxTestCaseArray(ObjCNewSyntaxTest): + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_read_array(self): + self.runToBreakpoint() + + self.expect( + "expr --object-description -- immutable_array[0]", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["foo"]) + + self.expect( + "expr --object-description -- mutable_array[0]", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["foo"]) + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_update_array(self): + self.runToBreakpoint() + + self.expect( + "expr --object-description -- mutable_array[0] = @\"bar\"", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["bar"]) + + self.expect( + "expr --object-description -- mutable_array[0]", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["bar"]) + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_array_literal(self): + self.runToBreakpoint() + + self.expect( + "expr --object-description -- @[ @\"foo\", @\"bar\" ]", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "NSArray", + "foo", + "bar"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntaxDictionary.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntaxDictionary.py new file mode 100644 index 00000000000..5291b46da2f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntaxDictionary.py @@ -0,0 +1,57 @@ +"""Test that the Objective-C syntax for dictionary/array literals and indexing works""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +from ObjCNewSyntaxTest import ObjCNewSyntaxTest + + +class ObjCNewSyntaxTestCaseDictionary(ObjCNewSyntaxTest): + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_read_dictionary(self): + self.runToBreakpoint() + + self.expect( + "expr --object-description -- immutable_dictionary[@\"key\"]", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["value"]) + + self.expect( + "expr --object-description -- mutable_dictionary[@\"key\"]", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["value"]) + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_update_dictionary(self): + self.runToBreakpoint() + + self.expect( + "expr --object-description -- mutable_dictionary[@\"key\"] = @\"object\"", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["object"]) + + self.expect( + "expr --object-description -- mutable_dictionary[@\"key\"]", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["object"]) + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_dictionary_literal(self): + self.runToBreakpoint() + + self.expect( + "expr --object-description -- @{ @\"key\" : @\"object\" }", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "key", + "object"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntaxLiteral.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntaxLiteral.py new file mode 100644 index 00000000000..e17343bed72 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntaxLiteral.py @@ -0,0 +1,78 @@ +"""Test that the Objective-C syntax for dictionary/array literals and indexing works""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +from ObjCNewSyntaxTest import ObjCNewSyntaxTest + + +class ObjCNewSyntaxTestCaseLiteral(ObjCNewSyntaxTest): + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_char_literal(self): + self.runToBreakpoint() + + self.expect("expr --object-description -- @'a'", + VARIABLES_DISPLAYED_CORRECTLY, substrs=[str(ord('a'))]) + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_integer_literals(self): + self.runToBreakpoint() + + self.expect( + "expr --object-description -- @1", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["1"]) + + self.expect( + "expr --object-description -- @1l", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["1"]) + + self.expect( + "expr --object-description -- @1ul", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["1"]) + + self.expect( + "expr --object-description -- @1ll", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["1"]) + + self.expect( + "expr --object-description -- @1ull", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["1"]) + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_float_literal(self): + self.runToBreakpoint() + + self.expect("expr -- @123.45", VARIABLES_DISPLAYED_CORRECTLY, + substrs=["NSNumber", "123.45"]) + + @skipUnlessDarwin + @skipIf(macos_version=["<", "10.12"]) + @expectedFailureAll(archs=["i[3-6]86"]) + def test_expressions_in_literals(self): + self.runToBreakpoint() + + self.expect( + "expr --object-description -- @( 1 + 3 )", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=["4"]) + self.expect( + "expr -- @((char*)\"Hello world\" + 6)", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "NSString", + "world"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/main.m new file mode 100644 index 00000000000..d77ba5b10de --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/main.m @@ -0,0 +1,21 @@ +#import <Foundation/Foundation.h> + +int main() +{ + @autoreleasepool + { + // NSArrays + NSArray *immutable_array = @[ @"foo", @"bar" ]; + NSMutableArray *mutable_array = [NSMutableArray arrayWithCapacity:2]; + [mutable_array addObjectsFromArray:immutable_array]; + + // NSDictionaries + NSDictionary *immutable_dictionary = @{ @"key" : @"value" }; + NSMutableDictionary *mutable_dictionary = [NSMutableDictionary dictionaryWithCapacity:1]; + [mutable_dictionary addEntriesFromDictionary:immutable_dictionary]; + + NSNumber *one = @1; + + NSLog(@"Stop here"); // Set breakpoint 0 here. + } +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-optimized/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-optimized/Makefile new file mode 100644 index 00000000000..5fb128dcc7e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-optimized/Makefile @@ -0,0 +1,6 @@ +OBJC_SOURCES := main.m + +CFLAGS ?= -arch $(ARCH) -g -O2 +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-optimized/TestObjcOptimized.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-optimized/TestObjcOptimized.py new file mode 100644 index 00000000000..6209f14e7e4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-optimized/TestObjcOptimized.py @@ -0,0 +1,72 @@ +""" +Test that objective-c expression parser continues to work for optimized build. + +Fixed a bug in the expression parser where the 'this' +or 'self' variable was not properly read if the compiler +optimized it into a register. +""" + + + +import lldb +import re + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +# rdar://problem/9087739 +# test failure: objc_optimized does not work for "-C clang -A i386" + + +@skipUnlessDarwin +class ObjcOptimizedTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + myclass = "MyClass" + mymethod = "description" + method_spec = "-[%s %s]" % (myclass, mymethod) + + def test_break(self): + """Test 'expr member' continues to work for optimized build.""" + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_symbol( + self, + self.method_spec, + num_expected_locations=1, + sym_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + self.expect( + "thread backtrace", + STOPPED_DUE_TO_BREAKPOINT, + substrs=["stop reason = breakpoint"], + patterns=[ + "frame.*0:.*%s %s" % + (self.myclass, + self.mymethod)]) + + self.expect('expression member', + startstr="(int) $0 = 5") + + # <rdar://problem/12693963> + interp = self.dbg.GetCommandInterpreter() + result = lldb.SBCommandReturnObject() + interp.HandleCommand('frame variable self', result) + output = result.GetOutput() + + desired_pointer = "0x0" + + mo = re.search("0x[0-9a-f]+", output) + + if mo: + desired_pointer = mo.group(0) + + self.expect('expression (self)', + substrs=[("(%s *) $1 = " % self.myclass), desired_pointer]) + + self.expect('expression self->non_member', error=True, + substrs=["does not have a member named 'non_member'"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-optimized/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-optimized/main.m new file mode 100644 index 00000000000..df88eea0f86 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-optimized/main.m @@ -0,0 +1,44 @@ +#import <Foundation/Foundation.h> + +@interface MyClass : NSObject { + int member; +} + +- (id)initWithMember:(int)_member; +- (NSString*)description; +@end + +@implementation MyClass + +- (id)initWithMember:(int)_member +{ + if (self = [super init]) + { + member = _member; + } + return self; +} + +- (void)dealloc +{ + [super dealloc]; +} + +// Set a breakpoint on '-[MyClass description]' and test expressions: expr member +- (NSString *)description +{ + return [NSString stringWithFormat:@"%d", member]; +} +@end + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + MyClass *my_object = [[MyClass alloc] initWithMember:5]; + + NSLog(@"MyObject %@", [my_object description]); + + [pool release]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/Makefile new file mode 100644 index 00000000000..afecbf96948 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py new file mode 100644 index 00000000000..3092c3f086a --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/TestObjCProperty.py @@ -0,0 +1,135 @@ +""" +Use lldb Python API to verify that expression evaluation for property references uses the correct getters and setters +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCPropertyTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + # Find the line number to break for main.c. + self.source_name = 'main.m' + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_objc_properties(self): + """Test that expr uses the correct property getters and setters""" + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target from the debugger. + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + # Set up our breakpoints: + + main_bkpt = target.BreakpointCreateBySourceRegex( + "Set a breakpoint here.", lldb.SBFileSpec(self.source_name)) + self.assertTrue(main_bkpt and + main_bkpt.GetNumLocations() == 1, + VALID_BREAKPOINT) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process.GetState() == lldb.eStateStopped, + PROCESS_STOPPED) + + threads = lldbutil.get_threads_stopped_at_breakpoint( + process, main_bkpt) + self.assertTrue(len(threads) == 1) + thread = threads[0] + frame = thread.GetFrameAtIndex(0) + + mine = frame.FindVariable("mine") + self.assertTrue(mine.IsValid()) + access_count = mine.GetChildMemberWithName("_access_count") + self.assertTrue(access_count.IsValid()) + start_access_count = access_count.GetValueAsUnsigned(123456) + self.assertTrue(start_access_count != 123456) + + # + # The first set of tests test calling the getter & setter of + # a property that actually only has a getter & setter and no + # @property. + # + nonexistant_value = frame.EvaluateExpression( + "mine.nonexistantInt", False) + nonexistant_error = nonexistant_value.GetError() + self.assertTrue(nonexistant_error.Success()) + nonexistant_int = nonexistant_value.GetValueAsUnsigned(123456) + self.assertTrue(nonexistant_int == 6) + + # Calling the getter function would up the access count, so make sure + # that happened. + + new_access_count = access_count.GetValueAsUnsigned(123456) + self.assertTrue(new_access_count - start_access_count == 1) + start_access_count = new_access_count + + # + # Now call the setter, then make sure that + nonexistant_change = frame.EvaluateExpression( + "mine.nonexistantInt = 10", False) + nonexistant_error = nonexistant_change.GetError() + self.assertTrue(nonexistant_error.Success()) + + # Calling the setter function would up the access count, so make sure + # that happened. + + new_access_count = access_count.GetValueAsUnsigned(123456) + self.assertTrue(new_access_count - start_access_count == 1) + start_access_count = new_access_count + + # + # Now we call the getter of a property that is backed by an ivar, + # make sure it works and that we actually update the backing ivar. + # + + backed_value = frame.EvaluateExpression("mine.backedInt", False) + backed_error = backed_value.GetError() + self.assertTrue(backed_error.Success()) + backing_value = mine.GetChildMemberWithName("_backedInt") + self.assertTrue(backing_value.IsValid()) + self.assertTrue(backed_value.GetValueAsUnsigned(12345) + == backing_value.GetValueAsUnsigned(23456)) + + unbacked_value = frame.EvaluateExpression("mine.unbackedInt", False) + unbacked_error = unbacked_value.GetError() + self.assertTrue(unbacked_error.Success()) + + idWithProtocol_value = frame.EvaluateExpression( + "mine.idWithProtocol", False) + idWithProtocol_error = idWithProtocol_value.GetError() + self.assertTrue(idWithProtocol_error.Success()) + self.assertTrue(idWithProtocol_value.GetTypeName() == "id") + + # Make sure that class property getter works as expected + value = frame.EvaluateExpression("BaseClass.classInt", False) + self.assertTrue(value.GetError().Success()) + self.assertTrue(value.GetValueAsUnsigned(11111) == 123) + + # Make sure that class property setter works as expected + value = frame.EvaluateExpression("BaseClass.classInt = 234", False) + self.assertTrue(value.GetError().Success()) + + # Verify that setter above actually worked + value = frame.EvaluateExpression("BaseClass.classInt", False) + self.assertTrue(value.GetError().Success()) + self.assertTrue(value.GetValueAsUnsigned(11111) == 234) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m new file mode 100644 index 00000000000..8d14759fb38 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-property/main.m @@ -0,0 +1,113 @@ +#import <Foundation/Foundation.h> + +@protocol MyProtocol + +-(const char *)hello; + +@end + +static int _class_int = 123; + +@interface BaseClass : NSObject +{ + int _backedInt; + int _access_count; +} + +- (int) nonexistantInt; +- (void) setNonexistantInt: (int) in_int; + +- (int) myGetUnbackedInt; +- (void) mySetUnbackedInt: (int) in_int; + +- (int) getAccessCount; + ++(BaseClass *) baseClassWithBackedInt: (int) inInt andUnbackedInt: (int) inOtherInt; + +@property(getter=myGetUnbackedInt,setter=mySetUnbackedInt:) int unbackedInt; +@property int backedInt; +@property (nonatomic, assign) id <MyProtocol> idWithProtocol; +@property(class) int classInt; +@end + +@implementation BaseClass +@synthesize unbackedInt; +@synthesize backedInt = _backedInt; + ++ (BaseClass *) baseClassWithBackedInt: (int) inInt andUnbackedInt: (int) inOtherInt +{ + BaseClass *new = [[BaseClass alloc] init]; + + new->_backedInt = inInt; + new->unbackedInt = inOtherInt; + + return new; +} + +- (int) myGetUnbackedInt +{ + // NSLog (@"Getting BaseClass::unbackedInt - %d.\n", unbackedInt); + _access_count++; + return unbackedInt; +} + +- (void) mySetUnbackedInt: (int) in_int +{ + // NSLog (@"Setting BaseClass::unbackedInt from %d to %d.", unbackedInt, in_int); + _access_count++; + unbackedInt = in_int; +} + +- (int) nonexistantInt +{ + // NSLog (@"Getting BaseClass::nonexistantInt - %d.\n", 5); + _access_count++; + return 6; +} + +- (void) setNonexistantInt: (int) in_int +{ + // NSLog (@"Setting BaseClass::nonexistantInt from 7 to %d.", in_int); + _access_count++; +} + ++ (int) classInt +{ + return _class_int; +} + ++ (void) setClassInt:(int) n +{ + _class_int = n; +} + +- (int) getAccessCount +{ + return _access_count; +} +@end + +int +main () +{ + BaseClass *mine = [BaseClass baseClassWithBackedInt: 10 andUnbackedInt: 20]; + + // Set a breakpoint here. + int nonexistant = mine.nonexistantInt; + + int backedInt = mine.backedInt; + + int unbackedInt = mine.unbackedInt; + + id idWithProtocol = mine.idWithProtocol; + + NSLog (@"Results for %p: nonexistant: %d backed: %d unbacked: %d accessCount: %d.", + mine, + nonexistant, + backedInt, + unbackedInt, + [mine getAccessCount]); + return 0; + +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/Makefile new file mode 100644 index 00000000000..afecbf96948 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/TestRuntimeIvars.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/TestRuntimeIvars.py new file mode 100644 index 00000000000..f1b36943ece --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/TestRuntimeIvars.py @@ -0,0 +1,8 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipIfFreeBSD, decorators.skipIfLinux, + decorators.skipIfWindows, decorators.skipIfNetBSD, + decorators.skipIf(archs=["i386", "i686"])]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/main.m new file mode 100644 index 00000000000..1f5a9b077e2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-runtime-ivars/main.m @@ -0,0 +1,10 @@ +#import <Foundation/Foundation.h> + +int main () +{ + @autoreleasepool + { + NSLog(@"Hello"); //% self.expect("expression -- *((NSConcretePointerArray*)[NSPointerArray strongObjectsPointerArray])", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["count", "capacity", "options", "mutations"]); + //% self.expect("expression -- ((NSConcretePointerArray*)[NSPointerArray strongObjectsPointerArray])->count", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["unsigned"]); + } +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/Makefile new file mode 100644 index 00000000000..0ad7e356316 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/Makefile @@ -0,0 +1,14 @@ +OBJC_SOURCES := static.m +LD_EXTRAS := -lobjc -framework Foundation + +default: a.out.stripped + +a.out.stripped: a.out.dSYM + strip -o a.out.stripped a.out + ln -sf a.out.dSYM a.out.stripped.dSYM + +clean:: + rm -f a.out.stripped + rm -rf $(wildcard *.dSYM) + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/TestObjCStaticMethodStripped.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/TestObjCStaticMethodStripped.py new file mode 100644 index 00000000000..8ee73eda3f7 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/TestObjCStaticMethodStripped.py @@ -0,0 +1,77 @@ +"""Test calling functions in static methods with a stripped binary.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCStaticMethodStripped(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "static.m" + self.break_line = line_number( + self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + @skipIf( + debug_info=no_match("dsym"), + bugnumber="This test requires a stripped binary and a dSYM") + #<rdar://problem/12042992> + def test_with_python_api(self): + """Test calling functions in static methods with a stripped binary.""" + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + bpt = target.BreakpointCreateByLocation( + self.main_source, self.break_line) + self.assertTrue(bpt, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread_list = lldbutil.get_threads_stopped_at_breakpoint(process, bpt) + + # Make sure we stopped at the first breakpoint. + self.assertTrue( + len(thread_list) != 0, + "No thread stopped at our breakpoint.") + self.assertTrue(len(thread_list) == 1, + "More than one thread stopped at our breakpoint.") + + # Now make sure we can call a function in the static method we've + # stopped in. + frame = thread_list[0].GetFrameAtIndex(0) + self.assertTrue(frame, "Got a valid frame 0 frame.") + + cmd_value = frame.EvaluateExpression("(char *) sel_getName (_cmd)") + self.assertTrue(cmd_value.IsValid()) + sel_name = cmd_value.GetSummary() + self.assertTrue( + sel_name == "\"doSomethingWithString:\"", + "Got the right value for the selector as string.") + + cmd_value = frame.EvaluateExpression( + "[Foo doSomethingElseWithString:string]") + self.assertTrue(cmd_value.IsValid()) + string_length = cmd_value.GetValueAsUnsigned() + self.assertTrue( + string_length == 27, + "Got the right value from another class method on the same class.") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/static.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/static.m new file mode 100644 index 00000000000..ec7b2ef6719 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method-stripped/static.m @@ -0,0 +1,29 @@ +#import <Foundation/Foundation.h> + +@interface Foo : NSObject ++(void) doSomethingWithString: (NSString *) string; +-(void) doSomethingWithNothing; +@end + +@implementation Foo ++(void) doSomethingWithString: (NSString *) string +{ + NSLog (@"String is: %@.", string); // Set breakpoint here. +} + ++(int) doSomethingElseWithString: (NSString *) string +{ + NSLog (@"String is still: %@.", string); + return [string length]; +} + +-(void) doSomethingWithNothing +{ +} +@end + +int main() +{ + [Foo doSomethingWithString: @"Some string I have in mind."]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method/Makefile new file mode 100644 index 00000000000..954dea47b32 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := static.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method/TestObjCStaticMethod.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method/TestObjCStaticMethod.py new file mode 100644 index 00000000000..ce18a07394b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method/TestObjCStaticMethod.py @@ -0,0 +1,72 @@ +"""Test calling functions in static methods.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCStaticMethod(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "static.m" + self.break_line = line_number( + self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + #<rdar://problem/9745789> "expression" can't call functions in class methods + def test_with_python_api(self): + """Test calling functions in static methods.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + bpt = target.BreakpointCreateByLocation( + self.main_source, self.break_line) + self.assertTrue(bpt, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread_list = lldbutil.get_threads_stopped_at_breakpoint(process, bpt) + + # Make sure we stopped at the first breakpoint. + self.assertTrue( + len(thread_list) != 0, + "No thread stopped at our breakpoint.") + self.assertTrue(len(thread_list) == 1, + "More than one thread stopped at our breakpoint.") + + # Now make sure we can call a function in the static method we've + # stopped in. + frame = thread_list[0].GetFrameAtIndex(0) + self.assertTrue(frame, "Got a valid frame 0 frame.") + + cmd_value = frame.EvaluateExpression("(char *) sel_getName (_cmd)") + self.assertTrue(cmd_value.IsValid()) + sel_name = cmd_value.GetSummary() + self.assertTrue( + sel_name == "\"doSomethingWithString:\"", + "Got the right value for the selector as string.") + + cmd_value = frame.EvaluateExpression( + "[self doSomethingElseWithString:string]") + self.assertTrue(cmd_value.IsValid()) + string_length = cmd_value.GetValueAsUnsigned() + self.assertTrue( + string_length == 27, + "Got the right value from another class method on the same class.") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method/static.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method/static.m new file mode 100644 index 00000000000..ec7b2ef6719 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-static-method/static.m @@ -0,0 +1,29 @@ +#import <Foundation/Foundation.h> + +@interface Foo : NSObject ++(void) doSomethingWithString: (NSString *) string; +-(void) doSomethingWithNothing; +@end + +@implementation Foo ++(void) doSomethingWithString: (NSString *) string +{ + NSLog (@"String is: %@.", string); // Set breakpoint here. +} + ++(int) doSomethingElseWithString: (NSString *) string +{ + NSLog (@"String is still: %@.", string); + return [string length]; +} + +-(void) doSomethingWithNothing +{ +} +@end + +int main() +{ + [Foo doSomethingWithString: @"Some string I have in mind."]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-stepping/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-stepping/Makefile new file mode 100644 index 00000000000..9906470d530 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-stepping/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := stepping-tests.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-stepping/TestObjCStepping.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-stepping/TestObjCStepping.py new file mode 100644 index 00000000000..bf80995b109 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-stepping/TestObjCStepping.py @@ -0,0 +1,220 @@ +"""Test stepping through ObjC method dispatch in various forms.""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCStepping(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "stepping-tests.m" + self.source_randomMethod_line = line_number( + self.main_source, '// Source randomMethod start line.') + self.sourceBase_randomMethod_line = line_number( + self.main_source, '// SourceBase randomMethod start line.') + self.source_returnsStruct_start_line = line_number( + self.main_source, '// Source returnsStruct start line.') + self.sourceBase_returnsStruct_start_line = line_number( + self.main_source, '// SourceBase returnsStruct start line.') + self.stepped_past_nil_line = line_number( + self.main_source, '// Step over nil should stop here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi', 'basic_process']) + def test_with_python_api(self): + """Test stepping through ObjC method dispatch in various forms.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + self.main_source_spec = lldb.SBFileSpec(self.main_source) + + breakpoints_to_disable = [] + + break1 = target.BreakpointCreateBySourceRegex( + "// Set first breakpoint here.", self.main_source_spec) + self.assertTrue(break1, VALID_BREAKPOINT) + breakpoints_to_disable.append(break1) + + break2 = target.BreakpointCreateBySourceRegex( + "// Set second breakpoint here.", self.main_source_spec) + self.assertTrue(break2, VALID_BREAKPOINT) + breakpoints_to_disable.append(break2) + + break3 = target.BreakpointCreateBySourceRegex( + '// Set third breakpoint here.', self.main_source_spec) + self.assertTrue(break3, VALID_BREAKPOINT) + breakpoints_to_disable.append(break3) + + break4 = target.BreakpointCreateBySourceRegex( + '// Set fourth breakpoint here.', self.main_source_spec) + self.assertTrue(break4, VALID_BREAKPOINT) + breakpoints_to_disable.append(break4) + + break5 = target.BreakpointCreateBySourceRegex( + '// Set fifth breakpoint here.', self.main_source_spec) + self.assertTrue(break5, VALID_BREAKPOINT) + breakpoints_to_disable.append(break5) + + break_returnStruct_call_super = target.BreakpointCreateBySourceRegex( + '// Source returnsStruct call line.', self.main_source_spec) + self.assertTrue(break_returnStruct_call_super, VALID_BREAKPOINT) + breakpoints_to_disable.append(break_returnStruct_call_super) + + break_step_nil = target.BreakpointCreateBySourceRegex( + '// Set nil step breakpoint here.', self.main_source_spec) + self.assertTrue(break_step_nil, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint(process, break1) + if len(threads) != 1: + self.fail("Failed to stop at breakpoint 1.") + + thread = threads[0] + + mySource = thread.GetFrameAtIndex(0).FindVariable("mySource") + self.assertTrue(mySource, "Found mySource local variable.") + mySource_isa = mySource.GetChildMemberWithName("isa") + self.assertTrue(mySource_isa, "Found mySource->isa local variable.") + className = mySource_isa.GetSummary() + + if self.TraceOn(): + print(mySource_isa) + + # Lets delete mySource so we can check that after stepping a child variable + # with no parent persists and is useful. + del (mySource) + + # Now step in, that should leave us in the Source randomMethod: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue( + line_number == self.source_randomMethod_line, + "Stepped into Source randomMethod.") + + # Now step in again, through the super call, and that should leave us + # in the SourceBase randomMethod: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue( + line_number == self.sourceBase_randomMethod_line, + "Stepped through super into SourceBase randomMethod.") + + threads = lldbutil.continue_to_breakpoint(process, break2) + self.assertTrue( + len(threads) == 1, + "Continued to second breakpoint in main.") + + # Again, step in twice gets us to a stret method and a stret super + # call: + thread = threads[0] + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue( + line_number == self.source_returnsStruct_start_line, + "Stepped into Source returnsStruct.") + + threads = lldbutil.continue_to_breakpoint( + process, break_returnStruct_call_super) + self.assertTrue( + len(threads) == 1, + "Stepped to the call super line in Source returnsStruct.") + thread = threads[0] + + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue( + line_number == self.sourceBase_returnsStruct_start_line, + "Stepped through super into SourceBase returnsStruct.") + + # Cool now continue to get past the call that initializes the Observer, and then do our steps in again to see that + # we can find our way when we're stepping through a KVO swizzled + # object. + + threads = lldbutil.continue_to_breakpoint(process, break3) + self.assertTrue( + len(threads) == 1, + "Continued to third breakpoint in main, our object should now be swizzled.") + + newClassName = mySource_isa.GetSummary() + + if self.TraceOn(): + print("className is %s, newClassName is %s" % (className, newClassName)) + print(mySource_isa) + + self.assertTrue( + newClassName != className, + "The isa did indeed change, swizzled!") + + # Now step in, that should leave us in the Source randomMethod: + thread = threads[0] + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue( + line_number == self.source_randomMethod_line, + "Stepped into Source randomMethod in swizzled object.") + + # Now step in again, through the super call, and that should leave us + # in the SourceBase randomMethod: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue( + line_number == self.sourceBase_randomMethod_line, + "Stepped through super into SourceBase randomMethod in swizzled object.") + + threads = lldbutil.continue_to_breakpoint(process, break4) + self.assertTrue( + len(threads) == 1, + "Continued to fourth breakpoint in main.") + thread = threads[0] + + # Again, step in twice gets us to a stret method and a stret super + # call: + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue( + line_number == self.source_returnsStruct_start_line, + "Stepped into Source returnsStruct in swizzled object.") + + threads = lldbutil.continue_to_breakpoint( + process, break_returnStruct_call_super) + self.assertTrue( + len(threads) == 1, + "Stepped to the call super line in Source returnsStruct - second time.") + thread = threads[0] + + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue( + line_number == self.sourceBase_returnsStruct_start_line, + "Stepped through super into SourceBase returnsStruct in swizzled object.") + + for bkpt in breakpoints_to_disable: + bkpt.SetEnabled(False) + + threads = lldbutil.continue_to_breakpoint(process, break_step_nil) + self.assertTrue(len(threads) == 1, "Continued to step nil breakpoint.") + + thread.StepInto() + line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine() + self.assertTrue( + line_number == self.stepped_past_nil_line, + "Step in over dispatch to nil stepped over.") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-stepping/stepping-tests.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-stepping/stepping-tests.m new file mode 100644 index 00000000000..63db536dee4 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-stepping/stepping-tests.m @@ -0,0 +1,138 @@ +#import <Foundation/Foundation.h> +#include <stdio.h> + +struct return_me +{ + int first; + int second; +}; + +@interface SourceBase: NSObject +{ + struct return_me my_return; +} +- (SourceBase *) initWithFirst: (int) first andSecond: (int) second; +- (void) randomMethod; +- (struct return_me) returnsStruct; +@end + +@implementation SourceBase +- (void) randomMethod +{ + printf ("Called in SourceBase version of randomMethod.\n"); // SourceBase randomMethod start line. +} + +- (struct return_me) returnsStruct +{ + return my_return; // SourceBase returnsStruct start line. +} + +- (SourceBase *) initWithFirst: (int) first andSecond: (int) second +{ + my_return.first = first; + my_return.second = second; + + return self; +} +@end + +@interface Source : SourceBase +{ + int _property; +} +- (void) setProperty: (int) newValue; +- (void) randomMethod; +- (struct return_me) returnsStruct; +@end + +@implementation Source +- (void) setProperty: (int) newValue +{ + _property = newValue; +} + +- (void) randomMethod +{ + [super randomMethod]; // Source randomMethod start line. + printf ("Called in Source version of random method."); +} + +- (struct return_me) returnsStruct +{ + printf ("Called in Source version of returnsStruct.\n"); // Source returnsStruct start line. + return [super returnsStruct]; // Source returnsStruct call line. +} + +@end + +@interface Observer : NSObject +{ + Source *_source; +} ++ (Observer *) observerWithSource: (Source *) source; +- (Observer *) initWithASource: (Source *) source; +- (void) observeValueForKeyPath: (NSString *) path + ofObject: (id) object + change: (NSDictionary *) change + context: (void *) context; +@end + +@implementation Observer + ++ (Observer *) observerWithSource: (Source *) inSource; +{ + Observer *retval; + + retval = [[Observer alloc] initWithASource: inSource]; + return retval; +} + +- (Observer *) initWithASource: (Source *) source +{ + [super init]; + _source = source; + [_source addObserver: self + forKeyPath: @"property" + options: (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) + context: NULL]; + return self; +} + +- (void) observeValueForKeyPath: (NSString *) path + ofObject: (id) object + change: (NSDictionary *) change + context: (void *) context +{ + printf ("Observer function called.\n"); + return; +} +@end + +int main () +{ + Source *mySource; + Observer *myObserver; + struct return_me ret_val; + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + mySource = [[Source alloc] init]; + + [mySource randomMethod]; // Set first breakpoint here. + ret_val = [mySource returnsStruct]; // Set second breakpoint here. + + myObserver = [Observer observerWithSource: mySource]; + + [mySource randomMethod]; // Set third breakpoint here. + ret_val = [mySource returnsStruct]; // Set fourth breakpoint here. + [mySource setProperty: 5]; // Set fifth breakpoint here. + + // We also had a bug where stepping into a method dispatch to nil turned + // into continue. So make sure that works here: + + mySource = nil; + [mySource randomMethod]; // Set nil step breakpoint here. + [pool release]; // Step over nil should stop here. + return 0; + +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/Makefile new file mode 100644 index 00000000000..d059a5c1c29 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := test.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/TestObjCStructArgument.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/TestObjCStructArgument.py new file mode 100644 index 00000000000..28188afc142 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/TestObjCStructArgument.py @@ -0,0 +1,66 @@ +"""Test passing structs to Objective-C methods.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCStructArgument(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "test.m" + self.break_line = line_number( + self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + @skipIf(debug_info=no_match(["gmodules"]), oslist=['ios', 'watchos', 'tvos', 'bridgeos'], archs=['armv7', 'arm64']) # this test program only builds for ios with -gmodules + def test_with_python_api(self): + """Test passing structs to Objective-C methods.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + bpt = target.BreakpointCreateByLocation( + self.main_source, self.break_line) + self.assertTrue(bpt, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread_list = lldbutil.get_threads_stopped_at_breakpoint(process, bpt) + + # Make sure we stopped at the first breakpoint. + self.assertTrue( + len(thread_list) != 0, + "No thread stopped at our breakpoint.") + self.assertTrue(len(thread_list) == 1, + "More than one thread stopped at our breakpoint.") + + frame = thread_list[0].GetFrameAtIndex(0) + self.assertTrue(frame, "Got a valid frame 0 frame.") + + self.expect("p [summer sumThings:tts]", substrs=['9']) + + self.expect( + "po [NSValue valueWithRect:rect]", + substrs=['NSRect: {{0, 0}, {10, 20}}']) + + # Now make sure we can call a method that returns a struct without + # crashing. + cmd_value = frame.EvaluateExpression("[provider getRange]") + self.assertTrue(cmd_value.IsValid()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/test.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/test.m new file mode 100644 index 00000000000..6b13a3a3d59 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-argument/test.m @@ -0,0 +1,40 @@ +#import <Foundation/Foundation.h> +#include <TargetConditionals.h> + +#if TARGET_OS_IPHONE +@import CoreGraphics; +typedef CGRect NSRect; +#endif + +struct things_to_sum { + int a; + int b; + int c; +}; + +@interface ThingSummer : NSObject { +}; +-(int)sumThings:(struct things_to_sum)tts; +@end + +@implementation ThingSummer +-(int)sumThings:(struct things_to_sum)tts +{ + return tts.a + tts.b + tts.c; +} +@end + +int main() +{ + @autoreleasepool + { + ThingSummer *summer = [ThingSummer alloc]; + struct things_to_sum tts = { 2, 3, 4 }; + int ret = [summer sumThings:tts]; + NSRect rect = {{0, 0}, {10, 20}}; + // The Objective-C V1 runtime won't read types from metadata so we need + // NSValue in our debug info to use it in our test. + NSValue *v = [NSValue valueWithRect:rect]; + return rect.origin.x; // Set breakpoint here. + } +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/Makefile new file mode 100644 index 00000000000..d059a5c1c29 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := test.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/TestObjCStructReturn.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/TestObjCStructReturn.py new file mode 100644 index 00000000000..c8c54848a99 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/TestObjCStructReturn.py @@ -0,0 +1,59 @@ +"""Test calling functions in class methods.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCClassMethod(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "test.m" + self.break_line = line_number( + self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test calling functions in class methods.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + bpt = target.BreakpointCreateByLocation( + self.main_source, self.break_line) + self.assertTrue(bpt, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread_list = lldbutil.get_threads_stopped_at_breakpoint(process, bpt) + + # Make sure we stopped at the first breakpoint. + self.assertTrue( + len(thread_list) != 0, + "No thread stopped at our breakpoint.") + self.assertTrue(len(thread_list) == 1, + "More than one thread stopped at our breakpoint.") + + frame = thread_list[0].GetFrameAtIndex(0) + self.assertTrue(frame, "Got a valid frame 0 frame.") + + # Now make sure we can call a method that returns a struct without + # crashing. + cmd_value = frame.EvaluateExpression("[provider getRange]") + self.assertTrue(cmd_value.IsValid()) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/test.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/test.m new file mode 100644 index 00000000000..aafe231ea81 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-struct-return/test.m @@ -0,0 +1,23 @@ +#import <Foundation/Foundation.h> + +@interface RangeProvider : NSObject { +}; +-(NSRange)getRange; +@end + +@implementation RangeProvider +-(NSRange)getRange +{ + return NSMakeRange(0, 3); +} +@end + +int main() +{ + @autoreleasepool + { + RangeProvider *provider = [RangeProvider alloc]; + NSRange range = [provider getRange]; // Set breakpoint here. + return 0; + } +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-super/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-super/Makefile new file mode 100644 index 00000000000..e6db3dee37b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-super/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := class.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-super/TestObjCSuper.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-super/TestObjCSuper.py new file mode 100644 index 00000000000..5cb46e007d8 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-super/TestObjCSuper.py @@ -0,0 +1,64 @@ +"""Test calling methods on super.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestObjCSuperMethod(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers to break inside main(). + self.main_source = "class.m" + self.break_line = line_number( + self.main_source, '// Set breakpoint here.') + + @skipUnlessDarwin + @add_test_categories(['pyapi']) + def test_with_python_api(self): + """Test calling methods on super.""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + bpt = target.BreakpointCreateByLocation( + self.main_source, self.break_line) + self.assertTrue(bpt, VALID_BREAKPOINT) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + thread_list = lldbutil.get_threads_stopped_at_breakpoint(process, bpt) + + # Make sure we stopped at the first breakpoint. + self.assertTrue( + len(thread_list) != 0, + "No thread stopped at our breakpoint.") + self.assertTrue(len(thread_list) == 1, + "More than one thread stopped at our breakpoint.") + + # Now make sure we can call a function in the class method we've + # stopped in. + frame = thread_list[0].GetFrameAtIndex(0) + self.assertTrue(frame, "Got a valid frame 0 frame.") + + cmd_value = frame.EvaluateExpression("[self get]") + self.assertTrue(cmd_value.IsValid()) + self.assertTrue(cmd_value.GetValueAsUnsigned() == 2) + + cmd_value = frame.EvaluateExpression("[super get]") + self.assertTrue(cmd_value.IsValid()) + self.assertTrue(cmd_value.GetValueAsUnsigned() == 1) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-super/class.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-super/class.m new file mode 100644 index 00000000000..b55b649aaae --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc-super/class.m @@ -0,0 +1,39 @@ +#import <Foundation/Foundation.h> + +@interface Foo : NSObject { +} +-(int)get; +@end + +@implementation Foo +-(int)get +{ + return 1; +} +@end + +@interface Bar : Foo { +} +-(int)get; +@end + +@implementation Bar +-(int)get +{ + return 2; +} + +-(int)callme +{ + return [self get]; // Set breakpoint here. +} +@end + +int main() +{ + @autoreleasepool + { + Bar *bar = [Bar alloc]; + return [bar callme]; + } +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/Makefile new file mode 100644 index 00000000000..afecbf96948 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/TestObjCDirectMethods.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/TestObjCDirectMethods.py new file mode 100644 index 00000000000..f0152de1ac3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/TestObjCDirectMethods.py @@ -0,0 +1,5 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [decorators.skipUnlessDarwin]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/main.m new file mode 100644 index 00000000000..6799f22500c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/objc_direct-methods/main.m @@ -0,0 +1,92 @@ +#import <Foundation/Foundation.h> + +int side_effect = 0; + +NSString *str = @"some string"; + +const char *directCallConflictingName() { + return "wrong function"; +} + +@interface Foo : NSObject { + int instance_var; +} +-(int) entryPoint; +@end + +@implementation Foo +-(int) entryPoint +{ + // Try calling directly with self. Same as in the main method otherwise. + return 0; //%self.expect("expr [self directCallNoArgs]", substrs=["called directCallNoArgs"]) + //%self.expect("expr [self directCallArgs: 1111]", substrs=["= 2345"]) + //%self.expect("expr side_effect = 0; [self directCallVoidReturn]; side_effect", substrs=["= 4321"]) + //%self.expect("expr [self directCallNSStringArg: str]", substrs=['@"some string"']) + //%self.expect("expr [self directCallIdArg: (id)str]", substrs=['@"some string appendix"']) + //%self.expect("expr [self directCallConflictingName]", substrs=["correct function"]) + //%self.expect("expr [self directCallWithCategory]", substrs=["called function with category"]) +} + +// Declare several objc_direct functions we can test. +-(const char *) directCallNoArgs __attribute__((objc_direct)) +{ + return "called directCallNoArgs"; +} + +-(void) directCallVoidReturn __attribute__((objc_direct)) +{ + side_effect = 4321; +} + +-(int) directCallArgs:(int)i __attribute__((objc_direct)) +{ + // Use the arg in some way to make sure that gets passed correctly. + return i + 1234; +} + +-(NSString *) directCallNSStringArg:(NSString *)str __attribute__((objc_direct)) +{ + return str; +} + +-(NSString *) directCallIdArg:(id)param __attribute__((objc_direct)) +{ + return [param stringByAppendingString:@" appendix"]; +} + +// We have another function with the same name above. Make sure this doesn't influence +// what we call. +-(const char *) directCallConflictingName __attribute__((objc_direct)) +{ + return "correct function"; +} +@end + + +@interface Foo (Cat) +@end + +@implementation Foo (Cat) +-(const char *) directCallWithCategory __attribute__((objc_direct)) +{ + return "called function with category"; +} +@end + +int main() +{ + Foo *foo = [[Foo alloc] init]; + [foo directCallNoArgs]; + [foo directCallArgs: 1]; + [foo directCallVoidReturn]; + [foo directCallNSStringArg: str]; + [foo directCallIdArg: (id)str]; + [foo entryPoint]; //%self.expect("expr [foo directCallNoArgs]", substrs=["called directCallNoArgs"]) + //%self.expect("expr [foo directCallArgs: 1111]", substrs=["= 2345"]) + //%self.expect("expr side_effect = 0; [foo directCallVoidReturn]; side_effect", substrs=["= 4321"]) + //%self.expect("expr [foo directCallNSStringArg: str]", substrs=['@"some string"']) + //%self.expect("expr [foo directCallIdArg: (id)str]", substrs=['@"some string appendix"']) + //%self.expect("expr [foo directCallConflictingName]", substrs=["correct function"]) + //%self.expect("expr [foo directCallWithCategory]", substrs=["called function with category"]) + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/orderedset/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/orderedset/Makefile new file mode 100644 index 00000000000..afecbf96948 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/orderedset/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/orderedset/TestOrderedSet.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/orderedset/TestOrderedSet.py new file mode 100644 index 00000000000..90c6bc32f77 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/orderedset/TestOrderedSet.py @@ -0,0 +1,18 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestOrderedSet(TestBase): + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test_ordered_set(self): + self.build() + src_file = "main.m" + src_file_spec = lldb.SBFileSpec(src_file) + (target, process, thread, main_breakpoint) = lldbutil.run_to_source_breakpoint(self, + "break here", src_file_spec, exe_name = "a.out") + frame = thread.GetSelectedFrame() + self.expect("expr -d run -- orderedSet", substrs=["3 elements"]) + self.expect("expr -d run -- *orderedSet", substrs=["(int)1", "(int)2", "(int)3"]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/orderedset/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/orderedset/main.m new file mode 100644 index 00000000000..e3f01622693 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/orderedset/main.m @@ -0,0 +1,8 @@ +#import <Foundation/Foundation.h> + +int main() { + NSOrderedSet *orderedSet = + [NSOrderedSet orderedSetWithArray:@[@1,@2,@3,@1]]; + NSLog(@"%@",orderedSet); + return 0; // break here +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/print-obj/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/print-obj/Makefile new file mode 100644 index 00000000000..2eab56265f5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/print-obj/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := blocked.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/print-obj/TestPrintObj.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/print-obj/TestPrintObj.py new file mode 100644 index 00000000000..9b3ec33db4e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/print-obj/TestPrintObj.py @@ -0,0 +1,91 @@ +""" +Test "print object" where another thread blocks the print object from making progress. +""" + +from __future__ import print_function + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class PrintObjTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # My source program. + self.source = "blocked.m" + # Find the line numbers to break at. + self.line = line_number(self.source, '// Set a breakpoint here.') + + def test_print_obj(self): + """ + Test "print object" where another thread blocks the print object from making progress. + + Set a breakpoint on the line in my_pthread_routine. Then switch threads + to the main thread, and do print the lock_me object. Since that will + try to get the lock already gotten by my_pthread_routime thread, it will + have to switch to running all threads, and that should then succeed. + """ + d = {'EXE': 'b.out'} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + exe = self.getBuildArtifact('b.out') + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertTrue(breakpoint, VALID_BREAKPOINT) + self.runCmd("breakpoint list") + + # Launch the process, and do not stop at the entry point. + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + + self.runCmd("thread backtrace all") + + # Let's get the current stopped thread. We'd like to switch to the + # other thread to issue our 'po lock_me' command. + import lldbsuite.test.lldbutil as lldbutil + this_thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue(this_thread) + + # Find the other thread. The iteration protocol of SBProcess and the + # rich comparison methods (__eq__/__ne__) of SBThread come in handy. + other_thread = None + for t in process: + if t != this_thread: + other_thread = t + break + + # Set the other thread as the selected thread to issue our 'po' + # command.other + self.assertTrue(other_thread) + process.SetSelectedThread(other_thread) + if self.TraceOn(): + print("selected thread:" + lldbutil.get_description(other_thread)) + self.runCmd("thread backtrace") + + # We want to traverse the frame to the one corresponding to blocked.m to + # issue our 'po lock_me' command. + + depth = other_thread.GetNumFrames() + for i in range(depth): + frame = other_thread.GetFrameAtIndex(i) + name = frame.GetFunctionName() + if name == 'main': + other_thread.SetSelectedFrame(i) + if self.TraceOn(): + print("selected frame:" + lldbutil.get_description(frame)) + break + + self.expect("po lock_me", OBJECT_PRINTED_CORRECTLY, + substrs=['I am pretty special.']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/print-obj/blocked.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/print-obj/blocked.m new file mode 100644 index 00000000000..58771264062 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/print-obj/blocked.m @@ -0,0 +1,72 @@ +//===-- blocked.m --------------------------------------------------*- ObjC -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This file is for testing running "print object" in a case where another thread +// blocks the print object from making progress. Set a breakpoint on the line in +// my_pthread_routine as indicated. Then switch threads to the main thread, and +// do print the lock_me object. Since that will try to get the lock already gotten +// by my_pthread_routime thread, it will have to switch to running all threads, and +// that should then succeed. +// + +#include <Foundation/Foundation.h> +#include <pthread.h> + +static pthread_mutex_t test_mutex; + +static void Mutex_Init (void) +{ + pthread_mutexattr_t tmp_mutex_attr; + pthread_mutexattr_init(&tmp_mutex_attr); + pthread_mutex_init(&test_mutex, &tmp_mutex_attr); +} + +@interface LockMe :NSObject +{ + +} +- (NSString *) description; +@end + +@implementation LockMe +- (NSString *) description +{ + printf ("LockMe trying to get the lock.\n"); + pthread_mutex_lock(&test_mutex); + printf ("LockMe got the lock.\n"); + pthread_mutex_unlock(&test_mutex); + return @"I am pretty special.\n"; +} +@end + +void * +my_pthread_routine (void *data) +{ + printf ("my_pthread_routine about to enter.\n"); + pthread_mutex_lock(&test_mutex); + printf ("Releasing Lock.\n"); // Set a breakpoint here. + pthread_mutex_unlock(&test_mutex); + return NULL; +} + +int +main () +{ + pthread_attr_t tmp_attr; + pthread_attr_init (&tmp_attr); + pthread_t my_pthread; + + Mutex_Init (); + + LockMe *lock_me = [[LockMe alloc] init]; + pthread_create (&my_pthread, &tmp_attr, my_pthread_routine, NULL); + + pthread_join (my_pthread, NULL); + + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ptr_refs/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ptr_refs/Makefile new file mode 100644 index 00000000000..845553d5e3f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ptr_refs/Makefile @@ -0,0 +1,3 @@ +OBJC_SOURCES := main.m + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ptr_refs/TestPtrRefsObjC.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ptr_refs/TestPtrRefsObjC.py new file mode 100644 index 00000000000..aade40c06b6 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ptr_refs/TestPtrRefsObjC.py @@ -0,0 +1,47 @@ +""" +Test the ptr_refs tool on Darwin with Objective-C +""" + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestPtrRefsObjC(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test_ptr_refs(self): + """Test the ptr_refs tool on Darwin with Objective-C""" + self.build() + exe = self.getBuildArtifact("a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + main_file_spec = lldb.SBFileSpec('main.m') + breakpoint = target.BreakpointCreateBySourceRegex( + 'break', main_file_spec) + self.assertTrue(breakpoint and + breakpoint.GetNumLocations() == 1, + VALID_BREAKPOINT) + + process = target.LaunchSimple( + None, None, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # Frame #0 should be on self.line1 and the break condition should hold. + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + + frame = thread.GetFrameAtIndex(0) + + self.dbg.HandleCommand("script import lldb.macosx.heap") + self.expect("ptr_refs self", substrs=["malloc", "stack"]) + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ptr_refs/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ptr_refs/main.m new file mode 100644 index 00000000000..94bf0fb9fc5 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/ptr_refs/main.m @@ -0,0 +1,38 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +@interface MyClass : NSObject { +}; +-(void)test; +@end + +@implementation MyClass +-(void)test { + printf("%p\n", self); // break here +} +@end + +@interface MyOwner : NSObject { + @public id ownedThing; // should be id, to test <rdar://problem/31363513> +}; +@end + +@implementation MyOwner +@end + +int main (int argc, char const *argv[]) { + @autoreleasepool { + MyOwner *owner = [[MyOwner alloc] init]; + owner->ownedThing = [[MyClass alloc] init]; + [(MyClass*)owner->ownedThing test]; + } + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/radar-9691614/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/radar-9691614/Makefile new file mode 100644 index 00000000000..37dd8f40a9d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/radar-9691614/Makefile @@ -0,0 +1,6 @@ +OBJC_SOURCES := main.m + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/radar-9691614/TestObjCMethodReturningBOOL.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/radar-9691614/TestObjCMethodReturningBOOL.py new file mode 100644 index 00000000000..632ef7bfe73 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/radar-9691614/TestObjCMethodReturningBOOL.py @@ -0,0 +1,45 @@ +""" +Test that objective-c method returning BOOL works correctly. +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class MethodReturningBOOLTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to break inside main(). + self.main_source = "main.m" + self.line = line_number(self.main_source, '// Set breakpoint here.') + + def test_method_ret_BOOL(self): + """Test that objective-c method returning BOOL works correctly.""" + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + + exe = self.getBuildArtifact(self.exe_name) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, "main.m", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + self.expect("process status", STOPPED_DUE_TO_BREAKPOINT, + substrs=[" at %s:%d" % (self.main_source, self.line), + "stop reason = breakpoint"]) + + # rdar://problem/9691614 + self.runCmd('p (int)[my isValid]') diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/radar-9691614/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/radar-9691614/main.m new file mode 100644 index 00000000000..bb87d673452 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/radar-9691614/main.m @@ -0,0 +1,67 @@ +#import <Foundation/Foundation.h> +#include <stdio.h> + +@interface MyString : NSObject { + NSString *str; + NSDate *date; + BOOL _is_valid; +} + +- (id)initWithNSString:(NSString *)string; +- (BOOL)isValid; +@end + +@implementation MyString +- (id)initWithNSString:(NSString *)string +{ + if (self = [super init]) + { + str = [NSString stringWithString:string]; + date = [NSDate date]; + } + _is_valid = YES; + return self; +} + +- (BOOL)isValid +{ + return _is_valid; +} + +- (void)dealloc +{ + [date release]; + [str release]; + [super dealloc]; +} + +- (NSString *)description +{ + return [str stringByAppendingFormat:@" with timestamp: %@", date]; +} +@end + +void +Test_MyString (const char *program) +{ + NSString *str = [NSString stringWithFormat:@"Hello from '%s'", program]; + MyString *my = [[MyString alloc] initWithNSString:str]; + if ([my isValid]) + printf("my is valid!\n"); + + NSLog(@"NSString instance: %@", [str description]); // Set breakpoint here. + // Test 'p (int)[my isValid]'. + // The expression parser should not crash -- rdar://problem/9691614. + + NSLog(@"MyString instance: %@", [my description]); +} + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + Test_MyString (argv[0]); + + [pool release]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/Makefile new file mode 100644 index 00000000000..37dd8f40a9d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/Makefile @@ -0,0 +1,6 @@ +OBJC_SOURCES := main.m + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/TestRdar10967107.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/TestRdar10967107.py new file mode 100644 index 00000000000..c6633b7fe52 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/TestRdar10967107.py @@ -0,0 +1,70 @@ +""" +Test that CoreFoundation classes CFGregorianDate and CFRange are not improperly uniqued +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class Rdar10967107TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to break inside main(). + self.main_source = "main.m" + self.line = line_number(self.main_source, '// Set breakpoint here.') + + def test_cfrange_diff_cfgregoriandate(self): + """Test that CoreFoundation classes CFGregorianDate and CFRange are not improperly uniqued.""" + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + + exe = self.getBuildArtifact(self.exe_name) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + self.main_source, + self.line, + num_expected_locations=1, + loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + # check that each type is correctly bound to its list of children + self.expect( + "frame variable cf_greg_date --raw", + substrs=[ + 'year', + 'month', + 'day', + 'hour', + 'minute', + 'second']) + self.expect( + "frame variable cf_range --raw", + substrs=[ + 'location', + 'length']) + # check that printing both does not somehow confuse LLDB + self.expect( + "frame variable --raw", + substrs=[ + 'year', + 'month', + 'day', + 'hour', + 'minute', + 'second', + 'location', + 'length']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/main.m new file mode 100644 index 00000000000..386a458950b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-10967107/main.m @@ -0,0 +1,13 @@ +#import <Foundation/Foundation.h> + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + NSDate *date1 = [NSDate date]; + CFGregorianDate cf_greg_date = CFAbsoluteTimeGetGregorianDate(CFDateGetAbsoluteTime((CFDateRef)date1), NULL); + CFRange cf_range = {4,4}; + + [pool release]; // Set breakpoint here. + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/Makefile new file mode 100644 index 00000000000..37dd8f40a9d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/Makefile @@ -0,0 +1,6 @@ +OBJC_SOURCES := main.m + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/TestRdar11355592.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/TestRdar11355592.py new file mode 100644 index 00000000000..f9e825ada43 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/TestRdar11355592.py @@ -0,0 +1,79 @@ +""" +Test that we do not attempt to make a dynamic type for a 'const char*' +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +class Rdar10967107TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to break inside main(). + self.main_source = "main.m" + self.line = line_number(self.main_source, '// Set breakpoint here.') + + def test_charstar_dyntype(self): + """Test that we do not attempt to make a dynamic type for a 'const char*'""" + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + + exe = self.getBuildArtifact(self.exe_name) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + self.main_source, + self.line, + num_expected_locations=1, + loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + # check that we correctly see the const char*, even with dynamic types + # on + self.expect("frame variable -raw-output my_string", substrs=['const char *']) + self.expect( + "frame variable my_string --raw-output --dynamic-type run-target", + substrs=['const char *']) + # check that expr also gets it right + self.expect("e -R -- my_string", substrs=['const char *']) + self.expect("expr -R -d run -- my_string", substrs=['const char *']) + # but check that we get the real Foolie as such + self.expect("frame variable my_foolie", substrs=['FoolMeOnce *']) + self.expect( + "frame variable my_foolie --dynamic-type run-target", + substrs=['FoolMeOnce *']) + # check that expr also gets it right + self.expect("expr my_foolie", substrs=['FoolMeOnce *']) + self.expect("expr -d run -- my_foolie", substrs=['FoolMeOnce *']) + # now check that assigning a true string does not break anything + self.runCmd("next") + # check that we correctly see the const char*, even with dynamic types + # on + self.expect("frame variable my_string", substrs=['const char *']) + self.expect( + "frame variable my_string --dynamic-type run-target", + substrs=['const char *']) + # check that expr also gets it right + self.expect("expr my_string", substrs=['const char *']) + self.expect("expr -d run -- my_string", substrs=['const char *']) + # but check that we get the real Foolie as such + self.expect("frame variable my_foolie", substrs=['FoolMeOnce *']) + self.expect( + "frame variable my_foolie --dynamic-type run-target", + substrs=['FoolMeOnce *']) + # check that expr also gets it right + self.expect("expr my_foolie", substrs=['FoolMeOnce *']) + self.expect("expr -d run -- my_foolie", substrs=['FoolMeOnce *']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/main.m new file mode 100644 index 00000000000..09b3b18a787 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-11355592/main.m @@ -0,0 +1,37 @@ +#import <Foundation/Foundation.h> + +@interface FoolMeOnce : NSObject +{ + int32_t value_one; // ivars needed to make 32-bit happy + int32_t value_two; +} +- (FoolMeOnce *) initWithFirst: (int32_t) first andSecond: (int32_t) second; + +@property int32_t value_one; +@property int32_t value_two; + +@end + +@implementation FoolMeOnce +@synthesize value_one; +@synthesize value_two; +- (FoolMeOnce *) initWithFirst: (int32_t) first andSecond: (int32_t) second +{ + value_one = first; + value_two = second; + return self; +} +@end + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + FoolMeOnce *my_foolie = [[FoolMeOnce alloc] initWithFirst: 20 andSecond: 55]; + const char *my_string = (char *) my_foolie; + + my_string = "Now this is a REAL string..."; // Set breakpoint here. + + [pool release]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/Makefile new file mode 100644 index 00000000000..919000e6402 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/Makefile @@ -0,0 +1,9 @@ +OBJC_SOURCES := main.m + +include Makefile.rules + +ifneq (,$(findstring arm,$(ARCH))) + LD_EXTRAS = -framework Foundation -framework UIKit +else + LD_EXTRAS = -framework Foundation -framework Cocoa +endif diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/TestRdar12408181.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/TestRdar12408181.py new file mode 100644 index 00000000000..8f262a3413d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/TestRdar12408181.py @@ -0,0 +1,69 @@ +""" +Test that we are able to find out how many children NSWindow has +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +# TODO: The Jenkins testers on OS X fail running this test because they don't +# have access to WindowServer so NSWindow doesn't work. We should disable this +# test if WindowServer isn't available. +# Note: Simply applying the @skipIf decorator here confuses the test harness +# and gives a spurious failure. +@skipUnlessDarwin +class Rdar12408181TestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # We'll use the test method name as the exe_name. + self.exe_name = self.testMethodName + # Find the line number to break inside main(). + self.main_source = "main.m" + self.line = line_number(self.main_source, '// Set breakpoint here.') + + def test_nswindow_count(self): + """Test that we are able to find out how many children NSWindow has.""" + + self.skipTest("Skipping this test due to timeout flakiness") + + d = {'EXE': self.exe_name} + self.build(dictionary=d) + self.setTearDownCleanup(dictionary=d) + + exe = self.getBuildArtifact(self.exe_name) + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + lldbutil.run_break_set_by_file_and_line( + self, + self.main_source, + self.line, + num_expected_locations=1, + loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + if self.frame().EvaluateExpression( + '(void*)_CGSDefaultConnection()').GetValueAsUnsigned() != 0: + window = self.frame().FindVariable("window") + window_dynamic = window.GetDynamicValue(lldb.eDynamicCanRunTarget) + self.assertTrue( + window.GetNumChildren() > 1, + "NSWindow (static) only has 1 child!") + self.assertTrue( + window_dynamic.GetNumChildren() > 1, + "NSWindow (dynamic) only has 1 child!") + self.assertTrue( + window.GetChildAtIndex(0).IsValid(), + "NSWindow (static) has an invalid child") + self.assertTrue( + window_dynamic.GetChildAtIndex(0).IsValid(), + "NSWindow (dynamic) has an invalid child") + else: + self.skipTest('no WindowServer connection') diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/main.m new file mode 100644 index 00000000000..858ba2a4a22 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/rdar-12408181/main.m @@ -0,0 +1,24 @@ +#import <Foundation/Foundation.h> +#if defined (__i386__) || defined (__x86_64__) +#import <Cocoa/Cocoa.h> +#else +#import <UIKit/UIKit.h> +#endif + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; +#if defined (__i386__) || defined (__x86_64__) + + [NSApplication sharedApplication]; + NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,100,100) styleMask:NSBorderlessWindowMask backing:NSBackingStoreRetained defer:NO]; + [window setCanHide:YES]; +#else + [UIApplication sharedApplication]; + CGRect rect = { 0, 0, 100, 100}; + UIWindow* window = [[UIWindow alloc] initWithFrame:rect]; +#endif + [pool release]; // Set breakpoint here. + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Bar.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Bar.h new file mode 100644 index 00000000000..5ee6acb2425 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Bar.h @@ -0,0 +1,12 @@ +#import <Foundation/Foundation.h> + +@class InternalClass; + +@interface Bar : NSObject { + @private + InternalClass *storage; +} + +- (NSString *)description; + +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Bar.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Bar.m new file mode 100644 index 00000000000..21c39066f8e --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Bar.m @@ -0,0 +1,43 @@ +#import "Bar.h" + +@interface InternalClass : NSObject { + @public + NSString *foo; + NSString *bar; +} +@end + +@implementation InternalClass +@end + +@interface Bar () +{ + NSString *_hidden_ivar; +} + +@end + +@implementation Bar + +- (id)init +{ + self = [super init]; + if (self) { + _hidden_ivar = [NSString stringWithFormat:@"%p: @Bar", self]; + } + return self; // Set breakpoint where Bar is an implementation +} + +- (void)dealloc +{ + [_hidden_ivar release]; + [super dealloc]; +} + +- (NSString *)description +{ + return [_hidden_ivar copyWithZone:NULL]; +} + +@end + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Foo.h b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Foo.h new file mode 100644 index 00000000000..d58da600765 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Foo.h @@ -0,0 +1,11 @@ +#import <Foundation/Foundation.h> + +#import "Bar.h" + +@interface Foo : NSObject { + Bar *_bar; +} + +- (NSString *)description; + +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Foo.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Foo.m new file mode 100644 index 00000000000..bcdeaeffc29 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Foo.m @@ -0,0 +1,25 @@ +#import "Foo.h" + +@implementation Foo + +- (id)init +{ + self = [super init]; + if (self) { + _bar = [[Bar alloc] init]; + } + return self; // Set breakpoint where Bar is an interface +} + +- (void)dealloc +{ + [_bar release]; + [super dealloc]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%p: @Foo { _bar = %@ }", self, _bar]; +} + +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Makefile new file mode 100644 index 00000000000..f1498efac1d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := Bar.m Foo.m main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/TestRealDefinition.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/TestRealDefinition.py new file mode 100644 index 00000000000..002bc6cbf82 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/TestRealDefinition.py @@ -0,0 +1,98 @@ +"""Test that types defined in shared libraries work correctly.""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestRealDefinition(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test_frame_var_after_stop_at_interface(self): + """Test that we can find the implementation for an objective C type""" + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + self.build() + self.common_setup() + + line = line_number( + 'Foo.m', '// Set breakpoint where Bar is an interface') + lldbutil.run_break_set_by_file_and_line( + self, 'Foo.m', line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Run and stop at Foo + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs=[' resolved, hit count = 1']) + + self.runCmd("continue", RUN_SUCCEEDED) + + # Run at stop at main + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs=[' resolved, hit count = 1']) + + # This should display correctly. + self.expect( + "frame variable foo->_bar->_hidden_ivar", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "(NSString *)", + "foo->_bar->_hidden_ivar = 0x"]) + + @skipUnlessDarwin + def test_frame_var_after_stop_at_implementation(self): + """Test that we can find the implementation for an objective C type""" + if self.getArchitecture() == 'i386': + self.skipTest("requires modern objc runtime") + self.build() + self.common_setup() + + line = line_number( + 'Bar.m', '// Set breakpoint where Bar is an implementation') + lldbutil.run_break_set_by_file_and_line( + self, 'Bar.m', line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # Run and stop at Foo + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs=[' resolved, hit count = 1']) + + self.runCmd("continue", RUN_SUCCEEDED) + + # Run at stop at main + self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, + substrs=[' resolved, hit count = 1']) + + # This should display correctly. + self.expect( + "frame variable foo->_bar->_hidden_ivar", + VARIABLES_DISPLAYED_CORRECTLY, + substrs=[ + "(NSString *)", + "foo->_bar->_hidden_ivar = 0x"]) + + def common_setup(self): + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + line = line_number('main.m', '// Set breakpoint in main') + lldbutil.run_break_set_by_file_and_line( + self, "main.m", line, num_expected_locations=1, loc_exact=True) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/main.m new file mode 100644 index 00000000000..8c31dc9abb3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/real-definition/main.m @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <stdint.h> +#import <Foundation/Foundation.h> +#import "Foo.h" + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + Foo *foo = [[Foo alloc] init]; + NSLog (@"foo is %@", foo); // Set breakpoint in main + [pool release]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/sample/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/sample/Makefile new file mode 100644 index 00000000000..afecbf96948 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/sample/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/sample/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/sample/main.m new file mode 100644 index 00000000000..9dffc71aaac --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/sample/main.m @@ -0,0 +1,70 @@ +#import <Foundation/Foundation.h> + + +@interface MyString : NSObject { + NSString *_string; + NSDate *_date; +} +- (id)initWithNSString:(NSString *)string; + +@property (copy) NSString *string; +@property (readonly,getter=getTheDate) NSDate *date; + +- (NSDate *) getTheDate; +@end + +@implementation MyString + +@synthesize string = _string; +@synthesize date = _date; + +- (id)initWithNSString:(NSString *)string +{ + if (self = [super init]) + { + _string = [NSString stringWithString:string]; + _date = [NSDate date]; + } + return self; +} + +- (void) dealloc +{ + [_date release]; + [_string release]; + [super dealloc]; +} + +- (NSDate *) getTheDate +{ + return _date; +} + +- (NSString *)description +{ + return [_string stringByAppendingFormat:@" with timestamp: %@", _date]; +} +@end + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + static NSString *g_global_nsstr = @"Howdy"; + + MyString *myStr = [[MyString alloc] initWithNSString: [NSString stringWithFormat:@"string %i", 1]]; + NSString *str1 = myStr.string; + NSString *str2 = [NSString stringWithFormat:@"string %i", 2]; + NSString *str3 = [NSString stringWithFormat:@"string %i", 3]; + NSArray *array = [NSArray arrayWithObjects: str1, str2, str3, nil]; + NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: + str1, @"1", + str2, @"2", + str3, @"3", + myStr.date, @"date", + nil]; + + id str_id = str1; + SEL sel = @selector(length); + [pool release]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/self/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/self/Makefile new file mode 100644 index 00000000000..644046c69ea --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/self/Makefile @@ -0,0 +1,4 @@ +OBJC_SOURCES := main.m +LD_EXTRAS ?= -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/self/TestObjCSelf.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/self/TestObjCSelf.py new file mode 100644 index 00000000000..81d6b79ad53 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/self/TestObjCSelf.py @@ -0,0 +1,39 @@ +""" +Tests that ObjC member variables are available where they should be. +""" +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCSelfTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test_with_run_command(self): + """Test that the appropriate member variables are available when stopped in Objective-C class and instance methods""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + self.set_breakpoint(line_number('main.m', '// breakpoint 1')) + self.set_breakpoint(line_number('main.m', '// breakpoint 2')) + + self.runCmd("process launch", RUN_SUCCEEDED) + + self.expect("expression -- m_a = 2", + startstr="(int) $0 = 2") + + self.runCmd("process continue") + + # This would be disallowed if we enforced const. But we don't. + self.expect("expression -- m_a = 2", + error=True) + + self.expect("expression -- s_a", + startstr="(int) $1 = 5") + + def set_breakpoint(self, line): + lldbutil.run_break_set_by_file_and_line( + self, "main.m", line, num_expected_locations=1, loc_exact=True) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/self/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/self/main.m new file mode 100644 index 00000000000..8f4e61202a3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/self/main.m @@ -0,0 +1,53 @@ +//===-- main.m ------------------------------------------*- Objective-C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +@interface A : NSObject +{ + int m_a; +} +-(id)init; +-(void)accessMember:(int)a; ++(void)accessStaticMember:(int)a; +@end + +static int s_a = 5; + +@implementation A +-(id)init +{ + self = [super init]; + + if (self) + m_a = 2; + + return self; +} + +-(void)accessMember:(int)a +{ + m_a = a; // breakpoint 1 +} + ++(void)accessStaticMember:(int)a +{ + s_a = a; // breakpoint 2 +} +@end + +int main() +{ + NSAutoreleasePool *pool = [NSAutoreleasePool alloc]; + A *my_a = [[A alloc] init]; + + [my_a accessMember:3]; + [A accessStaticMember:5]; + + [pool release]; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/Makefile new file mode 100644 index 00000000000..37dd8f40a9d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/Makefile @@ -0,0 +1,6 @@ +OBJC_SOURCES := main.m + + + +LD_EXTRAS := -framework Foundation +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py new file mode 100644 index 00000000000..85ad6286716 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/TestObjCSingleEntryDictionary.py @@ -0,0 +1,74 @@ +"""Test that we properly vend children for a single entry NSDictionary""" + + + +import unittest2 + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ObjCSingleEntryDictionaryTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break inside main(). + self.line = line_number('main.m', '// break here') + + @skipUnlessDarwin + @expectedFailureAll(oslist=['watchos'], bugnumber="rdar://problem/34642736") # bug in NSDictionary formatting on watchos + def test_single_entry_dict(self): + self.build() + exe = self.getBuildArtifact("a.out") + self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + + # Break inside the foo function which takes a bar_ptr argument. + lldbutil.run_break_set_by_file_and_line( + self, "main.m", self.line, num_expected_locations=1, loc_exact=True) + + self.runCmd("run", RUN_SUCCEEDED) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + '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']) + + d1 = self.frame().FindVariable("d1") + d1.SetPreferSyntheticValue(True) + d1.SetPreferDynamicValue(lldb.eDynamicCanRunTarget) + + self.assertTrue( + d1.GetNumChildren() == 1, + "dictionary has != 1 child elements") + pair = d1.GetChildAtIndex(0) + pair.SetPreferSyntheticValue(True) + pair.SetPreferDynamicValue(lldb.eDynamicCanRunTarget) + + self.assertTrue( + pair.GetNumChildren() == 2, + "pair has != 2 child elements") + + key = pair.GetChildMemberWithName("key") + value = pair.GetChildMemberWithName("value") + + key.SetPreferSyntheticValue(True) + key.SetPreferDynamicValue(lldb.eDynamicCanRunTarget) + value.SetPreferSyntheticValue(True) + value.SetPreferDynamicValue(lldb.eDynamicCanRunTarget) + + self.assertTrue( + key.GetSummary() == '@"key"', + "key doesn't contain key") + self.assertTrue( + value.GetSummary() == '@"value"', + "value doesn't contain value") diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/main.m new file mode 100644 index 00000000000..be472fd43c3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/single-entry-dictionary/main.m @@ -0,0 +1,7 @@ +#import <Foundation/Foundation.h> + +int main() { + NSDictionary *d1 = @{@"key" : @"value"}; + NSLog(@"%@\n", d1); // break here + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/unicode-string/TestUnicodeString.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/unicode-string/TestUnicodeString.py new file mode 100644 index 00000000000..c9986aafd7d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/unicode-string/TestUnicodeString.py @@ -0,0 +1,6 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipUnlessDarwin]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/unicode-string/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/unicode-string/main.m new file mode 100644 index 00000000000..e55eb1ede9b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/unicode-string/main.m @@ -0,0 +1,5 @@ +#import <Foundation/Foundation.h> + +int main() { + NSLog(@"凸"); //% self.expect("po @\"凹\"", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["凹"]) +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/variadic_methods/TestVariadicMethods.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/variadic_methods/TestVariadicMethods.py new file mode 100644 index 00000000000..562d9ae01e2 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/variadic_methods/TestVariadicMethods.py @@ -0,0 +1,7 @@ +from lldbsuite.test import lldbinline +from lldbsuite.test import decorators + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipIfFreeBSD, decorators.skipIfLinux, + decorators.skipIfWindows, decorators.skipIfNetBSD]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/variadic_methods/main.m b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/variadic_methods/main.m new file mode 100644 index 00000000000..609d783dd59 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objc/variadic_methods/main.m @@ -0,0 +1,30 @@ +//===-- main.m -------------------------------------------*- Objective-C-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#import <Foundation/Foundation.h> + +@interface VarClass : NSObject +- (id) lottaArgs: (id) first, ...; +@end + +@implementation VarClass +- (id) lottaArgs: (id) first, ... +{ + return first; +} +@end + +int +main() +{ + VarClass *my_var = [[VarClass alloc] init]; + id something = [my_var lottaArgs: @"111", @"222", nil]; + NSLog (@"%@ - %@", my_var, something); //% self.expect("expression -O -- [my_var lottaArgs:@\"111\", @\"222\", nil]", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["111"]) + return 0; +} + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/Makefile new file mode 100644 index 00000000000..bae88debbb1 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/Makefile @@ -0,0 +1,10 @@ +OBJCXX_SOURCES := main.mm myobject.mm +include Makefile.rules +CFLAGS_NO_DEBUG = +ifeq "$(OS)" "Darwin" + CFLAGS_NO_DEBUG += -arch $(ARCH) +endif + +# myobject.o needs to be built without debug info +myobject.o: myobject.mm + $(CXX) $(CFLAGS_NO_DEBUG) -c -o $@ $< diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/TestNameClash.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/TestNameClash.py new file mode 100644 index 00000000000..19832aefee9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/TestNameClash.py @@ -0,0 +1,7 @@ +from lldbsuite.test import decorators +from lldbsuite.test import lldbinline + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipIfFreeBSD, decorators.skipIfLinux, + decorators.skipIfWindows, decorators.skipIfNetBSD]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/main.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/main.mm new file mode 100644 index 00000000000..b74871f4270 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/main.mm @@ -0,0 +1,21 @@ +#import <Foundation/Foundation.h> + +namespace NS { + class MyObject { int i = 42; }; + NS::MyObject globalObject; +} + +@interface MyObject: NSObject +@end + +int main () +{ + @autoreleasepool + { + MyObject *o = [MyObject alloc]; + return 0; //% self.expect("fr var o", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["(MyObject"]); + //% self.expect("fr var globalObject", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["42"]); + } +} + + diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/myobject.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/myobject.mm new file mode 100644 index 00000000000..051c4e5eb1d --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/class-name-clash/myobject.mm @@ -0,0 +1,7 @@ +#import <Foundation/Foundation.h> + +@interface MyObject : NSObject +@end + +@implementation MyObject +@end diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/cxx-bridged-po/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/cxx-bridged-po/Makefile new file mode 100644 index 00000000000..7cfe4a3f0fd --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/cxx-bridged-po/Makefile @@ -0,0 +1,4 @@ +OBJCXX_SOURCES := main.mm +LD_EXTRAS := -lobjc -framework CoreFoundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/cxx-bridged-po/TestObjCXXBridgedPO.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/cxx-bridged-po/TestObjCXXBridgedPO.py new file mode 100644 index 00000000000..6f3275b861c --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/cxx-bridged-po/TestObjCXXBridgedPO.py @@ -0,0 +1,21 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + +class TestObjCXXBridgedPO(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipUnlessDarwin + def test_bridged_type_po(self): + self.build() + lldbutil.run_to_source_breakpoint( + self, 'break here', lldb.SBFileSpec('main.mm')) + self.expect('po num', + "did not get the Objective-C object description", + substrs=['CFNumber', '0x', '42']) + pointer_val = str(self.frame().FindVariable('num').GetValue()) + self.expect('po '+pointer_val, + "did not get the Objective-C object description", + substrs=['CFNumber', '0x', '42']) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/cxx-bridged-po/main.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/cxx-bridged-po/main.mm new file mode 100644 index 00000000000..e376456033f --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/cxx-bridged-po/main.mm @@ -0,0 +1,12 @@ +#include <CoreFoundation/CoreFoundation.h> + +void stop() {} + +int main(int argc, char **argv) +{ + int value = 42; + CFNumberRef num; + num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &value); + stop(); // break here + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/Makefile new file mode 100644 index 00000000000..3af75c304c3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/Makefile @@ -0,0 +1,4 @@ +OBJCXX_SOURCES := main.mm +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/TestObjCXXHideRuntimeValues.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/TestObjCXXHideRuntimeValues.py new file mode 100644 index 00000000000..cc6ac20b84b --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/TestObjCXXHideRuntimeValues.py @@ -0,0 +1,47 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil +import unittest2 + + +class TestObjCXXHideRuntimeSupportValues(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @skipIfFreeBSD + @skipIfLinux + @skipIfWindows + @skipIfNetBSD + def test_hide_runtime_support_values(self): + self.build() + _, process, _, _ = lldbutil.run_to_source_breakpoint( + self, 'break here', lldb.SBFileSpec('main.mm')) + + var_opts = lldb.SBVariablesOptions() + var_opts.SetIncludeArguments(True) + var_opts.SetIncludeLocals(True) + var_opts.SetInScopeOnly(True) + var_opts.SetIncludeStatics(False) + var_opts.SetIncludeRuntimeSupportValues(False) + var_opts.SetUseDynamic(lldb.eDynamicCanRunTarget) + values = self.frame().GetVariables(var_opts) + + def shows_var(name): + for value in values: + if value.name == name: + return True + return False + # ObjC method. + values = self.frame().GetVariables(var_opts) + self.assertFalse(shows_var("this")) + self.assertTrue(shows_var("self")) + self.assertTrue(shows_var("_cmd")) + self.assertTrue(shows_var("c")) + + process.Continue() + # C++ method. + values = self.frame().GetVariables(var_opts) + self.assertTrue(shows_var("this")) + self.assertFalse(shows_var("self")) + self.assertFalse(shows_var("_cmd")) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/main.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/main.mm new file mode 100644 index 00000000000..c192f386f22 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/hide-runtime-values/main.mm @@ -0,0 +1,28 @@ +#import <Foundation/Foundation.h> + +void baz() {} + +struct MyClass { + void bar() { + baz(); // break here + } +}; + +@interface MyObject : NSObject {} +- (void)foo; +@end + +@implementation MyObject +- (void)foo { + MyClass c; + c.bar(); // break here +} +@end + +int main (int argc, char const *argv[]) { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + id obj = [MyObject new]; + [obj foo]; + [pool release]; + return 0; +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/TestIvarVector.py b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/TestIvarVector.py new file mode 100644 index 00000000000..19832aefee9 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/TestIvarVector.py @@ -0,0 +1,7 @@ +from lldbsuite.test import decorators +from lldbsuite.test import lldbinline + +lldbinline.MakeInlineTest( + __file__, globals(), [ + decorators.skipIfFreeBSD, decorators.skipIfLinux, + decorators.skipIfWindows, decorators.skipIfNetBSD]) diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/main.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/main.mm new file mode 100644 index 00000000000..36eda1da2ac --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/objcxx-ivar-vector/main.mm @@ -0,0 +1,33 @@ +#import <Foundation/Foundation.h> + +#include <vector> + +@interface MyElement : NSObject { +} +@end + +@interface MyClass : NSObject { + std::vector<MyElement *> elements; +}; + +-(void)doSomething; + +@end + +@implementation MyClass + +-(void)doSomething +{ + NSLog(@"Hello"); //% self.expect("expression -- elements", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["vector", "MyElement"]); +} + +@end + +int main () +{ + @autoreleasepool + { + MyClass *c = [MyClass alloc]; + [c doSomething]; + } +} diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/sample/Makefile b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/sample/Makefile new file mode 100644 index 00000000000..3af75c304c3 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/sample/Makefile @@ -0,0 +1,4 @@ +OBJCXX_SOURCES := main.mm +LD_EXTRAS := -lobjc -framework Foundation + +include Makefile.rules diff --git a/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/sample/main.mm b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/sample/main.mm new file mode 100644 index 00000000000..c9a2172c368 --- /dev/null +++ b/gnu/llvm/lldb/packages/Python/lldbsuite/test/lang/objcxx/sample/main.mm @@ -0,0 +1,71 @@ +#import <Foundation/Foundation.h> +#include <iostream> + +@interface MyString : NSObject { + NSString *_string; + NSDate *_date; +} +- (id)initWithNSString:(NSString *)string; + +@property (copy) NSString *string; +@property (readonly,getter=getTheDate) NSDate *date; + +- (NSDate *) getTheDate; +@end + +@implementation MyString + +@synthesize string = _string; +@synthesize date = _date; + +- (id)initWithNSString:(NSString *)string +{ + if (self = [super init]) + { + _string = [NSString stringWithString:string]; + _date = [NSDate date]; + } + return self; +} + +- (void) dealloc +{ + [_date release]; + [_string release]; + [super dealloc]; +} + +- (NSDate *) getTheDate +{ + return _date; +} + +- (NSString *)description +{ + return [_string stringByAppendingFormat:@" with timestamp: %@", _date]; +} +@end + +int main (int argc, char const *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + static NSString *g_global_nsstr = @"Howdy"; + + MyString *myStr = [[MyString alloc] initWithNSString: [NSString stringWithFormat:@"string %i", 1]]; + NSString *str1 = myStr.string; + NSString *str2 = [NSString stringWithFormat:@"string %i", 2]; + NSString *str3 = [NSString stringWithFormat:@"string %i", 3]; + NSArray *array = [NSArray arrayWithObjects: str1, str2, str3, nil]; + NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: + str1, @"1", + str2, @"2", + str3, @"3", + myStr.date, @"date", + nil]; + + id str_id = str1; + SEL sel = @selector(length); + [pool release]; + std::cout << "Hello, objc++!\n"; + return 0; +} |