1"""
2Test lldb data formatter subsystem for bitset for libcxx and libstdcpp.
3"""
4
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12USE_LIBSTDCPP = "USE_LIBSTDCPP"
13USE_LIBCPP = "USE_LIBCPP"
14VALUE = "VALUE"
15REFERENCE = "REFERENCE"
16POINTER = "POINTER"
17
18class GenericBitsetDataFormatterTestCase(TestBase):
19
20    def setUp(self):
21        TestBase.setUp(self)
22        primes = [1]*1000
23        primes[0] = primes[1] = 0
24        for i in range(2, len(primes)):
25            for j in range(2*i, len(primes), i):
26                primes[j] = 0
27        self.primes = primes
28
29    def getBitsetVariant(self, size, variant):
30        if variant == VALUE:
31            return "std::bitset<" + str(size) + ">"
32        elif variant == REFERENCE:
33            return "std::bitset<" + str(size) + "> &"
34        elif variant == POINTER:
35            return "std::bitset<" + str(size) + "> *"
36        return ""
37
38    def check(self, name, size, variant):
39        var = self.frame().FindVariable(name)
40        self.assertTrue(var.IsValid())
41        self.assertEqual(var.GetNumChildren(), size)
42        children = []
43        for i in range(size):
44            child = var.GetChildAtIndex(i)
45            children.append(ValueCheck(value=str(bool(child.GetValueAsUnsigned())).lower()))
46            self.assertEqual(child.GetValueAsUnsigned(), self.primes[i],
47                    "variable: %s, index: %d"%(name, size))
48        self.expect_var_path(name,type=self.getBitsetVariant(size,variant),children=children)
49
50    def do_test_value(self, stdlib_type):
51        """Test that std::bitset is displayed correctly"""
52        self.build(dictionary={stdlib_type: "1"})
53
54        lldbutil.run_to_source_breakpoint(self, '// break here',
55                lldb.SBFileSpec("main.cpp", False))
56
57        self.check("empty", 0, VALUE)
58        self.check("small", 13, VALUE)
59        self.check("medium", 70, VALUE)
60        self.check("large", 1000, VALUE)
61
62    @add_test_categories(["libstdcxx"])
63    def test_value_libstdcpp(self):
64        self.do_test_value(USE_LIBSTDCPP)
65
66    @add_test_categories(["libc++"])
67    def test_value_libcpp(self):
68        self.do_test_value(USE_LIBCPP)
69
70    def do_test_ptr_and_ref(self, stdlib_type):
71        """Test that ref and ptr to std::bitset is displayed correctly"""
72        self.build(dictionary={stdlib_type: "1"})
73
74        (_, process, _, bkpt) = lldbutil.run_to_source_breakpoint(self,
75                'Check ref and ptr',
76                lldb.SBFileSpec("main.cpp", False))
77
78        self.check("ref", 13, REFERENCE)
79        self.check("ptr", 13, POINTER)
80
81        lldbutil.continue_to_breakpoint(process, bkpt)
82
83        self.check("ref", 70, REFERENCE)
84        self.check("ptr", 70, POINTER)
85
86        lldbutil.continue_to_breakpoint(process, bkpt)
87
88        self.check("ref", 1000, REFERENCE)
89        self.check("ptr", 1000, POINTER)
90
91    @add_test_categories(["libstdcxx"])
92    def test_ptr_and_ref_libstdcpp(self):
93        self.do_test_ptr_and_ref(USE_LIBSTDCPP)
94
95    @add_test_categories(["libc++"])
96    def test_ptr_and_ref_libcpp(self):
97        self.do_test_ptr_and_ref(USE_LIBCPP)
98