xref: /llvm-project/lldb/test/API/lang/cpp/dynamic-value/TestCppValueCast.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""
2Test lldb Python API SBValue::Cast(SBType) for C++ types.
3"""
4
5import lldb
6from lldbsuite.test.decorators import *
7from lldbsuite.test.lldbtest import *
8from lldbsuite.test import lldbutil
9
10
11class CppValueCastTestCase(TestBase):
12    @skipIf(bugnumber="llvm.org/PR36714")
13    @add_test_categories(["pyapi"])
14    def test_value_cast_with_virtual_inheritance(self):
15        """Test SBValue::Cast(SBType) API for C++ types with virtual inheritance."""
16        self.build(dictionary=self.d_virtual)
17        self.setTearDownCleanup(dictionary=self.d_virtual)
18        self.do_sbvalue_cast(self.exe_name)
19
20    @add_test_categories(["pyapi"])
21    def test_value_cast_with_regular_inheritance(self):
22        """Test SBValue::Cast(SBType) API for C++ types with regular inheritance."""
23        self.build(dictionary=self.d_regular)
24        self.setTearDownCleanup(dictionary=self.d_regular)
25        self.do_sbvalue_cast(self.exe_name)
26
27    def setUp(self):
28        # Call super's setUp().
29        TestBase.setUp(self)
30
31        # Find the line number to break for main.c.
32        self.source = "sbvalue-cast.cpp"
33        self.line = line_number(self.source, "// Set breakpoint here.")
34        self.exe_name = self.testMethodName
35        self.d_virtual = {
36            "CXX_SOURCES": self.source,
37            "EXE": self.exe_name,
38            "CFLAGS_EXTRAS": "-DDO_VIRTUAL_INHERITANCE",
39        }
40        self.d_regular = {"CXX_SOURCES": self.source, "EXE": self.exe_name}
41
42    def do_sbvalue_cast(self, exe_name):
43        """Test SBValue::Cast(SBType) API for C++ types."""
44        exe = self.getBuildArtifact(exe_name)
45
46        # Create a target from the debugger.
47
48        target = self.dbg.CreateTarget(exe)
49        self.assertTrue(target, VALID_TARGET)
50
51        # Set up our breakpoints:
52
53        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
54        self.assertTrue(breakpoint, VALID_BREAKPOINT)
55
56        # Now launch the process, and do not stop at the entry point.
57        process = target.LaunchSimple(None, None, self.get_process_working_directory())
58
59        self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
60
61        # Find DerivedA and DerivedB types.
62        typeA = target.FindFirstType("DerivedA")
63        typeB = target.FindFirstType("DerivedB")
64        self.DebugSBType(typeA)
65        self.DebugSBType(typeB)
66        self.assertTrue(typeA)
67        self.assertTrue(typeB)
68        error = lldb.SBError()
69
70        # First stop is for DerivedA instance.
71        threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint)
72        self.assertEqual(len(threads), 1)
73        thread = threads[0]
74        frame0 = thread.GetFrameAtIndex(0)
75
76        tellerA = frame0.FindVariable("teller", lldb.eNoDynamicValues)
77        self.DebugSBValue(tellerA)
78        self.assertEqual(
79            tellerA.GetChildMemberWithName("m_base_val").GetValueAsUnsigned(error, 0),
80            20,
81        )
82
83        if self.TraceOn():
84            for child in tellerA:
85                print("child name:", child.GetName())
86                print(child)
87
88        # Call SBValue.Cast() to obtain instanceA.
89        instanceA = tellerA.Cast(typeA.GetPointerType())
90        self.DebugSBValue(instanceA)
91
92        # Iterate through all the children and print their values.
93        if self.TraceOn():
94            for child in instanceA:
95                print("child name:", child.GetName())
96                print(child)
97        a_member_val = instanceA.GetChildMemberWithName("m_a_val")
98        self.DebugSBValue(a_member_val)
99        self.assertEqual(a_member_val.GetValueAsUnsigned(error, 0), 10)
100
101        # Second stop is for DerivedB instance.
102        threads = lldbutil.continue_to_breakpoint(process, breakpoint)
103        self.assertEqual(len(threads), 1)
104        thread = threads[0]
105        frame0 = thread.GetFrameAtIndex(0)
106
107        tellerB = frame0.FindVariable("teller", lldb.eNoDynamicValues)
108        self.DebugSBValue(tellerB)
109        self.assertEqual(
110            tellerB.GetChildMemberWithName("m_base_val").GetValueAsUnsigned(error, 0),
111            12,
112        )
113
114        if self.TraceOn():
115            for child in tellerB:
116                print("child name:", child.GetName())
117                print(child)
118
119        # Call SBValue.Cast() to obtain instanceB.
120        instanceB = tellerB.Cast(typeB.GetPointerType())
121        self.DebugSBValue(instanceB)
122
123        # Iterate through all the children and print their values.
124        if self.TraceOn():
125            for child in instanceB:
126                print("child name:", child.GetName())
127                print(child)
128        b_member_val = instanceB.GetChildMemberWithName("m_b_val")
129        self.DebugSBValue(b_member_val)
130        self.assertEqual(b_member_val.GetValueAsUnsigned(error, 0), 36)
131