brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.2 KiB · b9ae28d Raw
92 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "DAP.h"10#include "EventHelper.h"11#include "JSONUtils.h"12#include "Protocol/ProtocolEvents.h"13#include "RequestHandler.h"14 15using namespace lldb_dap::protocol;16 17namespace lldb_dap {18 19/// Set the variable with the given name in the variable container to a new20/// value. Clients should only call this request if the corresponding capability21/// `supportsSetVariable` is true.22///23/// If a debug adapter implements both `setVariable` and `setExpression`,24/// a client will only use `setExpression` if the variable has an evaluateName25/// property.26llvm::Expected<SetVariableResponseBody>27SetVariableRequestHandler::Run(const SetVariableArguments &args) const {28  const auto args_name = llvm::StringRef(args.name);29 30  if (args.variablesReference == UINT64_MAX) {31    return llvm::make_error<DAPError>(32        llvm::formatv("invalid reference {}", args.variablesReference).str(),33        llvm::inconvertibleErrorCode(),34        /*show_user=*/false);35  }36 37  constexpr llvm::StringRef return_value_name = "(Return Value)";38  if (args_name == return_value_name)39    return llvm::make_error<DAPError>(40        "cannot change the value of the return value");41 42  lldb::SBValue variable =43      dap.variables.FindVariable(args.variablesReference, args_name);44 45  if (!variable.IsValid())46    return llvm::make_error<DAPError>("could not find variable in scope");47 48  lldb::SBError error;49  const bool success = variable.SetValueFromCString(args.value.c_str(), error);50  if (!success)51    return llvm::make_error<DAPError>(error.GetCString());52 53  VariableDescription desc(variable,54                           dap.configuration.enableAutoVariableSummaries);55 56  SetVariableResponseBody body;57  body.value = desc.display_value;58  body.type = desc.display_type_name;59 60  // We don't know the index of the variable in our dap.variables61  // so always insert a new one to get its variablesReference.62  // is_permanent is false because debug console does not support63  // setVariable request.64  const int64_t new_var_ref =65      dap.variables.InsertVariable(variable, /*is_permanent=*/false);66  if (variable.MightHaveChildren()) {67    body.variablesReference = new_var_ref;68    if (desc.type_obj.IsArrayType())69      body.indexedVariables = variable.GetNumChildren();70    else71      body.namedVariables = variable.GetNumChildren();72  }73 74  if (const lldb::addr_t addr = variable.GetLoadAddress();75      addr != LLDB_INVALID_ADDRESS)76    body.memoryReference = addr;77 78  if (ValuePointsToCode(variable))79    body.valueLocationReference = new_var_ref;80 81  // Also send invalidated event to signal client that some variables82  // (e.g. references) can be changed.83  SendInvalidatedEvent(dap, {InvalidatedEventBody::eAreaVariables});84 85  // Also send memory event to signal client that variable memory was changed.86  SendMemoryEvent(dap, variable);87 88  return body;89}90 91} // namespace lldb_dap92