xref: /freebsd-src/contrib/llvm-project/lldb/include/lldb/Utility/FileSpecList.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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