1 //===-- Mangled.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_CORE_MANGLED_H 10 #define LLDB_CORE_MANGLED_H 11 12 #include "lldb/Core/DemangledNameInfo.h" 13 #include "lldb/Utility/ConstString.h" 14 #include "lldb/lldb-enumerations.h" 15 #include "lldb/lldb-forward.h" 16 #include "lldb/lldb-types.h" 17 #include "llvm/ADT/StringRef.h" 18 19 #include <cstddef> 20 #include <memory> 21 22 namespace lldb_private { 23 24 /// \class Mangled Mangled.h "lldb/Core/Mangled.h" 25 /// A class that handles mangled names. 26 /// 27 /// Designed to handle mangled names. The demangled version of any names will 28 /// be computed when the demangled name is accessed through the Demangled() 29 /// accessor. This class can also tokenize the demangled version of the name 30 /// for powerful searches. Functions and symbols could make instances of this 31 /// class for their mangled names. Uniqued string pools are used for the 32 /// mangled, demangled, and token string values to allow for faster 33 /// comparisons and for efficient memory use. 34 class Mangled { 35 public: 36 enum NamePreference { 37 ePreferMangled, 38 ePreferDemangled, 39 ePreferDemangledWithoutArguments 40 }; 41 42 enum ManglingScheme { 43 eManglingSchemeNone = 0, 44 eManglingSchemeMSVC, 45 eManglingSchemeItanium, 46 eManglingSchemeRustV0, 47 eManglingSchemeD, 48 eManglingSchemeSwift, 49 }; 50 51 /// Default constructor. 52 /// 53 /// Initialize with both mangled and demangled names empty. 54 Mangled() = default; 55 56 /// Construct with name. 57 /// 58 /// Constructor with an optional string and auto-detect if \a name is 59 /// mangled or not. 60 /// 61 /// \param[in] name 62 /// The already const name to copy into this object. 63 explicit Mangled(ConstString name); 64 65 explicit Mangled(llvm::StringRef name); 66 67 bool operator==(const Mangled &rhs) const { 68 return m_mangled == rhs.m_mangled && 69 GetDemangledName() == rhs.GetDemangledName(); 70 } 71 72 bool operator!=(const Mangled &rhs) const { 73 return !(*this == rhs); 74 } 75 76 /// Convert to bool operator. 77 /// 78 /// This allows code to check any Mangled objects to see if they contain 79 /// anything valid using code such as: 80 /// 81 /// \code 82 /// Mangled mangled(...); 83 /// if (mangled) 84 /// { ... 85 /// \endcode 86 /// 87 /// \return 88 /// Returns \b true if either the mangled or unmangled name is set, 89 /// \b false if the object has an empty mangled and unmangled name. 90 explicit operator bool() const; 91 92 /// Clear the mangled and demangled values. 93 void Clear(); 94 95 /// Compare the mangled string values 96 /// 97 /// Compares the Mangled::GetName() string in \a lhs and \a rhs. 98 /// 99 /// \param[in] lhs 100 /// A const reference to the Left Hand Side object to compare. 101 /// 102 /// \param[in] rhs 103 /// A const reference to the Right Hand Side object to compare. 104 /// 105 /// \return 106 /// -1 if \a lhs is less than \a rhs 107 /// 0 if \a lhs is equal to \a rhs 108 /// 1 if \a lhs is greater than \a rhs 109 static int Compare(const Mangled &lhs, const Mangled &rhs); 110 111 /// Dump a description of this object to a Stream \a s. 112 /// 113 /// Dump a Mangled object to stream \a s. We don't force our demangled name 114 /// to be computed currently (we don't use the accessor). 115 /// 116 /// \param[in] s 117 /// The stream to which to dump the object description. 118 void Dump(Stream *s) const; 119 120 /// Dump a debug description of this object to a Stream \a s. 121 /// 122 /// \param[in] s 123 /// The stream to which to dump the object description. 124 void DumpDebug(Stream *s) const; 125 126 /// Demangled name get accessor. 127 /// 128 /// \return 129 /// A const reference to the demangled name string object. 130 ConstString GetDemangledName() const; 131 132 /// Display demangled name get accessor. 133 /// 134 /// \return 135 /// A const reference to the display demangled name string object. 136 ConstString GetDisplayDemangledName() const; 137 SetDemangledName(ConstString name)138 void SetDemangledName(ConstString name) { 139 m_demangled = name; 140 m_demangled_info.reset(); 141 } 142 SetMangledName(ConstString name)143 void SetMangledName(ConstString name) { 144 m_mangled = name; 145 m_demangled_info.reset(); 146 } 147 148 /// Mangled name get accessor. 149 /// 150 /// \return 151 /// A reference to the mangled name string object. GetMangledName()152 ConstString &GetMangledName() { return m_mangled; } 153 154 /// Mangled name get accessor. 155 /// 156 /// \return 157 /// A const reference to the mangled name string object. GetMangledName()158 ConstString GetMangledName() const { return m_mangled; } 159 160 /// Best name get accessor. 161 /// 162 /// \param[in] preference 163 /// Which name would you prefer to get? 164 /// 165 /// \return 166 /// A const reference to the preferred name string object if this 167 /// object has a valid name of that kind, else a const reference to the 168 /// other name is returned. 169 ConstString GetName(NamePreference preference = ePreferDemangled) const; 170 171 /// Check if "name" matches either the mangled or demangled name. 172 /// 173 /// \param[in] name 174 /// A name to match against both strings. 175 /// 176 /// \return 177 /// \b True if \a name matches either name, \b false otherwise. NameMatches(ConstString name)178 bool NameMatches(ConstString name) const { 179 if (m_mangled == name) 180 return true; 181 return GetDemangledName() == name; 182 } 183 bool NameMatches(const RegularExpression ®ex) const; 184 185 /// Get the memory cost of this object. 186 /// 187 /// Return the size in bytes that this object takes in memory. This returns 188 /// the size in bytes of this object, not any shared string values it may 189 /// refer to. 190 /// 191 /// \return 192 /// The number of bytes that this object occupies in memory. 193 size_t MemorySize() const; 194 195 /// Set the string value in this object. 196 /// 197 /// This version auto detects if the string is mangled by inspecting the 198 /// string value and looking for common mangling prefixes. 199 /// 200 /// \param[in] name 201 /// The already const version of the name for this object. 202 void SetValue(ConstString name); 203 204 /// Try to guess the language from the mangling. 205 /// 206 /// For a mangled name to have a language it must have both a mangled and a 207 /// demangled name and it can be guessed from the mangling what the language 208 /// is. Note: this will return C++ for any language that uses Itanium ABI 209 /// mangling. 210 /// 211 /// Standard C function names will return eLanguageTypeUnknown because they 212 /// aren't mangled and it isn't clear what language the name represents 213 /// (there will be no mangled name). 214 /// 215 /// \return 216 /// The language for the mangled/demangled name, eLanguageTypeUnknown 217 /// if there is no mangled or demangled counterpart. 218 lldb::LanguageType GuessLanguage() const; 219 220 /// Function signature for filtering mangled names. 221 using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme); 222 223 /// Get rich mangling information. This is optimized for batch processing 224 /// while populating a name index. To get the pure demangled name string for 225 /// a single entity, use GetDemangledName() instead. 226 /// 227 /// For names that match the Itanium mangling scheme, this uses LLVM's 228 /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin 229 /// parser currently. 230 /// 231 /// This function is thread-safe when used with different \a context 232 /// instances in different threads. 233 /// 234 /// \param[in] context 235 /// The context for this function. A single instance can be stack- 236 /// allocated in the caller's frame and used for multiple calls. 237 /// 238 /// \param[in] skip_mangled_name 239 /// A filtering function for skipping entities based on name and mangling 240 /// scheme. This can be null if unused. 241 /// 242 /// \return 243 /// True on success, false otherwise. 244 bool GetRichManglingInfo(RichManglingContext &context, 245 SkipMangledNameFn *skip_mangled_name); 246 247 /// Try to identify the mangling scheme used. 248 /// \param[in] name 249 /// The name we are attempting to identify the mangling scheme for. 250 /// 251 /// \return 252 /// eManglingSchemeNone if no known mangling scheme could be identified 253 /// for s, otherwise the enumerator for the mangling scheme detected. 254 static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name); 255 256 static bool IsMangledName(llvm::StringRef name); 257 258 /// Decode a serialized version of this object from data. 259 /// 260 /// \param data 261 /// The decoder object that references the serialized data. 262 /// 263 /// \param offset_ptr 264 /// A pointer that contains the offset from which the data will be decoded 265 /// from that gets updated as data gets decoded. 266 /// 267 /// \param strtab 268 /// All strings in cache files are put into string tables for efficiency 269 /// and cache file size reduction. Strings are stored as uint32_t string 270 /// table offsets in the cache data. 271 bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, 272 const StringTableReader &strtab); 273 274 /// Encode this object into a data encoder object. 275 /// 276 /// This allows this object to be serialized to disk. 277 /// 278 /// \param encoder 279 /// A data encoder object that serialized bytes will be encoded into. 280 /// 281 /// \param strtab 282 /// All strings in cache files are put into string tables for efficiency 283 /// and cache file size reduction. Strings are stored as uint32_t string 284 /// table offsets in the cache data. 285 void Encode(DataEncoder &encoder, ConstStringTable &strtab) const; 286 287 /// Retrieve \c DemangledNameInfo of the demangled name held by this object. 288 const std::optional<DemangledNameInfo> &GetDemangledInfo() const; 289 290 private: 291 /// If \c force is \c false, this function will re-use the previously 292 /// demangled name (if any). If \c force is \c true (or the mangled name 293 /// on this object was not previously demangled), demangle and cache the 294 /// name. 295 ConstString GetDemangledNameImpl(bool force) const; 296 297 /// The mangled version of the name. 298 ConstString m_mangled; 299 300 /// Mutable so we can get it on demand with 301 /// a const version of this object. 302 mutable ConstString m_demangled; 303 304 /// If available, holds information about where in \c m_demangled certain 305 /// parts of the name (e.g., basename, arguments, etc.) begin and end. 306 mutable std::optional<DemangledNameInfo> m_demangled_info = std::nullopt; 307 }; 308 309 Stream &operator<<(Stream &s, const Mangled &obj); 310 311 } // namespace lldb_private 312 313 #endif // LLDB_CORE_MANGLED_H 314