
This updates all the existing memory reference fields to use `lldb::addr_t` directly. A few places were using `std::string` and decoding the value in the request handler and other places had unique ways of parsing addresses. This unifies all of these references with the `DecodeMemoryReference` helper in JSONUtils.h. Additionally, for the types I updated, I tried to simplify the POD types some and moved default values out of RequestHandlers and into the protocol POD types.
84 lines
2.8 KiB
C++
84 lines
2.8 KiB
C++
//===-- SetVariableRequestHandler.cpp -------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "DAP.h"
|
|
#include "EventHelper.h"
|
|
#include "JSONUtils.h"
|
|
#include "RequestHandler.h"
|
|
|
|
using namespace lldb_dap::protocol;
|
|
|
|
namespace lldb_dap {
|
|
|
|
/// Set the variable with the given name in the variable container to a new
|
|
/// value. Clients should only call this request if the corresponding capability
|
|
/// `supportsSetVariable` is true.
|
|
///
|
|
/// If a debug adapter implements both `setVariable` and `setExpression`,
|
|
/// a client will only use `setExpression` if the variable has an evaluateName
|
|
/// property.
|
|
llvm::Expected<SetVariableResponseBody>
|
|
SetVariableRequestHandler::Run(const SetVariableArguments &args) const {
|
|
const auto args_name = llvm::StringRef(args.name);
|
|
|
|
if (args.variablesReference == UINT64_MAX) {
|
|
return llvm::make_error<DAPError>(
|
|
llvm::formatv("invalid reference {}", args.variablesReference).str(),
|
|
llvm::inconvertibleErrorCode(),
|
|
/*show_user=*/false);
|
|
}
|
|
|
|
constexpr llvm::StringRef return_value_name = "(Return Value)";
|
|
if (args_name == return_value_name)
|
|
return llvm::make_error<DAPError>(
|
|
"cannot change the value of the return value");
|
|
|
|
lldb::SBValue variable =
|
|
dap.variables.FindVariable(args.variablesReference, args_name);
|
|
|
|
if (!variable.IsValid())
|
|
return llvm::make_error<DAPError>("could not find variable in scope");
|
|
|
|
lldb::SBError error;
|
|
const bool success = variable.SetValueFromCString(args.value.c_str(), error);
|
|
if (!success)
|
|
return llvm::make_error<DAPError>(error.GetCString());
|
|
|
|
VariableDescription desc(variable,
|
|
dap.configuration.enableAutoVariableSummaries);
|
|
|
|
SetVariableResponseBody body;
|
|
body.value = desc.display_value;
|
|
body.type = desc.display_type_name;
|
|
|
|
// We don't know the index of the variable in our dap.variables
|
|
// so always insert a new one to get its variablesReference.
|
|
// is_permanent is false because debug console does not support
|
|
// setVariable request.
|
|
const int64_t new_var_ref =
|
|
dap.variables.InsertVariable(variable, /*is_permanent=*/false);
|
|
if (variable.MightHaveChildren()) {
|
|
body.variablesReference = new_var_ref;
|
|
if (desc.type_obj.IsArrayType())
|
|
body.indexedVariables = variable.GetNumChildren();
|
|
else
|
|
body.namedVariables = variable.GetNumChildren();
|
|
}
|
|
|
|
if (const lldb::addr_t addr = variable.GetLoadAddress();
|
|
addr != LLDB_INVALID_ADDRESS)
|
|
body.memoryReference = addr;
|
|
|
|
if (ValuePointsToCode(variable))
|
|
body.valueLocationReference = new_var_ref;
|
|
|
|
return body;
|
|
}
|
|
|
|
} // namespace lldb_dap
|