1 """Test that anonymous structs/unions are transparent to member access"""
5 from lldbsuite
.test
.decorators
import *
6 from lldbsuite
.test
.lldbtest
import *
7 from lldbsuite
.test
import lldbutil
10 class AnonymousTestCase(TestBase
):
13 bugnumber
="llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC",
15 def test_expr_nest(self
):
17 self
.common_setup(self
.line0
)
19 # These should display correctly.
21 "expression n->foo.d", VARIABLES_DISPLAYED_CORRECTLY
, substrs
=["= 4"]
24 self
.expect("expression n->b", VARIABLES_DISPLAYED_CORRECTLY
, substrs
=["= 2"])
26 def test_expr_child(self
):
28 self
.common_setup(self
.line1
)
30 # These should display correctly.
32 "expression c->foo.d", VARIABLES_DISPLAYED_CORRECTLY
, substrs
=["= 4"]
36 "expression c->grandchild.b", VARIABLES_DISPLAYED_CORRECTLY
, substrs
=["= 2"]
41 bugnumber
="llvm.org/pr15036: This particular regression was introduced by r181498",
43 def test_expr_grandchild(self
):
45 self
.common_setup(self
.line2
)
47 # These should display correctly.
49 "expression g.child.foo.d", VARIABLES_DISPLAYED_CORRECTLY
, substrs
=["= 4"]
53 "expression g.child.b", VARIABLES_DISPLAYED_CORRECTLY
, substrs
=["= 2"]
56 def test_expr_parent(self
):
58 if "clang" in self
.getCompiler() and "3.4" in self
.getCompilerVersion():
60 "llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef"
62 self
.common_setup(self
.line2
)
64 # These should display correctly.
67 VARIABLES_DISPLAYED_CORRECTLY
,
68 substrs
=["(type_z *) $", " = NULL"],
73 VARIABLES_DISPLAYED_CORRECTLY
,
74 substrs
=["(type_y) $", "dummy = 2"],
77 def test_expr_null(self
):
79 self
.common_setup(self
.line2
)
81 # This should fail because pz is 0, but it succeeds on OS/X.
82 # This fails on Linux with an upstream error "Couldn't dematerialize struct", as does "p *n" with "int *n = 0".
83 # Note that this can also trigger llvm.org/pr15036 when run
84 # interactively at the lldb command prompt.
85 self
.expect("expression *(type_z *)pz", error
=True)
87 def test_child_by_name(self
):
90 # Set debugger into synchronous mode
91 self
.dbg
.SetAsync(False)
94 exe
= self
.getBuildArtifact("a.out")
95 target
= self
.dbg
.CreateTarget(exe
)
96 self
.assertTrue(target
, VALID_TARGET
)
98 break_in_main
= target
.BreakpointCreateBySourceRegex(
99 "// Set breakpoint 2 here.", lldb
.SBFileSpec(self
.source
)
101 self
.assertTrue(break_in_main
, VALID_BREAKPOINT
)
103 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
104 self
.assertTrue(process
, PROCESS_IS_VALID
)
106 threads
= lldbutil
.get_threads_stopped_at_breakpoint(process
, break_in_main
)
107 if len(threads
) != 1:
108 self
.fail("Failed to stop at breakpoint in main.")
111 frame
= thread
.frames
[0]
113 if not frame
.IsValid():
114 self
.fail("Failed to get frame 0.")
116 var_n
= frame
.FindVariable("n")
117 if not var_n
.IsValid():
118 self
.fail("Failed to get the variable 'n'")
120 elem_a
= var_n
.GetChildMemberWithName("a")
121 if not elem_a
.IsValid():
122 self
.fail("Failed to get the element a in n")
124 error
= lldb
.SBError()
125 value
= elem_a
.GetValueAsSigned(error
, 1000)
126 if not error
.Success() or value
!= 0:
127 self
.fail("failed to get the correct value for element a in n")
129 def test_nest_flat(self
):
131 self
.common_setup(self
.line2
)
133 # These should display correctly.
135 "frame variable n --flat",
136 substrs
=["n.a = 0", "n.b = 2", "n.foo.c = 0", "n.foo.d = 4"],
140 # Call super's setUp().
142 # Find the line numbers to break in main.c.
143 self
.source
= "main.c"
144 self
.line0
= line_number(self
.source
, "// Set breakpoint 0 here.")
145 self
.line1
= line_number(self
.source
, "// Set breakpoint 1 here.")
146 self
.line2
= line_number(self
.source
, "// Set breakpoint 2 here.")
148 def common_setup(self
, line
):
149 # Set debugger into synchronous mode
150 self
.dbg
.SetAsync(False)
153 exe
= self
.getBuildArtifact("a.out")
154 target
= self
.dbg
.CreateTarget(exe
)
155 self
.assertTrue(target
, VALID_TARGET
)
157 # Set breakpoints inside and outside methods that take pointers to the
159 lldbutil
.run_break_set_by_file_and_line(
160 self
, self
.source
, line
, num_expected_locations
=1, loc_exact
=True
163 # Now launch the process, and do not stop at entry point.
164 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
165 self
.assertTrue(process
, PROCESS_IS_VALID
)
167 # The stop reason of the thread should be breakpoint.
170 STOPPED_DUE_TO_BREAKPOINT
,
171 substrs
=["stopped", "stop reason = breakpoint"],
174 # The breakpoint should have a hit count of 1.
175 lldbutil
.check_breakpoint(self
, bpno
=1, expected_hit_count
=1)