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