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