[MLIR] print/parse resource handle key quoted and escaped (#119746)
[llvm-project.git] / lldb / test / API / commands / expression / diagnostics / TestExprDiagnostics.py
blobb476a807c6dc0e998784e3222aff54f206269c18
1 """
2 Test the diagnostics emitted by our embeded Clang instance that parses expressions.
3 """
5 import lldb
6 from lldbsuite.test.lldbtest import *
7 from lldbsuite.test import lldbutil
8 from lldbsuite.test.decorators import *
11 class ExprDiagnosticsTestCase(TestBase):
12 def setUp(self):
13 # Call super's setUp().
14 TestBase.setUp(self)
16 self.main_source = "main.cpp"
17 self.main_source_spec = lldb.SBFileSpec(self.main_source)
19 def test_source_and_caret_printing(self):
20 """Test that the source and caret positions LLDB prints are correct"""
21 self.build()
23 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
24 self, "// Break here", self.main_source_spec
26 frame = thread.GetFrameAtIndex(0)
28 # Test that source/caret are at the right position.
29 value = frame.EvaluateExpression("unknown_identifier")
30 self.assertFalse(value.GetError().Success())
31 # We should get a nice diagnostic with a caret pointing at the start of
32 # the identifier.
33 self.assertIn(
34 """
35 1 | unknown_identifier
36 | ^
37 """,
38 value.GetError().GetCString(),
40 self.assertIn("<user expression 0>:1:1", value.GetError().GetCString())
42 # Same as above but with the identifier in the middle.
43 value = frame.EvaluateExpression("1 + unknown_identifier")
44 self.assertFalse(value.GetError().Success())
45 self.assertIn(
46 """
47 1 | 1 + unknown_identifier
48 | ^
49 """,
50 value.GetError().GetCString(),
53 # Multiline expressions.
54 value = frame.EvaluateExpression("int a = 0;\nfoobar +=1;\na")
55 self.assertFalse(value.GetError().Success())
56 # We should still get the right line information and caret position.
57 self.assertIn(
58 """
59 2 | foobar +=1;
60 | ^
61 """,
62 value.GetError().GetCString(),
65 # It's the second line of the user expression.
66 self.assertIn("<user expression 2>:2:1", value.GetError().GetCString())
68 # Top-level expressions.
69 top_level_opts = lldb.SBExpressionOptions()
70 top_level_opts.SetTopLevel(True)
72 value = frame.EvaluateExpression("void foo(unknown_type x) {}", top_level_opts)
73 self.assertFalse(value.GetError().Success())
74 self.assertIn(
75 """
76 1 | void foo(unknown_type x) {}
77 | ^
78 """,
79 value.GetError().GetCString(),
82 # Top-level expressions might use a different wrapper code, but the file name should still
83 # be the same.
84 self.assertIn("<user expression 3>:1:10", value.GetError().GetCString())
86 # Multiline top-level expressions.
87 value = frame.EvaluateExpression("void x() {}\nvoid foo;", top_level_opts)
88 self.assertFalse(value.GetError().Success())
89 self.assertIn(
90 """
91 2 | void foo;
92 | ^
93 """,
94 value.GetError().GetCString(),
97 self.assertIn("<user expression 4>:2:6", value.GetError().GetCString())
99 # Test that we render Clang's 'notes' correctly.
100 value = frame.EvaluateExpression(
101 "struct SFoo{}; struct SFoo { int x; };", top_level_opts
103 self.assertFalse(value.GetError().Success())
104 self.assertIn(
105 "<user expression 5>:1:8: previous definition is here\n",
106 value.GetError().GetCString(),
108 self.assertIn(
110 1 | struct SFoo{}; struct SFoo { int x; };
112 """,
113 value.GetError().GetCString(),
116 # Declarations from the debug information currently have no debug information. It's not clear what
117 # we should do in this case, but we should at least not print anything that's wrong.
118 # In the future our declarations should have valid source locations.
119 value = frame.EvaluateExpression("struct FooBar { double x };", top_level_opts)
120 self.assertFalse(value.GetError().Success())
121 self.assertIn(
122 "error: <user expression 6>:1:8: redefinition of 'FooBar'\n",
123 value.GetError().GetCString(),
125 self.assertIn(
127 1 | struct FooBar { double x };
129 """,
130 value.GetError().GetCString(),
133 value = frame.EvaluateExpression("foo(1, 2)")
134 self.assertFalse(value.GetError().Success())
135 self.assertIn(
136 "error: <user expression 7>:1:1: no matching function for call to 'foo'\n",
137 value.GetError().GetCString(),
139 self.assertIn(
141 1 | foo(1, 2)
142 | ^~~
143 note: candidate function not viable: requires single argument 'x', but 2 arguments were provided
144 """,
145 value.GetError().GetCString(),
148 # Redefine something that we defined in a user-expression. We should use the previous expression file name
149 # for the original decl.
150 value = frame.EvaluateExpression("struct Redef { double x; };", top_level_opts)
151 value = frame.EvaluateExpression("struct Redef { float y; };", top_level_opts)
152 self.assertFalse(value.GetError().Success())
153 self.assertIn(
154 """error: <user expression 9>:1:8: redefinition of 'Redef'
155 1 | struct Redef { float y; };
157 <user expression 8>:1:8: previous definition is here
158 1 | struct Redef { double x; };
160 """,
161 value.GetError().GetCString(),
164 @add_test_categories(["objc"])
165 def test_source_locations_from_objc_modules(self):
166 self.build()
168 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
169 self, "// Break here", self.main_source_spec
171 frame = thread.GetFrameAtIndex(0)
173 # Import foundation so that the Obj-C module is loaded (which contains source locations
174 # that can be used by LLDB).
175 self.runCmd("expr --language objective-c++ -- @import Foundation")
176 value = frame.EvaluateExpression("NSLog(1);")
177 self.assertFalse(value.GetError().Success())
178 # LLDB should print the source line that defines NSLog. To not rely on any
179 # header paths/line numbers or the actual formatting of the Foundation headers, only look
180 # for a few tokens in the output.
181 # File path should come from Foundation framework.
182 self.assertIn("/Foundation.framework/", value.GetError().GetCString())
183 # The NSLog definition source line should be printed. Return value and
184 # the first argument are probably stable enough that this test can check for them.
185 self.assertIn("void NSLog(NSString *format", value.GetError().GetCString())
187 def test_error_type(self):
188 """Test the error reporting in the API"""
189 self.build()
191 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
192 self, "// Break here", self.main_source_spec
194 frame = thread.GetFrameAtIndex(0)
195 value = frame.EvaluateExpression('#error("I am error.")')
196 error = value.GetError()
197 self.assertEqual(error.GetType(), lldb.eErrorTypeExpression)
198 value = frame.FindVariable("f")
199 self.assertTrue(value.IsValid())
200 desc = value.GetObjectDescription()
201 self.assertEqual(desc, None)
203 def test_command_expr_sbdata(self):
204 """Test the structured diagnostics data"""
205 self.build()
207 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
208 self, "// Break here", self.main_source_spec
211 def check_error(diags):
212 # Version.
213 version = diags.GetValueForKey("version")
214 self.assertEqual(version.GetIntegerValue(), 1)
216 details = diags.GetValueForKey("details")
218 # Detail 1/2: undeclared 'a'
219 diag = details.GetItemAtIndex(0)
221 severity = diag.GetValueForKey("severity")
222 message = diag.GetValueForKey("message")
223 rendered = diag.GetValueForKey("rendered")
224 sloc = diag.GetValueForKey("source_location")
225 filename = sloc.GetValueForKey("file")
226 hidden = sloc.GetValueForKey("hidden")
227 in_user_input = sloc.GetValueForKey("in_user_input")
229 self.assertEqual(str(severity), "error")
230 self.assertIn("undeclared identifier 'a'", str(message))
231 # The rendered string should contain the source file.
232 self.assertIn("user expression", str(rendered))
233 self.assertIn("user expression", str(filename))
234 self.assertFalse(hidden.GetBooleanValue())
235 self.assertTrue(in_user_input.GetBooleanValue())
237 # Detail 1/2: undeclared 'b'
238 diag = details.GetItemAtIndex(1)
239 message = diag.GetValueForKey("message")
240 self.assertIn("undeclared identifier 'b'", str(message))
242 # Test diagnostics in CommandReturnObject
243 interp = self.dbg.GetCommandInterpreter()
244 cro = lldb.SBCommandReturnObject()
245 interp.HandleCommand("expression -- a+b", cro)
247 diags = cro.GetErrorData()
248 check_error(diags)
250 # Test diagnostics in SBError
251 frame = thread.GetSelectedFrame()
252 value = frame.EvaluateExpression("a+b")
253 error = value.GetError()
254 self.assertTrue(error.Fail())
255 self.assertEqual(error.GetType(), lldb.eErrorTypeExpression)
256 data = error.GetErrorData()
257 version = data.GetValueForKey("version")
258 self.assertEqual(version.GetIntegerValue(), 1)
259 err_ty = data.GetValueForKey("type")
260 self.assertEqual(err_ty.GetIntegerValue(), lldb.eErrorTypeExpression)
261 diags = data.GetValueForKey("errors").GetItemAtIndex(0)
262 check_error(diags)