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 19 namespace lldb_private { 20 class Stream; 21 22 /// A list of support files for a CompileUnit. 23 class SupportFileList { 24 public: 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(std::make_shared<SupportFile>(file)); 36 } 37 void Append(std::shared_ptr<SupportFile> &&file) { 38 m_files.push_back(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 /// \param[in] realpath_prefixes 68 /// Paths that start with one of the prefixes in this list will be 69 /// realpath'ed to resolve any symlinks. 70 /// 71 /// \return 72 /// The index of the file that matches \a file if it is found, 73 /// else UINT32_MAX is returned. 74 size_t 75 FindCompatibleIndex(size_t idx, const FileSpec &file, 76 RealpathPrefixes *realpath_prefixes = nullptr) const; 77 78 template <class... Args> void EmplaceBack(Args &&...args) { 79 m_files.push_back( 80 std::make_shared<SupportFile>(std::forward<Args>(args)...)); 81 } 82 83 protected: 84 collection m_files; ///< A collection of FileSpec objects. 85 }; 86 87 /// \class FileSpecList FileSpecList.h "lldb/Utility/FileSpecList.h" 88 /// A file collection class. 89 /// 90 /// A class that contains a mutable list of FileSpec objects. 91 class FileSpecList { 92 public: 93 typedef std::vector<FileSpec> collection; 94 typedef collection::const_iterator const_iterator; 95 96 /// Default constructor. 97 /// 98 /// Initialize this object with an empty file list. 99 FileSpecList(); 100 101 /// Copy constructor. 102 FileSpecList(const FileSpecList &rhs) = default; 103 104 /// Move constructor 105 FileSpecList(FileSpecList &&rhs) = default; 106 107 /// Initialize this object from a vector of FileSpecs 108 FileSpecList(std::vector<FileSpec> &&rhs) : m_files(std::move(rhs)) {} 109 110 /// Destructor. 111 ~FileSpecList(); 112 113 /// Assignment operator. 114 /// 115 /// Replace the file list in this object with the file list from \a rhs. 116 /// 117 /// \param[in] rhs 118 /// A file list object to copy. 119 /// 120 /// \return 121 /// A const reference to this object. 122 FileSpecList &operator=(const FileSpecList &rhs) = default; 123 124 /// Move-assignment operator. 125 FileSpecList &operator=(FileSpecList &&rhs) = default; 126 127 /// Append a FileSpec object to the list. 128 /// 129 /// Appends \a file to the end of the file list. 130 /// 131 /// \param[in] file 132 /// A new file to append to this file list. 133 void Append(const FileSpec &file); 134 135 /// Append a FileSpec object if unique. 136 /// 137 /// Appends \a file to the end of the file list if it doesn't already exist 138 /// in the file list. 139 /// 140 /// \param[in] file 141 /// A new file to append to this file list. 142 /// 143 /// \return 144 /// \b true if the file was appended, \b false otherwise. 145 bool AppendIfUnique(const FileSpec &file); 146 147 /// Inserts a new FileSpec into the FileSpecList constructed in-place with 148 /// the given arguments. 149 /// 150 /// \param[in] args 151 /// Arguments to create the FileSpec 152 template <class... Args> void EmplaceBack(Args &&...args) { 153 m_files.emplace_back(std::forward<Args>(args)...); 154 } 155 156 /// Clears the file list. 157 void Clear(); 158 159 /// Dumps the file list to the supplied stream pointer "s". 160 /// 161 /// \param[in] s 162 /// The stream that will be used to dump the object description. 163 void Dump(Stream *s, const char *separator_cstr = "\n") const; 164 165 /// Find a file index. 166 /// 167 /// Find the index of the file in the file spec list that matches \a file 168 /// starting \a idx entries into the file spec list. 169 /// 170 /// \param[in] idx 171 /// An index into the file list. 172 /// 173 /// \param[in] file 174 /// The file specification to search for. 175 /// 176 /// \param[in] full 177 /// Should FileSpec::Equal be called with "full" true or false. 178 /// 179 /// \return 180 /// The index of the file that matches \a file if it is found, 181 /// else UINT32_MAX is returned. 182 size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const; 183 184 /// Get file at index. 185 /// 186 /// Gets a file from the file list. If \a idx is not a valid index, an empty 187 /// FileSpec object will be returned. The file objects that are returned can 188 /// be tested using FileSpec::operator void*(). 189 /// 190 /// \param[in] idx 191 /// An index into the file list. 192 /// 193 /// \return 194 /// A copy of the FileSpec object at index \a idx. If \a idx 195 /// is out of range, then an empty FileSpec object will be 196 /// returned. 197 const FileSpec &GetFileSpecAtIndex(size_t idx) const; 198 199 /// Get the memory cost of this object. 200 /// 201 /// Return the size in bytes that this object takes in memory. This returns 202 /// the size in bytes of this object, not any shared string values it may 203 /// refer to. 204 /// 205 /// \return 206 /// The number of bytes that this object occupies in memory. 207 size_t MemorySize() const; 208 209 bool IsEmpty() const { return m_files.empty(); } 210 211 /// Get the number of files in the file list. 212 /// 213 /// \return 214 /// The number of files in the file spec list. 215 size_t GetSize() const; 216 217 bool Insert(size_t idx, const FileSpec &file) { 218 if (idx < m_files.size()) { 219 m_files.insert(m_files.begin() + idx, file); 220 return true; 221 } else if (idx == m_files.size()) { 222 m_files.push_back(file); 223 return true; 224 } 225 return false; 226 } 227 228 bool Replace(size_t idx, const FileSpec &file) { 229 if (idx < m_files.size()) { 230 m_files[idx] = file; 231 return true; 232 } 233 return false; 234 } 235 236 bool Remove(size_t idx) { 237 if (idx < m_files.size()) { 238 m_files.erase(m_files.begin() + idx); 239 return true; 240 } 241 return false; 242 } 243 244 const_iterator begin() const { return m_files.begin(); } 245 const_iterator end() const { return m_files.end(); } 246 247 llvm::iterator_range<const_iterator> files() const { 248 return llvm::make_range(begin(), end()); 249 } 250 251 protected: 252 collection m_files; ///< A collection of FileSpec objects. 253 }; 254 255 } // namespace lldb_private 256 257 #endif // LLDB_CORE_FILESPECLIST_H 258