[Lldb-commits] [lldb] 974c2f5 - [lldb] Modernize and expand TestCppBitfields
Raphael Isemann via lldb-commits
lldb-commits at lists.llvm.org
Mon Oct 25 09:19:50 PDT 2021
Author: Raphael Isemann
Date: 2021-10-25T18:19:26+02:00
New Revision: 974c2f5e22112659549a54ff95ee310a1aac469d
URL: https://github.com/llvm/llvm-project/commit/974c2f5e22112659549a54ff95ee310a1aac469d
DIFF: https://github.com/llvm/llvm-project/commit/974c2f5e22112659549a54ff95ee310a1aac469d.diff
LOG: [lldb] Modernize and expand TestCppBitfields
* clang-format test source.
* Removed the dead setup code.
* Using expect_expr etc. instead of raw expect.
* Slightly expanded with tests for vtable pointers (which mostly just crash atm.)
* Removed some other minor test guideline problems.
Added:
Modified:
lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py
lldb/test/API/lang/cpp/bitfields/main.cpp
Removed:
################################################################################
diff --git a/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py b/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py
index c67446f47803..4cdaf32ca065 100644
--- a/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py
+++ b/lldb/test/API/lang/cpp/bitfields/TestCppBitfields.py
@@ -10,143 +10,165 @@ 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.')
-
- def test_and_run_command(self):
- """Test 'frame variable ...' on a variable with bitfields."""
+ @no_debug_info_test
+ def test_bitfields(self):
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("expr uwbf",
- substrs=['a = 255',
- 'b = 65535',
- 'c = 4294967295',
- 'x = 4294967295'] )
-
- self.expect("expr uwubf",
- substrs=['a = 16777215',
- 'x = 4294967295'] )
-
- 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',
- ])
-
- self.expect(
- "frame variable --show-types derived",
- VARIABLES_DISPLAYED_CORRECTLY,
- substrs=[
- '(uint32_t) b_a = 2',
- '(uint32_t:1) d_a = 1',
- ])
-
- self.expect(
- "frame variable --show-types bb",
- VARIABLES_DISPLAYED_CORRECTLY,
- substrs=[
- '(bool:1) a = true',
- '(bool:1) b = false',
- '(bool:2) c = true',
- '(bool:2) d = true',
- ])
+ lldbutil.run_to_source_breakpoint(self, '// break here',
+ lldb.SBFileSpec("main.cpp", False))
+
+ # Accessing LargeBitsA.
+ self.expect_expr("lba", result_children=[
+ ValueCheck(name="", type="int:32"),
+ ValueCheck(name="a", type="unsigned int:20", value="2")
+ ])
+ self.expect_expr("lba.a", result_type="unsigned int", result_value="2")
+
+
+ # Accessing LargeBitsB.
+ self.expect_expr("lbb", result_children=[
+ ValueCheck(name="a", type="unsigned int:1", value="1"),
+ ValueCheck(name="", type="int:31"),
+ ValueCheck(name="b", type="unsigned int:20", value="3")
+ ])
+ self.expect_expr("lbb.b", result_type="unsigned int", result_value="3")
+
+
+ # Accessing LargeBitsC.
+ self.expect_expr("lbc", result_children=[
+ ValueCheck(name="", type="int:22"),
+ ValueCheck(name="a", type="unsigned int:1", value="1"),
+ ValueCheck(name="b", type="unsigned int:1", value="0"),
+ ValueCheck(name="c", type="unsigned int:5", value="4"),
+ ValueCheck(name="d", type="unsigned int:1", value="1"),
+ ValueCheck(name="", type="int:2"),
+ ValueCheck(name="e", type="unsigned int:20", value="20"),
+ ])
+ self.expect_expr("lbc.c", result_type="unsigned int", result_value="4")
+
+
+ # Accessing LargeBitsD.
+ self.expect_expr("lbd", result_children=[
+ ValueCheck(name="arr", type="char[3]", summary='"ab"'),
+ ValueCheck(name="", type="int:32"),
+ ValueCheck(name="a", type="unsigned int:20", value="5")
+ ])
+ self.expect_expr("lbd.a", result_type="unsigned int", result_value="5")
+
+
+ # Test BitfieldsInStructInUnion.
+ # FIXME: This needs some more explanation for what it's actually testing.
+ nested_struct_children = [
+ ValueCheck(name="", type="int:22"),
+ ValueCheck(name="a", type="uint64_t:1", value="1"),
+ ValueCheck(name="b", type="uint64_t:1", value="0"),
+ ValueCheck(name="c", type="uint64_t:1", value="1"),
+ ValueCheck(name="d", type="uint64_t:1", value="0"),
+ ValueCheck(name="e", type="uint64_t:1", value="1"),
+ ValueCheck(name="f", type="uint64_t:1", value="0"),
+ ValueCheck(name="g", type="uint64_t:1", value="1"),
+ ValueCheck(name="h", type="uint64_t:1", value="0"),
+ ValueCheck(name="i", type="uint64_t:1", value="1"),
+ ValueCheck(name="j", type="uint64_t:1", value="0"),
+ ValueCheck(name="k", type="uint64_t:1", value="1")
+ ]
+ self.expect_expr("bitfields_in_struct_in_union",
+ result_type="BitfieldsInStructInUnion",
+ result_children=[ValueCheck(name="", children=[
+ ValueCheck(name="f", children=nested_struct_children)
+ ])]
+ )
+ self.expect_expr("bitfields_in_struct_in_union.f.a",
+ result_type="uint64_t", result_value="1")
+
+
+ # Unions with bitfields.
+ self.expect_expr("uwbf", result_type="UnionWithBitfields", result_children=[
+ ValueCheck(name="a", value="255"),
+ ValueCheck(name="b", value="65535"),
+ ValueCheck(name="c", value="4294967295"),
+ ValueCheck(name="x", value="4294967295")
+ ])
+ self.expect_expr("uwubf", result_type="UnionWithUnnamedBitfield",
+ result_children=[
+ ValueCheck(name="a", value="16777215"),
+ ValueCheck(name="x", value="4294967295")
+ ]
+ )
+
+ # Class with a base class and a bitfield.
+ self.expect_expr("derived", result_type="Derived", result_children=[
+ ValueCheck(name="Base", children=[
+ ValueCheck(name="b_a", value="2", type="uint32_t")
+ ]),
+ ValueCheck(name="d_a", value="1", type="uint32_t:1")
+ ])
+
+
+ # Struct with bool bitfields.
+ self.expect_expr("bb", result_type="", result_children=[
+ ValueCheck(name="a", value="true", type="bool:1"),
+ ValueCheck(name="b", value="false", type="bool:1"),
+ ValueCheck(name="c", value="true", type="bool:2"),
+ ValueCheck(name="d", value="true", type="bool:2")
+ ])
bb = self.frame().FindVariable('bb')
- self.assertTrue(bb.IsValid())
+ self.assertSuccess(bb.GetError())
bb_a = bb.GetChildAtIndex(0)
- self.assertTrue(bb_a.IsValid())
+ self.assertSuccess(bb_a.GetError())
self.assertEqual(bb_a.GetValueAsUnsigned(), 1)
self.assertEqual(bb_a.GetValueAsSigned(), 1)
bb_b = bb.GetChildAtIndex(1)
- self.assertTrue(bb_b.IsValid())
+ self.assertSuccess(bb_b.GetError())
self.assertEqual(bb_b.GetValueAsUnsigned(), 0)
self.assertEqual(bb_b.GetValueAsSigned(), 0)
bb_c = bb.GetChildAtIndex(2)
- self.assertTrue(bb_c.IsValid())
+ self.assertSuccess(bb_c.GetError())
self.assertEqual(bb_c.GetValueAsUnsigned(), 1)
self.assertEqual(bb_c.GetValueAsSigned(), 1)
bb_d = bb.GetChildAtIndex(3)
- self.assertTrue(bb_d.IsValid())
+ self.assertSuccess(bb_d.GetError())
self.assertEqual(bb_d.GetValueAsUnsigned(), 1)
self.assertEqual(bb_d.GetValueAsSigned(), 1)
+
+ # Test a class with a base class that has a vtable ptr. The derived
+ # class has bitfields.
+ base_with_vtable_children = [
+ ValueCheck(name="a", type="unsigned int:4", value="5"),
+ ValueCheck(name="b", type="unsigned int:4", value="0"),
+ ValueCheck(name="c", type="unsigned int:4", value="5")
+ ]
+ self.expect_expr("base_with_vtable", result_children=base_with_vtable_children)
+ self.expect_var_path("base_with_vtable", children=base_with_vtable_children)
+
+ # FIXME: These all crash due the vtable ptr.
+ @skipIf
+ @no_debug_info_test
+ def test_bitfield_behind_vtable_ptr(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, '// break here',
+ lldb.SBFileSpec("main.cpp", False))
+
+ # Test a class with a vtable ptr and bitfields.
+ with_vtable_children = [
+ ValueCheck(name="a", type="unsigned int:4", value="5"),
+ ValueCheck(name="b", type="unsigned int:4", value="0"),
+ ValueCheck(name="c", type="unsigned int:4", value="5")
+ ]
+ self.expect_expr("with_vtable", result_children=with_vtable_children)
+ self.expect_var_path("with_vtable", children=with_vtable_children)
+
+ # Test a class with a vtable ptr and unnamed bitfield directly after.
+ with_vtable_and_unnamed_children = [
+ ValueCheck(name="", type="unsigned int:4", value="0"),
+ ValueCheck(name="b", type="unsigned int:4", value="0"),
+ ValueCheck(name="c", type="unsigned int:4", value="5")
+ ]
+ self.expect_expr("with_vtable_and_unnamed",
+ result_children=with_vtable_and_unnamed_children)
+ self.expect_var_path("with_vtable_and_unnamed",
+ children=with_vtable_and_unnamed_children)
diff --git a/lldb/test/API/lang/cpp/bitfields/main.cpp b/lldb/test/API/lang/cpp/bitfields/main.cpp
index a9887b5e826e..e40f1648ac83 100644
--- a/lldb/test/API/lang/cpp/bitfields/main.cpp
+++ b/lldb/test/API/lang/cpp/bitfields/main.cpp
@@ -1,87 +1,119 @@
#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;
-
- class B {
- public:
- uint32_t b_a;
+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;
+
+struct BitfieldsInStructInUnion {
+ 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 BitfieldsInStructInUnion;
};
- class D : public B {
- public:
- uint32_t d_a : 1;
- } derived;
-
- union union_with_bitfields {
- unsigned int a : 8;
- unsigned int b : 16;
- unsigned int c : 32;
- unsigned int x;
- } uwbf;
+ union {
+ struct fields f;
+ };
- union union_with_unnamed_bitfield {
- unsigned int : 16, a : 24;
- unsigned int x;
- } uwubf;
+ BitfieldsInStructInUnion() {
+ 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;
+ }
+} bitfields_in_struct_in_union;
+
+class Base {
+public:
+ uint32_t b_a;
+};
+
+class Derived : public Base {
+public:
+ uint32_t d_a : 1;
+} derived;
+
+union UnionWithBitfields {
+ unsigned int a : 8;
+ unsigned int b : 16;
+ unsigned int c : 32;
+ unsigned int x;
+} uwbf;
+
+union UnionWithUnnamedBitfield {
+ unsigned int : 16, a : 24;
+ unsigned int x;
+} uwubf;
+
+struct BoolBits {
+ bool a : 1;
+ bool b : 1;
+ bool c : 2;
+ bool d : 2;
+};
+
+struct WithVTable {
+ virtual ~WithVTable() {}
+ unsigned a : 4;
+ unsigned b : 4;
+ unsigned c : 4;
+};
+WithVTable with_vtable;
+
+struct WithVTableAndUnnamed {
+ virtual ~WithVTableAndUnnamed() {}
+ unsigned a : 4;
+ unsigned b : 4;
+ unsigned c : 4;
+};
+WithVTableAndUnnamed with_vtable_and_unnamed;
+
+struct BaseWithVTable {
+ virtual ~BaseWithVTable() {}
+};
+struct HasBaseWithVTable : BaseWithVTable {
+ unsigned a : 4;
+ unsigned b : 4;
+ unsigned c : 4;
+};
+HasBaseWithVTable base_with_vtable;
+int main(int argc, char const *argv[]) {
lba.a = 2;
lbb.a = 1;
@@ -104,17 +136,23 @@ int main(int argc, char const *argv[]) {
uwbf.x = 0xFFFFFFFF;
uwubf.x = 0xFFFFFFFF;
- struct BoolBits {
- bool a : 1;
- bool b : 1;
- bool c : 2;
- bool d : 2;
- } bb;
-
+ BoolBits bb;
bb.a = 0b1;
bb.b = 0b0;
bb.c = 0b11;
bb.d = 0b01;
- return 0; // Set break point at this line.
+ with_vtable.a = 5;
+ with_vtable.b = 0;
+ with_vtable.c = 5;
+
+ with_vtable_and_unnamed.a = 5;
+ with_vtable_and_unnamed.b = 0;
+ with_vtable_and_unnamed.c = 5;
+
+ base_with_vtable.a = 5;
+ base_with_vtable.b = 0;
+ base_with_vtable.c = 5;
+
+ return 0; // break here
}
More information about the lldb-commits
mailing list