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-exception
6//
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] name
19/// The value to place into the "name" key
20///
21/// \param[in] variablesReference
22/// The value to place into the "variablesReference" key
23///
24/// \param[in] namedVariables
25/// The value to place into the "namedVariables" key
26///
27/// \param[in] expensive
28/// The value to place into the "expensive" key
29///
30/// \return
31/// 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 the
39 // "locals" scope.
40 // vscode only expands the first non-expensive scope, this causes friction
41 // if we add the arguments above the local scope as the locals scope will not
42 // be expanded if we enter a function with arguments. It becomes more
43 // 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(frame_id: args.frameId);
59
60 // As the user selects different stack frames in the GUI, a "scopes" request
61 // will be sent to the DAP. This is the only way we know that the user has
62 // selected a frame in a thread. There are no other notifications that are
63 // sent and VS code doesn't allow multiple frames to show variables
64 // concurrently. If we select the thread and frame as the "scopes" requests
65 // are sent, this allows users to type commands in the debugger console
66 // with a backtick character to run lldb commands and these lldb commands
67 // will now have the right context selected as they are run. If the user
68 // types "`bt" into the debugger console, and we had another thread selected
69 // in the LLDB library, we would show the wrong thing to the user. If the
70 // users switch threads with a lldb command like "`thread select 14", the
71 // GUI will not update as there are no "event" notification packets that
72 // allow us to change the currently selected thread or frame in the GUI that
73 // 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(name: "Locals", VARREF_LOCALS,
89 namedVariables: dap.variables.locals.GetSize(), expensive: false),
90 CreateScope(name: "Globals", VARREF_GLOBALS,
91 namedVariables: dap.variables.globals.GetSize(), expensive: false),
92 CreateScope(name: "Registers", VARREF_REGS,
93 namedVariables: dap.variables.registers.GetSize(), expensive: false)};
94
95 return ScopesResponseBody{.scopes: std::move(scopes)};
96}
97
98} // namespace lldb_dap
99

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