blob: 094710633ead16ab42814593343ddb37e0da6e86 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Mangled.cpp ---------------------------------------------*- 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
Greg Claytone9982672012-08-06 15:55:38 +000010
Filipe Cabecinhasdd393952012-09-11 18:11:12 +000011// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
12#include <cstddef>
Zachary Turnera45fa2c2015-01-14 18:34:43 +000013#if defined(_MSC_VER)
14#include "lldb/Host/windows/windows.h"
15#include <Dbghelp.h>
Leny Kholodovca951202015-07-02 15:54:13 +000016#pragma comment(lib, "dbghelp.lib")
Chaoren Lin7f951142015-05-28 21:19:31 +000017#define LLDB_USE_BUILTIN_DEMANGLER
Colin Riley61979cc2013-11-20 15:19:08 +000018#elif defined (__FreeBSD__)
Greg Clayton19c8e782013-10-30 18:42:59 +000019#define LLDB_USE_BUILTIN_DEMANGLER
20#else
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include <cxxabi.h>
Virgile Bellod0c5c772013-09-18 08:09:31 +000022#endif
Greg Claytone9982672012-08-06 15:55:38 +000023
Greg Clayton19c8e782013-10-30 18:42:59 +000024#ifdef LLDB_USE_BUILTIN_DEMANGLER
25
Kate Stonee2b21862014-07-22 17:03:38 +000026// Provide a fast-path demangler implemented in FastDemangle.cpp until it can
27// replace the existing C++ demangler with a complete implementation
Chaoren Lin7f951142015-05-28 21:19:31 +000028#include "lldb/Core/FastDemangle.h"
29#include "lldb/Core/CxaDemangle.h"
Ying Chenb6762732015-05-28 21:06:36 +000030
Greg Clayton19c8e782013-10-30 18:42:59 +000031#endif
32
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033
Greg Claytone41e5892010-09-03 23:26:12 +000034#include "llvm/ADT/DenseMap.h"
35
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036#include "lldb/Core/ConstString.h"
37#include "lldb/Core/Mangled.h"
Greg Clayton83c5cd92010-11-14 22:13:40 +000038#include "lldb/Core/RegularExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/Core/Stream.h"
40#include "lldb/Core/Timer.h"
Jason Molendaaff1b352014-10-10 23:07:36 +000041#include "lldb/Target/CPPLanguageRuntime.h"
Eli Friedman88966972010-06-09 08:50:27 +000042#include <ctype.h>
43#include <string.h>
Daniel Maleac91e4ab2013-05-31 20:21:38 +000044#include <stdlib.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045
Jason Molendaaff1b352014-10-10 23:07:36 +000046
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047using namespace lldb_private;
48
Chaoren Lin7f951142015-05-28 21:19:31 +000049static inline Mangled::ManglingScheme
50cstring_mangling_scheme(const char *s)
Greg Clayton5e0c5e82012-07-18 20:47:40 +000051{
52 if (s)
Chaoren Lin7f951142015-05-28 21:19:31 +000053 {
54 if (s[0] == '?')
55 return Mangled::eManglingSchemeMSVC;
56 if (s[0] == '_' && s[1] == 'Z')
57 return Mangled::eManglingSchemeItanium;
58 }
59 return Mangled::eManglingSchemeNone;
60}
61
62static inline bool
63cstring_is_mangled(const char *s)
64{
65 return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
Greg Clayton5e0c5e82012-07-18 20:47:40 +000066}
67
Jason Molendaaff1b352014-10-10 23:07:36 +000068static const ConstString &
69get_demangled_name_without_arguments (const Mangled *obj)
70{
71 // This pair is <mangled name, demangled name without function arguments>
72 static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args;
73
74 // Need to have the mangled & demangled names we're currently examining as statics
75 // so we can return a const ref to them at the end of the func if we don't have
76 // anything better.
77 static ConstString g_last_mangled;
78 static ConstString g_last_demangled;
79
80 ConstString mangled = obj->GetMangledName ();
81 ConstString demangled = obj->GetDemangledName ();
82
83 if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled)
84 {
85 return g_most_recent_mangled_to_name_sans_args.second;
86 }
87
88 g_last_demangled = demangled;
89 g_last_mangled = mangled;
90
91 const char *mangled_name_cstr = mangled.GetCString();
Jason Molendaaff1b352014-10-10 23:07:36 +000092
93 if (demangled && mangled_name_cstr && mangled_name_cstr[0])
94 {
95 if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
96 (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name
97 mangled_name_cstr[2] != 'G' && // avoid guard variables
98 mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back)
99 {
100 CPPLanguageRuntime::MethodName cxx_method (demangled);
101 if (!cxx_method.GetBasename().empty() && !cxx_method.GetContext().empty())
102 {
103 std::string shortname = cxx_method.GetContext().str();
104 shortname += "::";
105 shortname += cxx_method.GetBasename().str();
106 ConstString result(shortname.c_str());
107 g_most_recent_mangled_to_name_sans_args.first = mangled;
108 g_most_recent_mangled_to_name_sans_args.second = result;
109 return g_most_recent_mangled_to_name_sans_args.second;
110 }
111 }
112 }
113
114 if (demangled)
115 return g_last_demangled;
116 return g_last_mangled;
117}
118
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119#pragma mark Mangled
120//----------------------------------------------------------------------
121// Default constructor
122//----------------------------------------------------------------------
123Mangled::Mangled () :
124 m_mangled(),
125 m_demangled()
126{
127}
128
129//----------------------------------------------------------------------
130// Constructor with an optional string and a boolean indicating if it is
131// the mangled version.
132//----------------------------------------------------------------------
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000133Mangled::Mangled (const ConstString &s, bool mangled) :
134 m_mangled(),
135 m_demangled()
136{
137 if (s)
138 SetValue(s, mangled);
139}
140
Greg Clayton037520e2012-07-18 23:18:10 +0000141Mangled::Mangled (const ConstString &s) :
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000142 m_mangled(),
143 m_demangled()
144{
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000145 if (s)
146 SetValue(s);
147}
148
149//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150// Destructor
151//----------------------------------------------------------------------
152Mangled::~Mangled ()
153{
154}
155
156//----------------------------------------------------------------------
157// Convert to pointer operator. This allows code to check any Mangled
158// objects to see if they contain anything valid using code such as:
159//
160// Mangled mangled(...);
161// if (mangled)
162// { ...
163//----------------------------------------------------------------------
164Mangled::operator void* () const
165{
166 return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
167}
168
169//----------------------------------------------------------------------
170// Logical NOT operator. This allows code to check any Mangled
171// objects to see if they are invalid using code such as:
172//
173// Mangled mangled(...);
174// if (!file_spec)
175// { ...
176//----------------------------------------------------------------------
177bool
178Mangled::operator! () const
179{
180 return !m_mangled;
181}
182
183//----------------------------------------------------------------------
184// Clear the mangled and demangled values.
185//----------------------------------------------------------------------
186void
187Mangled::Clear ()
188{
189 m_mangled.Clear();
190 m_demangled.Clear();
191}
192
193
194//----------------------------------------------------------------------
Bruce Mitchener58ef3912015-06-18 05:27:05 +0000195// Compare the string values.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196//----------------------------------------------------------------------
197int
198Mangled::Compare (const Mangled& a, const Mangled& b)
199{
Jim Ingham89bf5e92010-09-15 00:13:44 +0000200 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201}
202
203
204
205//----------------------------------------------------------------------
206// Set the string value in this objects. If "mangled" is true, then
207// the mangled named is set with the new value in "s", else the
208// demangled name is set.
209//----------------------------------------------------------------------
210void
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000211Mangled::SetValue (const ConstString &s, bool mangled)
212{
213 if (s)
214 {
215 if (mangled)
216 {
217 m_demangled.Clear();
218 m_mangled = s;
219 }
220 else
221 {
222 m_demangled = s;
223 m_mangled.Clear();
224 }
225 }
226 else
227 {
228 m_demangled.Clear();
229 m_mangled.Clear();
230 }
231}
232
233void
234Mangled::SetValue (const ConstString &name)
235{
236 if (name)
237 {
238 if (cstring_is_mangled(name.GetCString()))
239 {
240 m_demangled.Clear();
241 m_mangled = name;
242 }
243 else
244 {
245 m_demangled = name;
246 m_mangled.Clear();
247 }
248 }
249 else
250 {
251 m_demangled.Clear();
252 m_mangled.Clear();
253 }
254}
255
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256//----------------------------------------------------------------------
257// Generate the demangled name on demand using this accessor. Code in
258// this class will need to use this accessor if it wishes to decode
259// the demangled name. The result is cached and will be kept until a
260// new string value is supplied to this object, or until the end of the
261// object's lifetime.
262//----------------------------------------------------------------------
263const ConstString&
264Mangled::GetDemangledName () const
265{
266 // Check to make sure we have a valid mangled name and that we
267 // haven't already decoded our mangled name.
268 if (m_mangled && !m_demangled)
269 {
270 // We need to generate and cache the demangled name.
271 Timer scoped_timer (__PRETTY_FUNCTION__,
272 "Mangled::GetDemangledName (m_mangled = %s)",
273 m_mangled.GetCString());
274
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000275 // Don't bother running anything that isn't mangled
Chaoren Lin7f951142015-05-28 21:19:31 +0000276 const char *mangled_name = m_mangled.GetCString();
277 ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
278 if (mangling_scheme != eManglingSchemeNone &&
279 !m_mangled.GetMangledCounterpart(m_demangled))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000280 {
Chaoren Lin7f951142015-05-28 21:19:31 +0000281 // We didn't already mangle this name, demangle it and if all goes well
282 // add it to our map.
283 char *demangled_name = nullptr;
284 switch (mangling_scheme)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000285 {
Chaoren Lin7f951142015-05-28 21:19:31 +0000286 case eManglingSchemeMSVC:
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000287 {
Chaoren Lin7f951142015-05-28 21:19:31 +0000288#if defined(_MSC_VER)
289 const size_t demangled_length = 2048;
290 demangled_name = static_cast<char *>(::malloc(demangled_length));
291 ::ZeroMemory(demangled_name, demangled_length);
292 DWORD result = ::UnDecorateSymbolName(mangled_name, demangled_name, demangled_length,
293 UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected keywords
294 UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc keywords
295 UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
296 UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers
297 UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
298 );
299 if (result == 0)
300 {
301 free(demangled_name);
302 demangled_name = nullptr;
303 }
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000304#endif
Chaoren Lin7f951142015-05-28 21:19:31 +0000305 break;
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000306 }
Chaoren Lin7f951142015-05-28 21:19:31 +0000307 case eManglingSchemeItanium:
308 {
309#ifdef LLDB_USE_BUILTIN_DEMANGLER
310 // Try to use the fast-path demangler first for the
311 // performance win, falling back to the full demangler only
312 // when necessary
313 demangled_name = FastDemangle(mangled_name, m_mangled.GetLength());
314 if (!demangled_name)
315 demangled_name = __cxa_demangle(mangled_name, NULL, NULL, NULL);
316#else
317 demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
318#endif
319 break;
320 }
321 case eManglingSchemeNone:
322 break;
323 }
324 if (demangled_name)
325 {
326 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
327 free(demangled_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328 }
329 }
Jason Molenda3f8688b2010-12-15 04:27:04 +0000330 if (!m_demangled)
331 {
332 // Set the demangled string to the empty string to indicate we
333 // tried to parse it once and failed.
334 m_demangled.SetCString("");
335 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336 }
337
338 return m_demangled;
339}
340
Greg Clayton83c5cd92010-11-14 22:13:40 +0000341
Enrico Granatac1f705c2015-07-06 18:28:46 +0000342ConstString
343Mangled::GetDisplayDemangledName () const
344{
345 return GetDemangledName();
346}
347
Greg Clayton83c5cd92010-11-14 22:13:40 +0000348bool
349Mangled::NameMatches (const RegularExpression& regex) const
350{
351 if (m_mangled && regex.Execute (m_mangled.AsCString()))
352 return true;
353
354 if (GetDemangledName() && regex.Execute (m_demangled.AsCString()))
355 return true;
356 return false;
357}
358
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359//----------------------------------------------------------------------
360// Get the demangled name if there is one, else return the mangled name.
361//----------------------------------------------------------------------
362const ConstString&
Jim Ingham08b87e02010-09-14 22:03:00 +0000363Mangled::GetName (Mangled::NamePreference preference) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364{
Jason Molendaaff1b352014-10-10 23:07:36 +0000365 if (preference == ePreferDemangledWithoutArguments)
366 {
367 // Call the accessor to make sure we get a demangled name in case
368 // it hasn't been demangled yet...
369 GetDemangledName();
370
371 return get_demangled_name_without_arguments (this);
372 }
Greg Clayton87425432010-09-14 23:44:49 +0000373 if (preference == ePreferDemangled)
Jim Ingham08b87e02010-09-14 22:03:00 +0000374 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000375 // Call the accessor to make sure we get a demangled name in case
376 // it hasn't been demangled yet...
377 if (GetDemangledName())
378 return m_demangled;
Greg Clayton87425432010-09-14 23:44:49 +0000379 return m_mangled;
380 }
381 else
382 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000383 if (m_mangled)
384 return m_mangled;
385 return GetDemangledName();
Jim Ingham08b87e02010-09-14 22:03:00 +0000386 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387}
388
389//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390// Dump a Mangled object to stream "s". We don't force our
391// demangled name to be computed currently (we don't use the accessor).
392//----------------------------------------------------------------------
393void
394Mangled::Dump (Stream *s) const
395{
396 if (m_mangled)
397 {
398 *s << ", mangled = " << m_mangled;
399 }
400 if (m_demangled)
401 {
402 const char * demangled = m_demangled.AsCString();
403 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
404 }
405}
406
407//----------------------------------------------------------------------
408// Dumps a debug version of this string with extra object and state
409// information to stream "s".
410//----------------------------------------------------------------------
411void
412Mangled::DumpDebug (Stream *s) const
413{
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000414 s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void*) * 2),
415 static_cast<const void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 m_mangled.DumpDebug(s);
417 s->Printf(", demangled = ");
418 m_demangled.DumpDebug(s);
419}
420
421//----------------------------------------------------------------------
422// Return the size in byte that this object takes in memory. The size
423// includes the size of the objects it owns, and not the strings that
424// it references because they are shared strings.
425//----------------------------------------------------------------------
426size_t
427Mangled::MemorySize () const
428{
429 return m_mangled.MemorySize() + m_demangled.MemorySize();
430}
431
Greg Clayton94976f72015-01-23 23:18:53 +0000432lldb::LanguageType
Dawn Perchik1f93e862015-06-25 19:14:34 +0000433Mangled::GuessLanguage () const
Greg Clayton94976f72015-01-23 23:18:53 +0000434{
435 ConstString mangled = GetMangledName();
436 if (mangled)
437 {
438 if (GetDemangledName())
439 {
440 if (cstring_is_mangled(mangled.GetCString()))
441 return lldb::eLanguageTypeC_plus_plus;
442 }
443 }
444 return lldb::eLanguageTypeUnknown;
445}
446
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447//----------------------------------------------------------------------
448// Dump OBJ to the supplied stream S.
449//----------------------------------------------------------------------
450Stream&
451operator << (Stream& s, const Mangled& obj)
452{
453 if (obj.GetMangledName())
454 s << "mangled = '" << obj.GetMangledName() << "'";
455
456 const ConstString& demangled = obj.GetDemangledName();
457 if (demangled)
458 s << ", demangled = '" << demangled << '\'';
459 else
460 s << ", demangled = <error>";
461 return s;
462}