1//===-- SetVariableRequestHandler.cpp -------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "DAP.h"
10#include "EventHelper.h"
11#include "JSONUtils.h"
12#include "RequestHandler.h"
13
14using namespace lldb_dap::protocol;
15
16namespace lldb_dap {
17
18/// Set the variable with the given name in the variable container to a new
19/// value. Clients should only call this request if the corresponding capability
20/// `supportsSetVariable` is true.
21///
22/// If a debug adapter implements both `setVariable` and `setExpression`,
23/// a client will only use `setExpression` if the variable has an evaluateName
24/// property.
25llvm::Expected<SetVariableResponseBody>
26SetVariableRequestHandler::Run(const SetVariableArguments &args) const {
27 const auto args_name = llvm::StringRef(args.name);
28
29 if (args.variablesReference == UINT64_MAX) {
30 return llvm::make_error<DAPError>(
31 Args: llvm::formatv(Fmt: "invalid reference {}", Vals: args.variablesReference).str(),
32 Args: llvm::inconvertibleErrorCode(),
33 /*show_user=*/Args: false);
34 }
35
36 constexpr llvm::StringRef return_value_name = "(Return Value)";
37 if (args_name == return_value_name)
38 return llvm::make_error<DAPError>(
39 Args: "cannot change the value of the return value");
40
41 lldb::SBValue variable =
42 dap.variables.FindVariable(variablesReference: args.variablesReference, name: args_name);
43
44 if (!variable.IsValid())
45 return llvm::make_error<DAPError>(Args: "could not find variable in scope");
46
47 lldb::SBError error;
48 const bool success = variable.SetValueFromCString(value_str: args.value.c_str(), error);
49 if (!success)
50 return llvm::make_error<DAPError>(Args: error.GetCString());
51
52 VariableDescription desc(variable,
53 dap.configuration.enableAutoVariableSummaries);
54
55 SetVariableResponseBody body;
56 body.value = desc.display_value;
57 body.type = desc.display_type_name;
58
59 // We don't know the index of the variable in our dap.variables
60 // so always insert a new one to get its variablesReference.
61 // is_permanent is false because debug console does not support
62 // setVariable request.
63 const int64_t new_var_ref =
64 dap.variables.InsertVariable(variable, /*is_permanent=*/false);
65 if (variable.MightHaveChildren()) {
66 body.variablesReference = new_var_ref;
67 if (desc.type_obj.IsArrayType())
68 body.indexedVariables = variable.GetNumChildren();
69 else
70 body.namedVariables = variable.GetNumChildren();
71
72 } else {
73 body.variablesReference = 0;
74 }
75
76 if (const lldb::addr_t addr = variable.GetLoadAddress();
77 addr != LLDB_INVALID_ADDRESS)
78 body.memoryReference = EncodeMemoryReference(addr);
79
80 if (ValuePointsToCode(v: variable))
81 body.valueLocationReference = new_var_ref;
82
83 return body;
84}
85
86} // namespace lldb_dap
87

source code of lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp