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