1import lldb
2from lldbsuite.test.decorators import *
3from lldbsuite.test.lldbtest import *
4from lldbsuite.test import lldbutil
5
6
7class TestCase(TestBase):
8    def test(self):
9        """
10        Tests that running the utility expression that retrieves the Objective-C
11        class list works even when user-code contains functions with apparently
12        conflicting identifiers (e.g. 'free') but that are not in the global
13        scope.
14
15        This is *not* supposed to test what happens when there are actual
16        conflicts such as when a user somehow defined their own '::free'
17        function.
18        """
19
20        self.build()
21        lldbutil.run_to_source_breakpoint(
22            self, "// break here", lldb.SBFileSpec("main.mm")
23        )
24
25        # First check our side effect variable is in its initial state.
26        self.expect_expr("called_function", result_summary='"none"')
27
28        # Get the (dynamic) type of our 'id' variable so that our Objective-C
29        # runtime information is updated.
30        str_val = self.expect_expr("str")
31        dyn_val = str_val.GetDynamicValue(lldb.eDynamicCanRunTarget)
32        dyn_type = dyn_val.GetTypeName()
33
34        # Check our side effect variable which should still be in its initial
35        # state if none of our trap functions were called.
36        # If this is failing, then LLDB called one of the trap functions.
37        self.expect_expr("called_function", result_summary='"none"')
38
39        # Double check that our dynamic type is correct. This is done last
40        # as the assert message from above is the more descriptive one (it
41        # contains the unintentionally called function).
42        self.assertEqual(dyn_type, "__NSCFConstantString *")
43