Skip to content

Commit 697e5e6

Browse files
committed
[lldb] Inline expression evaluator error visualization
This patch is a reworking of Pete Lawrence's (@PortalPete) proposal for better expression evaluator error messages: #80938 Before: ``` $ lldb -o "expr a+b" (lldb) expr a+b error: <user expression 0>:1:1: use of undeclared identifier 'a' a+b ^ error: <user expression 0>:1:3: use of undeclared identifier 'b' a+b ^ ``` After: ``` (lldb) expr a+b ^ ^ │ ╰─ error: use of undeclared identifier 'b' ╰─ error: use of undeclared identifier 'a' ``` This eliminates the confusing `<user expression 0>:1:3` source location and avoids echoing the expression to the console again, which results in a cleaner presentation that makes it easier to grasp what's going on.
1 parent 9f014cf commit 697e5e6

File tree

71 files changed

+433
-270
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+433
-270
lines changed

lldb/include/lldb/Interpreter/CommandAlias.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class CommandAlias : public CommandObject {
5656

5757
void SetHelpLong(llvm::StringRef str) override;
5858

59-
void Execute(const char *args_string, CommandReturnObject &result) override;
59+
void Execute(const char *args_string, std::optional<uint16_t> offset_in_command,CommandReturnObject &result) override;
6060

6161
lldb::CommandObjectSP GetUnderlyingCommand() {
6262
return m_underlying_command_sp;

lldb/include/lldb/Interpreter/CommandObject.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,11 @@ class CommandObject : public std::enable_shared_from_this<CommandObject> {
340340
return false;
341341
}
342342

343+
/// \param offset_in_command is on what column \c args_string
344+
/// appears, if applicable. This enables diagnostics that refer back
345+
/// to the user input.
343346
virtual void Execute(const char *args_string,
347+
std::optional<uint16_t> offset_in_command,
344348
CommandReturnObject &result) = 0;
345349

346350
protected:
@@ -421,10 +425,14 @@ class CommandObjectParsed : public CommandObject {
421425

422426
~CommandObjectParsed() override = default;
423427

424-
void Execute(const char *args_string, CommandReturnObject &result) override;
428+
void Execute(const char *args_string,
429+
std::optional<uint16_t> offset_in_command,
430+
CommandReturnObject &result) override;
425431

426432
protected:
427-
virtual void DoExecute(Args &command, CommandReturnObject &result) = 0;
433+
virtual void DoExecute(Args &command,
434+
std::optional<uint16_t> offset_in_command,
435+
CommandReturnObject &result) = 0;
428436

429437
bool WantsRawCommandString() override { return false; }
430438
};
@@ -438,10 +446,13 @@ class CommandObjectRaw : public CommandObject {
438446

439447
~CommandObjectRaw() override = default;
440448

441-
void Execute(const char *args_string, CommandReturnObject &result) override;
449+
void Execute(const char *args_string,
450+
std::optional<uint16_t> offset_in_command,
451+
CommandReturnObject &result) override;
442452

443453
protected:
444454
virtual void DoExecute(llvm::StringRef command,
455+
std::optional<uint16_t> offset_in_command,
445456
CommandReturnObject &result) = 0;
446457

447458
bool WantsRawCommandString() override { return true; }

lldb/include/lldb/Interpreter/CommandObjectMultiword.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ class CommandObjectMultiword : public CommandObject {
5959
std::optional<std::string> GetRepeatCommand(Args &current_command_args,
6060
uint32_t index) override;
6161

62-
void Execute(const char *args_string, CommandReturnObject &result) override;
62+
void Execute(const char *args_string,
63+
std::optional<uint16_t> offset_in_command,
64+
CommandReturnObject &result) override;
6365

6466
bool IsRemovable() const override { return m_can_be_removed; }
6567

@@ -129,7 +131,9 @@ class CommandObjectProxy : public CommandObject {
129131
/// Execute is called) and \a GetProxyCommandObject returned null.
130132
virtual llvm::StringRef GetUnsupportedError();
131133

132-
void Execute(const char *args_string, CommandReturnObject &result) override;
134+
void Execute(const char *args_string,
135+
std::optional<uint16_t> offset_in_command,
136+
CommandReturnObject &result) override;
133137

134138
protected:
135139
// These two want to iterate over the subcommand dictionary.

lldb/source/API/SBCommandInterpreter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class CommandPluginInterfaceImplementation : public CommandObjectParsed {
7171
}
7272

7373
protected:
74-
void DoExecute(Args &command, CommandReturnObject &result) override {
74+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
7575
SBCommandReturnObject sb_return(result);
7676
SBCommandInterpreter sb_interpreter(&m_interpreter);
7777
SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());

lldb/source/Commands/CommandObjectApropos.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ CommandObjectApropos::CommandObjectApropos(CommandInterpreter &interpreter)
2626

2727
CommandObjectApropos::~CommandObjectApropos() = default;
2828

29-
void CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) {
29+
void CommandObjectApropos::DoExecute(Args &args, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) {
3030
const size_t argc = args.GetArgumentCount();
3131

3232
if (argc == 1) {

lldb/source/Commands/CommandObjectApropos.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class CommandObjectApropos : public CommandObjectParsed {
2323
~CommandObjectApropos() override;
2424

2525
protected:
26-
void DoExecute(Args &command, CommandReturnObject &result) override;
26+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override;
2727
};
2828

2929
} // namespace lldb_private

lldb/source/Commands/CommandObjectBreakpoint.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ class CommandObjectBreakpointSet : public CommandObjectParsed {
538538
};
539539

540540
protected:
541-
void DoExecute(Args &command, CommandReturnObject &result) override {
541+
void DoExecute(Args &args, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
542542
Target &target =
543543
m_dummy_options.m_use_dummy ? GetDummyTarget() : GetTarget();
544544

@@ -839,7 +839,7 @@ class CommandObjectBreakpointModify : public CommandObjectParsed {
839839
Options *GetOptions() override { return &m_options; }
840840

841841
protected:
842-
void DoExecute(Args &command, CommandReturnObject &result) override {
842+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
843843
Target &target = m_dummy_opts.m_use_dummy ? GetDummyTarget() : GetTarget();
844844

845845
std::unique_lock<std::recursive_mutex> lock;
@@ -903,7 +903,7 @@ class CommandObjectBreakpointEnable : public CommandObjectParsed {
903903
}
904904

905905
protected:
906-
void DoExecute(Args &command, CommandReturnObject &result) override {
906+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
907907
Target &target = GetTarget();
908908

909909
std::unique_lock<std::recursive_mutex> lock;
@@ -1010,7 +1010,7 @@ the second re-enables the first location.");
10101010
}
10111011

10121012
protected:
1013-
void DoExecute(Args &command, CommandReturnObject &result) override {
1013+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
10141014
Target &target = GetTarget();
10151015
std::unique_lock<std::recursive_mutex> lock;
10161016
target.GetBreakpointList().GetListMutex(lock);
@@ -1148,7 +1148,7 @@ class CommandObjectBreakpointList : public CommandObjectParsed {
11481148
};
11491149

11501150
protected:
1151-
void DoExecute(Args &command, CommandReturnObject &result) override {
1151+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
11521152
Target &target = m_options.m_use_dummy ? GetDummyTarget() : GetTarget();
11531153

11541154
const BreakpointList &breakpoints =
@@ -1267,7 +1267,7 @@ class CommandObjectBreakpointClear : public CommandObjectParsed {
12671267
};
12681268

12691269
protected:
1270-
void DoExecute(Args &command, CommandReturnObject &result) override {
1270+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
12711271
Target &target = GetTarget();
12721272

12731273
// The following are the various types of breakpoints that could be
@@ -1416,7 +1416,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
14161416
};
14171417

14181418
protected:
1419-
void DoExecute(Args &command, CommandReturnObject &result) override {
1419+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
14201420
Target &target = m_options.m_use_dummy ? GetDummyTarget() : GetTarget();
14211421
result.Clear();
14221422

@@ -1669,7 +1669,7 @@ class CommandObjectBreakpointNameConfigure : public CommandObjectParsed {
16691669
Options *GetOptions() override { return &m_option_group; }
16701670

16711671
protected:
1672-
void DoExecute(Args &command, CommandReturnObject &result) override {
1672+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
16731673

16741674
const size_t argc = command.GetArgumentCount();
16751675
if (argc == 0) {
@@ -1758,7 +1758,7 @@ class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
17581758
Options *GetOptions() override { return &m_option_group; }
17591759

17601760
protected:
1761-
void DoExecute(Args &command, CommandReturnObject &result) override {
1761+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
17621762
if (!m_name_options.m_name.OptionWasSet()) {
17631763
result.AppendError("No name option provided.");
17641764
return;
@@ -1832,7 +1832,7 @@ class CommandObjectBreakpointNameDelete : public CommandObjectParsed {
18321832
Options *GetOptions() override { return &m_option_group; }
18331833

18341834
protected:
1835-
void DoExecute(Args &command, CommandReturnObject &result) override {
1835+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
18361836
if (!m_name_options.m_name.OptionWasSet()) {
18371837
result.AppendError("No name option provided.");
18381838
return;
@@ -1896,7 +1896,7 @@ class CommandObjectBreakpointNameList : public CommandObjectParsed {
18961896
Options *GetOptions() override { return &m_option_group; }
18971897

18981898
protected:
1899-
void DoExecute(Args &command, CommandReturnObject &result) override {
1899+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
19001900
Target &target =
19011901
m_name_options.m_use_dummy ? GetDummyTarget() : GetTarget();
19021902

@@ -2209,7 +2209,7 @@ class CommandObjectBreakpointRead : public CommandObjectParsed {
22092209
};
22102210

22112211
protected:
2212-
void DoExecute(Args &command, CommandReturnObject &result) override {
2212+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
22132213
Target &target = GetTarget();
22142214

22152215
std::unique_lock<std::recursive_mutex> lock;
@@ -2319,7 +2319,7 @@ class CommandObjectBreakpointWrite : public CommandObjectParsed {
23192319
};
23202320

23212321
protected:
2322-
void DoExecute(Args &command, CommandReturnObject &result) override {
2322+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
23232323
Target &target = GetTarget();
23242324

23252325
std::unique_lock<std::recursive_mutex> lock;

lldb/source/Commands/CommandObjectBreakpointCommand.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,8 @@ are no syntax errors may indicate that a function was declared but never called.
319319
bool m_stop_on_error;
320320
bool m_use_dummy;
321321
};
322-
323322
protected:
324-
void DoExecute(Args &command, CommandReturnObject &result) override {
323+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
325324
Target &target = m_options.m_use_dummy ? GetDummyTarget() : GetTarget();
326325

327326
const BreakpointList &breakpoints = target.GetBreakpointList();
@@ -479,7 +478,7 @@ class CommandObjectBreakpointCommandDelete : public CommandObjectParsed {
479478
};
480479

481480
protected:
482-
void DoExecute(Args &command, CommandReturnObject &result) override {
481+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
483482
Target &target = m_options.m_use_dummy ? GetDummyTarget() : GetTarget();
484483

485484
const BreakpointList &breakpoints = target.GetBreakpointList();
@@ -546,7 +545,7 @@ class CommandObjectBreakpointCommandList : public CommandObjectParsed {
546545
~CommandObjectBreakpointCommandList() override = default;
547546

548547
protected:
549-
void DoExecute(Args &command, CommandReturnObject &result) override {
548+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
550549
Target &target = GetTarget();
551550

552551
const BreakpointList &breakpoints = target.GetBreakpointList();

lldb/source/Commands/CommandObjectCommands.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class CommandObjectCommandsSource : public CommandObjectParsed {
110110
OptionValueBoolean m_cmd_relative_to_command_file;
111111
};
112112

113-
void DoExecute(Args &command, CommandReturnObject &result) override {
113+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command,CommandReturnObject &result) override {
114114
if (command.GetArgumentCount() != 1) {
115115
result.AppendErrorWithFormat(
116116
"'%s' takes exactly one executable filename argument.\n",
@@ -370,7 +370,7 @@ other command as far as there is only one alias command match.");
370370
~CommandObjectCommandsAlias() override = default;
371371

372372
protected:
373-
void DoExecute(llvm::StringRef raw_command_line,
373+
void DoExecute(llvm::StringRef raw_command_line, std::optional<uint16_t> offset_in_command,
374374
CommandReturnObject &result) override {
375375
if (raw_command_line.empty()) {
376376
result.AppendError("'command alias' requires at least two arguments");
@@ -625,7 +625,7 @@ class CommandObjectCommandsUnalias : public CommandObjectParsed {
625625
}
626626

627627
protected:
628-
void DoExecute(Args &args, CommandReturnObject &result) override {
628+
void DoExecute(Args &args, std::optional<uint16_t> offset_in_command,CommandReturnObject &result) override {
629629
CommandObject::CommandMap::iterator pos;
630630
CommandObject *cmd_obj;
631631

@@ -701,7 +701,7 @@ class CommandObjectCommandsDelete : public CommandObjectParsed {
701701
}
702702

703703
protected:
704-
void DoExecute(Args &args, CommandReturnObject &result) override {
704+
void DoExecute(Args &args, std::optional<uint16_t> offset_in_command,CommandReturnObject &result) override {
705705
CommandObject::CommandMap::iterator pos;
706706

707707
if (args.empty()) {
@@ -825,7 +825,7 @@ a number follows 'f':"
825825
}
826826
}
827827

828-
void DoExecute(Args &command, CommandReturnObject &result) override {
828+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
829829
const size_t argc = command.GetArgumentCount();
830830
if (argc == 0) {
831831
result.AppendError("usage: 'command regex <command-name> "
@@ -1082,7 +1082,7 @@ class CommandObjectPythonFunction : public CommandObjectRaw {
10821082
bool WantsCompletion() override { return true; }
10831083

10841084
protected:
1085-
void DoExecute(llvm::StringRef raw_command_line,
1085+
void DoExecute(llvm::StringRef raw_command_line, std::optional<uint16_t> offset_in_command,
10861086
CommandReturnObject &result) override {
10871087
ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter();
10881088

@@ -1190,7 +1190,7 @@ class CommandObjectScriptingObjectRaw : public CommandObjectRaw {
11901190
}
11911191

11921192
protected:
1193-
void DoExecute(llvm::StringRef raw_command_line,
1193+
void DoExecute(llvm::StringRef raw_command_line, std::optional<uint16_t> offset_in_command,
11941194
CommandReturnObject &result) override {
11951195
ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter();
11961196

@@ -1931,7 +1931,7 @@ class CommandObjectScriptingObjectParsed : public CommandObjectParsed {
19311931
}
19321932

19331933
protected:
1934-
void DoExecute(Args &args,
1934+
void DoExecute(Args &args, std::optional<uint16_t> offset_in_command,
19351935
CommandReturnObject &result) override {
19361936
ScriptInterpreter *scripter = GetDebugger().GetScriptInterpreter();
19371937

@@ -2023,7 +2023,7 @@ class CommandObjectCommandsScriptImport : public CommandObjectParsed {
20232023
bool silent = false;
20242024
};
20252025

2026-
void DoExecute(Args &command, CommandReturnObject &result) override {
2026+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
20272027
if (command.empty()) {
20282028
result.AppendError("command script import needs one or more arguments");
20292029
return;
@@ -2250,7 +2250,7 @@ class CommandObjectCommandsScriptAdd : public CommandObjectParsed,
22502250
io_handler.SetIsDone(true);
22512251
}
22522252

2253-
void DoExecute(Args &command, CommandReturnObject &result) override {
2253+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
22542254
if (GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) {
22552255
result.AppendError("only scripting language supported for scripted "
22562256
"commands is currently Python");
@@ -2373,7 +2373,7 @@ class CommandObjectCommandsScriptList : public CommandObjectParsed {
23732373

23742374
~CommandObjectCommandsScriptList() override = default;
23752375

2376-
void DoExecute(Args &command, CommandReturnObject &result) override {
2376+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
23772377
m_interpreter.GetHelp(result, CommandInterpreter::eCommandTypesUserDef);
23782378

23792379
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -2391,7 +2391,7 @@ class CommandObjectCommandsScriptClear : public CommandObjectParsed {
23912391
~CommandObjectCommandsScriptClear() override = default;
23922392

23932393
protected:
2394-
void DoExecute(Args &command, CommandReturnObject &result) override {
2394+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
23952395
m_interpreter.RemoveAllUser();
23962396

23972397
result.SetStatus(eReturnStatusSuccessFinishResult);
@@ -2420,7 +2420,7 @@ class CommandObjectCommandsScriptDelete : public CommandObjectParsed {
24202420
}
24212421

24222422
protected:
2423-
void DoExecute(Args &command, CommandReturnObject &result) override {
2423+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
24242424

24252425
llvm::StringRef root_cmd = command[0].ref();
24262426
size_t num_args = command.GetArgumentCount();
@@ -2604,7 +2604,7 @@ class CommandObjectCommandsContainerAdd : public CommandObjectParsed {
26042604
std::string m_long_help;
26052605
bool m_overwrite = false;
26062606
};
2607-
void DoExecute(Args &command, CommandReturnObject &result) override {
2607+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
26082608
size_t num_args = command.GetArgumentCount();
26092609

26102610
if (num_args == 0) {
@@ -2684,7 +2684,7 @@ class CommandObjectCommandsContainerDelete : public CommandObjectParsed {
26842684
}
26852685

26862686
protected:
2687-
void DoExecute(Args &command, CommandReturnObject &result) override {
2687+
void DoExecute(Args &command, std::optional<uint16_t> offset_in_command, CommandReturnObject &result) override {
26882688
size_t num_args = command.GetArgumentCount();
26892689

26902690
if (num_args == 0) {

lldb/source/Commands/CommandObjectDWIMPrint.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ CommandObjectDWIMPrint::CommandObjectDWIMPrint(CommandInterpreter &interpreter)
5050

5151
Options *CommandObjectDWIMPrint::GetOptions() { return &m_option_group; }
5252

53-
void CommandObjectDWIMPrint::DoExecute(StringRef command,
53+
void CommandObjectDWIMPrint::DoExecute(StringRef command,std::optional<uint16_t> offset_in_command,
5454
CommandReturnObject &result) {
5555
m_option_group.NotifyOptionParsingStarting(&m_exe_ctx);
5656
OptionsWithRaw args{command};

0 commit comments

Comments
 (0)