1//===-- FileSpecList.h ------------------------------------------*- 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#ifndef LLDB_CORE_FILESPECLIST_H
10#define LLDB_CORE_FILESPECLIST_H
11
12#include "lldb/Utility/FileSpec.h"
13#include "lldb/Utility/SupportFile.h"
14#include "lldb/lldb-forward.h"
15
16#include <cstddef>
17#include <vector>
18
19namespace lldb_private {
20class Stream;
21
22/// A list of support files for a CompileUnit.
23class SupportFileList {
24public:
25 SupportFileList(){};
26 SupportFileList(const SupportFileList &) = delete;
27 SupportFileList(SupportFileList &&other) = default;
28
29 typedef std::vector<std::shared_ptr<SupportFile>> collection;
30 typedef collection::const_iterator const_iterator;
31 const_iterator begin() const { return m_files.begin(); }
32 const_iterator end() const { return m_files.end(); }
33
34 void Append(const FileSpec &file) {
35 return Append(file: std::make_shared<SupportFile>(args: file));
36 }
37 void Append(std::shared_ptr<SupportFile> &&file) {
38 m_files.push_back(x: std::move(file));
39 }
40 // FIXME: Only used by SymbolFilePDB. Replace with a DenseSet at call site.
41 bool AppendIfUnique(const FileSpec &file);
42 size_t GetSize() const { return m_files.size(); }
43 const FileSpec &GetFileSpecAtIndex(size_t idx) const;
44 lldb::SupportFileSP GetSupportFileAtIndex(size_t idx) const;
45 size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const;
46 /// Find a compatible file index.
47 ///
48 /// Find the index of a compatible file in the file spec list that matches \a
49 /// file starting \a idx entries into the file spec list. A file is considered
50 /// compatible if:
51 /// - The file matches exactly (only filename if \a file has no directory)
52 /// - If \a file is relative and any file in the list has this same suffix
53 /// - If any file in the list is relative and the relative path is a suffix
54 /// of \a file
55 ///
56 /// This is used to implement better matching for setting breakpoints in
57 /// source files where an IDE might specify a full path when setting the
58 /// breakpoint and debug info contains relative paths, if a user specifies
59 /// a relative path when setting a breakpoint.
60 ///
61 /// \param[in] idx
62 /// An index into the file list.
63 ///
64 /// \param[in] file
65 /// The file specification to search for.
66 ///
67 /// \return
68 /// The index of the file that matches \a file if it is found,
69 /// else UINT32_MAX is returned.
70 size_t FindCompatibleIndex(size_t idx, const FileSpec &file) const;
71
72 template <class... Args> void EmplaceBack(Args &&...args) {
73 m_files.push_back(
74 std::make_shared<SupportFile>(std::forward<Args>(args)...));
75 }
76
77protected:
78 collection m_files; ///< A collection of FileSpec objects.
79};
80
81/// \class FileSpecList FileSpecList.h "lldb/Utility/FileSpecList.h"
82/// A file collection class.
83///
84/// A class that contains a mutable list of FileSpec objects.
85class FileSpecList {
86public:
87 typedef std::vector<FileSpec> collection;
88 typedef collection::const_iterator const_iterator;
89
90 /// Default constructor.
91 ///
92 /// Initialize this object with an empty file list.
93 FileSpecList();
94
95 /// Copy constructor.
96 FileSpecList(const FileSpecList &rhs) = default;
97
98 /// Move constructor
99 FileSpecList(FileSpecList &&rhs) = default;
100
101 /// Initialize this object from a vector of FileSpecs
102 FileSpecList(std::vector<FileSpec> &&rhs) : m_files(std::move(rhs)) {}
103
104 /// Destructor.
105 ~FileSpecList();
106
107 /// Assignment operator.
108 ///
109 /// Replace the file list in this object with the file list from \a rhs.
110 ///
111 /// \param[in] rhs
112 /// A file list object to copy.
113 ///
114 /// \return
115 /// A const reference to this object.
116 FileSpecList &operator=(const FileSpecList &rhs) = default;
117
118 /// Move-assignment operator.
119 FileSpecList &operator=(FileSpecList &&rhs) = default;
120
121 /// Append a FileSpec object to the list.
122 ///
123 /// Appends \a file to the end of the file list.
124 ///
125 /// \param[in] file
126 /// A new file to append to this file list.
127 void Append(const FileSpec &file);
128
129 /// Append a FileSpec object if unique.
130 ///
131 /// Appends \a file to the end of the file list if it doesn't already exist
132 /// in the file list.
133 ///
134 /// \param[in] file
135 /// A new file to append to this file list.
136 ///
137 /// \return
138 /// \b true if the file was appended, \b false otherwise.
139 bool AppendIfUnique(const FileSpec &file);
140
141 /// Inserts a new FileSpec into the FileSpecList constructed in-place with
142 /// the given arguments.
143 ///
144 /// \param[in] args
145 /// Arguments to create the FileSpec
146 template <class... Args> void EmplaceBack(Args &&...args) {
147 m_files.emplace_back(std::forward<Args>(args)...);
148 }
149
150 /// Clears the file list.
151 void Clear();
152
153 /// Dumps the file list to the supplied stream pointer "s".
154 ///
155 /// \param[in] s
156 /// The stream that will be used to dump the object description.
157 void Dump(Stream *s, const char *separator_cstr = "\n") const;
158
159 /// Find a file index.
160 ///
161 /// Find the index of the file in the file spec list that matches \a file
162 /// starting \a idx entries into the file spec list.
163 ///
164 /// \param[in] idx
165 /// An index into the file list.
166 ///
167 /// \param[in] file
168 /// The file specification to search for.
169 ///
170 /// \param[in] full
171 /// Should FileSpec::Equal be called with "full" true or false.
172 ///
173 /// \return
174 /// The index of the file that matches \a file if it is found,
175 /// else UINT32_MAX is returned.
176 size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const;
177
178 /// Get file at index.
179 ///
180 /// Gets a file from the file list. If \a idx is not a valid index, an empty
181 /// FileSpec object will be returned. The file objects that are returned can
182 /// be tested using FileSpec::operator void*().
183 ///
184 /// \param[in] idx
185 /// An index into the file list.
186 ///
187 /// \return
188 /// A copy of the FileSpec object at index \a idx. If \a idx
189 /// is out of range, then an empty FileSpec object will be
190 /// returned.
191 const FileSpec &GetFileSpecAtIndex(size_t idx) const;
192
193 /// Get the memory cost of this object.
194 ///
195 /// Return the size in bytes that this object takes in memory. This returns
196 /// the size in bytes of this object, not any shared string values it may
197 /// refer to.
198 ///
199 /// \return
200 /// The number of bytes that this object occupies in memory.
201 size_t MemorySize() const;
202
203 bool IsEmpty() const { return m_files.empty(); }
204
205 /// Get the number of files in the file list.
206 ///
207 /// \return
208 /// The number of files in the file spec list.
209 size_t GetSize() const;
210
211 bool Insert(size_t idx, const FileSpec &file) {
212 if (idx < m_files.size()) {
213 m_files.insert(position: m_files.begin() + idx, x: file);
214 return true;
215 } else if (idx == m_files.size()) {
216 m_files.push_back(x: file);
217 return true;
218 }
219 return false;
220 }
221
222 bool Replace(size_t idx, const FileSpec &file) {
223 if (idx < m_files.size()) {
224 m_files[idx] = file;
225 return true;
226 }
227 return false;
228 }
229
230 bool Remove(size_t idx) {
231 if (idx < m_files.size()) {
232 m_files.erase(position: m_files.begin() + idx);
233 return true;
234 }
235 return false;
236 }
237
238 const_iterator begin() const { return m_files.begin(); }
239 const_iterator end() const { return m_files.end(); }
240
241protected:
242 collection m_files; ///< A collection of FileSpec objects.
243};
244
245} // namespace lldb_private
246
247#endif // LLDB_CORE_FILESPECLIST_H
248

source code of lldb/include/lldb/Utility/FileSpecList.h