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 &regex,
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