xref: /llvm-project/lldb/test/API/lang/cpp/namespace/TestNamespaceLookup.py (revision a575e6e5ca1eb7b2ae4b906f9bf3be2ba20a80a0)
1"""
2Test the printing of anonymous and named namespace variables.
3"""
4
5
6import unittest
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11from lldbsuite.test import lldbplatformutil
12
13class NamespaceLookupTestCase(TestBase):
14    def setUp(self):
15        # Call super's setUp().
16        TestBase.setUp(self)
17        # Break inside different scopes and evaluate value
18        self.line_break_global_scope = line_number("ns.cpp", "// BP_global_scope")
19        self.line_break_file_scope = line_number("ns2.cpp", "// BP_file_scope")
20        self.line_break_ns_scope = line_number("ns2.cpp", "// BP_ns_scope")
21        self.line_break_nested_ns_scope = line_number(
22            "ns2.cpp", "// BP_nested_ns_scope"
23        )
24        self.line_break_nested_ns_scope_after_using = line_number(
25            "ns2.cpp", "// BP_nested_ns_scope_after_using"
26        )
27        self.line_break_before_using_directive = line_number(
28            "ns3.cpp", "// BP_before_using_directive"
29        )
30        self.line_break_after_using_directive = line_number(
31            "ns3.cpp", "// BP_after_using_directive"
32        )
33
34    def runToBkpt(self, command):
35        self.runCmd(command, RUN_SUCCEEDED)
36        # The stop reason of the thread should be breakpoint.
37        self.expect(
38            "thread list",
39            STOPPED_DUE_TO_BREAKPOINT,
40            substrs=["stopped", "stop reason = breakpoint"],
41        )
42
43    @skipIfWindows  # This is flakey on Windows: llvm.org/pr38373
44    @unittest.expectedFailure  # CU-local objects incorrectly scoped
45    def test_scope_lookup_with_run_command_globals(self):
46        """Test scope lookup of functions in lldb."""
47        self.build()
48
49        lldbutil.run_to_source_breakpoint(
50            self, self.line_break_global_scope, lldb.SBFileSpec("ns.cpp")
51        )
52
53        lldbutil.run_break_set_by_file_and_line(
54            self,
55            "ns3.cpp",
56            self.line_break_before_using_directive,
57            num_expected_locations=1,
58            loc_exact=False,
59        )
60
61        lldbutil.run_break_set_by_file_and_line(
62            self,
63            "ns3.cpp",
64            self.line_break_after_using_directive,
65            num_expected_locations=1,
66            loc_exact=False,
67        )
68
69        # Run to BP_global_scope at file scope
70        self.runToBkpt("run")
71
72        # FIXME: LLDB does not correctly scope CU-local objects.
73        # LLDB currently lumps functions from all files into
74        # a single AST and depending on the order with which
75        # functions are considered, LLDB can incorrectly call
76        # the static local ns.cpp::func() instead of the expected
77        # ::func()
78
79        # Evaluate func() - should call ::func()
80        self.expect_expr("func()", expect_type="int", expect_value="1")
81
82        # Evaluate ::func() - should call A::func()
83        self.expect_expr("::func()", result_type="int", result_value="1")
84
85        # Continue to BP_before_using_directive at file scope
86        self.runToBkpt("continue")
87
88        # Evaluate func() - should call ::func()
89        self.expect_expr("func()", result_type="int", result_value="1")
90
91        # Evaluate ::func() - should call ::func()
92        self.expect_expr("::func()", result_type="int", result_value="1")
93
94        # Continue to BP_after_using_directive at file scope
95        self.runToBkpt("continue")
96
97        # Evaluate ::func() - should call ::func()
98        self.expect_expr("::func()", result_type="int", result_value="1")
99
100    @skipIfWindows  # This is flakey on Windows: llvm.org/pr38373
101    def test_scope_lookup_with_run_command(self):
102        """Test scope lookup of functions in lldb."""
103        self.build()
104        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
105
106        lldbutil.run_break_set_by_file_and_line(
107            self,
108            "ns.cpp",
109            self.line_break_global_scope,
110            num_expected_locations=1,
111            loc_exact=False,
112        )
113        lldbutil.run_break_set_by_file_and_line(
114            self,
115            "ns2.cpp",
116            self.line_break_ns_scope,
117            num_expected_locations=1,
118            loc_exact=False,
119        )
120        lldbutil.run_break_set_by_file_and_line(
121            self,
122            "ns2.cpp",
123            self.line_break_nested_ns_scope,
124            num_expected_locations=1,
125            loc_exact=False,
126        )
127        lldbutil.run_break_set_by_file_and_line(
128            self,
129            "ns2.cpp",
130            self.line_break_nested_ns_scope_after_using,
131            num_expected_locations=1,
132            loc_exact=False,
133        )
134        lldbutil.run_break_set_by_file_and_line(
135            self,
136            "ns2.cpp",
137            self.line_break_file_scope,
138            num_expected_locations=1,
139            loc_exact=False,
140        )
141        lldbutil.run_break_set_by_file_and_line(
142            self,
143            "ns3.cpp",
144            self.line_break_before_using_directive,
145            num_expected_locations=1,
146            loc_exact=False,
147        )
148        lldbutil.run_break_set_by_file_and_line(
149            self,
150            "ns3.cpp",
151            self.line_break_after_using_directive,
152            num_expected_locations=1,
153            loc_exact=False,
154        )
155
156        # Run to BP_global_scope at global scope
157        self.runToBkpt("run")
158
159        # Evaluate A::B::func() - should call A::B::func()
160        self.expect_expr("A::B::func()", result_type="int", result_value="4")
161        # Evaluate func(10) - should call ::func(int)
162        self.expect_expr("func(10)", result_type="int", result_value="11")
163        # Evaluate A::foo() - should call A::foo()
164        self.expect_expr("A::foo()", result_type="int", result_value="42")
165
166        # Continue to BP_file_scope at file scope
167        self.runToBkpt("continue")
168        # FIXME: In DWARF 5 with dsyms, the ordering of functions is slightly
169        # different, which also hits the same issues mentioned previously.
170        if (
171            int(lldbplatformutil.getDwarfVersion()) <= 4
172            or self.getDebugInfo() == "dwarf"
173        ):
174            self.expect_expr("func()", result_type="int", result_value="2")
175
176        # Continue to BP_ns_scope at ns scope
177        self.runToBkpt("continue")
178        # Evaluate func(10) - should call A::func(int)
179        self.expect_expr("func(10)", result_type="int", result_value="13")
180        # Evaluate B::func() - should call B::func()
181        self.expect_expr("B::func()", result_type="int", result_value="4")
182        # Evaluate func() - should call A::func()
183        self.expect_expr("func()", result_type="int", result_value="3")
184
185        # Continue to BP_nested_ns_scope at nested ns scope
186        self.runToBkpt("continue")
187        # Evaluate func() - should call A::B::func()
188        self.expect_expr("func()", result_type="int", result_value="4")
189        # Evaluate A::func() - should call A::func()
190        self.expect_expr("A::func()", result_type="int", result_value="3")
191
192        # Evaluate func(10) - should call A::func(10)
193        # NOTE: Under the rules of C++, this test would normally get an error
194        # because A::B::func() hides A::func(), but lldb intentionally
195        # disobeys these rules so that the intended overload can be found
196        # by only removing duplicates if they have the same type.
197        self.expect_expr("func(10)", result_type="int", result_value="13")
198
199        # Continue to BP_nested_ns_scope_after_using at nested ns scope after
200        # using declaration
201        self.runToBkpt("continue")
202        # Evaluate A::func(10) - should call A::func(int)
203        self.expect_expr("A::func(10)", result_type="int", result_value="13")
204
205        # Continue to BP_before_using_directive at global scope before using
206        # declaration
207        self.runToBkpt("continue")
208        # Evaluate B::func() - should call B::func()
209        self.expect_expr("B::func()", result_type="int", result_value="4")
210
211        # Continue to BP_after_using_directive at global scope after using
212        # declaration
213        self.runToBkpt("continue")
214        # Evaluate B::func() - should call B::func()
215        self.expect_expr("B::func()", result_type="int", result_value="4")
216
217    @unittest.expectedFailure  # lldb scope lookup of functions bugs
218    def test_function_scope_lookup_with_run_command(self):
219        """Test scope lookup of functions in lldb."""
220        self.build()
221        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
222
223        lldbutil.run_break_set_by_file_and_line(
224            self,
225            "ns.cpp",
226            self.line_break_global_scope,
227            num_expected_locations=1,
228            loc_exact=False,
229        )
230        lldbutil.run_break_set_by_file_and_line(
231            self,
232            "ns2.cpp",
233            self.line_break_ns_scope,
234            num_expected_locations=1,
235            loc_exact=False,
236        )
237
238        # Run to BP_global_scope at global scope
239        self.runToBkpt("run")
240        # Evaluate foo() - should call ::foo()
241        # FIXME: lldb finds Y::foo because lookup for variables is done
242        # before functions.
243        self.expect_expr("foo()", result_type="int", result_value="42")
244        # Evaluate ::foo() - should call ::foo()
245        # FIXME: lldb finds Y::foo because lookup for variables is done
246        # before functions and :: is ignored.
247        self.expect_expr("::foo()", result_type="int", result_value="42")
248
249        # Continue to BP_ns_scope at ns scope
250        self.runToBkpt("continue")
251        # Evaluate foo() - should call A::foo()
252        # FIXME: lldb finds Y::foo because lookup for variables is done
253        # before functions.
254        self.expect_expr("foo()", result_type="int", result_value="42")
255
256    # NOTE: this test may fail on older systems that don't emit import
257    # entries in DWARF - may need to add checks for compiler versions here.
258    @skipIf(compiler="gcc", oslist=["linux"], debug_info=["dwo"])  # Skip to avoid crash
259    def test_scope_after_using_directive_lookup_with_run_command(self):
260        """Test scope lookup after using directive in lldb."""
261        self.build()
262        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
263
264        lldbutil.run_break_set_by_file_and_line(
265            self,
266            "ns3.cpp",
267            self.line_break_after_using_directive,
268            num_expected_locations=1,
269            loc_exact=False,
270        )
271
272        # Run to BP_after_using_directive at global scope after using
273        # declaration
274        self.runToBkpt("run")
275        # Evaluate func2() - should call A::func2()
276        self.expect_expr("func2()", result_type="int", result_value="3")
277
278    @unittest.expectedFailure  # lldb scope lookup after using declaration bugs
279    # NOTE: this test may fail on older systems that don't emit import
280    # emtries in DWARF - may need to add checks for compiler versions here.
281    def test_scope_after_using_declaration_lookup_with_run_command(self):
282        """Test scope lookup after using declaration in lldb."""
283        self.build()
284        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
285
286        lldbutil.run_break_set_by_file_and_line(
287            self,
288            "ns2.cpp",
289            self.line_break_nested_ns_scope_after_using,
290            num_expected_locations=1,
291            loc_exact=False,
292        )
293
294        # Run to BP_nested_ns_scope_after_using at nested ns scope after using
295        # declaration
296        self.runToBkpt("run")
297        # Evaluate func() - should call A::func()
298        self.expect_expr("func()", result_type="int", result_value="3")
299
300    @unittest.expectedFailure  # lldb scope lookup ambiguity after using bugs
301    def test_scope_ambiguity_after_using_lookup_with_run_command(self):
302        """Test scope lookup ambiguity after using in lldb."""
303        self.build()
304        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
305
306        lldbutil.run_break_set_by_file_and_line(
307            self,
308            "ns3.cpp",
309            self.line_break_after_using_directive,
310            num_expected_locations=1,
311            loc_exact=False,
312        )
313
314        # Run to BP_after_using_directive at global scope after using
315        # declaration
316        self.runToBkpt("run")
317        # Evaluate func() - should get error: ambiguous
318        # FIXME: This test fails because lldb removes duplicates if they have
319        # the same type.
320        self.expect("expr -- func()", startstr="error")
321
322    def test_scope_lookup_shadowed_by_using_with_run_command(self):
323        """Test scope lookup shadowed by using in lldb."""
324        self.build()
325        self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
326
327        lldbutil.run_break_set_by_file_and_line(
328            self,
329            "ns2.cpp",
330            self.line_break_nested_ns_scope,
331            num_expected_locations=1,
332            loc_exact=False,
333        )
334
335        # Run to BP_nested_ns_scope at nested ns scope
336        self.runToBkpt("run")
337        # Evaluate func(10) - should call A::func(10)
338        # NOTE: Under the rules of C++, this test would normally get an error
339        # because A::B::func() shadows A::func(), but lldb intentionally
340        # disobeys these rules so that the intended overload can be found
341        # by only removing duplicates if they have the same type.
342        self.expect_expr("func(10)", result_type="int", result_value="13")
343