TestCppValueCast.py revision e745f4db0cff7214674cd421dd690f05bd2a28e1
1"""
2Test lldb Python API SBValue::Cast(SBType) for C++ types.
3"""
4
5import os, time
6import re
7import unittest2
8import lldb, lldbutil
9from lldbtest import *
10
11class CppValueCastTestCase(TestBase):
12
13    mydir = os.path.join("lang", "cpp", "dynamic-value")
14
15    # rdar://problem/10808472 SBValue::Cast test case is failing (virtual inheritance)
16    @unittest2.expectedFailure
17    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
18    @python_api_test
19    def test_value_cast_with_dsym_and_virtual_inheritance(self):
20        """Test SBValue::Cast(SBType) API for C++ types with virtual inheritance."""
21        self.buildDsym(dictionary=self.d_virtual)
22        self.do_sbvalue_cast(self.exe_name)
23
24    # rdar://problem/10808472 SBValue::Cast test case is failing (virtual inheritance)
25    @unittest2.expectedFailure
26    @python_api_test
27    def test_value_cast_with_dwarf_and_virtual_inheritance(self):
28        """Test SBValue::Cast(SBType) API for C++ types with virtual inheritance."""
29        self.buildDwarf(dictionary=self.d_virtual)
30        self.do_sbvalue_cast(self.exe_name)
31
32    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
33    @python_api_test
34    def test_value_cast_with_dsym_and_regular_inheritance(self):
35        """Test SBValue::Cast(SBType) API for C++ types with regular inheritance."""
36        self.buildDsym(dictionary=self.d_regular)
37        self.do_sbvalue_cast(self.exe_name)
38
39    @python_api_test
40    def test_value_cast_with_dwarf_and_regular_inheritance(self):
41        """Test SBValue::Cast(SBType) API for C++ types with regular inheritance."""
42        self.buildDwarf(dictionary=self.d_regular)
43        self.do_sbvalue_cast(self.exe_name)
44
45    def setUp(self):
46        # Call super's setUp().
47        TestBase.setUp(self)
48
49        # Find the line number to break for main.c.
50        self.source = 'sbvalue-cast.cpp';
51        self.line = line_number(self.source, '// Set breakpoint here.')
52        self.exe_name = self.testMethodName
53        self.d_virtual = {'CXX_SOURCES': self.source, 'EXE': self.exe_name, 'CFLAGS_EXTRAS': '-DVIRTUAL=YES'}
54        self.d_regular = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
55
56    def do_sbvalue_cast (self, exe_name):
57        """Test SBValue::Cast(SBType) API for C++ types."""
58        exe = os.path.join(os.getcwd(), exe_name)
59
60        # Create a target from the debugger.
61
62        target = self.dbg.CreateTarget (exe)
63        self.assertTrue(target, VALID_TARGET)
64
65        # Set up our breakpoints:
66
67        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
68        self.assertTrue(breakpoint, VALID_BREAKPOINT)
69
70        # Now launch the process, and do not stop at the entry point.
71        process = target.LaunchSimple (None, None, os.getcwd())
72
73        self.assertTrue(process.GetState() == lldb.eStateStopped,
74                        PROCESS_STOPPED)
75
76        # Find DerivedA and DerivedB types.
77        typeA = target.FindFirstType('DerivedA')
78        typeB = target.FindFirstType('DerivedB')
79        self.DebugSBType(typeA)
80        self.DebugSBType(typeB)
81        self.assertTrue(typeA)
82        self.assertTrue(typeB)
83        error = lldb.SBError()
84
85        # First stop is for DerivedA instance.
86        threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
87        self.assertTrue (len(threads) == 1)
88        thread = threads[0]
89        frame0 = thread.GetFrameAtIndex(0)
90
91        tellerA = frame0.FindVariable('teller', lldb.eNoDynamicValues)
92        self.DebugSBValue(tellerA)
93        self.assertTrue(tellerA.GetChildMemberWithName('m_base_val').GetValueAsUnsigned(error, 0) == 20)
94
95        if self.TraceOn():
96            for child in tellerA:
97                print "child name:", child.GetName()
98                print child
99
100        # Call SBValue.Cast() to obtain instanceA.
101        instanceA = tellerA.Cast(typeA.GetPointerType())
102        self.DebugSBValue(instanceA)
103
104        # Iterate through all the children and print their values.
105        if self.TraceOn():
106            for child in instanceA:
107                print "child name:", child.GetName()
108                print child
109        a_member_val = instanceA.GetChildMemberWithName('m_a_val')
110        self.DebugSBValue(a_member_val)
111        self.assertTrue(a_member_val.GetValueAsUnsigned(error, 0) == 10)
112
113        # Second stop is for DerivedB instance.
114        threads = lldbutil.continue_to_breakpoint (process, breakpoint)
115        self.assertTrue (len(threads) == 1)
116        thread = threads[0]
117        frame0 = thread.GetFrameAtIndex(0)
118
119        tellerB = frame0.FindVariable('teller', lldb.eNoDynamicValues)
120        self.DebugSBValue(tellerB)
121        self.assertTrue(tellerB.GetChildMemberWithName('m_base_val').GetValueAsUnsigned(error, 0) == 12)
122
123        if self.TraceOn():
124            for child in tellerB:
125                print "child name:", child.GetName()
126                print child
127
128        # Call SBValue.Cast() to obtain instanceB.
129        instanceB = tellerB.Cast(typeB.GetPointerType())
130        self.DebugSBValue(instanceB)
131
132        # Iterate through all the children and print their values.
133        if self.TraceOn():
134            for child in instanceB:
135                print "child name:", child.GetName()
136                print child
137        b_member_val = instanceB.GetChildMemberWithName('m_b_val')
138        self.DebugSBValue(b_member_val)
139        self.assertTrue(b_member_val.GetValueAsUnsigned(error, 0) == 36)
140
141
142if __name__ == '__main__':
143    import atexit
144    lldb.SBDebugger.Initialize()
145    atexit.register(lambda: lldb.SBDebugger.Terminate())
146    unittest2.main()
147