//===-- 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 SetVariableRequestHandler::Run(const SetVariableArguments &args) const { const auto args_name = llvm::StringRef(args.name); if (args.variablesReference == UINT64_MAX) { return llvm::make_error( 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( "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("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(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