blob: e1b0738ce4d96714b5f2bdf597d48ad00754d79c [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 &
Greg Claytonddaf6a72015-07-08 22:32:23 +000069get_demangled_name_without_arguments (ConstString mangled, ConstString demangled)
Jason Molendaaff1b352014-10-10 23:07:36 +000070{
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
Jason Molendaaff1b352014-10-10 23:07:36 +000080 if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled)
81 {
82 return g_most_recent_mangled_to_name_sans_args.second;
83 }
84
85 g_last_demangled = demangled;
86 g_last_mangled = mangled;
87
88 const char *mangled_name_cstr = mangled.GetCString();
Jason Molendaaff1b352014-10-10 23:07:36 +000089
90 if (demangled && mangled_name_cstr && mangled_name_cstr[0])
91 {
92 if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
93 (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name
94 mangled_name_cstr[2] != 'G' && // avoid guard variables
95 mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back)
96 {
97 CPPLanguageRuntime::MethodName cxx_method (demangled);
Tamas Berghammer5aa27e12015-07-24 08:54:22 +000098 if (!cxx_method.GetBasename().empty())
Jason Molendaaff1b352014-10-10 23:07:36 +000099 {
Tamas Berghammer5aa27e12015-07-24 08:54:22 +0000100 std::string shortname;
101 if (!cxx_method.GetContext().empty())
102 shortname = cxx_method.GetContext().str() + "::";
Jason Molendaaff1b352014-10-10 23:07:36 +0000103 shortname += cxx_method.GetBasename().str();
104 ConstString result(shortname.c_str());
105 g_most_recent_mangled_to_name_sans_args.first = mangled;
106 g_most_recent_mangled_to_name_sans_args.second = result;
107 return g_most_recent_mangled_to_name_sans_args.second;
108 }
109 }
110 }
111
112 if (demangled)
113 return g_last_demangled;
114 return g_last_mangled;
115}
116
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117#pragma mark Mangled
118//----------------------------------------------------------------------
119// Default constructor
120//----------------------------------------------------------------------
121Mangled::Mangled () :
122 m_mangled(),
123 m_demangled()
124{
125}
126
127//----------------------------------------------------------------------
128// Constructor with an optional string and a boolean indicating if it is
129// the mangled version.
130//----------------------------------------------------------------------
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000131Mangled::Mangled (const ConstString &s, bool mangled) :
132 m_mangled(),
133 m_demangled()
134{
135 if (s)
136 SetValue(s, mangled);
137}
138
Greg Clayton037520e2012-07-18 23:18:10 +0000139Mangled::Mangled (const ConstString &s) :
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000140 m_mangled(),
141 m_demangled()
142{
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000143 if (s)
144 SetValue(s);
145}
146
147//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148// Destructor
149//----------------------------------------------------------------------
150Mangled::~Mangled ()
151{
152}
153
154//----------------------------------------------------------------------
155// Convert to pointer operator. This allows code to check any Mangled
156// objects to see if they contain anything valid using code such as:
157//
158// Mangled mangled(...);
159// if (mangled)
160// { ...
161//----------------------------------------------------------------------
162Mangled::operator void* () const
163{
164 return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
165}
166
167//----------------------------------------------------------------------
168// Logical NOT operator. This allows code to check any Mangled
169// objects to see if they are invalid using code such as:
170//
171// Mangled mangled(...);
172// if (!file_spec)
173// { ...
174//----------------------------------------------------------------------
175bool
176Mangled::operator! () const
177{
178 return !m_mangled;
179}
180
181//----------------------------------------------------------------------
182// Clear the mangled and demangled values.
183//----------------------------------------------------------------------
184void
185Mangled::Clear ()
186{
187 m_mangled.Clear();
188 m_demangled.Clear();
189}
190
191
192//----------------------------------------------------------------------
Bruce Mitchener58ef3912015-06-18 05:27:05 +0000193// Compare the string values.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000194//----------------------------------------------------------------------
195int
196Mangled::Compare (const Mangled& a, const Mangled& b)
197{
Greg Claytonddaf6a72015-07-08 22:32:23 +0000198 return ConstString::Compare(a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199}
200
201
202
203//----------------------------------------------------------------------
204// Set the string value in this objects. If "mangled" is true, then
205// the mangled named is set with the new value in "s", else the
206// demangled name is set.
207//----------------------------------------------------------------------
208void
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000209Mangled::SetValue (const ConstString &s, bool mangled)
210{
211 if (s)
212 {
213 if (mangled)
214 {
215 m_demangled.Clear();
216 m_mangled = s;
217 }
218 else
219 {
220 m_demangled = s;
221 m_mangled.Clear();
222 }
223 }
224 else
225 {
226 m_demangled.Clear();
227 m_mangled.Clear();
228 }
229}
230
231void
232Mangled::SetValue (const ConstString &name)
233{
234 if (name)
235 {
236 if (cstring_is_mangled(name.GetCString()))
237 {
238 m_demangled.Clear();
239 m_mangled = name;
240 }
241 else
242 {
243 m_demangled = name;
244 m_mangled.Clear();
245 }
246 }
247 else
248 {
249 m_demangled.Clear();
250 m_mangled.Clear();
251 }
252}
253
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000254//----------------------------------------------------------------------
255// Generate the demangled name on demand using this accessor. Code in
256// this class will need to use this accessor if it wishes to decode
257// the demangled name. The result is cached and will be kept until a
258// new string value is supplied to this object, or until the end of the
259// object's lifetime.
260//----------------------------------------------------------------------
261const ConstString&
Greg Claytonddaf6a72015-07-08 22:32:23 +0000262Mangled::GetDemangledName (lldb::LanguageType language) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263{
264 // Check to make sure we have a valid mangled name and that we
265 // haven't already decoded our mangled name.
266 if (m_mangled && !m_demangled)
267 {
268 // We need to generate and cache the demangled name.
269 Timer scoped_timer (__PRETTY_FUNCTION__,
270 "Mangled::GetDemangledName (m_mangled = %s)",
271 m_mangled.GetCString());
272
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000273 // Don't bother running anything that isn't mangled
Chaoren Lin7f951142015-05-28 21:19:31 +0000274 const char *mangled_name = m_mangled.GetCString();
275 ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
276 if (mangling_scheme != eManglingSchemeNone &&
277 !m_mangled.GetMangledCounterpart(m_demangled))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000278 {
Chaoren Lin7f951142015-05-28 21:19:31 +0000279 // We didn't already mangle this name, demangle it and if all goes well
280 // add it to our map.
281 char *demangled_name = nullptr;
282 switch (mangling_scheme)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283 {
Chaoren Lin7f951142015-05-28 21:19:31 +0000284 case eManglingSchemeMSVC:
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000285 {
Chaoren Lin7f951142015-05-28 21:19:31 +0000286#if defined(_MSC_VER)
287 const size_t demangled_length = 2048;
288 demangled_name = static_cast<char *>(::malloc(demangled_length));
289 ::ZeroMemory(demangled_name, demangled_length);
290 DWORD result = ::UnDecorateSymbolName(mangled_name, demangled_name, demangled_length,
291 UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected keywords
292 UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc keywords
293 UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
294 UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers
295 UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
296 );
297 if (result == 0)
298 {
299 free(demangled_name);
300 demangled_name = nullptr;
301 }
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000302#endif
Chaoren Lin7f951142015-05-28 21:19:31 +0000303 break;
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000304 }
Chaoren Lin7f951142015-05-28 21:19:31 +0000305 case eManglingSchemeItanium:
306 {
307#ifdef LLDB_USE_BUILTIN_DEMANGLER
308 // Try to use the fast-path demangler first for the
309 // performance win, falling back to the full demangler only
310 // when necessary
311 demangled_name = FastDemangle(mangled_name, m_mangled.GetLength());
312 if (!demangled_name)
313 demangled_name = __cxa_demangle(mangled_name, NULL, NULL, NULL);
314#else
315 demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
316#endif
317 break;
318 }
319 case eManglingSchemeNone:
320 break;
321 }
322 if (demangled_name)
323 {
324 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
325 free(demangled_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326 }
327 }
Jason Molenda3f8688b2010-12-15 04:27:04 +0000328 if (!m_demangled)
329 {
330 // Set the demangled string to the empty string to indicate we
331 // tried to parse it once and failed.
332 m_demangled.SetCString("");
333 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000334 }
335
336 return m_demangled;
337}
338
Greg Clayton83c5cd92010-11-14 22:13:40 +0000339
Enrico Granatac1f705c2015-07-06 18:28:46 +0000340ConstString
Greg Claytonddaf6a72015-07-08 22:32:23 +0000341Mangled::GetDisplayDemangledName (lldb::LanguageType language) const
Enrico Granatac1f705c2015-07-06 18:28:46 +0000342{
Greg Claytonddaf6a72015-07-08 22:32:23 +0000343 return GetDemangledName(language);
Enrico Granatac1f705c2015-07-06 18:28:46 +0000344}
345
Greg Clayton83c5cd92010-11-14 22:13:40 +0000346bool
Greg Claytonddaf6a72015-07-08 22:32:23 +0000347Mangled::NameMatches (const RegularExpression& regex, lldb::LanguageType language) const
Greg Clayton83c5cd92010-11-14 22:13:40 +0000348{
349 if (m_mangled && regex.Execute (m_mangled.AsCString()))
350 return true;
Greg Claytonddaf6a72015-07-08 22:32:23 +0000351
352 ConstString demangled = GetDemangledName(language);
353 if (demangled && regex.Execute (demangled.AsCString()))
Greg Clayton83c5cd92010-11-14 22:13:40 +0000354 return true;
355 return false;
356}
357
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358//----------------------------------------------------------------------
359// Get the demangled name if there is one, else return the mangled name.
360//----------------------------------------------------------------------
Greg Claytonddaf6a72015-07-08 22:32:23 +0000361ConstString
362Mangled::GetName (lldb::LanguageType language, Mangled::NamePreference preference) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000363{
Greg Claytonddaf6a72015-07-08 22:32:23 +0000364 ConstString demangled = GetDemangledName(language);
365
Jason Molendaaff1b352014-10-10 23:07:36 +0000366 if (preference == ePreferDemangledWithoutArguments)
367 {
Greg Claytonddaf6a72015-07-08 22:32:23 +0000368 return get_demangled_name_without_arguments (m_mangled, demangled);
Jason Molendaaff1b352014-10-10 23:07:36 +0000369 }
Greg Clayton87425432010-09-14 23:44:49 +0000370 if (preference == ePreferDemangled)
Jim Ingham08b87e02010-09-14 22:03:00 +0000371 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000372 // Call the accessor to make sure we get a demangled name in case
373 // it hasn't been demangled yet...
Greg Claytonddaf6a72015-07-08 22:32:23 +0000374 if (demangled)
375 return demangled;
Greg Clayton87425432010-09-14 23:44:49 +0000376 return m_mangled;
377 }
378 else
379 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000380 if (m_mangled)
381 return m_mangled;
Greg Claytonddaf6a72015-07-08 22:32:23 +0000382 return demangled;
Jim Ingham08b87e02010-09-14 22:03:00 +0000383 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384}
385
386//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387// Dump a Mangled object to stream "s". We don't force our
388// demangled name to be computed currently (we don't use the accessor).
389//----------------------------------------------------------------------
390void
391Mangled::Dump (Stream *s) const
392{
393 if (m_mangled)
394 {
395 *s << ", mangled = " << m_mangled;
396 }
397 if (m_demangled)
398 {
399 const char * demangled = m_demangled.AsCString();
400 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
401 }
402}
403
404//----------------------------------------------------------------------
405// Dumps a debug version of this string with extra object and state
406// information to stream "s".
407//----------------------------------------------------------------------
408void
409Mangled::DumpDebug (Stream *s) const
410{
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000411 s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void*) * 2),
412 static_cast<const void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000413 m_mangled.DumpDebug(s);
414 s->Printf(", demangled = ");
415 m_demangled.DumpDebug(s);
416}
417
418//----------------------------------------------------------------------
419// Return the size in byte that this object takes in memory. The size
420// includes the size of the objects it owns, and not the strings that
421// it references because they are shared strings.
422//----------------------------------------------------------------------
423size_t
424Mangled::MemorySize () const
425{
426 return m_mangled.MemorySize() + m_demangled.MemorySize();
427}
428
Greg Clayton94976f72015-01-23 23:18:53 +0000429lldb::LanguageType
Dawn Perchik1f93e862015-06-25 19:14:34 +0000430Mangled::GuessLanguage () const
Greg Clayton94976f72015-01-23 23:18:53 +0000431{
432 ConstString mangled = GetMangledName();
433 if (mangled)
434 {
Greg Claytonddaf6a72015-07-08 22:32:23 +0000435 if (GetDemangledName(lldb::eLanguageTypeUnknown))
Greg Clayton94976f72015-01-23 23:18:53 +0000436 {
437 if (cstring_is_mangled(mangled.GetCString()))
438 return lldb::eLanguageTypeC_plus_plus;
439 }
440 }
441 return lldb::eLanguageTypeUnknown;
442}
443
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000444//----------------------------------------------------------------------
445// Dump OBJ to the supplied stream S.
446//----------------------------------------------------------------------
447Stream&
448operator << (Stream& s, const Mangled& obj)
449{
450 if (obj.GetMangledName())
451 s << "mangled = '" << obj.GetMangledName() << "'";
452
Greg Claytonddaf6a72015-07-08 22:32:23 +0000453 const ConstString& demangled = obj.GetDemangledName(lldb::eLanguageTypeUnknown);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454 if (demangled)
455 s << ", demangled = '" << demangled << '\'';
456 else
457 s << ", demangled = <error>";
458 return s;
459}