Skip to content

Commit 3d0c616

Browse files
authored
[lldb-dap] Move the Variables struct into its own file (#140393)
Move the Variables struct out of DAP.h and into its own file to reduce the complexity of the latter. This PR also makes the members that are implementation details private and adds a handful of basic unit tests.
1 parent 5ab3c52 commit 3d0c616

File tree

7 files changed

+264
-143
lines changed

7 files changed

+264
-143
lines changed

lldb/tools/lldb-dap/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ add_lldb_library(lldbDAP
2323
RunInTerminal.cpp
2424
SourceBreakpoint.cpp
2525
Transport.cpp
26+
Variables.cpp
2627
Watchpoint.cpp
2728

2829
Handler/ResponseHandler.cpp

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,45 +1017,6 @@ lldb::SBError DAP::WaitForProcessToStop(std::chrono::seconds seconds) {
10171017
return error;
10181018
}
10191019

1020-
void Variables::Clear() {
1021-
locals.Clear();
1022-
globals.Clear();
1023-
registers.Clear();
1024-
referenced_variables.clear();
1025-
}
1026-
1027-
int64_t Variables::GetNewVariableReference(bool is_permanent) {
1028-
if (is_permanent)
1029-
return next_permanent_var_ref++;
1030-
return next_temporary_var_ref++;
1031-
}
1032-
1033-
bool Variables::IsPermanentVariableReference(int64_t var_ref) {
1034-
return var_ref >= PermanentVariableStartIndex;
1035-
}
1036-
1037-
lldb::SBValue Variables::GetVariable(int64_t var_ref) const {
1038-
if (IsPermanentVariableReference(var_ref)) {
1039-
auto pos = referenced_permanent_variables.find(var_ref);
1040-
if (pos != referenced_permanent_variables.end())
1041-
return pos->second;
1042-
} else {
1043-
auto pos = referenced_variables.find(var_ref);
1044-
if (pos != referenced_variables.end())
1045-
return pos->second;
1046-
}
1047-
return lldb::SBValue();
1048-
}
1049-
1050-
int64_t Variables::InsertVariable(lldb::SBValue variable, bool is_permanent) {
1051-
int64_t var_ref = GetNewVariableReference(is_permanent);
1052-
if (is_permanent)
1053-
referenced_permanent_variables.insert(std::make_pair(var_ref, variable));
1054-
else
1055-
referenced_variables.insert(std::make_pair(var_ref, variable));
1056-
return var_ref;
1057-
}
1058-
10591020
bool StartDebuggingRequestHandler::DoExecute(
10601021
lldb::SBDebugger debugger, char **command,
10611022
lldb::SBCommandReturnObject &result) {
@@ -1292,60 +1253,6 @@ DAP::GetInstructionBPFromStopReason(lldb::SBThread &thread) {
12921253
return inst_bp;
12931254
}
12941255

1295-
lldb::SBValueList *Variables::GetTopLevelScope(int64_t variablesReference) {
1296-
switch (variablesReference) {
1297-
case VARREF_LOCALS:
1298-
return &locals;
1299-
case VARREF_GLOBALS:
1300-
return &globals;
1301-
case VARREF_REGS:
1302-
return &registers;
1303-
default:
1304-
return nullptr;
1305-
}
1306-
}
1307-
1308-
lldb::SBValue Variables::FindVariable(uint64_t variablesReference,
1309-
llvm::StringRef name) {
1310-
lldb::SBValue variable;
1311-
if (lldb::SBValueList *top_scope = GetTopLevelScope(variablesReference)) {
1312-
bool is_duplicated_variable_name = name.contains(" @");
1313-
// variablesReference is one of our scopes, not an actual variable it is
1314-
// asking for a variable in locals or globals or registers
1315-
int64_t end_idx = top_scope->GetSize();
1316-
// Searching backward so that we choose the variable in closest scope
1317-
// among variables of the same name.
1318-
for (int64_t i = end_idx - 1; i >= 0; --i) {
1319-
lldb::SBValue curr_variable = top_scope->GetValueAtIndex(i);
1320-
std::string variable_name = CreateUniqueVariableNameForDisplay(
1321-
curr_variable, is_duplicated_variable_name);
1322-
if (variable_name == name) {
1323-
variable = curr_variable;
1324-
break;
1325-
}
1326-
}
1327-
} else {
1328-
// This is not under the globals or locals scope, so there are no
1329-
// duplicated names.
1330-
1331-
// We have a named item within an actual variable so we need to find it
1332-
// withing the container variable by name.
1333-
lldb::SBValue container = GetVariable(variablesReference);
1334-
variable = container.GetChildMemberWithName(name.data());
1335-
if (!variable.IsValid()) {
1336-
if (name.starts_with("[")) {
1337-
llvm::StringRef index_str(name.drop_front(1));
1338-
uint64_t index = 0;
1339-
if (!index_str.consumeInteger(0, index)) {
1340-
if (index_str == "]")
1341-
variable = container.GetChildAtIndex(index);
1342-
}
1343-
}
1344-
}
1345-
}
1346-
return variable;
1347-
}
1348-
13491256
protocol::Capabilities DAP::GetCapabilities() {
13501257
protocol::Capabilities capabilities;
13511258

lldb/tools/lldb-dap/DAP.h

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "Protocol/ProtocolTypes.h"
2121
#include "SourceBreakpoint.h"
2222
#include "Transport.h"
23+
#include "Variables.h"
2324
#include "lldb/API/SBBroadcaster.h"
2425
#include "lldb/API/SBCommandInterpreter.h"
2526
#include "lldb/API/SBDebugger.h"
@@ -30,8 +31,6 @@
3031
#include "lldb/API/SBMutex.h"
3132
#include "lldb/API/SBTarget.h"
3233
#include "lldb/API/SBThread.h"
33-
#include "lldb/API/SBValue.h"
34-
#include "lldb/API/SBValueList.h"
3534
#include "lldb/lldb-types.h"
3635
#include "llvm/ADT/DenseMap.h"
3736
#include "llvm/ADT/DenseSet.h"
@@ -52,10 +51,6 @@
5251
#include <thread>
5352
#include <vector>
5453

55-
#define VARREF_LOCALS (int64_t)1
56-
#define VARREF_GLOBALS (int64_t)2
57-
#define VARREF_REGS (int64_t)3
58-
#define VARREF_FIRST_VAR_IDX (int64_t)4
5954
#define NO_TYPENAME "<no-type>"
6055

6156
namespace lldb_dap {
@@ -88,50 +83,6 @@ enum class PacketStatus {
8883

8984
enum class ReplMode { Variable = 0, Command, Auto };
9085

91-
struct Variables {
92-
/// Variable_reference start index of permanent expandable variable.
93-
static constexpr int64_t PermanentVariableStartIndex = (1ll << 32);
94-
95-
lldb::SBValueList locals;
96-
lldb::SBValueList globals;
97-
lldb::SBValueList registers;
98-
99-
int64_t next_temporary_var_ref{VARREF_FIRST_VAR_IDX};
100-
int64_t next_permanent_var_ref{PermanentVariableStartIndex};
101-
102-
/// Variables that are alive in this stop state.
103-
/// Will be cleared when debuggee resumes.
104-
llvm::DenseMap<int64_t, lldb::SBValue> referenced_variables;
105-
/// Variables that persist across entire debug session.
106-
/// These are the variables evaluated from debug console REPL.
107-
llvm::DenseMap<int64_t, lldb::SBValue> referenced_permanent_variables;
108-
109-
/// Check if \p var_ref points to a variable that should persist for the
110-
/// entire duration of the debug session, e.g. repl expandable variables
111-
static bool IsPermanentVariableReference(int64_t var_ref);
112-
113-
/// \return a new variableReference.
114-
/// Specify is_permanent as true for variable that should persist entire
115-
/// debug session.
116-
int64_t GetNewVariableReference(bool is_permanent);
117-
118-
/// \return the expandable variable corresponding with variableReference
119-
/// value of \p value.
120-
/// If \p var_ref is invalid an empty SBValue is returned.
121-
lldb::SBValue GetVariable(int64_t var_ref) const;
122-
123-
/// Insert a new \p variable.
124-
/// \return variableReference assigned to this expandable variable.
125-
int64_t InsertVariable(lldb::SBValue variable, bool is_permanent);
126-
127-
lldb::SBValueList *GetTopLevelScope(int64_t variablesReference);
128-
129-
lldb::SBValue FindVariable(uint64_t variablesReference, llvm::StringRef name);
130-
131-
/// Clear all scope variables and non-permanent expandable variables.
132-
void Clear();
133-
};
134-
13586
struct StartDebuggingRequestHandler : public lldb::SBCommandPluginInterface {
13687
DAP &dap;
13788
explicit StartDebuggingRequestHandler(DAP &d) : dap(d) {};

lldb/tools/lldb-dap/Variables.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//===-- Variables.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 "Variables.h"
10+
#include "JSONUtils.h"
11+
12+
using namespace lldb_dap;
13+
14+
lldb::SBValueList *Variables::GetTopLevelScope(int64_t variablesReference) {
15+
switch (variablesReference) {
16+
case VARREF_LOCALS:
17+
return &locals;
18+
case VARREF_GLOBALS:
19+
return &globals;
20+
case VARREF_REGS:
21+
return &registers;
22+
default:
23+
return nullptr;
24+
}
25+
}
26+
27+
void Variables::Clear() {
28+
locals.Clear();
29+
globals.Clear();
30+
registers.Clear();
31+
m_referencedvariables.clear();
32+
}
33+
34+
int64_t Variables::GetNewVariableReference(bool is_permanent) {
35+
if (is_permanent)
36+
return m_next_permanent_var_ref++;
37+
return m_next_temporary_var_ref++;
38+
}
39+
40+
bool Variables::IsPermanentVariableReference(int64_t var_ref) {
41+
return var_ref >= PermanentVariableStartIndex;
42+
}
43+
44+
lldb::SBValue Variables::GetVariable(int64_t var_ref) const {
45+
if (IsPermanentVariableReference(var_ref)) {
46+
auto pos = m_referencedpermanent_variables.find(var_ref);
47+
if (pos != m_referencedpermanent_variables.end())
48+
return pos->second;
49+
} else {
50+
auto pos = m_referencedvariables.find(var_ref);
51+
if (pos != m_referencedvariables.end())
52+
return pos->second;
53+
}
54+
return lldb::SBValue();
55+
}
56+
57+
int64_t Variables::InsertVariable(lldb::SBValue variable, bool is_permanent) {
58+
int64_t var_ref = GetNewVariableReference(is_permanent);
59+
if (is_permanent)
60+
m_referencedpermanent_variables.insert(std::make_pair(var_ref, variable));
61+
else
62+
m_referencedvariables.insert(std::make_pair(var_ref, variable));
63+
return var_ref;
64+
}
65+
66+
lldb::SBValue Variables::FindVariable(uint64_t variablesReference,
67+
llvm::StringRef name) {
68+
lldb::SBValue variable;
69+
if (lldb::SBValueList *top_scope = GetTopLevelScope(variablesReference)) {
70+
bool is_duplicated_variable_name = name.contains(" @");
71+
// variablesReference is one of our scopes, not an actual variable it is
72+
// asking for a variable in locals or globals or registers
73+
int64_t end_idx = top_scope->GetSize();
74+
// Searching backward so that we choose the variable in closest scope
75+
// among variables of the same name.
76+
for (int64_t i = end_idx - 1; i >= 0; --i) {
77+
lldb::SBValue curr_variable = top_scope->GetValueAtIndex(i);
78+
std::string variable_name = CreateUniqueVariableNameForDisplay(
79+
curr_variable, is_duplicated_variable_name);
80+
if (variable_name == name) {
81+
variable = curr_variable;
82+
break;
83+
}
84+
}
85+
} else {
86+
// This is not under the globals or locals scope, so there are no
87+
// duplicated names.
88+
89+
// We have a named item within an actual variable so we need to find it
90+
// withing the container variable by name.
91+
lldb::SBValue container = GetVariable(variablesReference);
92+
variable = container.GetChildMemberWithName(name.data());
93+
if (!variable.IsValid()) {
94+
if (name.starts_with("[")) {
95+
llvm::StringRef index_str(name.drop_front(1));
96+
uint64_t index = 0;
97+
if (!index_str.consumeInteger(0, index)) {
98+
if (index_str == "]")
99+
variable = container.GetChildAtIndex(index);
100+
}
101+
}
102+
}
103+
}
104+
return variable;
105+
}

lldb/tools/lldb-dap/Variables.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//===-- Variables.h -----------------------------------------------------*-===//
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+
#ifndef LLDB_TOOLS_LLDB_DAP_VARIABLES_H
10+
#define LLDB_TOOLS_LLDB_DAP_VARIABLES_H
11+
12+
#include "lldb/API/SBValue.h"
13+
#include "lldb/API/SBValueList.h"
14+
#include "llvm/ADT/DenseMap.h"
15+
16+
#define VARREF_FIRST_VAR_IDX (int64_t)4
17+
#define VARREF_LOCALS (int64_t)1
18+
#define VARREF_GLOBALS (int64_t)2
19+
#define VARREF_REGS (int64_t)3
20+
21+
namespace lldb_dap {
22+
23+
struct Variables {
24+
lldb::SBValueList locals;
25+
lldb::SBValueList globals;
26+
lldb::SBValueList registers;
27+
28+
/// Check if \p var_ref points to a variable that should persist for the
29+
/// entire duration of the debug session, e.g. repl expandable variables
30+
static bool IsPermanentVariableReference(int64_t var_ref);
31+
32+
/// \return a new variableReference.
33+
/// Specify is_permanent as true for variable that should persist entire
34+
/// debug session.
35+
int64_t GetNewVariableReference(bool is_permanent);
36+
37+
/// \return the expandable variable corresponding with variableReference
38+
/// value of \p value.
39+
/// If \p var_ref is invalid an empty SBValue is returned.
40+
lldb::SBValue GetVariable(int64_t var_ref) const;
41+
42+
/// Insert a new \p variable.
43+
/// \return variableReference assigned to this expandable variable.
44+
int64_t InsertVariable(lldb::SBValue variable, bool is_permanent);
45+
46+
lldb::SBValueList *GetTopLevelScope(int64_t variablesReference);
47+
48+
lldb::SBValue FindVariable(uint64_t variablesReference, llvm::StringRef name);
49+
50+
/// Clear all scope variables and non-permanent expandable variables.
51+
void Clear();
52+
53+
private:
54+
/// Variable_reference start index of permanent expandable variable.
55+
static constexpr int64_t PermanentVariableStartIndex = (1ll << 32);
56+
57+
/// Variables that are alive in this stop state.
58+
/// Will be cleared when debuggee resumes.
59+
llvm::DenseMap<int64_t, lldb::SBValue> m_referencedvariables;
60+
61+
/// Variables that persist across entire debug session.
62+
/// These are the variables evaluated from debug console REPL.
63+
llvm::DenseMap<int64_t, lldb::SBValue> m_referencedpermanent_variables;
64+
65+
int64_t m_next_temporary_var_ref{VARREF_FIRST_VAR_IDX};
66+
int64_t m_next_permanent_var_ref{PermanentVariableStartIndex};
67+
};
68+
69+
} // namespace lldb_dap
70+
71+
#endif

lldb/unittests/DAP/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_lldb_unittest(DAPTests
66
ProtocolTypesTest.cpp
77
TestBase.cpp
88
TransportTest.cpp
9+
VariablesTest.cpp
910

1011
LINK_LIBS
1112
lldbDAP

0 commit comments

Comments
 (0)