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/JSON.h" 15#include <map> 16#include <mutex> 17#include <optional> 18#include <vector> 19 20namespace lldb_private { 21 22class PathMappingList { 23public: 24 typedef void (*ChangedCallback)(const PathMappingList &path_list, 25 void *baton); 26 27 // Constructors and Destructors 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::recursive_mutex> lock(m_mutex); 56 return m_pairs.empty(); 57 } 58 59 size_t GetSize() const { 60 std::lock_guard<std::recursive_mutex> lock(m_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 FindIndexForPath(llvm::StringRef path) const; 137 138 uint32_t GetModificationID() const { 139 std::lock_guard<std::recursive_mutex> lock(m_mutex); 140 return m_mod_id; 141 } 142 143protected: 144 mutable std::recursive_mutex m_mutex; 145 typedef std::pair<ConstString, ConstString> pair; 146 typedef std::vector<pair> collection; 147 typedef collection::iterator iterator; 148 typedef collection::const_iterator const_iterator; 149 150 iterator FindIteratorForPath(ConstString path); 151 152 const_iterator FindIteratorForPath(ConstString path) const; 153 154 collection m_pairs; 155 ChangedCallback m_callback = nullptr; 156 void *m_callback_baton = nullptr; 157 uint32_t m_mod_id = 0; // Incremented anytime anything is added or removed. 158}; 159 160} // namespace lldb_private 161 162#endif // LLDB_TARGET_PATHMAPPINGLIST_H 163