1 //===-- Mangled.h -----------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_Mangled_h_ 11 #define liblldb_Mangled_h_ 12 #if defined(__cplusplus) 13 14 #include "lldb/lldb-enumerations.h" 15 #include "lldb/lldb-forward.h" 16 17 #include "lldb/Utility/ConstString.h" 18 19 #include "llvm/ADT/StringRef.h" 20 21 #include <memory> 22 #include <stddef.h> 23 24 namespace lldb_private { 25 26 //---------------------------------------------------------------------- 27 /// @class Mangled Mangled.h "lldb/Core/Mangled.h" 28 /// A class that handles mangled names. 29 /// 30 /// Designed to handle mangled names. The demangled version of any names will 31 /// be computed when the demangled name is accessed through the Demangled() 32 /// acccessor. This class can also tokenize the demangled version of the name 33 /// for powerful searches. Functions and symbols could make instances of this 34 /// class for their mangled names. Uniqued string pools are used for the 35 /// mangled, demangled, and token string values to allow for faster 36 /// comparisons and for efficient memory use. 37 //---------------------------------------------------------------------- 38 class Mangled { 39 public: 40 enum NamePreference { 41 ePreferMangled, 42 ePreferDemangled, 43 ePreferDemangledWithoutArguments 44 }; 45 46 enum ManglingScheme { 47 eManglingSchemeNone = 0, 48 eManglingSchemeMSVC, 49 eManglingSchemeItanium 50 }; 51 52 //---------------------------------------------------------------------- 53 /// Default constructor. 54 /// 55 /// Initialize with both mangled and demangled names empty. 56 //---------------------------------------------------------------------- 57 Mangled(); 58 59 //---------------------------------------------------------------------- 60 /// Construct with name. 61 /// 62 /// Constructor with an optional string and a boolean indicating if it is 63 /// the mangled version. 64 /// 65 /// @param[in] name 66 /// The already const name to copy into this object. 67 /// 68 /// @param[in] is_mangled 69 /// If \b true then \a name is a mangled name, if \b false then 70 /// \a name is demangled. 71 //---------------------------------------------------------------------- 72 Mangled(const ConstString &name, bool is_mangled); 73 Mangled(llvm::StringRef name, bool is_mangled); 74 75 //---------------------------------------------------------------------- 76 /// Construct with name. 77 /// 78 /// Constructor with an optional string and auto-detect if \a name is 79 /// mangled or not. 80 /// 81 /// @param[in] name 82 /// The already const name to copy into this object. 83 //---------------------------------------------------------------------- 84 explicit Mangled(const ConstString &name); 85 86 explicit Mangled(llvm::StringRef name); 87 88 //---------------------------------------------------------------------- 89 /// Destructor 90 /// 91 /// Releases its ref counts on the mangled and demangled strings that live 92 /// in the global string pool. 93 //---------------------------------------------------------------------- 94 ~Mangled(); 95 96 //---------------------------------------------------------------------- 97 /// Convert to pointer operator. 98 /// 99 /// This allows code to check a Mangled object to see if it contains a valid 100 /// mangled name using code such as: 101 /// 102 /// @code 103 /// Mangled mangled(...); 104 /// if (mangled) 105 /// { ... 106 /// @endcode 107 /// 108 /// @return 109 /// A pointer to this object if either the mangled or unmangled 110 /// name is set, NULL otherwise. 111 //---------------------------------------------------------------------- 112 operator void *() const; 113 114 //---------------------------------------------------------------------- 115 /// Logical NOT operator. 116 /// 117 /// This allows code to check a Mangled object to see if it contains an 118 /// empty mangled name using code such as: 119 /// 120 /// @code 121 /// Mangled mangled(...); 122 /// if (!mangled) 123 /// { ... 124 /// @endcode 125 /// 126 /// @return 127 /// Returns \b true if the object has an empty mangled and 128 /// unmangled name, \b false otherwise. 129 //---------------------------------------------------------------------- 130 bool operator!() const; 131 132 //---------------------------------------------------------------------- 133 /// Clear the mangled and demangled values. 134 //---------------------------------------------------------------------- 135 void Clear(); 136 137 //---------------------------------------------------------------------- 138 /// Compare the mangled string values 139 /// 140 /// Compares the Mangled::GetName() string in \a lhs and \a rhs. 141 /// 142 /// @param[in] lhs 143 /// A const reference to the Left Hand Side object to compare. 144 /// 145 /// @param[in] rhs 146 /// A const reference to the Right Hand Side object to compare. 147 /// 148 /// @return 149 /// @li -1 if \a lhs is less than \a rhs 150 /// @li 0 if \a lhs is equal to \a rhs 151 /// @li 1 if \a lhs is greater than \a rhs 152 //---------------------------------------------------------------------- 153 static int Compare(const Mangled &lhs, const Mangled &rhs); 154 155 //---------------------------------------------------------------------- 156 /// Dump a description of this object to a Stream \a s. 157 /// 158 /// Dump a Mangled object to stream \a s. We don't force our demangled name 159 /// to be computed currently (we don't use the accessor). 160 /// 161 /// @param[in] s 162 /// The stream to which to dump the object description. 163 //---------------------------------------------------------------------- 164 void Dump(Stream *s) const; 165 166 //---------------------------------------------------------------------- 167 /// Dump a debug description of this object to a Stream \a s. 168 /// 169 /// @param[in] s 170 /// The stream to which to dump the object description. 171 //---------------------------------------------------------------------- 172 void DumpDebug(Stream *s) const; 173 174 //---------------------------------------------------------------------- 175 /// Demangled name get accessor. 176 /// 177 /// @return 178 /// A const reference to the demangled name string object. 179 //---------------------------------------------------------------------- 180 const ConstString &GetDemangledName(lldb::LanguageType language) const; 181 182 //---------------------------------------------------------------------- 183 /// Display demangled name get accessor. 184 /// 185 /// @return 186 /// A const reference to the display demangled name string object. 187 //---------------------------------------------------------------------- 188 ConstString GetDisplayDemangledName(lldb::LanguageType language) const; 189 SetDemangledName(const ConstString & name)190 void SetDemangledName(const ConstString &name) { m_demangled = name; } 191 SetMangledName(const ConstString & name)192 void SetMangledName(const ConstString &name) { m_mangled = name; } 193 194 //---------------------------------------------------------------------- 195 /// Mangled name get accessor. 196 /// 197 /// @return 198 /// A reference to the mangled name string object. 199 //---------------------------------------------------------------------- GetMangledName()200 ConstString &GetMangledName() { return m_mangled; } 201 202 //---------------------------------------------------------------------- 203 /// Mangled name get accessor. 204 /// 205 /// @return 206 /// A const reference to the mangled name string object. 207 //---------------------------------------------------------------------- GetMangledName()208 const ConstString &GetMangledName() const { return m_mangled; } 209 210 //---------------------------------------------------------------------- 211 /// Best name get accessor. 212 /// 213 /// @param[in] preference 214 /// Which name would you prefer to get? 215 /// 216 /// @return 217 /// A const reference to the preferred name string object if this 218 /// object has a valid name of that kind, else a const reference to the 219 /// other name is returned. 220 //---------------------------------------------------------------------- 221 ConstString GetName(lldb::LanguageType language, 222 NamePreference preference = ePreferDemangled) const; 223 224 //---------------------------------------------------------------------- 225 /// Check if "name" matches either the mangled or demangled name. 226 /// 227 /// @param[in] name 228 /// A name to match against both strings. 229 /// 230 /// @return 231 /// \b True if \a name matches either name, \b false otherwise. 232 //---------------------------------------------------------------------- NameMatches(const ConstString & name,lldb::LanguageType language)233 bool NameMatches(const ConstString &name, lldb::LanguageType language) const { 234 if (m_mangled == name) 235 return true; 236 return GetDemangledName(language) == name; 237 } 238 bool NameMatches(const RegularExpression ®ex, 239 lldb::LanguageType language) const; 240 241 //---------------------------------------------------------------------- 242 /// Get the memory cost of this object. 243 /// 244 /// Return the size in bytes that this object takes in memory. This returns 245 /// the size in bytes of this object, not any shared string values it may 246 /// refer to. 247 /// 248 /// @return 249 /// The number of bytes that this object occupies in memory. 250 /// 251 /// @see ConstString::StaticMemorySize () 252 //---------------------------------------------------------------------- 253 size_t MemorySize() const; 254 255 //---------------------------------------------------------------------- 256 /// Set the string value in this object. 257 /// 258 /// If \a is_mangled is \b true, then the mangled named is set to \a name, 259 /// else the demangled name is set to \a name. 260 /// 261 /// @param[in] name 262 /// The already const version of the name for this object. 263 /// 264 /// @param[in] is_mangled 265 /// If \b true then \a name is a mangled name, if \b false then 266 /// \a name is demangled. 267 //---------------------------------------------------------------------- 268 void SetValue(const ConstString &name, bool is_mangled); 269 270 //---------------------------------------------------------------------- 271 /// Set the string value in this object. 272 /// 273 /// This version auto detects if the string is mangled by inspecting the 274 /// string value and looking for common mangling prefixes. 275 /// 276 /// @param[in] name 277 /// The already const version of the name for this object. 278 //---------------------------------------------------------------------- 279 void SetValue(const ConstString &name); 280 281 //---------------------------------------------------------------------- 282 /// Try to guess the language from the mangling. 283 /// 284 /// For a mangled name to have a language it must have both a mangled and a 285 /// demangled name and it can be guessed from the mangling what the language 286 /// is. Note: this will return C++ for any language that uses Itanium ABI 287 /// mangling. 288 /// 289 /// Standard C function names will return eLanguageTypeUnknown because they 290 /// aren't mangled and it isn't clear what language the name represents 291 /// (there will be no mangled name). 292 /// 293 /// @return 294 /// The language for the mangled/demangled name, eLanguageTypeUnknown 295 /// if there is no mangled or demangled counterpart. 296 //---------------------------------------------------------------------- 297 lldb::LanguageType GuessLanguage() const; 298 299 /// Function signature for filtering mangled names. 300 using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme); 301 302 //---------------------------------------------------------------------- 303 /// Trigger explicit demangling to obtain rich mangling information. This is 304 /// optimized for batch processing while populating a name index. To get the 305 /// pure demangled name string for a single entity, use GetDemangledName() 306 /// instead. 307 /// 308 /// For names that match the Itanium mangling scheme, this uses LLVM's 309 /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin 310 /// parser currently. 311 /// 312 /// This function is thread-safe when used with different \a context 313 /// instances in different threads. 314 /// 315 /// @param[in] context 316 /// The context for this function. A single instance can be stack- 317 /// allocated in the caller's frame and used for multiple calls. 318 /// 319 /// @param[in] skip_mangled_name 320 /// A filtering function for skipping entities based on name and mangling 321 /// scheme. This can be null if unused. 322 /// 323 /// @return 324 /// True on success, false otherwise. 325 //---------------------------------------------------------------------- 326 bool DemangleWithRichManglingInfo(RichManglingContext &context, 327 SkipMangledNameFn *skip_mangled_name); 328 329 private: 330 //---------------------------------------------------------------------- 331 /// Mangled member variables. 332 //---------------------------------------------------------------------- 333 ConstString m_mangled; ///< The mangled version of the name 334 mutable ConstString m_demangled; ///< Mutable so we can get it on demand with 335 ///a const version of this object 336 }; 337 338 Stream &operator<<(Stream &s, const Mangled &obj); 339 340 } // namespace lldb_private 341 342 #endif // #if defined(__cplusplus) 343 #endif // liblldb_Mangled_h_ 344