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