Skip to content

Commit b8db2a9

Browse files
committed
[lldb] Add expression command options in dwim-print
Adopt `expression`'s options in `dwim-print`. This is primarily added to support the `--language`/`-l` flag. Differential Revision: https://reviews.llvm.org/D144114 (cherry picked from commit 920b46e)
1 parent 1c6ca35 commit b8db2a9

File tree

7 files changed

+109
-65
lines changed

7 files changed

+109
-65
lines changed

lldb/include/lldb/Interpreter/Options.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "lldb/lldb-private.h"
2121

2222
#include "llvm/ADT/ArrayRef.h"
23+
#include "llvm/ADT/StringRef.h"
2324

2425
namespace lldb_private {
2526

@@ -290,6 +291,21 @@ class OptionGroupOptions : public Options {
290291
/// copying the option definition.
291292
void Append(OptionGroup *group, uint32_t src_mask, uint32_t dst_mask);
292293

294+
/// Append selected options from a OptionGroup class.
295+
///
296+
/// Append the subset of options from \a group, where the "long_option" value
297+
/// is _not_ in \a exclude_long_options.
298+
///
299+
/// \param[in] group
300+
/// A group of options to take option values from and copy their
301+
/// definitions into this class.
302+
///
303+
/// \param[in] exclude_long_options
304+
/// A set of long option strings which indicate which option values values
305+
/// to limit from \a group.
306+
void Append(OptionGroup *group,
307+
llvm::ArrayRef<llvm::StringRef> exclude_long_options);
308+
293309
void Finalize();
294310

295311
bool DidFinalize() { return m_did_finalize; }

lldb/source/Commands/CommandObjectDWIMPrint.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ CommandObjectDWIMPrint::CommandObjectDWIMPrint(CommandInterpreter &interpreter)
3636
OptionGroupFormat::OPTION_GROUP_FORMAT |
3737
OptionGroupFormat::OPTION_GROUP_GDB_FMT,
3838
LLDB_OPT_SET_1);
39+
StringRef exclude_expr_options[] = {"debug", "top-level"};
40+
m_option_group.Append(&m_expr_options, exclude_expr_options);
3941
m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4042
m_option_group.Finalize();
4143
}
@@ -57,11 +59,11 @@ bool CommandObjectDWIMPrint::DoExecute(StringRef command,
5759
m_cmd_name);
5860
return false;
5961
}
62+
6063
auto verbosity = GetDebugger().GetDWIMPrintVerbosity();
6164

6265
DumpValueObjectOptions dump_options = m_varobj_options.GetAsDumpOptions(
63-
eLanguageRuntimeDescriptionDisplayVerbosityFull,
64-
m_format_options.GetFormat());
66+
m_expr_options.m_verbosity, m_format_options.GetFormat());
6567

6668
// First, try `expr` as the name of a frame variable.
6769
if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
@@ -87,9 +89,12 @@ bool CommandObjectDWIMPrint::DoExecute(StringRef command,
8789
Target &target = target_ptr ? *target_ptr : GetDummyTarget();
8890

8991
auto *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
92+
const EvaluateExpressionOptions eval_options =
93+
m_expr_options.GetEvaluateExpressionOptions(target, m_varobj_options);
9094
ValueObjectSP valobj_sp;
91-
if (target.EvaluateExpression(expr, exe_scope, valobj_sp) ==
92-
eExpressionCompleted) {
95+
ExpressionResults expr_result =
96+
target.EvaluateExpression(expr, exe_scope, valobj_sp, eval_options);
97+
if (expr_result == eExpressionCompleted) {
9398
if (verbosity != eDWIMPrintVerbosityNone) {
9499
StringRef flags;
95100
if (args.HasArgs())

lldb/source/Commands/CommandObjectDWIMPrint.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTDWIMPRINT_H
1010
#define LLDB_SOURCE_COMMANDS_COMMANDOBJECTDWIMPRINT_H
1111

12+
#include "CommandObjectExpression.h"
1213
#include "lldb/Interpreter/CommandObject.h"
1314
#include "lldb/Interpreter/OptionGroupFormat.h"
1415
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
@@ -42,6 +43,7 @@ class CommandObjectDWIMPrint : public CommandObjectRaw {
4243
OptionGroupOptions m_option_group;
4344
OptionGroupFormat m_format_options = lldb::eFormatDefault;
4445
OptionGroupValueObjectDisplay m_varobj_options;
46+
CommandObjectExpression::CommandOptions m_expr_options;
4547
};
4648

4749
} // namespace lldb_private

lldb/source/Commands/CommandObjectExpression.cpp

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,60 @@ CommandObjectExpression::CommandOptions::GetDefinitions() {
194194
return llvm::makeArrayRef(g_expression_options);
195195
}
196196

197+
EvaluateExpressionOptions
198+
CommandObjectExpression::CommandOptions::GetEvaluateExpressionOptions(
199+
const Target &target, const OptionGroupValueObjectDisplay &display_opts) {
200+
EvaluateExpressionOptions options;
201+
options.SetCoerceToId(display_opts.use_objc);
202+
if (m_verbosity == eLanguageRuntimeDescriptionDisplayVerbosityCompact)
203+
options.SetSuppressPersistentResult(display_opts.use_objc);
204+
options.SetUnwindOnError(unwind_on_error);
205+
options.SetIgnoreBreakpoints(ignore_breakpoints);
206+
options.SetKeepInMemory(true);
207+
options.SetUseDynamic(display_opts.use_dynamic);
208+
options.SetTryAllThreads(try_all_threads);
209+
options.SetDebug(debug);
210+
211+
// BEGIN SWIFT
212+
options.SetBindGenericTypes(bind_generic_types);
213+
// If the language was not specified in the expression command,
214+
// set it to the language in the target's properties if
215+
// specified, else default to the language for the frame.
216+
if (language != eLanguageTypeUnknown) {
217+
// END SWIFT
218+
options.SetLanguage(language);
219+
// BEGIN SWIFT
220+
}
221+
// END SWIFT
222+
223+
options.SetExecutionPolicy(
224+
allow_jit ? EvaluateExpressionOptions::default_execution_policy
225+
: lldb_private::eExecutionPolicyNever);
226+
227+
bool auto_apply_fixits;
228+
if (this->auto_apply_fixits == eLazyBoolCalculate)
229+
auto_apply_fixits = target.GetEnableAutoApplyFixIts();
230+
else
231+
auto_apply_fixits = this->auto_apply_fixits == eLazyBoolYes;
232+
233+
options.SetAutoApplyFixIts(auto_apply_fixits);
234+
options.SetRetriesWithFixIts(target.GetNumberOfRetriesWithFixits());
235+
236+
if (top_level)
237+
options.SetExecutionPolicy(eExecutionPolicyTopLevel);
238+
239+
// If there is any chance we are going to stop and want to see what went
240+
// wrong with our expression, we should generate debug info
241+
if (!ignore_breakpoints || !unwind_on_error)
242+
options.SetGenerateDebugInfo(true);
243+
244+
if (timeout > 0)
245+
options.SetTimeout(std::chrono::microseconds(timeout));
246+
else
247+
options.SetTimeout(std::nullopt);
248+
return options;
249+
}
250+
197251
CommandObjectExpression::CommandObjectExpression(
198252
CommandInterpreter &interpreter)
199253
: CommandObjectRaw(interpreter, "expression",
@@ -358,62 +412,6 @@ CanBeUsedForElementCountPrinting(ValueObject &valobj) {
358412
return Status();
359413
}
360414

361-
EvaluateExpressionOptions
362-
CommandObjectExpression::GetEvalOptions(const Target &target) {
363-
EvaluateExpressionOptions options;
364-
options.SetCoerceToId(m_varobj_options.use_objc);
365-
if (m_command_options.m_verbosity ==
366-
eLanguageRuntimeDescriptionDisplayVerbosityCompact)
367-
options.SetSuppressPersistentResult(m_varobj_options.use_objc);
368-
options.SetUnwindOnError(m_command_options.unwind_on_error);
369-
options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints);
370-
options.SetKeepInMemory(true);
371-
options.SetUseDynamic(m_varobj_options.use_dynamic);
372-
options.SetTryAllThreads(m_command_options.try_all_threads);
373-
options.SetDebug(m_command_options.debug);
374-
375-
// BEGIN SWIFT
376-
options.SetBindGenericTypes(m_command_options.bind_generic_types);
377-
// If the language was not specified in the expression command,
378-
// set it to the language in the target's properties if
379-
// specified, else default to the language for the frame.
380-
if (m_command_options.language != eLanguageTypeUnknown) {
381-
// END SWIFT
382-
options.SetLanguage(m_command_options.language);
383-
// BEGIN SWIFT
384-
}
385-
// END SWIFT
386-
387-
options.SetExecutionPolicy(
388-
m_command_options.allow_jit
389-
? EvaluateExpressionOptions::default_execution_policy
390-
: lldb_private::eExecutionPolicyNever);
391-
392-
bool auto_apply_fixits;
393-
if (m_command_options.auto_apply_fixits == eLazyBoolCalculate)
394-
auto_apply_fixits = target.GetEnableAutoApplyFixIts();
395-
else
396-
auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes;
397-
398-
options.SetAutoApplyFixIts(auto_apply_fixits);
399-
options.SetRetriesWithFixIts(target.GetNumberOfRetriesWithFixits());
400-
401-
if (m_command_options.top_level)
402-
options.SetExecutionPolicy(eExecutionPolicyTopLevel);
403-
404-
// If there is any chance we are going to stop and want to see what went
405-
// wrong with our expression, we should generate debug info
406-
if (!m_command_options.ignore_breakpoints ||
407-
!m_command_options.unwind_on_error)
408-
options.SetGenerateDebugInfo(true);
409-
410-
if (m_command_options.timeout > 0)
411-
options.SetTimeout(std::chrono::microseconds(m_command_options.timeout));
412-
else
413-
options.SetTimeout(llvm::None);
414-
return options;
415-
}
416-
417415
bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
418416
Stream &output_stream,
419417
Stream &error_stream,
@@ -434,7 +432,8 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr,
434432
return false;
435433
}
436434

437-
const EvaluateExpressionOptions options = GetEvalOptions(target);
435+
const EvaluateExpressionOptions options =
436+
m_command_options.GetEvaluateExpressionOptions(target, m_varobj_options);
438437
ExpressionResults success = target.EvaluateExpression(
439438
expr, frame, result_valobj_sp, options, &m_fixed_expression);
440439

lldb/source/Commands/CommandObjectExpression.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ class CommandObjectExpression : public CommandObjectRaw,
3535

3636
void OptionParsingStarting(ExecutionContext *execution_context) override;
3737

38+
/// Return the appropriate expression options used for evaluating the
39+
/// expression in the given target.
40+
EvaluateExpressionOptions GetEvaluateExpressionOptions(
41+
const Target &target,
42+
const OptionGroupValueObjectDisplay &display_opts);
43+
3844
bool top_level;
3945
bool unwind_on_error;
4046
bool ignore_breakpoints;
@@ -70,10 +76,6 @@ class CommandObjectExpression : public CommandObjectRaw,
7076

7177
bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override;
7278

73-
/// Return the appropriate expression options used for evaluating the
74-
/// expression in the given target.
75-
EvaluateExpressionOptions GetEvalOptions(const Target &target);
76-
7779
/// Evaluates the given expression.
7880
/// \param output_stream The stream to which the evaluation result will be
7981
/// printed.

lldb/source/Interpreter/Options.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,19 @@ void OptionGroupOptions::Append(OptionGroup *group, uint32_t src_mask,
781781
}
782782
}
783783

784+
void OptionGroupOptions::Append(
785+
OptionGroup *group, llvm::ArrayRef<llvm::StringRef> exclude_long_options) {
786+
auto group_option_defs = group->GetDefinitions();
787+
for (uint32_t i = 0; i < group_option_defs.size(); ++i) {
788+
const auto &definition = group_option_defs[i];
789+
if (llvm::is_contained(exclude_long_options, definition.long_option))
790+
continue;
791+
792+
m_option_infos.push_back(OptionInfo(group, i));
793+
m_option_defs.push_back(definition);
794+
}
795+
}
796+
784797
void OptionGroupOptions::Finalize() {
785798
m_did_finalize = true;
786799
}

lldb/test/API/commands/dwim-print/TestDWIMPrint.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,10 @@ def test_display_flags(self):
103103
lldbutil.run_to_name_breakpoint(self, "main")
104104
self._expect_cmd(f"dwim-print -T -- argc", "frame variable")
105105
self._expect_cmd(f"dwim-print -T -- argc + 1", "expression")
106+
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")

0 commit comments

Comments
 (0)