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