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: SupportFileList()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; begin()31 const_iterator begin() const { return m_files.begin(); } end()32 const_iterator end() const { return m_files.end(); } 33 Append(const FileSpec & file)34 void Append(const FileSpec &file) { 35 return Append(std::make_shared<SupportFile>(file)); 36 } Append(std::shared_ptr<SupportFile> && file)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); GetSize()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 EmplaceBack(Args &&...args)72 template <class... Args> void EmplaceBack(Args &&...args) { 73 m_files.push_back( 74 std::make_shared<SupportFile>(std::forward<Args>(args)...)); 75 } 76 77 protected: 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. 85 class FileSpecList { 86 public: 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 FileSpecList(std::vector<FileSpec> && rhs)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 EmplaceBack(Args &&...args)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 IsEmpty()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 Insert(size_t idx,const FileSpec & file)211 bool Insert(size_t idx, const FileSpec &file) { 212 if (idx < m_files.size()) { 213 m_files.insert(m_files.begin() + idx, file); 214 return true; 215 } else if (idx == m_files.size()) { 216 m_files.push_back(file); 217 return true; 218 } 219 return false; 220 } 221 Replace(size_t idx,const FileSpec & file)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 Remove(size_t idx)230 bool Remove(size_t idx) { 231 if (idx < m_files.size()) { 232 m_files.erase(m_files.begin() + idx); 233 return true; 234 } 235 return false; 236 } 237 begin()238 const_iterator begin() const { return m_files.begin(); } end()239 const_iterator end() const { return m_files.end(); } 240 files()241 llvm::iterator_range<const_iterator> files() const { 242 return llvm::make_range(begin(), end()); 243 } 244 245 protected: 246 collection m_files; ///< A collection of FileSpec objects. 247 }; 248 249 } // namespace lldb_private 250 251 #endif // LLDB_CORE_FILESPECLIST_H 252