1 //===-- VariableList.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 "lldb/Symbol/VariableList.h"
10 
11 #include "lldb/Symbol/Block.h"
12 #include "lldb/Symbol/CompileUnit.h"
13 #include "lldb/Symbol/Function.h"
14 #include "lldb/Utility/RegularExpression.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 
19 // VariableList constructor
VariableList()20 VariableList::VariableList() : m_variables() {}
21 
22 // Destructor
23 VariableList::~VariableList() = default;
24 
AddVariable(const VariableSP & var_sp)25 void VariableList::AddVariable(const VariableSP &var_sp) {
26   m_variables.push_back(var_sp);
27 }
28 
AddVariableIfUnique(const lldb::VariableSP & var_sp)29 bool VariableList::AddVariableIfUnique(const lldb::VariableSP &var_sp) {
30   if (FindVariableIndex(var_sp) == UINT32_MAX) {
31     m_variables.push_back(var_sp);
32     return true;
33   }
34   return false;
35 }
36 
AddVariables(VariableList * variable_list)37 void VariableList::AddVariables(VariableList *variable_list) {
38   if (variable_list) {
39     std::copy(variable_list->m_variables.begin(), // source begin
40               variable_list->m_variables.end(),   // source end
41               back_inserter(m_variables));        // destination
42   }
43 }
44 
Clear()45 void VariableList::Clear() { m_variables.clear(); }
46 
GetVariableAtIndex(size_t idx) const47 VariableSP VariableList::GetVariableAtIndex(size_t idx) const {
48   VariableSP var_sp;
49   if (idx < m_variables.size())
50     var_sp = m_variables[idx];
51   return var_sp;
52 }
53 
RemoveVariableAtIndex(size_t idx)54 VariableSP VariableList::RemoveVariableAtIndex(size_t idx) {
55   VariableSP var_sp;
56   if (idx < m_variables.size()) {
57     var_sp = m_variables[idx];
58     m_variables.erase(m_variables.begin() + idx);
59   }
60   return var_sp;
61 }
62 
FindVariableIndex(const VariableSP & var_sp)63 uint32_t VariableList::FindVariableIndex(const VariableSP &var_sp) {
64   iterator pos, end = m_variables.end();
65   for (pos = m_variables.begin(); pos != end; ++pos) {
66     if (pos->get() == var_sp.get())
67       return std::distance(m_variables.begin(), pos);
68   }
69   return UINT32_MAX;
70 }
71 
FindVariable(ConstString name,bool include_static_members)72 VariableSP VariableList::FindVariable(ConstString name,
73                                       bool include_static_members) {
74   VariableSP var_sp;
75   iterator pos, end = m_variables.end();
76   for (pos = m_variables.begin(); pos != end; ++pos) {
77     if ((*pos)->NameMatches(name)) {
78       if (include_static_members || !(*pos)->IsStaticMember()) {
79         var_sp = (*pos);
80         break;
81       }
82     }
83   }
84   return var_sp;
85 }
86 
FindVariable(ConstString name,lldb::ValueType value_type,bool include_static_members)87 VariableSP VariableList::FindVariable(ConstString name,
88                                       lldb::ValueType value_type,
89                                       bool include_static_members) {
90   VariableSP var_sp;
91   iterator pos, end = m_variables.end();
92   for (pos = m_variables.begin(); pos != end; ++pos) {
93     if ((*pos)->NameMatches(name) && (*pos)->GetScope() == value_type) {
94       if (include_static_members || !(*pos)->IsStaticMember()) {
95         var_sp = (*pos);
96         break;
97       }
98     }
99   }
100   return var_sp;
101 }
102 
AppendVariablesIfUnique(VariableList & var_list)103 size_t VariableList::AppendVariablesIfUnique(VariableList &var_list) {
104   const size_t initial_size = var_list.GetSize();
105   iterator pos, end = m_variables.end();
106   for (pos = m_variables.begin(); pos != end; ++pos)
107     var_list.AddVariableIfUnique(*pos);
108   return var_list.GetSize() - initial_size;
109 }
110 
AppendVariablesIfUnique(const RegularExpression & regex,VariableList & var_list,size_t & total_matches)111 size_t VariableList::AppendVariablesIfUnique(const RegularExpression &regex,
112                                              VariableList &var_list,
113                                              size_t &total_matches) {
114   const size_t initial_size = var_list.GetSize();
115   iterator pos, end = m_variables.end();
116   for (pos = m_variables.begin(); pos != end; ++pos) {
117     if ((*pos)->NameMatches(regex)) {
118       // Note the total matches found
119       total_matches++;
120       // Only add this variable if it isn't already in the "var_list"
121       var_list.AddVariableIfUnique(*pos);
122     }
123   }
124   // Return the number of new unique variables added to "var_list"
125   return var_list.GetSize() - initial_size;
126 }
127 
AppendVariablesWithScope(lldb::ValueType type,VariableList & var_list,bool if_unique)128 size_t VariableList::AppendVariablesWithScope(lldb::ValueType type,
129                                               VariableList &var_list,
130                                               bool if_unique) {
131   const size_t initial_size = var_list.GetSize();
132   iterator pos, end = m_variables.end();
133   for (pos = m_variables.begin(); pos != end; ++pos) {
134     if ((*pos)->GetScope() == type) {
135       if (if_unique)
136         var_list.AddVariableIfUnique(*pos);
137       else
138         var_list.AddVariable(*pos);
139     }
140   }
141   // Return the number of new unique variables added to "var_list"
142   return var_list.GetSize() - initial_size;
143 }
144 
FindIndexForVariable(Variable * variable)145 uint32_t VariableList::FindIndexForVariable(Variable *variable) {
146   VariableSP var_sp;
147   iterator pos;
148   const iterator begin = m_variables.begin();
149   const iterator end = m_variables.end();
150   for (pos = m_variables.begin(); pos != end; ++pos) {
151     if ((*pos).get() == variable)
152       return std::distance(begin, pos);
153   }
154   return UINT32_MAX;
155 }
156 
MemorySize() const157 size_t VariableList::MemorySize() const {
158   size_t mem_size = sizeof(VariableList);
159   const_iterator pos, end = m_variables.end();
160   for (pos = m_variables.begin(); pos != end; ++pos)
161     mem_size += (*pos)->MemorySize();
162   return mem_size;
163 }
164 
GetSize() const165 size_t VariableList::GetSize() const { return m_variables.size(); }
166 
Dump(Stream * s,bool show_context) const167 void VariableList::Dump(Stream *s, bool show_context) const {
168   //  s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
169   //  s.Indent();
170   //  s << "VariableList\n";
171 
172   const_iterator pos, end = m_variables.end();
173   for (pos = m_variables.begin(); pos != end; ++pos) {
174     (*pos)->Dump(s, show_context);
175   }
176 }
177