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
16using namespace lldb;
17using namespace lldb_private;
18
19// VariableList constructor
20VariableList::VariableList() : m_variables() {}
21
22// Destructor
23VariableList::~VariableList() = default;
24
25void VariableList::AddVariable(const VariableSP &var_sp) {
26  m_variables.push_back(var_sp);
27}
28
29bool 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
37void 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
45void VariableList::Clear() { m_variables.clear(); }
46
47VariableSP 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
54VariableSP 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
63uint32_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
72VariableSP 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
87VariableSP 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
103size_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
111size_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
128size_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
145uint32_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
157size_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
165size_t VariableList::GetSize() const { return m_variables.size(); }
166
167void 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