xref: /llvm-project/lldb/test/API/lang/cpp/dynamic-value/TestCppValueCast.py (revision 193259cbcec77add8e189c4dedeefb15fef50d5e)
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
13    @skipIf(bugnumber="llvm.org/PR36714")
14    @add_test_categories(['pyapi'])
15    def test_value_cast_with_virtual_inheritance(self):
16        """Test SBValue::Cast(SBType) API for C++ types with virtual inheritance."""
17        self.build(dictionary=self.d_virtual)
18        self.setTearDownCleanup(dictionary=self.d_virtual)
19        self.do_sbvalue_cast(self.exe_name)
20
21    @add_test_categories(['pyapi'])
22    def test_value_cast_with_regular_inheritance(self):
23        """Test SBValue::Cast(SBType) API for C++ types with regular inheritance."""
24        self.build(dictionary=self.d_regular)
25        self.setTearDownCleanup(dictionary=self.d_regular)
26        self.do_sbvalue_cast(self.exe_name)
27
28    def setUp(self):
29        # Call super's setUp().
30        TestBase.setUp(self)
31
32        # Find the line number to break for main.c.
33        self.source = 'sbvalue-cast.cpp'
34        self.line = line_number(self.source, '// Set breakpoint here.')
35        self.exe_name = self.testMethodName
36        self.d_virtual = {
37            'CXX_SOURCES': self.source,
38            'EXE': self.exe_name,
39            'CFLAGS_EXTRAS': '-DDO_VIRTUAL_INHERITANCE'}
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(
58            None, None, self.get_process_working_directory())
59
60        self.assertState(process.GetState(), lldb.eStateStopped,
61                         PROCESS_STOPPED)
62
63        # Find DerivedA and DerivedB types.
64        typeA = target.FindFirstType('DerivedA')
65        typeB = target.FindFirstType('DerivedB')
66        self.DebugSBType(typeA)
67        self.DebugSBType(typeB)
68        self.assertTrue(typeA)
69        self.assertTrue(typeB)
70        error = lldb.SBError()
71
72        # First stop is for DerivedA instance.
73        threads = lldbutil.get_threads_stopped_at_breakpoint(
74            process, breakpoint)
75        self.assertEqual(len(threads), 1)
76        thread = threads[0]
77        frame0 = thread.GetFrameAtIndex(0)
78
79        tellerA = frame0.FindVariable('teller', lldb.eNoDynamicValues)
80        self.DebugSBValue(tellerA)
81        self.assertTrue(tellerA.GetChildMemberWithName(
82            'm_base_val').GetValueAsUnsigned(error, 0) == 20)
83
84        if self.TraceOn():
85            for child in tellerA:
86                print("child name:", child.GetName())
87                print(child)
88
89        # Call SBValue.Cast() to obtain instanceA.
90        instanceA = tellerA.Cast(typeA.GetPointerType())
91        self.DebugSBValue(instanceA)
92
93        # Iterate through all the children and print their values.
94        if self.TraceOn():
95            for child in instanceA:
96                print("child name:", child.GetName())
97                print(child)
98        a_member_val = instanceA.GetChildMemberWithName('m_a_val')
99        self.DebugSBValue(a_member_val)
100        self.assertEqual(a_member_val.GetValueAsUnsigned(error, 0), 10)
101
102        # Second stop is for DerivedB instance.
103        threads = lldbutil.continue_to_breakpoint(process, breakpoint)
104        self.assertEqual(len(threads), 1)
105        thread = threads[0]
106        frame0 = thread.GetFrameAtIndex(0)
107
108        tellerB = frame0.FindVariable('teller', lldb.eNoDynamicValues)
109        self.DebugSBValue(tellerB)
110        self.assertTrue(tellerB.GetChildMemberWithName(
111            'm_base_val').GetValueAsUnsigned(error, 0) == 12)
112
113        if self.TraceOn():
114            for child in tellerB:
115                print("child name:", child.GetName())
116                print(child)
117
118        # Call SBValue.Cast() to obtain instanceB.
119        instanceB = tellerB.Cast(typeB.GetPointerType())
120        self.DebugSBValue(instanceB)
121
122        # Iterate through all the children and print their values.
123        if self.TraceOn():
124            for child in instanceB:
125                print("child name:", child.GetName())
126                print(child)
127        b_member_val = instanceB.GetChildMemberWithName('m_b_val')
128        self.DebugSBValue(b_member_val)
129        self.assertEqual(b_member_val.GetValueAsUnsigned(error, 0), 36)
130