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
12using namespace lldb_dap;
13
14lldb::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
27void Variables::Clear() {
28 locals.Clear();
29 globals.Clear();
30 registers.Clear();
31 m_referencedvariables.clear();
32}
33
34int64_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
40bool Variables::IsPermanentVariableReference(int64_t var_ref) {
41 return var_ref >= PermanentVariableStartIndex;
42}
43
44lldb::SBValue Variables::GetVariable(int64_t var_ref) const {
45 if (IsPermanentVariableReference(var_ref)) {
46 auto pos = m_referencedpermanent_variables.find(Val: var_ref);
47 if (pos != m_referencedpermanent_variables.end())
48 return pos->second;
49 } else {
50 auto pos = m_referencedvariables.find(Val: var_ref);
51 if (pos != m_referencedvariables.end())
52 return pos->second;
53 }
54 return lldb::SBValue();
55}
56
57int64_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(KV: std::make_pair(x&: var_ref, y&: variable));
61 else
62 m_referencedvariables.insert(KV: std::make_pair(x&: var_ref, y&: variable));
63 return var_ref;
64}
65
66lldb::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(Other: " @");
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(idx: i);
78 std::string variable_name = CreateUniqueVariableNameForDisplay(
79 v&: curr_variable, is_name_duplicated: 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(var_ref: variablesReference);
92 variable = container.GetChildMemberWithName(name: name.data());
93 if (!variable.IsValid()) {
94 if (name.starts_with(Prefix: "[")) {
95 llvm::StringRef index_str(name.drop_front(N: 1));
96 uint64_t index = 0;
97 if (!index_str.consumeInteger(Radix: 0, Result&: index)) {
98 if (index_str == "]")
99 variable = container.GetChildAtIndex(idx: index);
100 }
101 }
102 }
103 }
104 return variable;
105}
106

source code of lldb/tools/lldb-dap/Variables.cpp