1"""
2Test lldb data formatter subsystem.
3"""
4
5from __future__ import print_function
6
7
8import lldb
9from lldbsuite.test.decorators import *
10from lldbsuite.test.lldbtest import *
11from lldbsuite.test import lldbutil
12
13
14class LibCxxAtomicTestCase(TestBase):
15
16    mydir = TestBase.compute_mydir(__file__)
17
18    def get_variable(self, name):
19        var = self.frame().FindVariable(name)
20        var.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
21        var.SetPreferSyntheticValue(True)
22        return var
23
24    @skipIf(compiler=["gcc"])
25    @add_test_categories(["libc++"])
26    def test(self):
27        """Test that std::atomic as defined by libc++ is correctly printed by LLDB"""
28        self.build()
29        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
30
31        bkpt = self.target().FindBreakpointByID(
32            lldbutil.run_break_set_by_source_regexp(
33                self, "Set break point at this line."))
34
35        self.runCmd("run", RUN_SUCCEEDED)
36
37        lldbutil.skip_if_library_missing(
38            self, self.target(), lldbutil.PrintableRegex("libc\+\+"))
39
40        # The stop reason of the thread should be breakpoint.
41        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
42                    substrs=['stopped',
43                             'stop reason = breakpoint'])
44
45        s_atomic = self.get_variable('s')
46        i_atomic = self.get_variable('i')
47
48        if self.TraceOn():
49            print(s_atomic)
50        if self.TraceOn():
51            print(i_atomic)
52
53        # Extract the content of the std::atomic wrappers.
54        self.assertEqual(s_atomic.GetNumChildren(), 1)
55        s = s_atomic.GetChildAtIndex(0)
56        self.assertEqual(i_atomic.GetNumChildren(), 1)
57        i = i_atomic.GetChildAtIndex(0)
58
59        self.assertEqual(i.GetValueAsUnsigned(0), 5, "i == 5")
60        self.assertEqual(s.GetNumChildren(), 2, "s has two children")
61        self.assertEqual(
62            s.GetChildAtIndex(0).GetValueAsUnsigned(0), 1,
63            "s.x == 1")
64        self.assertEqual(
65            s.GetChildAtIndex(1).GetValueAsUnsigned(0), 2,
66            "s.y == 2")
67
68        # Try printing the child that points to its own parent object.
69        # This should just treat the atomic pointer as a normal pointer.
70        self.expect("frame var p.child", substrs=["Value = 0x"])
71        self.expect("frame var p", substrs=["parent = {", "Value = 0x", "}"])
72        self.expect("frame var p.child.parent", substrs=["p.child.parent = {\n  Value = 0x"])
73