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