1061da546Spatrick //===-- Mangled.h -----------------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9dda28197Spatrick #ifndef LLDB_CORE_MANGLED_H 10dda28197Spatrick #define LLDB_CORE_MANGLED_H 11061da546Spatrick #if defined(__cplusplus) 12061da546Spatrick 13061da546Spatrick #include "lldb/lldb-enumerations.h" 14061da546Spatrick #include "lldb/lldb-forward.h" 15*f6aab3d8Srobert #include "lldb/lldb-types.h" 16061da546Spatrick #include "lldb/Utility/ConstString.h" 17061da546Spatrick #include "llvm/ADT/StringRef.h" 18061da546Spatrick 19be691f3bSpatrick #include <cstddef> 20061da546Spatrick #include <memory> 21061da546Spatrick 22061da546Spatrick namespace lldb_private { 23061da546Spatrick 24061da546Spatrick /// \class Mangled Mangled.h "lldb/Core/Mangled.h" 25061da546Spatrick /// A class that handles mangled names. 26061da546Spatrick /// 27061da546Spatrick /// Designed to handle mangled names. The demangled version of any names will 28061da546Spatrick /// be computed when the demangled name is accessed through the Demangled() 29*f6aab3d8Srobert /// accessor. This class can also tokenize the demangled version of the name 30061da546Spatrick /// for powerful searches. Functions and symbols could make instances of this 31061da546Spatrick /// class for their mangled names. Uniqued string pools are used for the 32061da546Spatrick /// mangled, demangled, and token string values to allow for faster 33061da546Spatrick /// comparisons and for efficient memory use. 34061da546Spatrick class Mangled { 35061da546Spatrick public: 36061da546Spatrick enum NamePreference { 37061da546Spatrick ePreferMangled, 38061da546Spatrick ePreferDemangled, 39061da546Spatrick ePreferDemangledWithoutArguments 40061da546Spatrick }; 41061da546Spatrick 42061da546Spatrick enum ManglingScheme { 43061da546Spatrick eManglingSchemeNone = 0, 44061da546Spatrick eManglingSchemeMSVC, 45be691f3bSpatrick eManglingSchemeItanium, 46*f6aab3d8Srobert eManglingSchemeRustV0, 47*f6aab3d8Srobert eManglingSchemeD 48061da546Spatrick }; 49061da546Spatrick 50061da546Spatrick /// Default constructor. 51061da546Spatrick /// 52061da546Spatrick /// Initialize with both mangled and demangled names empty. 53061da546Spatrick Mangled() = default; 54061da546Spatrick 55061da546Spatrick /// Construct with name. 56061da546Spatrick /// 57061da546Spatrick /// Constructor with an optional string and auto-detect if \a name is 58061da546Spatrick /// mangled or not. 59061da546Spatrick /// 60061da546Spatrick /// \param[in] name 61061da546Spatrick /// The already const name to copy into this object. 62061da546Spatrick explicit Mangled(ConstString name); 63061da546Spatrick 64061da546Spatrick explicit Mangled(llvm::StringRef name); 65061da546Spatrick 66*f6aab3d8Srobert bool operator==(const Mangled &rhs) const { 67*f6aab3d8Srobert return m_mangled == rhs.m_mangled && 68*f6aab3d8Srobert GetDemangledName() == rhs.GetDemangledName(); 69*f6aab3d8Srobert } 70*f6aab3d8Srobert 71*f6aab3d8Srobert bool operator!=(const Mangled &rhs) const { 72*f6aab3d8Srobert return !(*this == rhs); 73*f6aab3d8Srobert } 74*f6aab3d8Srobert 75*f6aab3d8Srobert /// Convert to bool operator. 76061da546Spatrick /// 77*f6aab3d8Srobert /// This allows code to check any Mangled objects to see if they contain 78*f6aab3d8Srobert /// anything valid using code such as: 79061da546Spatrick /// 80061da546Spatrick /// \code 81061da546Spatrick /// Mangled mangled(...); 82061da546Spatrick /// if (mangled) 83061da546Spatrick /// { ... 84061da546Spatrick /// \endcode 85061da546Spatrick /// 86061da546Spatrick /// \return 87*f6aab3d8Srobert /// Returns \b true if either the mangled or unmangled name is set, 88*f6aab3d8Srobert /// \b false if the object has an empty mangled and unmangled name. 89*f6aab3d8Srobert explicit operator bool() const; 90061da546Spatrick 91061da546Spatrick /// Clear the mangled and demangled values. 92061da546Spatrick void Clear(); 93061da546Spatrick 94061da546Spatrick /// Compare the mangled string values 95061da546Spatrick /// 96061da546Spatrick /// Compares the Mangled::GetName() string in \a lhs and \a rhs. 97061da546Spatrick /// 98061da546Spatrick /// \param[in] lhs 99061da546Spatrick /// A const reference to the Left Hand Side object to compare. 100061da546Spatrick /// 101061da546Spatrick /// \param[in] rhs 102061da546Spatrick /// A const reference to the Right Hand Side object to compare. 103061da546Spatrick /// 104061da546Spatrick /// \return 105061da546Spatrick /// -1 if \a lhs is less than \a rhs 106061da546Spatrick /// 0 if \a lhs is equal to \a rhs 107061da546Spatrick /// 1 if \a lhs is greater than \a rhs 108061da546Spatrick static int Compare(const Mangled &lhs, const Mangled &rhs); 109061da546Spatrick 110061da546Spatrick /// Dump a description of this object to a Stream \a s. 111061da546Spatrick /// 112061da546Spatrick /// Dump a Mangled object to stream \a s. We don't force our demangled name 113061da546Spatrick /// to be computed currently (we don't use the accessor). 114061da546Spatrick /// 115061da546Spatrick /// \param[in] s 116061da546Spatrick /// The stream to which to dump the object description. 117061da546Spatrick void Dump(Stream *s) const; 118061da546Spatrick 119061da546Spatrick /// Dump a debug description of this object to a Stream \a s. 120061da546Spatrick /// 121061da546Spatrick /// \param[in] s 122061da546Spatrick /// The stream to which to dump the object description. 123061da546Spatrick void DumpDebug(Stream *s) const; 124061da546Spatrick 125061da546Spatrick /// Demangled name get accessor. 126061da546Spatrick /// 127061da546Spatrick /// \return 128061da546Spatrick /// A const reference to the demangled name string object. 129dda28197Spatrick ConstString GetDemangledName() const; 130061da546Spatrick 131061da546Spatrick /// Display demangled name get accessor. 132061da546Spatrick /// 133061da546Spatrick /// \return 134061da546Spatrick /// A const reference to the display demangled name string object. 135dda28197Spatrick ConstString GetDisplayDemangledName() const; 136061da546Spatrick SetDemangledName(ConstString name)137061da546Spatrick void SetDemangledName(ConstString name) { m_demangled = name; } 138061da546Spatrick SetMangledName(ConstString name)139061da546Spatrick void SetMangledName(ConstString name) { m_mangled = name; } 140061da546Spatrick 141061da546Spatrick /// Mangled name get accessor. 142061da546Spatrick /// 143061da546Spatrick /// \return 144061da546Spatrick /// A reference to the mangled name string object. GetMangledName()145061da546Spatrick ConstString &GetMangledName() { return m_mangled; } 146061da546Spatrick 147061da546Spatrick /// Mangled name get accessor. 148061da546Spatrick /// 149061da546Spatrick /// \return 150061da546Spatrick /// A const reference to the mangled name string object. GetMangledName()151061da546Spatrick ConstString GetMangledName() const { return m_mangled; } 152061da546Spatrick 153061da546Spatrick /// Best name get accessor. 154061da546Spatrick /// 155061da546Spatrick /// \param[in] preference 156061da546Spatrick /// Which name would you prefer to get? 157061da546Spatrick /// 158061da546Spatrick /// \return 159061da546Spatrick /// A const reference to the preferred name string object if this 160061da546Spatrick /// object has a valid name of that kind, else a const reference to the 161061da546Spatrick /// other name is returned. 162dda28197Spatrick ConstString GetName(NamePreference preference = ePreferDemangled) const; 163061da546Spatrick 164061da546Spatrick /// Check if "name" matches either the mangled or demangled name. 165061da546Spatrick /// 166061da546Spatrick /// \param[in] name 167061da546Spatrick /// A name to match against both strings. 168061da546Spatrick /// 169061da546Spatrick /// \return 170061da546Spatrick /// \b True if \a name matches either name, \b false otherwise. NameMatches(ConstString name)171dda28197Spatrick bool NameMatches(ConstString name) const { 172061da546Spatrick if (m_mangled == name) 173061da546Spatrick return true; 174dda28197Spatrick return GetDemangledName() == name; 175061da546Spatrick } 176dda28197Spatrick bool NameMatches(const RegularExpression ®ex) const; 177061da546Spatrick 178061da546Spatrick /// Get the memory cost of this object. 179061da546Spatrick /// 180061da546Spatrick /// Return the size in bytes that this object takes in memory. This returns 181061da546Spatrick /// the size in bytes of this object, not any shared string values it may 182061da546Spatrick /// refer to. 183061da546Spatrick /// 184061da546Spatrick /// \return 185061da546Spatrick /// The number of bytes that this object occupies in memory. 186061da546Spatrick size_t MemorySize() const; 187061da546Spatrick 188061da546Spatrick /// Set the string value in this object. 189061da546Spatrick /// 190061da546Spatrick /// If \a is_mangled is \b true, then the mangled named is set to \a name, 191061da546Spatrick /// else the demangled name is set to \a name. 192061da546Spatrick /// 193061da546Spatrick /// \param[in] name 194061da546Spatrick /// The already const version of the name for this object. 195061da546Spatrick /// 196061da546Spatrick /// \param[in] is_mangled 197061da546Spatrick /// If \b true then \a name is a mangled name, if \b false then 198061da546Spatrick /// \a name is demangled. 199061da546Spatrick void SetValue(ConstString name, bool is_mangled); 200061da546Spatrick 201061da546Spatrick /// Set the string value in this object. 202061da546Spatrick /// 203061da546Spatrick /// This version auto detects if the string is mangled by inspecting the 204061da546Spatrick /// string value and looking for common mangling prefixes. 205061da546Spatrick /// 206061da546Spatrick /// \param[in] name 207061da546Spatrick /// The already const version of the name for this object. 208061da546Spatrick void SetValue(ConstString name); 209061da546Spatrick 210061da546Spatrick /// Try to guess the language from the mangling. 211061da546Spatrick /// 212061da546Spatrick /// For a mangled name to have a language it must have both a mangled and a 213061da546Spatrick /// demangled name and it can be guessed from the mangling what the language 214061da546Spatrick /// is. Note: this will return C++ for any language that uses Itanium ABI 215061da546Spatrick /// mangling. 216061da546Spatrick /// 217061da546Spatrick /// Standard C function names will return eLanguageTypeUnknown because they 218061da546Spatrick /// aren't mangled and it isn't clear what language the name represents 219061da546Spatrick /// (there will be no mangled name). 220061da546Spatrick /// 221061da546Spatrick /// \return 222061da546Spatrick /// The language for the mangled/demangled name, eLanguageTypeUnknown 223061da546Spatrick /// if there is no mangled or demangled counterpart. 224061da546Spatrick lldb::LanguageType GuessLanguage() const; 225061da546Spatrick 226061da546Spatrick /// Function signature for filtering mangled names. 227061da546Spatrick using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme); 228061da546Spatrick 229*f6aab3d8Srobert /// Get rich mangling information. This is optimized for batch processing 230*f6aab3d8Srobert /// while populating a name index. To get the pure demangled name string for 231*f6aab3d8Srobert /// a single entity, use GetDemangledName() instead. 232061da546Spatrick /// 233061da546Spatrick /// For names that match the Itanium mangling scheme, this uses LLVM's 234061da546Spatrick /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin 235061da546Spatrick /// parser currently. 236061da546Spatrick /// 237061da546Spatrick /// This function is thread-safe when used with different \a context 238061da546Spatrick /// instances in different threads. 239061da546Spatrick /// 240061da546Spatrick /// \param[in] context 241061da546Spatrick /// The context for this function. A single instance can be stack- 242061da546Spatrick /// allocated in the caller's frame and used for multiple calls. 243061da546Spatrick /// 244061da546Spatrick /// \param[in] skip_mangled_name 245061da546Spatrick /// A filtering function for skipping entities based on name and mangling 246061da546Spatrick /// scheme. This can be null if unused. 247061da546Spatrick /// 248061da546Spatrick /// \return 249061da546Spatrick /// True on success, false otherwise. 250*f6aab3d8Srobert bool GetRichManglingInfo(RichManglingContext &context, 251061da546Spatrick SkipMangledNameFn *skip_mangled_name); 252061da546Spatrick 253061da546Spatrick /// Try to identify the mangling scheme used. 254061da546Spatrick /// \param[in] name 255061da546Spatrick /// The name we are attempting to identify the mangling scheme for. 256061da546Spatrick /// 257061da546Spatrick /// \return 258061da546Spatrick /// eManglingSchemeNone if no known mangling scheme could be identified 259061da546Spatrick /// for s, otherwise the enumerator for the mangling scheme detected. 260061da546Spatrick static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name); 261061da546Spatrick 262*f6aab3d8Srobert /// Decode a serialized version of this object from data. 263*f6aab3d8Srobert /// 264*f6aab3d8Srobert /// \param data 265*f6aab3d8Srobert /// The decoder object that references the serialized data. 266*f6aab3d8Srobert /// 267*f6aab3d8Srobert /// \param offset_ptr 268*f6aab3d8Srobert /// A pointer that contains the offset from which the data will be decoded 269*f6aab3d8Srobert /// from that gets updated as data gets decoded. 270*f6aab3d8Srobert /// 271*f6aab3d8Srobert /// \param strtab 272*f6aab3d8Srobert /// All strings in cache files are put into string tables for efficiency 273*f6aab3d8Srobert /// and cache file size reduction. Strings are stored as uint32_t string 274*f6aab3d8Srobert /// table offsets in the cache data. 275*f6aab3d8Srobert bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, 276*f6aab3d8Srobert const StringTableReader &strtab); 277*f6aab3d8Srobert 278*f6aab3d8Srobert /// Encode this object into a data encoder object. 279*f6aab3d8Srobert /// 280*f6aab3d8Srobert /// This allows this object to be serialized to disk. 281*f6aab3d8Srobert /// 282*f6aab3d8Srobert /// \param encoder 283*f6aab3d8Srobert /// A data encoder object that serialized bytes will be encoded into. 284*f6aab3d8Srobert /// 285*f6aab3d8Srobert /// \param strtab 286*f6aab3d8Srobert /// All strings in cache files are put into string tables for efficiency 287*f6aab3d8Srobert /// and cache file size reduction. Strings are stored as uint32_t string 288*f6aab3d8Srobert /// table offsets in the cache data. 289*f6aab3d8Srobert void Encode(DataEncoder &encoder, ConstStringTable &strtab) const; 290*f6aab3d8Srobert 291061da546Spatrick private: 292061da546Spatrick /// Mangled member variables. 293061da546Spatrick ConstString m_mangled; ///< The mangled version of the name 294061da546Spatrick mutable ConstString m_demangled; ///< Mutable so we can get it on demand with 295061da546Spatrick ///a const version of this object 296061da546Spatrick }; 297061da546Spatrick 298061da546Spatrick Stream &operator<<(Stream &s, const Mangled &obj); 299061da546Spatrick 300061da546Spatrick } // namespace lldb_private 301061da546Spatrick 302061da546Spatrick #endif // #if defined(__cplusplus) 303dda28197Spatrick #endif // LLDB_CORE_MANGLED_H 304