brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · aaad0e2 Raw
99 lines · cpp
1//===-- ScopesRequestHandler.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 "RequestHandler.h"11 12using namespace lldb_dap::protocol;13namespace lldb_dap {14 15/// Creates a `protocol::Scope` struct.16///17///18/// \param[in] name19///     The value to place into the "name" key20///21/// \param[in] variablesReference22///     The value to place into the "variablesReference" key23///24/// \param[in] namedVariables25///     The value to place into the "namedVariables" key26///27/// \param[in] expensive28///     The value to place into the "expensive" key29///30/// \return31///     A `protocol::Scope`32static Scope CreateScope(const llvm::StringRef name, int64_t variablesReference,33                         int64_t namedVariables, bool expensive) {34  Scope scope;35  scope.name = name;36 37  // TODO: Support "arguments" and "return value" scope.38  // At the moment lldb-dap includes the arguments and return_value  into the39  // "locals" scope.40  // vscode only expands the first non-expensive scope, this causes friction41  // if we add the arguments above the local scope as the locals scope will not42  // be expanded if we enter a function with arguments. It becomes more43  // annoying when the scope has arguments, return_value and locals.44  if (variablesReference == VARREF_LOCALS)45    scope.presentationHint = Scope::eScopePresentationHintLocals;46  else if (variablesReference == VARREF_REGS)47    scope.presentationHint = Scope::eScopePresentationHintRegisters;48 49  scope.variablesReference = variablesReference;50  scope.namedVariables = namedVariables;51  scope.expensive = expensive;52 53  return scope;54}55 56llvm::Expected<ScopesResponseBody>57ScopesRequestHandler::Run(const ScopesArguments &args) const {58  lldb::SBFrame frame = dap.GetLLDBFrame(args.frameId);59 60  // As the user selects different stack frames in the GUI, a "scopes" request61  // will be sent to the DAP. This is the only way we know that the user has62  // selected a frame in a thread. There are no other notifications that are63  // sent and VS code doesn't allow multiple frames to show variables64  // concurrently. If we select the thread and frame as the "scopes" requests65  // are sent, this allows users to type commands in the debugger console66  // with a backtick character to run lldb commands and these lldb commands67  // will now have the right context selected as they are run. If the user68  // types "`bt" into the debugger console, and we had another thread selected69  // in the LLDB library, we would show the wrong thing to the user. If the70  // users switch threads with a lldb command like "`thread select 14", the71  // GUI will not update as there are no "event" notification packets that72  // allow us to change the currently selected thread or frame in the GUI that73  // I am aware of.74  if (frame.IsValid()) {75    frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());76    frame.GetThread().SetSelectedFrame(frame.GetFrameID());77  }78  dap.variables.locals = frame.GetVariables(/*arguments=*/true,79                                            /*locals=*/true,80                                            /*statics=*/false,81                                            /*in_scope_only=*/true);82  dap.variables.globals = frame.GetVariables(/*arguments=*/false,83                                             /*locals=*/false,84                                             /*statics=*/true,85                                             /*in_scope_only=*/true);86  dap.variables.registers = frame.GetRegisters();87 88  std::vector scopes = {CreateScope("Locals", VARREF_LOCALS,89                                    dap.variables.locals.GetSize(), false),90                        CreateScope("Globals", VARREF_GLOBALS,91                                    dap.variables.globals.GetSize(), false),92                        CreateScope("Registers", VARREF_REGS,93                                    dap.variables.registers.GetSize(), false)};94 95  return ScopesResponseBody{std::move(scopes)};96}97 98} // namespace lldb_dap99