Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / test / API / lang / objc / objc-dynamic-value / TestObjCDynamicValue.py
blobfd497c25ba7a9b66e39afe1169b2b2ecaa3c3267
1 """
2 Use lldb Python API to test dynamic values in ObjC
3 """
6 import lldb
7 from lldbsuite.test.decorators import *
8 from lldbsuite.test.lldbtest import *
9 from lldbsuite.test import lldbutil
12 class ObjCDynamicValueTestCase(TestBase):
13 def setUp(self):
14 # Call super's setUp().
15 TestBase.setUp(self)
17 # Find the line number to break for main.c.
19 self.source_name = "dynamic-value.m"
20 self.set_property_line = line_number(
21 self.source_name,
22 "// This is the line in setProperty, make sure we step to here.",
24 self.handle_SourceBase = line_number(
25 self.source_name, "// Break here to check dynamic values."
27 self.main_before_setProperty_line = line_number(
28 self.source_name, "// Break here to see if we can step into real method."
31 @add_test_categories(["pyapi"])
32 @expectedFailureDarwin("llvm.org/pr20271 rdar://18684107")
33 def test_get_objc_dynamic_vals(self):
34 """Test fetching ObjC dynamic values."""
35 if self.getArchitecture() == "i386":
36 # rdar://problem/9946499
37 self.skipTest("Dynamic types for ObjC V1 runtime not implemented")
39 self.build()
40 exe = self.getBuildArtifact("a.out")
42 # Create a target from the debugger.
44 target = self.dbg.CreateTarget(exe)
45 self.assertTrue(target, VALID_TARGET)
47 # Set up our breakpoints:
49 handle_SourceBase_bkpt = target.BreakpointCreateByLocation(
50 self.source_name, self.handle_SourceBase
52 self.assertTrue(
53 handle_SourceBase_bkpt and handle_SourceBase_bkpt.GetNumLocations() == 1,
54 VALID_BREAKPOINT,
57 main_before_setProperty_bkpt = target.BreakpointCreateByLocation(
58 self.source_name, self.main_before_setProperty_line
60 self.assertTrue(
61 main_before_setProperty_bkpt
62 and main_before_setProperty_bkpt.GetNumLocations() == 1,
63 VALID_BREAKPOINT,
66 # Now launch the process, and do not stop at the entry point.
67 process = target.LaunchSimple(None, None, self.get_process_working_directory())
69 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
71 threads = lldbutil.get_threads_stopped_at_breakpoint(
72 process, main_before_setProperty_bkpt
74 self.assertEquals(len(threads), 1)
75 thread = threads[0]
78 # At this point, myObserver has a Source pointer that is actually a KVO swizzled SourceDerived
79 # make sure we can get that properly:
81 frame = thread.GetFrameAtIndex(0)
82 myObserver = frame.FindVariable("myObserver", lldb.eDynamicCanRunTarget)
83 self.assertTrue(myObserver)
84 myObserver_source = myObserver.GetChildMemberWithName(
85 "_source", lldb.eDynamicCanRunTarget
87 self.examine_SourceDerived_ptr(myObserver_source)
90 # Make sure a static value can be correctly turned into a dynamic
91 # value.
93 frame = thread.GetFrameAtIndex(0)
94 myObserver_static = frame.FindVariable("myObserver", lldb.eNoDynamicValues)
95 self.assertTrue(myObserver_static)
96 myObserver = myObserver_static.GetDynamicValue(lldb.eDynamicCanRunTarget)
97 myObserver_source = myObserver.GetChildMemberWithName(
98 "_source", lldb.eDynamicCanRunTarget
100 self.examine_SourceDerived_ptr(myObserver_source)
102 # The "frame var" code uses another path to get into children, so let's
103 # make sure that works as well:
105 result = lldb.SBCommandReturnObject()
107 self.expect(
108 "frame var -d run-target myObserver->_source",
109 "frame var finds its way into a child member",
110 patterns=["\(SourceDerived \*\)"],
113 # check that our ObjC GetISA() does a good job at hiding KVO swizzled
114 # classes
116 self.expect(
117 "frame var -d run-target myObserver->_source -T",
118 "the KVO-ed class is hidden",
119 substrs=["SourceDerived"],
122 self.expect(
123 "frame var -d run-target myObserver->_source -T",
124 "the KVO-ed class is hidden",
125 matching=False,
126 substrs=["NSKVONotify"],
129 # This test is not entirely related to the main thrust of this test case, but since we're here,
130 # try stepping into setProperty, and make sure we get into the version
131 # in Source:
133 thread.StepInto()
135 threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonPlanComplete)
136 self.assertEquals(len(threads), 1)
137 line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry()
139 self.assertEqual(line_entry.GetLine(), self.set_property_line)
140 self.assertEqual(line_entry.GetFileSpec().GetFilename(), self.source_name)
142 # Okay, back to the main business. Continue to the handle_SourceBase
143 # and make sure we get the correct dynamic value.
145 threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt)
146 self.assertEquals(len(threads), 1)
147 thread = threads[0]
149 frame = thread.GetFrameAtIndex(0)
151 # Get "object" using FindVariable:
153 noDynamic = lldb.eNoDynamicValues
154 useDynamic = lldb.eDynamicCanRunTarget
156 object_static = frame.FindVariable("object", noDynamic)
157 object_dynamic = frame.FindVariable("object", useDynamic)
159 # Delete this object to make sure that this doesn't cause havoc with
160 # the dynamic object that depends on it.
161 del object_static
163 self.examine_SourceDerived_ptr(object_dynamic)
165 # Get "this" using FindValue, make sure that works too:
166 object_static = frame.FindValue(
167 "object", lldb.eValueTypeVariableArgument, noDynamic
169 object_dynamic = frame.FindValue(
170 "object", lldb.eValueTypeVariableArgument, useDynamic
172 del object_static
173 self.examine_SourceDerived_ptr(object_dynamic)
175 # Get "this" using the EvaluateExpression:
176 object_static = frame.EvaluateExpression("object", noDynamic)
177 object_dynamic = frame.EvaluateExpression("object", useDynamic)
178 del object_static
179 self.examine_SourceDerived_ptr(object_dynamic)
181 # Continue again to the handle_SourceBase and make sure we get the correct dynamic value.
182 # This one looks exactly the same, but in fact this is an "un-KVO'ed" version of SourceBase, so
183 # its isa pointer points to SourceBase not NSKVOSourceBase or
184 # whatever...
186 threads = lldbutil.continue_to_breakpoint(process, handle_SourceBase_bkpt)
187 self.assertEquals(len(threads), 1)
188 thread = threads[0]
190 frame = thread.GetFrameAtIndex(0)
192 # Get "object" using FindVariable:
194 object_static = frame.FindVariable("object", noDynamic)
195 object_dynamic = frame.FindVariable("object", useDynamic)
197 # Delete this object to make sure that this doesn't cause havoc with
198 # the dynamic object that depends on it.
199 del object_static
201 self.examine_SourceDerived_ptr(object_dynamic)
203 def examine_SourceDerived_ptr(self, object):
204 self.assertTrue(object)
205 self.assertNotEqual(object.GetTypeName().find("SourceDerived"), -1)
206 derivedValue = object.GetChildMemberWithName("_derivedValue")
207 self.assertTrue(derivedValue)
208 self.assertEquals(int(derivedValue.GetValue(), 0), 30)