xref: /llvm-project/lldb/include/lldb/Target/PathMappingList.h (revision 8f8e2b732635f03dc646a3c98db0b58a051745b8)
1 //===-- PathMappingList.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_TARGET_PATHMAPPINGLIST_H
10 #define LLDB_TARGET_PATHMAPPINGLIST_H
11 
12 #include "lldb/Utility/ConstString.h"
13 #include "lldb/Utility/Status.h"
14 #include "llvm/Support/Error.h"
15 #include "llvm/Support/JSON.h"
16 #include <map>
17 #include <mutex>
18 #include <optional>
19 #include <vector>
20 
21 namespace lldb_private {
22 
23 class PathMappingList {
24 public:
25   typedef void (*ChangedCallback)(const PathMappingList &path_list,
26                                   void *baton);
27 
28   PathMappingList();
29 
30   PathMappingList(ChangedCallback callback, void *callback_baton);
31 
32   PathMappingList(const PathMappingList &rhs);
33 
34   ~PathMappingList();
35 
36   const PathMappingList &operator=(const PathMappingList &rhs);
37 
38   void Append(llvm::StringRef path, llvm::StringRef replacement, bool notify);
39 
40   void Append(const PathMappingList &rhs, bool notify);
41 
42   /// Append <path, replacement> pair without duplication.
43   /// \return whether appending suceeds without duplication or not.
44   bool AppendUnique(llvm::StringRef path, llvm::StringRef replacement,
45                     bool notify);
46 
47   void Clear(bool notify);
48 
49   // By default, dump all pairs.
50   void Dump(Stream *s, int pair_index = -1);
51 
52   llvm::json::Value ToJSON();
53 
54   bool IsEmpty() const {
55     std::lock_guard<std::mutex> lock(m_pairs_mutex);
56     return m_pairs.empty();
57   }
58 
59   size_t GetSize() const {
60     std::lock_guard<std::mutex> lock(m_pairs_mutex);
61     return m_pairs.size();
62   }
63 
64   bool GetPathsAtIndex(uint32_t idx, ConstString &path,
65                        ConstString &new_path) const;
66 
67   void Insert(llvm::StringRef path, llvm::StringRef replacement,
68               uint32_t insert_idx, bool notify);
69 
70   bool Remove(size_t index, bool notify);
71 
72   bool Remove(ConstString path, bool notify);
73 
74   bool Replace(llvm::StringRef path, llvm::StringRef replacement, bool notify);
75 
76   bool Replace(llvm::StringRef path, llvm::StringRef replacement,
77                uint32_t index, bool notify);
78   bool RemapPath(ConstString path, ConstString &new_path) const;
79 
80   /// Remaps a source file given \a path into \a new_path.
81   ///
82   /// Remaps \a path if any source remappings match. This function
83   /// does NOT stat the file system so it can be used in tight loops
84   /// where debug info is being parsed.
85   ///
86   /// \param[in] path
87   ///     The original source file path to try and remap.
88   ///
89   /// \param[in] only_if_exists
90   ///     If \b true, besides matching \p path with the remapping rules, this
91   ///     tries to check with the filesystem that the remapped file exists. If
92   ///     no valid file is found, \b std::nullopt is returned. This might be
93   ///     expensive, specially on a network.
94   ///
95   ///     If \b false, then the existence of the returned remapping is not
96   ///     checked.
97   ///
98   /// \return
99   ///     The remapped filespec that may or may not exist on disk.
100   std::optional<FileSpec> RemapPath(llvm::StringRef path,
101                                     bool only_if_exists = false) const;
102   bool RemapPath(const char *, std::string &) const = delete;
103 
104   /// Perform reverse source path remap for input \a file.
105   /// Source maps contains a list of <from_original_path, to_new_path> mappings.
106   /// Reverse remap means locating a matching entry prefix using "to_new_path"
107   /// part and replacing it with "from_original_path" part if found.
108   ///
109   /// \param[in] file
110   ///     The source path to reverse remap.
111   /// \param[in] fixed
112   ///     The reversed mapped new path.
113   ///
114   /// \return
115   ///     std::nullopt if no remapping happens, otherwise, the matching source
116   ///     map entry's ""to_new_pathto"" part (which is the prefix of \a file) is
117   ///     returned.
118   std::optional<llvm::StringRef> ReverseRemapPath(const FileSpec &file,
119                                                   FileSpec &fixed) const;
120 
121   /// Finds a source file given a file spec using the path remappings.
122   ///
123   /// Tries to resolve \a orig_spec by checking the path remappings.
124   /// It makes sure the file exists by checking with the file system,
125   /// so this call can be expensive if the remappings are on a network
126   /// or are even on the local file system, so use this function
127   /// sparingly (not in a tight debug info parsing loop).
128   ///
129   /// \param[in] orig_spec
130   ///     The original source file path to try and remap.
131   ///
132   /// \return
133   ///     The newly remapped filespec that is guaranteed to exist.
134   std::optional<FileSpec> FindFile(const FileSpec &orig_spec) const;
135 
136   uint32_t GetModificationID() const {
137     std::lock_guard<std::mutex> lock(m_pairs_mutex);
138     return m_mod_id;
139   }
140 
141 protected:
142   typedef std::pair<ConstString, ConstString> pair;
143   typedef std::vector<pair> collection;
144   typedef collection::iterator iterator;
145   typedef collection::const_iterator const_iterator;
146 
147   void AppendNoLock(llvm::StringRef path, llvm::StringRef replacement);
148   uint32_t FindIndexForPathNoLock(llvm::StringRef path) const;
149   void Notify(bool notify) const;
150 
151   iterator FindIteratorForPath(ConstString path);
152 
153   const_iterator FindIteratorForPath(ConstString path) const;
154 
155   collection m_pairs;
156   mutable std::mutex m_pairs_mutex;
157 
158   ChangedCallback m_callback = nullptr;
159   void *m_callback_baton = nullptr;
160   mutable std::mutex m_callback_mutex;
161 
162   /// Incremented anytime anything is added to or removed from m_pairs. Also
163   /// protected by m_pairs_mutex.
164   uint32_t m_mod_id = 0;
165 };
166 
167 } // namespace lldb_private
168 
169 #endif // LLDB_TARGET_PATHMAPPINGLIST_H
170