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