343 lines · python
1"""2Test the printing of anonymous and named namespace variables.3"""4 5 6import unittest7import lldb8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10from lldbsuite.test import lldbutil11from lldbsuite.test import lldbplatformutil12 13class NamespaceLookupTestCase(TestBase):14 def setUp(self):15 # Call super's setUp().16 TestBase.setUp(self)17 # Break inside different scopes and evaluate value18 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/pr3837344 @unittest.expectedFailure # CU-local objects incorrectly scoped45 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 scope70 self.runToBkpt("run")71 72 # FIXME: LLDB does not correctly scope CU-local objects.73 # LLDB currently lumps functions from all files into74 # a single AST and depending on the order with which75 # functions are considered, LLDB can incorrectly call76 # the static local ns.cpp::func() instead of the expected77 # ::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 scope86 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 scope95 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/pr38373101 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 scope157 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 scope167 self.runToBkpt("continue")168 # FIXME: In DWARF 5 with dsyms, the ordering of functions is slightly169 # different, which also hits the same issues mentioned previously.170 if (171 int(lldbplatformutil.getDwarfVersion()) <= 4172 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 scope177 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 scope186 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 error194 # because A::B::func() hides A::func(), but lldb intentionally195 # disobeys these rules so that the intended overload can be found196 # 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 after200 # using declaration201 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 using206 # declaration207 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 using212 # declaration213 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 bugs218 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 scope239 self.runToBkpt("run")240 # Evaluate foo() - should call ::foo()241 # FIXME: lldb finds Y::foo because lookup for variables is done242 # 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 done246 # 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 scope250 self.runToBkpt("continue")251 # Evaluate foo() - should call A::foo()252 # FIXME: lldb finds Y::foo because lookup for variables is done253 # 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 import257 # entries in DWARF - may need to add checks for compiler versions here.258 @skipIf(compiler="gcc", oslist=["linux"], debug_info=["dwo"]) # Skip to avoid crash259 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 using273 # declaration274 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 bugs279 # NOTE: this test may fail on older systems that don't emit import280 # 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 using295 # declaration296 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 bugs301 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 using315 # declaration316 self.runToBkpt("run")317 # Evaluate func() - should get error: ambiguous318 # FIXME: This test fails because lldb removes duplicates if they have319 # 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 scope336 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 error339 # because A::B::func() shadows A::func(), but lldb intentionally340 # disobeys these rules so that the intended overload can be found341 # by only removing duplicates if they have the same type.342 self.expect_expr("func(10)", result_type="int", result_value="13")343