[clang] Informative error for lifetimebound in decl-spec (#118567)
[llvm-project.git] / lldb / test / API / commands / dwim-print / TestDWIMPrint.py
blob492d49f008a9e4993d28b8006880cccef4cf617a
1 """
2 Test dwim-print with variables, variable paths, and expressions.
3 """
5 import re
6 import lldb
7 from lldbsuite.test.lldbtest import *
8 from lldbsuite.test.decorators import *
9 import lldbsuite.test.lldbutil as lldbutil
12 class TestCase(TestBase):
13 def _run_cmd(self, cmd: str) -> str:
14 """Run the given lldb command and return its output."""
15 result = lldb.SBCommandReturnObject()
16 self.ci.HandleCommand(cmd, result)
17 return result.GetOutput().rstrip()
19 VAR_IDENT = re.compile(r"(?:\$\d+|[\w.]+) = ")
21 def _strip_result_var(self, string: str) -> str:
22 """
23 Strip (persistent) result variables (ex '$0 = ', or 'someVar = ', etc).
25 This allows for using the output of `expression`/`frame variable`, to
26 compare it to `dwim-print` output, which disables result variables.
27 """
28 return self.VAR_IDENT.subn("", string, 1)[0]
30 def _expect_cmd(
31 self,
32 dwim_cmd: str,
33 actual_cmd: str,
34 ) -> None:
35 """Run dwim-print and verify the output against the expected command."""
36 # Resolve the dwim-print command to either `expression` or `frame variable`.
37 substitute_cmd = dwim_cmd.replace("dwim-print", actual_cmd, 1)
38 interp = self.dbg.GetCommandInterpreter()
39 result = lldb.SBCommandReturnObject()
40 interp.ResolveCommand(substitute_cmd, result)
41 self.assertTrue(result.Succeeded(), result.GetError())
43 resolved_cmd = result.GetOutput()
44 if actual_cmd == "frame variable":
45 resolved_cmd = resolved_cmd.replace(" -- ", " ", 1)
47 resolved_cmd_output = self._run_cmd(resolved_cmd)
48 dwim_cmd_output = self._strip_result_var(resolved_cmd_output)
50 # Verify dwim-print chose the expected command.
51 self.runCmd("settings set dwim-print-verbosity full")
53 self.expect(
54 dwim_cmd,
55 substrs=[
56 f"note: ran `{resolved_cmd}`",
57 dwim_cmd_output,
61 def test_variables(self):
62 """Test dwim-print with variables."""
63 self.build()
64 lldbutil.run_to_name_breakpoint(self, "main")
65 vars = ("argc", "argv")
66 for var in vars:
67 self._expect_cmd(f"dwim-print {var}", "frame variable")
69 def test_variable_paths(self):
70 """Test dwim-print with variable path expressions."""
71 self.build()
72 lldbutil.run_to_name_breakpoint(self, "main")
73 exprs = ("&argc", "*argv", "argv[0]")
74 for expr in exprs:
75 self._expect_cmd(f"dwim-print {expr}", "expression")
77 def test_expressions(self):
78 """Test dwim-print with expressions."""
79 self.build()
80 lldbutil.run_to_name_breakpoint(self, "main")
81 exprs = ("argc + 1", "(void)argc", "(int)abs(argc)")
82 for expr in exprs:
83 self._expect_cmd(f"dwim-print {expr}", "expression")
85 def test_dummy_target_expressions(self):
86 """Test dwim-print's ability to evaluate expressions without a target."""
87 self._expect_cmd("dwim-print 1 + 2", "expression")
89 def test_gdb_format(self):
90 self.build()
91 lldbutil.run_to_name_breakpoint(self, "main")
92 self._expect_cmd(f"dwim-print/x argc", "frame variable")
93 self._expect_cmd(f"dwim-print/x argc + 1", "expression")
95 def test_format_flags(self):
96 self.build()
97 lldbutil.run_to_name_breakpoint(self, "main")
98 self._expect_cmd(f"dwim-print -fx -- argc", "frame variable")
99 self._expect_cmd(f"dwim-print -fx -- argc + 1", "expression")
101 def test_display_flags(self):
102 self.build()
103 lldbutil.run_to_name_breakpoint(self, "main")
104 self._expect_cmd(f"dwim-print -T -- argc", "frame variable")
105 self._expect_cmd(f"dwim-print -T -- argc + 1", "expression")
107 def test_expression_language(self):
108 """Test that the language flag doesn't affect the choice of command."""
109 self.build()
110 lldbutil.run_to_name_breakpoint(self, "main")
111 self._expect_cmd(f"dwim-print -l c++ -- argc", "frame variable")
112 self._expect_cmd(f"dwim-print -l c++ -- argc + 1", "expression")
114 def test_empty_expression(self):
115 self.build()
116 lldbutil.run_to_name_breakpoint(self, "main")
117 error_msg = "error: 'dwim-print' takes a variable or expression"
118 self.expect(f"dwim-print", error=True, startstr=error_msg)
119 self.expect(f"dwim-print -- ", error=True, startstr=error_msg)
121 def test_nested_values(self):
122 """Test dwim-print with nested values (structs, etc)."""
123 self.build()
124 lldbutil.run_to_source_breakpoint(
125 self, "break here", lldb.SBFileSpec("main.cpp")
127 self.runCmd("settings set auto-one-line-summaries false")
128 self._expect_cmd(f"dwim-print s", "frame variable")
129 self._expect_cmd(f"dwim-print (struct Structure)s", "expression")
131 def test_summary_strings(self):
132 """Test dwim-print with type summaries."""
133 self.build()
134 lldbutil.run_to_source_breakpoint(
135 self, "break here", lldb.SBFileSpec("main.cpp")
137 self.runCmd("settings set auto-one-line-summaries false")
138 self.runCmd("type summary add -e -s 'stub summary' Structure")
139 self._expect_cmd(f"dwim-print s", "frame variable")
140 self._expect_cmd(f"dwim-print (struct Structure)s", "expression")
141 self.runCmd("type summary delete Structure")
143 def test_void_result(self):
144 """Test dwim-print does not surface an error message for void expressions."""
145 self.build()
146 lldbutil.run_to_source_breakpoint(
147 self, "break here", lldb.SBFileSpec("main.cpp")
149 self.expect("dwim-print (void)15", matching=False, patterns=["(?i)error"])
151 def test_preserves_persistent_variables(self):
152 """Test dwim-print does not delete persistent variables."""
153 self.build()
154 lldbutil.run_to_source_breakpoint(
155 self, "break here", lldb.SBFileSpec("main.cpp")
157 self.expect("dwim-print int $i = 15")
158 # Run the same expression twice and verify success. This ensures the
159 # first command does not delete the persistent variable.
160 for _ in range(2):
161 self.expect("dwim-print $i", startstr="(int) 15")
163 def test_missing_type(self):
164 """The expected output of po opaque is its address (no error)"""
165 self.build()
166 lldbutil.run_to_source_breakpoint(
167 self, "break here", lldb.SBFileSpec("main.cpp")
169 self.expect("dwim-print -O -- opaque", substrs=["0x"])
171 def test_variable_expression_path(self):
172 """Test dwim-print supports certain variable expression paths."""
173 self.build()
174 lldbutil.run_to_source_breakpoint(
175 self, "break here", lldb.SBFileSpec("main.cpp")
177 self.runCmd("settings set auto-one-line-summaries false")
178 self._expect_cmd("dwim-print w.s", "frame variable")
179 self._expect_cmd("dwim-print wp->s", "expression")
181 def test_direct_child_access(self):
182 """Test dwim-print supports accessing members/ivars without qualification."""
183 self.build()
184 lldbutil.run_to_source_breakpoint(
185 self, "break inside", lldb.SBFileSpec("main.cpp")
187 self._expect_cmd("dwim-print number", "frame variable")