Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:45

0001 //===-- Mangled.h -----------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_CORE_MANGLED_H
0010 #define LLDB_CORE_MANGLED_H
0011 
0012 #include "lldb/lldb-enumerations.h"
0013 #include "lldb/lldb-forward.h"
0014 #include "lldb/lldb-types.h"
0015 #include "lldb/Utility/ConstString.h"
0016 #include "llvm/ADT/StringRef.h"
0017 
0018 #include <cstddef>
0019 #include <memory>
0020 
0021 namespace lldb_private {
0022 
0023 /// \class Mangled Mangled.h "lldb/Core/Mangled.h"
0024 /// A class that handles mangled names.
0025 ///
0026 /// Designed to handle mangled names. The demangled version of any names will
0027 /// be computed when the demangled name is accessed through the Demangled()
0028 /// accessor. This class can also tokenize the demangled version of the name
0029 /// for powerful searches. Functions and symbols could make instances of this
0030 /// class for their mangled names. Uniqued string pools are used for the
0031 /// mangled, demangled, and token string values to allow for faster
0032 /// comparisons and for efficient memory use.
0033 class Mangled {
0034 public:
0035   enum NamePreference {
0036     ePreferMangled,
0037     ePreferDemangled,
0038     ePreferDemangledWithoutArguments
0039   };
0040 
0041   enum ManglingScheme {
0042     eManglingSchemeNone = 0,
0043     eManglingSchemeMSVC,
0044     eManglingSchemeItanium,
0045     eManglingSchemeRustV0,
0046     eManglingSchemeD,
0047     eManglingSchemeSwift,
0048   };
0049 
0050   /// Default constructor.
0051   ///
0052   /// Initialize with both mangled and demangled names empty.
0053   Mangled() = default;
0054 
0055   /// Construct with name.
0056   ///
0057   /// Constructor with an optional string and auto-detect if \a name is
0058   /// mangled or not.
0059   ///
0060   /// \param[in] name
0061   ///     The already const name to copy into this object.
0062   explicit Mangled(ConstString name);
0063 
0064   explicit Mangled(llvm::StringRef name);
0065 
0066   bool operator==(const Mangled &rhs) const {
0067     return m_mangled == rhs.m_mangled &&
0068            GetDemangledName() == rhs.GetDemangledName();
0069   }
0070 
0071   bool operator!=(const Mangled &rhs) const {
0072     return !(*this == rhs);
0073   }
0074 
0075   /// Convert to bool operator.
0076   ///
0077   /// This allows code to check any Mangled objects to see if they contain
0078   /// anything valid using code such as:
0079   ///
0080   /// \code
0081   /// Mangled mangled(...);
0082   /// if (mangled)
0083   /// { ...
0084   /// \endcode
0085   ///
0086   /// \return
0087   ///     Returns \b true if either the mangled or unmangled name is set,
0088   ///     \b false if the object has an empty mangled and unmangled name.
0089   explicit operator bool() const;
0090 
0091   /// Clear the mangled and demangled values.
0092   void Clear();
0093 
0094   /// Compare the mangled string values
0095   ///
0096   /// Compares the Mangled::GetName() string in \a lhs and \a rhs.
0097   ///
0098   /// \param[in] lhs
0099   ///     A const reference to the Left Hand Side object to compare.
0100   ///
0101   /// \param[in] rhs
0102   ///     A const reference to the Right Hand Side object to compare.
0103   ///
0104   /// \return
0105   ///     -1 if \a lhs is less than \a rhs
0106   ///     0 if \a lhs is equal to \a rhs
0107   ///     1 if \a lhs is greater than \a rhs
0108   static int Compare(const Mangled &lhs, const Mangled &rhs);
0109 
0110   /// Dump a description of this object to a Stream \a s.
0111   ///
0112   /// Dump a Mangled object to stream \a s. We don't force our demangled name
0113   /// to be computed currently (we don't use the accessor).
0114   ///
0115   /// \param[in] s
0116   ///     The stream to which to dump the object description.
0117   void Dump(Stream *s) const;
0118 
0119   /// Dump a debug description of this object to a Stream \a s.
0120   ///
0121   /// \param[in] s
0122   ///     The stream to which to dump the object description.
0123   void DumpDebug(Stream *s) const;
0124 
0125   /// Demangled name get accessor.
0126   ///
0127   /// \return
0128   ///     A const reference to the demangled name string object.
0129   ConstString GetDemangledName() const;
0130 
0131   /// Display demangled name get accessor.
0132   ///
0133   /// \return
0134   ///     A const reference to the display demangled name string object.
0135   ConstString GetDisplayDemangledName() const;
0136 
0137   void SetDemangledName(ConstString name) { m_demangled = name; }
0138 
0139   void SetMangledName(ConstString name) { m_mangled = name; }
0140 
0141   /// Mangled name get accessor.
0142   ///
0143   /// \return
0144   ///     A reference to the mangled name string object.
0145   ConstString &GetMangledName() { return m_mangled; }
0146 
0147   /// Mangled name get accessor.
0148   ///
0149   /// \return
0150   ///     A const reference to the mangled name string object.
0151   ConstString GetMangledName() const { return m_mangled; }
0152 
0153   /// Best name get accessor.
0154   ///
0155   /// \param[in] preference
0156   ///     Which name would you prefer to get?
0157   ///
0158   /// \return
0159   ///     A const reference to the preferred name string object if this
0160   ///     object has a valid name of that kind, else a const reference to the
0161   ///     other name is returned.
0162   ConstString GetName(NamePreference preference = ePreferDemangled) const;
0163 
0164   /// Check if "name" matches either the mangled or demangled name.
0165   ///
0166   /// \param[in] name
0167   ///     A name to match against both strings.
0168   ///
0169   /// \return
0170   ///     \b True if \a name matches either name, \b false otherwise.
0171   bool NameMatches(ConstString name) const {
0172     if (m_mangled == name)
0173       return true;
0174     return GetDemangledName() == name;
0175   }
0176   bool NameMatches(const RegularExpression &regex) const;
0177 
0178   /// Get the memory cost of this object.
0179   ///
0180   /// Return the size in bytes that this object takes in memory. This returns
0181   /// the size in bytes of this object, not any shared string values it may
0182   /// refer to.
0183   ///
0184   /// \return
0185   ///     The number of bytes that this object occupies in memory.
0186   size_t MemorySize() const;
0187 
0188   /// Set the string value in this object.
0189   ///
0190   /// This version auto detects if the string is mangled by inspecting the
0191   /// string value and looking for common mangling prefixes.
0192   ///
0193   /// \param[in] name
0194   ///     The already const version of the name for this object.
0195   void SetValue(ConstString name);
0196 
0197   /// Try to guess the language from the mangling.
0198   ///
0199   /// For a mangled name to have a language it must have both a mangled and a
0200   /// demangled name and it can be guessed from the mangling what the language
0201   /// is.  Note: this will return C++ for any language that uses Itanium ABI
0202   /// mangling.
0203   ///
0204   /// Standard C function names will return eLanguageTypeUnknown because they
0205   /// aren't mangled and it isn't clear what language the name represents
0206   /// (there will be no mangled name).
0207   ///
0208   /// \return
0209   ///     The language for the mangled/demangled name, eLanguageTypeUnknown
0210   ///     if there is no mangled or demangled counterpart.
0211   lldb::LanguageType GuessLanguage() const;
0212 
0213   /// Function signature for filtering mangled names.
0214   using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme);
0215 
0216   /// Get rich mangling information. This is optimized for batch processing
0217   /// while populating a name index. To get the pure demangled name string for
0218   /// a single entity, use GetDemangledName() instead.
0219   ///
0220   /// For names that match the Itanium mangling scheme, this uses LLVM's
0221   /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
0222   /// parser currently.
0223   ///
0224   /// This function is thread-safe when used with different \a context
0225   /// instances in different threads.
0226   ///
0227   /// \param[in] context
0228   ///     The context for this function. A single instance can be stack-
0229   ///     allocated in the caller's frame and used for multiple calls.
0230   ///
0231   /// \param[in] skip_mangled_name
0232   ///     A filtering function for skipping entities based on name and mangling
0233   ///     scheme. This can be null if unused.
0234   ///
0235   /// \return
0236   ///     True on success, false otherwise.
0237   bool GetRichManglingInfo(RichManglingContext &context,
0238                            SkipMangledNameFn *skip_mangled_name);
0239 
0240   /// Try to identify the mangling scheme used.
0241   /// \param[in] name
0242   ///     The name we are attempting to identify the mangling scheme for.
0243   ///
0244   /// \return
0245   ///     eManglingSchemeNone if no known mangling scheme could be identified
0246   ///     for s, otherwise the enumerator for the mangling scheme detected.
0247   static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name);
0248 
0249   /// Decode a serialized version of this object from data.
0250   ///
0251   /// \param data
0252   ///   The decoder object that references the serialized data.
0253   ///
0254   /// \param offset_ptr
0255   ///   A pointer that contains the offset from which the data will be decoded
0256   ///   from that gets updated as data gets decoded.
0257   ///
0258   /// \param strtab
0259   ///   All strings in cache files are put into string tables for efficiency
0260   ///   and cache file size reduction. Strings are stored as uint32_t string
0261   ///   table offsets in the cache data.
0262   bool Decode(const DataExtractor &data, lldb::offset_t *offset_ptr,
0263               const StringTableReader &strtab);
0264 
0265   /// Encode this object into a data encoder object.
0266   ///
0267   /// This allows this object to be serialized to disk.
0268   ///
0269   /// \param encoder
0270   ///   A data encoder object that serialized bytes will be encoded into.
0271   ///
0272   /// \param strtab
0273   ///   All strings in cache files are put into string tables for efficiency
0274   ///   and cache file size reduction. Strings are stored as uint32_t string
0275   ///   table offsets in the cache data.
0276   void Encode(DataEncoder &encoder, ConstStringTable &strtab) const;
0277 
0278 private:
0279   /// Mangled member variables.
0280   ConstString m_mangled;           ///< The mangled version of the name
0281   mutable ConstString m_demangled; ///< Mutable so we can get it on demand with
0282                                    ///a const version of this object
0283 };
0284 
0285 Stream &operator<<(Stream &s, const Mangled &obj);
0286 
0287 } // namespace lldb_private
0288 
0289 #endif // LLDB_CORE_MANGLED_H