106c3fb27SDimitry Andric //===-- FileSpecList.h ------------------------------------------*- C++ -*-===// 206c3fb27SDimitry Andric // 306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 606c3fb27SDimitry Andric // 706c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 806c3fb27SDimitry Andric 906c3fb27SDimitry Andric #ifndef LLDB_CORE_FILESPECLIST_H 1006c3fb27SDimitry Andric #define LLDB_CORE_FILESPECLIST_H 1106c3fb27SDimitry Andric 1206c3fb27SDimitry Andric #include "lldb/Utility/FileSpec.h" 137a6dacacSDimitry Andric #include "lldb/Utility/SupportFile.h" 147a6dacacSDimitry Andric #include "lldb/lldb-forward.h" 1506c3fb27SDimitry Andric 1606c3fb27SDimitry Andric #include <cstddef> 1706c3fb27SDimitry Andric #include <vector> 1806c3fb27SDimitry Andric 1906c3fb27SDimitry Andric namespace lldb_private { 2006c3fb27SDimitry Andric class Stream; 2106c3fb27SDimitry Andric 221db9f3b2SDimitry Andric /// A list of support files for a CompileUnit. 231db9f3b2SDimitry Andric class SupportFileList { 241db9f3b2SDimitry Andric public: 251db9f3b2SDimitry Andric SupportFileList(){}; 261db9f3b2SDimitry Andric SupportFileList(const SupportFileList &) = delete; 271db9f3b2SDimitry Andric SupportFileList(SupportFileList &&other) = default; 281db9f3b2SDimitry Andric 297a6dacacSDimitry Andric typedef std::vector<std::shared_ptr<SupportFile>> collection; 301db9f3b2SDimitry Andric typedef collection::const_iterator const_iterator; 311db9f3b2SDimitry Andric const_iterator begin() const { return m_files.begin(); } 321db9f3b2SDimitry Andric const_iterator end() const { return m_files.end(); } 331db9f3b2SDimitry Andric 341db9f3b2SDimitry Andric void Append(const FileSpec &file) { 357a6dacacSDimitry Andric return Append(std::make_shared<SupportFile>(file)); 361db9f3b2SDimitry Andric } 377a6dacacSDimitry Andric void Append(std::shared_ptr<SupportFile> &&file) { 381db9f3b2SDimitry Andric m_files.push_back(std::move(file)); 391db9f3b2SDimitry Andric } 401db9f3b2SDimitry Andric // FIXME: Only used by SymbolFilePDB. Replace with a DenseSet at call site. 411db9f3b2SDimitry Andric bool AppendIfUnique(const FileSpec &file); 421db9f3b2SDimitry Andric size_t GetSize() const { return m_files.size(); } 431db9f3b2SDimitry Andric const FileSpec &GetFileSpecAtIndex(size_t idx) const; 447a6dacacSDimitry Andric lldb::SupportFileSP GetSupportFileAtIndex(size_t idx) const; 451db9f3b2SDimitry Andric size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const; 461db9f3b2SDimitry Andric /// Find a compatible file index. 471db9f3b2SDimitry Andric /// 481db9f3b2SDimitry Andric /// Find the index of a compatible file in the file spec list that matches \a 491db9f3b2SDimitry Andric /// file starting \a idx entries into the file spec list. A file is considered 501db9f3b2SDimitry Andric /// compatible if: 511db9f3b2SDimitry Andric /// - The file matches exactly (only filename if \a file has no directory) 521db9f3b2SDimitry Andric /// - If \a file is relative and any file in the list has this same suffix 531db9f3b2SDimitry Andric /// - If any file in the list is relative and the relative path is a suffix 541db9f3b2SDimitry Andric /// of \a file 551db9f3b2SDimitry Andric /// 561db9f3b2SDimitry Andric /// This is used to implement better matching for setting breakpoints in 571db9f3b2SDimitry Andric /// source files where an IDE might specify a full path when setting the 581db9f3b2SDimitry Andric /// breakpoint and debug info contains relative paths, if a user specifies 591db9f3b2SDimitry Andric /// a relative path when setting a breakpoint. 601db9f3b2SDimitry Andric /// 611db9f3b2SDimitry Andric /// \param[in] idx 621db9f3b2SDimitry Andric /// An index into the file list. 631db9f3b2SDimitry Andric /// 641db9f3b2SDimitry Andric /// \param[in] file 651db9f3b2SDimitry Andric /// The file specification to search for. 661db9f3b2SDimitry Andric /// 671db9f3b2SDimitry Andric /// \return 681db9f3b2SDimitry Andric /// The index of the file that matches \a file if it is found, 691db9f3b2SDimitry Andric /// else UINT32_MAX is returned. 701db9f3b2SDimitry Andric size_t FindCompatibleIndex(size_t idx, const FileSpec &file) const; 711db9f3b2SDimitry Andric 721db9f3b2SDimitry Andric template <class... Args> void EmplaceBack(Args &&...args) { 731db9f3b2SDimitry Andric m_files.push_back( 747a6dacacSDimitry Andric std::make_shared<SupportFile>(std::forward<Args>(args)...)); 751db9f3b2SDimitry Andric } 761db9f3b2SDimitry Andric 771db9f3b2SDimitry Andric protected: 781db9f3b2SDimitry Andric collection m_files; ///< A collection of FileSpec objects. 791db9f3b2SDimitry Andric }; 801db9f3b2SDimitry Andric 8106c3fb27SDimitry Andric /// \class FileSpecList FileSpecList.h "lldb/Utility/FileSpecList.h" 8206c3fb27SDimitry Andric /// A file collection class. 8306c3fb27SDimitry Andric /// 8406c3fb27SDimitry Andric /// A class that contains a mutable list of FileSpec objects. 8506c3fb27SDimitry Andric class FileSpecList { 8606c3fb27SDimitry Andric public: 8706c3fb27SDimitry Andric typedef std::vector<FileSpec> collection; 8806c3fb27SDimitry Andric typedef collection::const_iterator const_iterator; 8906c3fb27SDimitry Andric 9006c3fb27SDimitry Andric /// Default constructor. 9106c3fb27SDimitry Andric /// 9206c3fb27SDimitry Andric /// Initialize this object with an empty file list. 9306c3fb27SDimitry Andric FileSpecList(); 9406c3fb27SDimitry Andric 9506c3fb27SDimitry Andric /// Copy constructor. 9606c3fb27SDimitry Andric FileSpecList(const FileSpecList &rhs) = default; 9706c3fb27SDimitry Andric 9806c3fb27SDimitry Andric /// Move constructor 9906c3fb27SDimitry Andric FileSpecList(FileSpecList &&rhs) = default; 10006c3fb27SDimitry Andric 10106c3fb27SDimitry Andric /// Initialize this object from a vector of FileSpecs 10206c3fb27SDimitry Andric FileSpecList(std::vector<FileSpec> &&rhs) : m_files(std::move(rhs)) {} 10306c3fb27SDimitry Andric 10406c3fb27SDimitry Andric /// Destructor. 10506c3fb27SDimitry Andric ~FileSpecList(); 10606c3fb27SDimitry Andric 10706c3fb27SDimitry Andric /// Assignment operator. 10806c3fb27SDimitry Andric /// 10906c3fb27SDimitry Andric /// Replace the file list in this object with the file list from \a rhs. 11006c3fb27SDimitry Andric /// 11106c3fb27SDimitry Andric /// \param[in] rhs 11206c3fb27SDimitry Andric /// A file list object to copy. 11306c3fb27SDimitry Andric /// 11406c3fb27SDimitry Andric /// \return 11506c3fb27SDimitry Andric /// A const reference to this object. 11606c3fb27SDimitry Andric FileSpecList &operator=(const FileSpecList &rhs) = default; 11706c3fb27SDimitry Andric 11806c3fb27SDimitry Andric /// Move-assignment operator. 11906c3fb27SDimitry Andric FileSpecList &operator=(FileSpecList &&rhs) = default; 12006c3fb27SDimitry Andric 12106c3fb27SDimitry Andric /// Append a FileSpec object to the list. 12206c3fb27SDimitry Andric /// 12306c3fb27SDimitry Andric /// Appends \a file to the end of the file list. 12406c3fb27SDimitry Andric /// 12506c3fb27SDimitry Andric /// \param[in] file 12606c3fb27SDimitry Andric /// A new file to append to this file list. 12706c3fb27SDimitry Andric void Append(const FileSpec &file); 12806c3fb27SDimitry Andric 12906c3fb27SDimitry Andric /// Append a FileSpec object if unique. 13006c3fb27SDimitry Andric /// 13106c3fb27SDimitry Andric /// Appends \a file to the end of the file list if it doesn't already exist 13206c3fb27SDimitry Andric /// in the file list. 13306c3fb27SDimitry Andric /// 13406c3fb27SDimitry Andric /// \param[in] file 13506c3fb27SDimitry Andric /// A new file to append to this file list. 13606c3fb27SDimitry Andric /// 13706c3fb27SDimitry Andric /// \return 13806c3fb27SDimitry Andric /// \b true if the file was appended, \b false otherwise. 13906c3fb27SDimitry Andric bool AppendIfUnique(const FileSpec &file); 14006c3fb27SDimitry Andric 14106c3fb27SDimitry Andric /// Inserts a new FileSpec into the FileSpecList constructed in-place with 14206c3fb27SDimitry Andric /// the given arguments. 14306c3fb27SDimitry Andric /// 14406c3fb27SDimitry Andric /// \param[in] args 14506c3fb27SDimitry Andric /// Arguments to create the FileSpec 14606c3fb27SDimitry Andric template <class... Args> void EmplaceBack(Args &&...args) { 14706c3fb27SDimitry Andric m_files.emplace_back(std::forward<Args>(args)...); 14806c3fb27SDimitry Andric } 14906c3fb27SDimitry Andric 15006c3fb27SDimitry Andric /// Clears the file list. 15106c3fb27SDimitry Andric void Clear(); 15206c3fb27SDimitry Andric 15306c3fb27SDimitry Andric /// Dumps the file list to the supplied stream pointer "s". 15406c3fb27SDimitry Andric /// 15506c3fb27SDimitry Andric /// \param[in] s 15606c3fb27SDimitry Andric /// The stream that will be used to dump the object description. 15706c3fb27SDimitry Andric void Dump(Stream *s, const char *separator_cstr = "\n") const; 15806c3fb27SDimitry Andric 15906c3fb27SDimitry Andric /// Find a file index. 16006c3fb27SDimitry Andric /// 16106c3fb27SDimitry Andric /// Find the index of the file in the file spec list that matches \a file 16206c3fb27SDimitry Andric /// starting \a idx entries into the file spec list. 16306c3fb27SDimitry Andric /// 16406c3fb27SDimitry Andric /// \param[in] idx 16506c3fb27SDimitry Andric /// An index into the file list. 16606c3fb27SDimitry Andric /// 16706c3fb27SDimitry Andric /// \param[in] file 16806c3fb27SDimitry Andric /// The file specification to search for. 16906c3fb27SDimitry Andric /// 17006c3fb27SDimitry Andric /// \param[in] full 17106c3fb27SDimitry Andric /// Should FileSpec::Equal be called with "full" true or false. 17206c3fb27SDimitry Andric /// 17306c3fb27SDimitry Andric /// \return 17406c3fb27SDimitry Andric /// The index of the file that matches \a file if it is found, 17506c3fb27SDimitry Andric /// else UINT32_MAX is returned. 17606c3fb27SDimitry Andric size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const; 17706c3fb27SDimitry Andric 17806c3fb27SDimitry Andric /// Get file at index. 17906c3fb27SDimitry Andric /// 18006c3fb27SDimitry Andric /// Gets a file from the file list. If \a idx is not a valid index, an empty 18106c3fb27SDimitry Andric /// FileSpec object will be returned. The file objects that are returned can 18206c3fb27SDimitry Andric /// be tested using FileSpec::operator void*(). 18306c3fb27SDimitry Andric /// 18406c3fb27SDimitry Andric /// \param[in] idx 18506c3fb27SDimitry Andric /// An index into the file list. 18606c3fb27SDimitry Andric /// 18706c3fb27SDimitry Andric /// \return 18806c3fb27SDimitry Andric /// A copy of the FileSpec object at index \a idx. If \a idx 18906c3fb27SDimitry Andric /// is out of range, then an empty FileSpec object will be 19006c3fb27SDimitry Andric /// returned. 19106c3fb27SDimitry Andric const FileSpec &GetFileSpecAtIndex(size_t idx) const; 19206c3fb27SDimitry Andric 19306c3fb27SDimitry Andric /// Get the memory cost of this object. 19406c3fb27SDimitry Andric /// 19506c3fb27SDimitry Andric /// Return the size in bytes that this object takes in memory. This returns 19606c3fb27SDimitry Andric /// the size in bytes of this object, not any shared string values it may 19706c3fb27SDimitry Andric /// refer to. 19806c3fb27SDimitry Andric /// 19906c3fb27SDimitry Andric /// \return 20006c3fb27SDimitry Andric /// The number of bytes that this object occupies in memory. 20106c3fb27SDimitry Andric size_t MemorySize() const; 20206c3fb27SDimitry Andric 20306c3fb27SDimitry Andric bool IsEmpty() const { return m_files.empty(); } 20406c3fb27SDimitry Andric 20506c3fb27SDimitry Andric /// Get the number of files in the file list. 20606c3fb27SDimitry Andric /// 20706c3fb27SDimitry Andric /// \return 20806c3fb27SDimitry Andric /// The number of files in the file spec list. 20906c3fb27SDimitry Andric size_t GetSize() const; 21006c3fb27SDimitry Andric 21106c3fb27SDimitry Andric bool Insert(size_t idx, const FileSpec &file) { 21206c3fb27SDimitry Andric if (idx < m_files.size()) { 21306c3fb27SDimitry Andric m_files.insert(m_files.begin() + idx, file); 21406c3fb27SDimitry Andric return true; 21506c3fb27SDimitry Andric } else if (idx == m_files.size()) { 21606c3fb27SDimitry Andric m_files.push_back(file); 21706c3fb27SDimitry Andric return true; 21806c3fb27SDimitry Andric } 21906c3fb27SDimitry Andric return false; 22006c3fb27SDimitry Andric } 22106c3fb27SDimitry Andric 22206c3fb27SDimitry Andric bool Replace(size_t idx, const FileSpec &file) { 22306c3fb27SDimitry Andric if (idx < m_files.size()) { 22406c3fb27SDimitry Andric m_files[idx] = file; 22506c3fb27SDimitry Andric return true; 22606c3fb27SDimitry Andric } 22706c3fb27SDimitry Andric return false; 22806c3fb27SDimitry Andric } 22906c3fb27SDimitry Andric 23006c3fb27SDimitry Andric bool Remove(size_t idx) { 23106c3fb27SDimitry Andric if (idx < m_files.size()) { 23206c3fb27SDimitry Andric m_files.erase(m_files.begin() + idx); 23306c3fb27SDimitry Andric return true; 23406c3fb27SDimitry Andric } 23506c3fb27SDimitry Andric return false; 23606c3fb27SDimitry Andric } 23706c3fb27SDimitry Andric 23806c3fb27SDimitry Andric const_iterator begin() const { return m_files.begin(); } 23906c3fb27SDimitry Andric const_iterator end() const { return m_files.end(); } 24006c3fb27SDimitry Andric 241*0fca6ea1SDimitry Andric llvm::iterator_range<const_iterator> files() const { 242*0fca6ea1SDimitry Andric return llvm::make_range(begin(), end()); 243*0fca6ea1SDimitry Andric } 244*0fca6ea1SDimitry Andric 24506c3fb27SDimitry Andric protected: 24606c3fb27SDimitry Andric collection m_files; ///< A collection of FileSpec objects. 24706c3fb27SDimitry Andric }; 24806c3fb27SDimitry Andric 24906c3fb27SDimitry Andric } // namespace lldb_private 25006c3fb27SDimitry Andric 25106c3fb27SDimitry Andric #endif // LLDB_CORE_FILESPECLIST_H 252