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