199451b44SJordan Rupprecht"""Test that anonymous structs/unions are transparent to member access""" 299451b44SJordan Rupprecht 399451b44SJordan Rupprecht 499451b44SJordan Rupprechtimport lldb 599451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 699451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 799451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 899451b44SJordan Rupprecht 999451b44SJordan Rupprecht 1099451b44SJordan Rupprechtclass AnonymousTestCase(TestBase): 1199451b44SJordan Rupprecht @skipIf( 1299451b44SJordan Rupprecht compiler="icc", 13*2238dcc3SJonas Devlieghere bugnumber="llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC", 14*2238dcc3SJonas Devlieghere ) 1599451b44SJordan Rupprecht def test_expr_nest(self): 1699451b44SJordan Rupprecht self.build() 1799451b44SJordan Rupprecht self.common_setup(self.line0) 1899451b44SJordan Rupprecht 1999451b44SJordan Rupprecht # These should display correctly. 20*2238dcc3SJonas Devlieghere self.expect( 21*2238dcc3SJonas Devlieghere "expression n->foo.d", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 4"] 22*2238dcc3SJonas Devlieghere ) 2399451b44SJordan Rupprecht 24*2238dcc3SJonas Devlieghere self.expect("expression n->b", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 2"]) 2599451b44SJordan Rupprecht 2699451b44SJordan Rupprecht def test_expr_child(self): 2799451b44SJordan Rupprecht self.build() 2899451b44SJordan Rupprecht self.common_setup(self.line1) 2999451b44SJordan Rupprecht 3099451b44SJordan Rupprecht # These should display correctly. 31*2238dcc3SJonas Devlieghere self.expect( 32*2238dcc3SJonas Devlieghere "expression c->foo.d", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 4"] 33*2238dcc3SJonas Devlieghere ) 3499451b44SJordan Rupprecht 3599451b44SJordan Rupprecht self.expect( 36*2238dcc3SJonas Devlieghere "expression c->grandchild.b", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 2"] 37*2238dcc3SJonas Devlieghere ) 3899451b44SJordan Rupprecht 3999451b44SJordan Rupprecht @skipIf( 4099451b44SJordan Rupprecht compiler="icc", 41*2238dcc3SJonas Devlieghere bugnumber="llvm.org/pr15036: This particular regression was introduced by r181498", 42*2238dcc3SJonas Devlieghere ) 4399451b44SJordan Rupprecht def test_expr_grandchild(self): 4499451b44SJordan Rupprecht self.build() 4599451b44SJordan Rupprecht self.common_setup(self.line2) 4699451b44SJordan Rupprecht 4799451b44SJordan Rupprecht # These should display correctly. 48*2238dcc3SJonas Devlieghere self.expect( 49*2238dcc3SJonas Devlieghere "expression g.child.foo.d", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 4"] 50*2238dcc3SJonas Devlieghere ) 5199451b44SJordan Rupprecht 52*2238dcc3SJonas Devlieghere self.expect( 53*2238dcc3SJonas Devlieghere "expression g.child.b", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 2"] 54*2238dcc3SJonas Devlieghere ) 5599451b44SJordan Rupprecht 5699451b44SJordan Rupprecht def test_expr_parent(self): 5799451b44SJordan Rupprecht self.build() 5899451b44SJordan Rupprecht if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion(): 5999451b44SJordan Rupprecht self.skipTest( 60*2238dcc3SJonas Devlieghere "llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef" 61*2238dcc3SJonas Devlieghere ) 6299451b44SJordan Rupprecht self.common_setup(self.line2) 6399451b44SJordan Rupprecht 6499451b44SJordan Rupprecht # These should display correctly. 65*2238dcc3SJonas Devlieghere self.expect( 66*2238dcc3SJonas Devlieghere "expression pz", 67*2238dcc3SJonas Devlieghere VARIABLES_DISPLAYED_CORRECTLY, 68*2238dcc3SJonas Devlieghere substrs=["(type_z *) $", " = NULL"], 69*2238dcc3SJonas Devlieghere ) 7099451b44SJordan Rupprecht 71*2238dcc3SJonas Devlieghere self.expect( 72*2238dcc3SJonas Devlieghere "expression z.y", 73*2238dcc3SJonas Devlieghere VARIABLES_DISPLAYED_CORRECTLY, 74*2238dcc3SJonas Devlieghere substrs=["(type_y) $", "dummy = 2"], 75*2238dcc3SJonas Devlieghere ) 7699451b44SJordan Rupprecht 7799451b44SJordan Rupprecht def test_expr_null(self): 7899451b44SJordan Rupprecht self.build() 7999451b44SJordan Rupprecht self.common_setup(self.line2) 8099451b44SJordan Rupprecht 8199451b44SJordan Rupprecht # This should fail because pz is 0, but it succeeds on OS/X. 8299451b44SJordan Rupprecht # This fails on Linux with an upstream error "Couldn't dematerialize struct", as does "p *n" with "int *n = 0". 8399451b44SJordan Rupprecht # Note that this can also trigger llvm.org/pr15036 when run 8499451b44SJordan Rupprecht # interactively at the lldb command prompt. 8599451b44SJordan Rupprecht self.expect("expression *(type_z *)pz", error=True) 8699451b44SJordan Rupprecht 8799451b44SJordan Rupprecht def test_child_by_name(self): 8899451b44SJordan Rupprecht self.build() 8999451b44SJordan Rupprecht 9099451b44SJordan Rupprecht # Set debugger into synchronous mode 9199451b44SJordan Rupprecht self.dbg.SetAsync(False) 9299451b44SJordan Rupprecht 9399451b44SJordan Rupprecht # Create a target 9499451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 9599451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 9699451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 9799451b44SJordan Rupprecht 9899451b44SJordan Rupprecht break_in_main = target.BreakpointCreateBySourceRegex( 99*2238dcc3SJonas Devlieghere "// Set breakpoint 2 here.", lldb.SBFileSpec(self.source) 100*2238dcc3SJonas Devlieghere ) 10199451b44SJordan Rupprecht self.assertTrue(break_in_main, VALID_BREAKPOINT) 10299451b44SJordan Rupprecht 103*2238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 10499451b44SJordan Rupprecht self.assertTrue(process, PROCESS_IS_VALID) 10599451b44SJordan Rupprecht 106*2238dcc3SJonas Devlieghere threads = lldbutil.get_threads_stopped_at_breakpoint(process, break_in_main) 10799451b44SJordan Rupprecht if len(threads) != 1: 10899451b44SJordan Rupprecht self.fail("Failed to stop at breakpoint in main.") 10999451b44SJordan Rupprecht 11099451b44SJordan Rupprecht thread = threads[0] 11199451b44SJordan Rupprecht frame = thread.frames[0] 11299451b44SJordan Rupprecht 11399451b44SJordan Rupprecht if not frame.IsValid(): 11499451b44SJordan Rupprecht self.fail("Failed to get frame 0.") 11599451b44SJordan Rupprecht 11699451b44SJordan Rupprecht var_n = frame.FindVariable("n") 11799451b44SJordan Rupprecht if not var_n.IsValid(): 11899451b44SJordan Rupprecht self.fail("Failed to get the variable 'n'") 11999451b44SJordan Rupprecht 12099451b44SJordan Rupprecht elem_a = var_n.GetChildMemberWithName("a") 12199451b44SJordan Rupprecht if not elem_a.IsValid(): 12299451b44SJordan Rupprecht self.fail("Failed to get the element a in n") 12399451b44SJordan Rupprecht 12499451b44SJordan Rupprecht error = lldb.SBError() 12599451b44SJordan Rupprecht value = elem_a.GetValueAsSigned(error, 1000) 12699451b44SJordan Rupprecht if not error.Success() or value != 0: 12799451b44SJordan Rupprecht self.fail("failed to get the correct value for element a in n") 12899451b44SJordan Rupprecht 12999451b44SJordan Rupprecht def test_nest_flat(self): 13099451b44SJordan Rupprecht self.build() 13199451b44SJordan Rupprecht self.common_setup(self.line2) 13299451b44SJordan Rupprecht 13399451b44SJordan Rupprecht # These should display correctly. 134*2238dcc3SJonas Devlieghere self.expect( 135*2238dcc3SJonas Devlieghere "frame variable n --flat", 136*2238dcc3SJonas Devlieghere substrs=["n.a = 0", "n.b = 2", "n.foo.c = 0", "n.foo.d = 4"], 137*2238dcc3SJonas Devlieghere ) 13899451b44SJordan Rupprecht 13999451b44SJordan Rupprecht def setUp(self): 14099451b44SJordan Rupprecht # Call super's setUp(). 14199451b44SJordan Rupprecht TestBase.setUp(self) 14299451b44SJordan Rupprecht # Find the line numbers to break in main.c. 143*2238dcc3SJonas Devlieghere self.source = "main.c" 144*2238dcc3SJonas Devlieghere self.line0 = line_number(self.source, "// Set breakpoint 0 here.") 145*2238dcc3SJonas Devlieghere self.line1 = line_number(self.source, "// Set breakpoint 1 here.") 146*2238dcc3SJonas Devlieghere self.line2 = line_number(self.source, "// Set breakpoint 2 here.") 14799451b44SJordan Rupprecht 14899451b44SJordan Rupprecht def common_setup(self, line): 14999451b44SJordan Rupprecht # Set debugger into synchronous mode 15099451b44SJordan Rupprecht self.dbg.SetAsync(False) 15199451b44SJordan Rupprecht 15299451b44SJordan Rupprecht # Create a target 15399451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 15499451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 15599451b44SJordan Rupprecht self.assertTrue(target, VALID_TARGET) 15699451b44SJordan Rupprecht 15799451b44SJordan Rupprecht # Set breakpoints inside and outside methods that take pointers to the 15899451b44SJordan Rupprecht # containing struct. 15999451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 160*2238dcc3SJonas Devlieghere self, self.source, line, num_expected_locations=1, loc_exact=True 161*2238dcc3SJonas Devlieghere ) 16299451b44SJordan Rupprecht 16399451b44SJordan Rupprecht # Now launch the process, and do not stop at entry point. 164*2238dcc3SJonas Devlieghere process = target.LaunchSimple(None, None, self.get_process_working_directory()) 16599451b44SJordan Rupprecht self.assertTrue(process, PROCESS_IS_VALID) 16699451b44SJordan Rupprecht 16799451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint. 168*2238dcc3SJonas Devlieghere self.expect( 169*2238dcc3SJonas Devlieghere "thread list", 170*2238dcc3SJonas Devlieghere STOPPED_DUE_TO_BREAKPOINT, 171*2238dcc3SJonas Devlieghere substrs=["stopped", "stop reason = breakpoint"], 172*2238dcc3SJonas Devlieghere ) 17399451b44SJordan Rupprecht 17499451b44SJordan Rupprecht # The breakpoint should have a hit count of 1. 1759f0b5f9aSSYNOPSYS\georgiev lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1) 176