10b57cec5SDimitry Andric //===-- Mangled.h -----------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 95ffd83dbSDimitry Andric #ifndef LLDB_CORE_MANGLED_H 105ffd83dbSDimitry Andric #define LLDB_CORE_MANGLED_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h" 130b57cec5SDimitry Andric #include "lldb/lldb-forward.h" 140eae32dcSDimitry Andric #include "lldb/lldb-types.h" 150b57cec5SDimitry Andric #include "lldb/Utility/ConstString.h" 160b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 170b57cec5SDimitry Andric 18fe6060f1SDimitry Andric #include <cstddef> 190b57cec5SDimitry Andric #include <memory> 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace lldb_private { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric /// \class Mangled Mangled.h "lldb/Core/Mangled.h" 240b57cec5SDimitry Andric /// A class that handles mangled names. 250b57cec5SDimitry Andric /// 260b57cec5SDimitry Andric /// Designed to handle mangled names. The demangled version of any names will 270b57cec5SDimitry Andric /// be computed when the demangled name is accessed through the Demangled() 28bdd1243dSDimitry Andric /// accessor. This class can also tokenize the demangled version of the name 290b57cec5SDimitry Andric /// for powerful searches. Functions and symbols could make instances of this 300b57cec5SDimitry Andric /// class for their mangled names. Uniqued string pools are used for the 310b57cec5SDimitry Andric /// mangled, demangled, and token string values to allow for faster 320b57cec5SDimitry Andric /// comparisons and for efficient memory use. 330b57cec5SDimitry Andric class Mangled { 340b57cec5SDimitry Andric public: 350b57cec5SDimitry Andric enum NamePreference { 360b57cec5SDimitry Andric ePreferMangled, 370b57cec5SDimitry Andric ePreferDemangled, 380b57cec5SDimitry Andric ePreferDemangledWithoutArguments 390b57cec5SDimitry Andric }; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric enum ManglingScheme { 420b57cec5SDimitry Andric eManglingSchemeNone = 0, 430b57cec5SDimitry Andric eManglingSchemeMSVC, 44fe6060f1SDimitry Andric eManglingSchemeItanium, 45349cc55cSDimitry Andric eManglingSchemeRustV0, 465f757f3fSDimitry Andric eManglingSchemeD, 475f757f3fSDimitry Andric eManglingSchemeSwift, 480b57cec5SDimitry Andric }; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric /// Default constructor. 510b57cec5SDimitry Andric /// 520b57cec5SDimitry Andric /// Initialize with both mangled and demangled names empty. 539dba64beSDimitry Andric Mangled() = default; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric /// Construct with name. 560b57cec5SDimitry Andric /// 570b57cec5SDimitry Andric /// Constructor with an optional string and auto-detect if \a name is 580b57cec5SDimitry Andric /// mangled or not. 590b57cec5SDimitry Andric /// 600b57cec5SDimitry Andric /// \param[in] name 610b57cec5SDimitry Andric /// The already const name to copy into this object. 620b57cec5SDimitry Andric explicit Mangled(ConstString name); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric explicit Mangled(llvm::StringRef name); 650b57cec5SDimitry Andric 660eae32dcSDimitry Andric bool operator==(const Mangled &rhs) const { 670eae32dcSDimitry Andric return m_mangled == rhs.m_mangled && 680eae32dcSDimitry Andric GetDemangledName() == rhs.GetDemangledName(); 690eae32dcSDimitry Andric } 700eae32dcSDimitry Andric 710eae32dcSDimitry Andric bool operator!=(const Mangled &rhs) const { 720eae32dcSDimitry Andric return !(*this == rhs); 730eae32dcSDimitry Andric } 740eae32dcSDimitry Andric 7504eeddc0SDimitry Andric /// Convert to bool operator. 760b57cec5SDimitry Andric /// 7704eeddc0SDimitry Andric /// This allows code to check any Mangled objects to see if they contain 7804eeddc0SDimitry Andric /// anything valid using code such as: 790b57cec5SDimitry Andric /// 800b57cec5SDimitry Andric /// \code 810b57cec5SDimitry Andric /// Mangled mangled(...); 820b57cec5SDimitry Andric /// if (mangled) 830b57cec5SDimitry Andric /// { ... 840b57cec5SDimitry Andric /// \endcode 850b57cec5SDimitry Andric /// 860b57cec5SDimitry Andric /// \return 8704eeddc0SDimitry Andric /// Returns \b true if either the mangled or unmangled name is set, 8804eeddc0SDimitry Andric /// \b false if the object has an empty mangled and unmangled name. 8904eeddc0SDimitry Andric explicit operator bool() const; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric /// Clear the mangled and demangled values. 920b57cec5SDimitry Andric void Clear(); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric /// Compare the mangled string values 950b57cec5SDimitry Andric /// 960b57cec5SDimitry Andric /// Compares the Mangled::GetName() string in \a lhs and \a rhs. 970b57cec5SDimitry Andric /// 980b57cec5SDimitry Andric /// \param[in] lhs 990b57cec5SDimitry Andric /// A const reference to the Left Hand Side object to compare. 1000b57cec5SDimitry Andric /// 1010b57cec5SDimitry Andric /// \param[in] rhs 1020b57cec5SDimitry Andric /// A const reference to the Right Hand Side object to compare. 1030b57cec5SDimitry Andric /// 1040b57cec5SDimitry Andric /// \return 105480093f4SDimitry Andric /// -1 if \a lhs is less than \a rhs 106480093f4SDimitry Andric /// 0 if \a lhs is equal to \a rhs 107480093f4SDimitry Andric /// 1 if \a lhs is greater than \a rhs 1080b57cec5SDimitry Andric static int Compare(const Mangled &lhs, const Mangled &rhs); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric /// Dump a description of this object to a Stream \a s. 1110b57cec5SDimitry Andric /// 1120b57cec5SDimitry Andric /// Dump a Mangled object to stream \a s. We don't force our demangled name 1130b57cec5SDimitry Andric /// to be computed currently (we don't use the accessor). 1140b57cec5SDimitry Andric /// 1150b57cec5SDimitry Andric /// \param[in] s 1160b57cec5SDimitry Andric /// The stream to which to dump the object description. 1170b57cec5SDimitry Andric void Dump(Stream *s) const; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric /// Dump a debug description of this object to a Stream \a s. 1200b57cec5SDimitry Andric /// 1210b57cec5SDimitry Andric /// \param[in] s 1220b57cec5SDimitry Andric /// The stream to which to dump the object description. 1230b57cec5SDimitry Andric void DumpDebug(Stream *s) const; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric /// Demangled name get accessor. 1260b57cec5SDimitry Andric /// 1270b57cec5SDimitry Andric /// \return 1280b57cec5SDimitry Andric /// A const reference to the demangled name string object. 1295ffd83dbSDimitry Andric ConstString GetDemangledName() const; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric /// Display demangled name get accessor. 1320b57cec5SDimitry Andric /// 1330b57cec5SDimitry Andric /// \return 1340b57cec5SDimitry Andric /// A const reference to the display demangled name string object. 1355ffd83dbSDimitry Andric ConstString GetDisplayDemangledName() const; 1360b57cec5SDimitry Andric SetDemangledName(ConstString name)1370b57cec5SDimitry Andric void SetDemangledName(ConstString name) { m_demangled = name; } 1380b57cec5SDimitry Andric SetMangledName(ConstString name)1390b57cec5SDimitry Andric void SetMangledName(ConstString name) { m_mangled = name; } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric /// Mangled name get accessor. 1420b57cec5SDimitry Andric /// 1430b57cec5SDimitry Andric /// \return 1440b57cec5SDimitry Andric /// A reference to the mangled name string object. GetMangledName()1450b57cec5SDimitry Andric ConstString &GetMangledName() { return m_mangled; } 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric /// Mangled name get accessor. 1480b57cec5SDimitry Andric /// 1490b57cec5SDimitry Andric /// \return 1500b57cec5SDimitry Andric /// A const reference to the mangled name string object. GetMangledName()1510b57cec5SDimitry Andric ConstString GetMangledName() const { return m_mangled; } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric /// Best name get accessor. 1540b57cec5SDimitry Andric /// 1550b57cec5SDimitry Andric /// \param[in] preference 1560b57cec5SDimitry Andric /// Which name would you prefer to get? 1570b57cec5SDimitry Andric /// 1580b57cec5SDimitry Andric /// \return 1590b57cec5SDimitry Andric /// A const reference to the preferred name string object if this 1600b57cec5SDimitry Andric /// object has a valid name of that kind, else a const reference to the 1610b57cec5SDimitry Andric /// other name is returned. 1625ffd83dbSDimitry Andric ConstString GetName(NamePreference preference = ePreferDemangled) const; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric /// Check if "name" matches either the mangled or demangled name. 1650b57cec5SDimitry Andric /// 1660b57cec5SDimitry Andric /// \param[in] name 1670b57cec5SDimitry Andric /// A name to match against both strings. 1680b57cec5SDimitry Andric /// 1690b57cec5SDimitry Andric /// \return 1700b57cec5SDimitry Andric /// \b True if \a name matches either name, \b false otherwise. NameMatches(ConstString name)1715ffd83dbSDimitry Andric bool NameMatches(ConstString name) const { 1720b57cec5SDimitry Andric if (m_mangled == name) 1730b57cec5SDimitry Andric return true; 1745ffd83dbSDimitry Andric return GetDemangledName() == name; 1750b57cec5SDimitry Andric } 1765ffd83dbSDimitry Andric bool NameMatches(const RegularExpression ®ex) const; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric /// Get the memory cost of this object. 1790b57cec5SDimitry Andric /// 1800b57cec5SDimitry Andric /// Return the size in bytes that this object takes in memory. This returns 1810b57cec5SDimitry Andric /// the size in bytes of this object, not any shared string values it may 1820b57cec5SDimitry Andric /// refer to. 1830b57cec5SDimitry Andric /// 1840b57cec5SDimitry Andric /// \return 1850b57cec5SDimitry Andric /// The number of bytes that this object occupies in memory. 1860b57cec5SDimitry Andric size_t MemorySize() const; 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric /// Set the string value in this object. 1890b57cec5SDimitry Andric /// 1900b57cec5SDimitry Andric /// This version auto detects if the string is mangled by inspecting the 1910b57cec5SDimitry Andric /// string value and looking for common mangling prefixes. 1920b57cec5SDimitry Andric /// 1930b57cec5SDimitry Andric /// \param[in] name 1940b57cec5SDimitry Andric /// The already const version of the name for this object. 1950b57cec5SDimitry Andric void SetValue(ConstString name); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric /// Try to guess the language from the mangling. 1980b57cec5SDimitry Andric /// 1990b57cec5SDimitry Andric /// For a mangled name to have a language it must have both a mangled and a 2000b57cec5SDimitry Andric /// demangled name and it can be guessed from the mangling what the language 2010b57cec5SDimitry Andric /// is. Note: this will return C++ for any language that uses Itanium ABI 2020b57cec5SDimitry Andric /// mangling. 2030b57cec5SDimitry Andric /// 2040b57cec5SDimitry Andric /// Standard C function names will return eLanguageTypeUnknown because they 2050b57cec5SDimitry Andric /// aren't mangled and it isn't clear what language the name represents 2060b57cec5SDimitry Andric /// (there will be no mangled name). 2070b57cec5SDimitry Andric /// 2080b57cec5SDimitry Andric /// \return 2090b57cec5SDimitry Andric /// The language for the mangled/demangled name, eLanguageTypeUnknown 2100b57cec5SDimitry Andric /// if there is no mangled or demangled counterpart. 2110b57cec5SDimitry Andric lldb::LanguageType GuessLanguage() const; 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric /// Function signature for filtering mangled names. 2140b57cec5SDimitry Andric using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme); 2150b57cec5SDimitry Andric 216d56accc7SDimitry Andric /// Get rich mangling information. This is optimized for batch processing 217d56accc7SDimitry Andric /// while populating a name index. To get the pure demangled name string for 218d56accc7SDimitry Andric /// a single entity, use GetDemangledName() instead. 2190b57cec5SDimitry Andric /// 2200b57cec5SDimitry Andric /// For names that match the Itanium mangling scheme, this uses LLVM's 2210b57cec5SDimitry Andric /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin 2220b57cec5SDimitry Andric /// parser currently. 2230b57cec5SDimitry Andric /// 2240b57cec5SDimitry Andric /// This function is thread-safe when used with different \a context 2250b57cec5SDimitry Andric /// instances in different threads. 2260b57cec5SDimitry Andric /// 2270b57cec5SDimitry Andric /// \param[in] context 2280b57cec5SDimitry Andric /// The context for this function. A single instance can be stack- 2290b57cec5SDimitry Andric /// allocated in the caller's frame and used for multiple calls. 2300b57cec5SDimitry Andric /// 2310b57cec5SDimitry Andric /// \param[in] skip_mangled_name 2320b57cec5SDimitry Andric /// A filtering function for skipping entities based on name and mangling 2330b57cec5SDimitry Andric /// scheme. This can be null if unused. 2340b57cec5SDimitry Andric /// 2350b57cec5SDimitry Andric /// \return 2360b57cec5SDimitry Andric /// True on success, false otherwise. 237d56accc7SDimitry Andric bool GetRichManglingInfo(RichManglingContext &context, 2380b57cec5SDimitry Andric SkipMangledNameFn *skip_mangled_name); 2390b57cec5SDimitry Andric 240480093f4SDimitry Andric /// Try to identify the mangling scheme used. 241480093f4SDimitry Andric /// \param[in] name 242480093f4SDimitry Andric /// The name we are attempting to identify the mangling scheme for. 243480093f4SDimitry Andric /// 244480093f4SDimitry Andric /// \return 245480093f4SDimitry Andric /// eManglingSchemeNone if no known mangling scheme could be identified 246480093f4SDimitry Andric /// for s, otherwise the enumerator for the mangling scheme detected. 247480093f4SDimitry Andric static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name); 248480093f4SDimitry Andric 2490eae32dcSDimitry Andric /// Decode a serialized version of this object from data. 2500eae32dcSDimitry Andric /// 2510eae32dcSDimitry Andric /// \param data 2520eae32dcSDimitry Andric /// The decoder object that references the serialized data. 2530eae32dcSDimitry Andric /// 2540eae32dcSDimitry Andric /// \param offset_ptr 2550eae32dcSDimitry Andric /// A pointer that contains the offset from which the data will be decoded 2560eae32dcSDimitry Andric /// from that gets updated as data gets decoded. 2570eae32dcSDimitry Andric /// 2580eae32dcSDimitry Andric /// \param strtab 2590eae32dcSDimitry Andric /// All strings in cache files are put into string tables for efficiency 2600eae32dcSDimitry Andric /// and cache file size reduction. Strings are stored as uint32_t string 2610eae32dcSDimitry Andric /// table offsets in the cache data. 2620eae32dcSDimitry Andric bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, 2630eae32dcSDimitry Andric const StringTableReader &strtab); 2640eae32dcSDimitry Andric 2650eae32dcSDimitry Andric /// Encode this object into a data encoder object. 2660eae32dcSDimitry Andric /// 2670eae32dcSDimitry Andric /// This allows this object to be serialized to disk. 2680eae32dcSDimitry Andric /// 2690eae32dcSDimitry Andric /// \param encoder 2700eae32dcSDimitry Andric /// A data encoder object that serialized bytes will be encoded into. 2710eae32dcSDimitry Andric /// 2720eae32dcSDimitry Andric /// \param strtab 2730eae32dcSDimitry Andric /// All strings in cache files are put into string tables for efficiency 2740eae32dcSDimitry Andric /// and cache file size reduction. Strings are stored as uint32_t string 2750eae32dcSDimitry Andric /// table offsets in the cache data. 2760eae32dcSDimitry Andric void Encode(DataEncoder &encoder, ConstStringTable &strtab) const; 2770eae32dcSDimitry Andric 2780b57cec5SDimitry Andric private: 2790b57cec5SDimitry Andric /// Mangled member variables. 2800b57cec5SDimitry Andric ConstString m_mangled; ///< The mangled version of the name 2810b57cec5SDimitry Andric mutable ConstString m_demangled; ///< Mutable so we can get it on demand with 2820b57cec5SDimitry Andric ///a const version of this object 2830b57cec5SDimitry Andric }; 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric Stream &operator<<(Stream &s, const Mangled &obj); 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric } // namespace lldb_private 2880b57cec5SDimitry Andric 2895ffd83dbSDimitry Andric #endif // LLDB_CORE_MANGLED_H 290