1*f6aab3d8Srobert //===-- CommandObjectDWIMPrint.cpp ------------------------------*- C++ -*-===//
2*f6aab3d8Srobert //
3*f6aab3d8Srobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*f6aab3d8Srobert // See https://llvm.org/LICENSE.txt for license information.
5*f6aab3d8Srobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*f6aab3d8Srobert //
7*f6aab3d8Srobert //===----------------------------------------------------------------------===//
8*f6aab3d8Srobert
9*f6aab3d8Srobert #include "CommandObjectDWIMPrint.h"
10*f6aab3d8Srobert
11*f6aab3d8Srobert #include "lldb/Core/ValueObject.h"
12*f6aab3d8Srobert #include "lldb/Interpreter/CommandInterpreter.h"
13*f6aab3d8Srobert #include "lldb/Interpreter/CommandObject.h"
14*f6aab3d8Srobert #include "lldb/Interpreter/CommandReturnObject.h"
15*f6aab3d8Srobert #include "lldb/Target/StackFrame.h"
16*f6aab3d8Srobert #include "lldb/Utility/ConstString.h"
17*f6aab3d8Srobert #include "lldb/lldb-enumerations.h"
18*f6aab3d8Srobert #include "lldb/lldb-forward.h"
19*f6aab3d8Srobert
20*f6aab3d8Srobert using namespace llvm;
21*f6aab3d8Srobert using namespace lldb;
22*f6aab3d8Srobert using namespace lldb_private;
23*f6aab3d8Srobert
CommandObjectDWIMPrint(CommandInterpreter & interpreter)24*f6aab3d8Srobert CommandObjectDWIMPrint::CommandObjectDWIMPrint(CommandInterpreter &interpreter)
25*f6aab3d8Srobert : CommandObjectRaw(interpreter, "dwim-print",
26*f6aab3d8Srobert "Print a variable or expression.",
27*f6aab3d8Srobert "dwim-print [<variable-name> | <expression>]",
28*f6aab3d8Srobert eCommandProcessMustBePaused | eCommandTryTargetAPILock) {
29*f6aab3d8Srobert }
30*f6aab3d8Srobert
DoExecute(StringRef expr,CommandReturnObject & result)31*f6aab3d8Srobert bool CommandObjectDWIMPrint::DoExecute(StringRef expr,
32*f6aab3d8Srobert CommandReturnObject &result) {
33*f6aab3d8Srobert // Ignore leading and trailing whitespace.
34*f6aab3d8Srobert expr = expr.trim();
35*f6aab3d8Srobert
36*f6aab3d8Srobert if (expr.empty()) {
37*f6aab3d8Srobert result.AppendErrorWithFormatv("'{0}' takes a variable or expression",
38*f6aab3d8Srobert m_cmd_name);
39*f6aab3d8Srobert return false;
40*f6aab3d8Srobert }
41*f6aab3d8Srobert
42*f6aab3d8Srobert auto verbosity = GetDebugger().GetDWIMPrintVerbosity();
43*f6aab3d8Srobert
44*f6aab3d8Srobert // First, try `expr` as the name of a frame variable.
45*f6aab3d8Srobert if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
46*f6aab3d8Srobert auto valobj_sp = frame->FindVariable(ConstString(expr));
47*f6aab3d8Srobert if (valobj_sp && valobj_sp->GetError().Success()) {
48*f6aab3d8Srobert if (verbosity == eDWIMPrintVerbosityFull)
49*f6aab3d8Srobert result.AppendMessageWithFormatv("note: ran `frame variable {0}`", expr);
50*f6aab3d8Srobert valobj_sp->Dump(result.GetOutputStream());
51*f6aab3d8Srobert result.SetStatus(eReturnStatusSuccessFinishResult);
52*f6aab3d8Srobert return true;
53*f6aab3d8Srobert }
54*f6aab3d8Srobert }
55*f6aab3d8Srobert
56*f6aab3d8Srobert // Second, also lastly, try `expr` as a source expression to evaluate.
57*f6aab3d8Srobert {
58*f6aab3d8Srobert Target *target_ptr = m_exe_ctx.GetTargetPtr();
59*f6aab3d8Srobert // Fallback to the dummy target, which can allow for expression evaluation.
60*f6aab3d8Srobert Target &target = target_ptr ? *target_ptr : GetDummyTarget();
61*f6aab3d8Srobert
62*f6aab3d8Srobert auto *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
63*f6aab3d8Srobert ValueObjectSP valobj_sp;
64*f6aab3d8Srobert if (target.EvaluateExpression(expr, exe_scope, valobj_sp) ==
65*f6aab3d8Srobert eExpressionCompleted) {
66*f6aab3d8Srobert if (verbosity != eDWIMPrintVerbosityNone)
67*f6aab3d8Srobert result.AppendMessageWithFormatv("note: ran `expression -- {0}`", expr);
68*f6aab3d8Srobert valobj_sp->Dump(result.GetOutputStream());
69*f6aab3d8Srobert result.SetStatus(eReturnStatusSuccessFinishResult);
70*f6aab3d8Srobert return true;
71*f6aab3d8Srobert } else {
72*f6aab3d8Srobert if (valobj_sp)
73*f6aab3d8Srobert result.SetError(valobj_sp->GetError());
74*f6aab3d8Srobert else
75*f6aab3d8Srobert result.AppendErrorWithFormatv(
76*f6aab3d8Srobert "unknown error evaluating expression `{0}`", expr);
77*f6aab3d8Srobert return false;
78*f6aab3d8Srobert }
79*f6aab3d8Srobert }
80*f6aab3d8Srobert }
81