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 #if defined(__cplusplus) 12 13 #include "lldb/lldb-enumerations.h" 14 #include "lldb/lldb-forward.h" 15 16 #include "lldb/Utility/ConstString.h" 17 18 #include "llvm/ADT/StringRef.h" 19 20 #include <cstddef> 21 #include <memory> 22 23 namespace lldb_private { 24 25 /// \class Mangled Mangled.h "lldb/Core/Mangled.h" 26 /// A class that handles mangled names. 27 /// 28 /// Designed to handle mangled names. The demangled version of any names will 29 /// be computed when the demangled name is accessed through the Demangled() 30 /// acccessor. This class can also tokenize the demangled version of the name 31 /// for powerful searches. Functions and symbols could make instances of this 32 /// class for their mangled names. Uniqued string pools are used for the 33 /// mangled, demangled, and token string values to allow for faster 34 /// comparisons and for efficient memory use. 35 class Mangled { 36 public: 37 enum NamePreference { 38 ePreferMangled, 39 ePreferDemangled, 40 ePreferDemangledWithoutArguments 41 }; 42 43 enum ManglingScheme { 44 eManglingSchemeNone = 0, 45 eManglingSchemeMSVC, 46 eManglingSchemeItanium, 47 eManglingSchemeRustV0 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 /// Convert to pointer operator. 67 /// 68 /// This allows code to check a Mangled object to see if it contains a valid 69 /// mangled name using code such as: 70 /// 71 /// \code 72 /// Mangled mangled(...); 73 /// if (mangled) 74 /// { ... 75 /// \endcode 76 /// 77 /// \return 78 /// A pointer to this object if either the mangled or unmangled 79 /// name is set, NULL otherwise. 80 operator void *() const; 81 82 /// Logical NOT operator. 83 /// 84 /// This allows code to check a Mangled object to see if it contains an 85 /// empty mangled name using code such as: 86 /// 87 /// \code 88 /// Mangled mangled(...); 89 /// if (!mangled) 90 /// { ... 91 /// \endcode 92 /// 93 /// \return 94 /// Returns \b true if the object has an empty mangled and 95 /// unmangled name, \b false otherwise. 96 bool operator!() const; 97 98 /// Clear the mangled and demangled values. 99 void Clear(); 100 101 /// Compare the mangled string values 102 /// 103 /// Compares the Mangled::GetName() string in \a lhs and \a rhs. 104 /// 105 /// \param[in] lhs 106 /// A const reference to the Left Hand Side object to compare. 107 /// 108 /// \param[in] rhs 109 /// A const reference to the Right Hand Side object to compare. 110 /// 111 /// \return 112 /// -1 if \a lhs is less than \a rhs 113 /// 0 if \a lhs is equal to \a rhs 114 /// 1 if \a lhs is greater than \a rhs 115 static int Compare(const Mangled &lhs, const Mangled &rhs); 116 117 /// Dump a description of this object to a Stream \a s. 118 /// 119 /// Dump a Mangled object to stream \a s. We don't force our demangled name 120 /// to be computed currently (we don't use the accessor). 121 /// 122 /// \param[in] s 123 /// The stream to which to dump the object description. 124 void Dump(Stream *s) const; 125 126 /// Dump a debug description of this object to a Stream \a s. 127 /// 128 /// \param[in] s 129 /// The stream to which to dump the object description. 130 void DumpDebug(Stream *s) const; 131 132 /// Demangled name get accessor. 133 /// 134 /// \return 135 /// A const reference to the demangled name string object. 136 ConstString GetDemangledName() const; 137 138 /// Display demangled name get accessor. 139 /// 140 /// \return 141 /// A const reference to the display demangled name string object. 142 ConstString GetDisplayDemangledName() const; 143 SetDemangledName(ConstString name)144 void SetDemangledName(ConstString name) { m_demangled = name; } 145 SetMangledName(ConstString name)146 void SetMangledName(ConstString name) { m_mangled = name; } 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 /// 194 /// \see ConstString::StaticMemorySize () 195 size_t MemorySize() const; 196 197 /// Set the string value in this object. 198 /// 199 /// If \a is_mangled is \b true, then the mangled named is set to \a name, 200 /// else the demangled name is set to \a name. 201 /// 202 /// \param[in] name 203 /// The already const version of the name for this object. 204 /// 205 /// \param[in] is_mangled 206 /// If \b true then \a name is a mangled name, if \b false then 207 /// \a name is demangled. 208 void SetValue(ConstString name, bool is_mangled); 209 210 /// Set the string value in this object. 211 /// 212 /// This version auto detects if the string is mangled by inspecting the 213 /// string value and looking for common mangling prefixes. 214 /// 215 /// \param[in] name 216 /// The already const version of the name for this object. 217 void SetValue(ConstString name); 218 219 /// Try to guess the language from the mangling. 220 /// 221 /// For a mangled name to have a language it must have both a mangled and a 222 /// demangled name and it can be guessed from the mangling what the language 223 /// is. Note: this will return C++ for any language that uses Itanium ABI 224 /// mangling. 225 /// 226 /// Standard C function names will return eLanguageTypeUnknown because they 227 /// aren't mangled and it isn't clear what language the name represents 228 /// (there will be no mangled name). 229 /// 230 /// \return 231 /// The language for the mangled/demangled name, eLanguageTypeUnknown 232 /// if there is no mangled or demangled counterpart. 233 lldb::LanguageType GuessLanguage() const; 234 235 /// Function signature for filtering mangled names. 236 using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme); 237 238 /// Trigger explicit demangling to obtain rich mangling information. This is 239 /// optimized for batch processing while populating a name index. To get the 240 /// pure demangled name string for a single entity, use GetDemangledName() 241 /// instead. 242 /// 243 /// For names that match the Itanium mangling scheme, this uses LLVM's 244 /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin 245 /// parser currently. 246 /// 247 /// This function is thread-safe when used with different \a context 248 /// instances in different threads. 249 /// 250 /// \param[in] context 251 /// The context for this function. A single instance can be stack- 252 /// allocated in the caller's frame and used for multiple calls. 253 /// 254 /// \param[in] skip_mangled_name 255 /// A filtering function for skipping entities based on name and mangling 256 /// scheme. This can be null if unused. 257 /// 258 /// \return 259 /// True on success, false otherwise. 260 bool DemangleWithRichManglingInfo(RichManglingContext &context, 261 SkipMangledNameFn *skip_mangled_name); 262 263 /// Try to identify the mangling scheme used. 264 /// \param[in] name 265 /// The name we are attempting to identify the mangling scheme for. 266 /// 267 /// \return 268 /// eManglingSchemeNone if no known mangling scheme could be identified 269 /// for s, otherwise the enumerator for the mangling scheme detected. 270 static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name); 271 272 private: 273 /// Mangled member variables. 274 ConstString m_mangled; ///< The mangled version of the name 275 mutable ConstString m_demangled; ///< Mutable so we can get it on demand with 276 ///a const version of this object 277 }; 278 279 Stream &operator<<(Stream &s, const Mangled &obj); 280 281 } // namespace lldb_private 282 283 #endif // #if defined(__cplusplus) 284 #endif // LLDB_CORE_MANGLED_H 285