[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