blob: cf351ba920cf6161f3069e658f173b4cad2e2796 [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"
Jim Inghamaa816b82015-09-02 01:59:14 +000041#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
Dawn Perchikbfd96182015-12-16 19:40:00 +000042#include "Plugins/Language/ObjC/ObjCLanguage.h"
Eli Friedman88966972010-06-09 08:50:27 +000043#include <ctype.h>
44#include <string.h>
Daniel Maleac91e4ab2013-05-31 20:21:38 +000045#include <stdlib.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046
Jason Molendaaff1b352014-10-10 23:07:36 +000047
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048using namespace lldb_private;
49
Chaoren Lin7f951142015-05-28 21:19:31 +000050static inline Mangled::ManglingScheme
51cstring_mangling_scheme(const char *s)
Greg Clayton5e0c5e82012-07-18 20:47:40 +000052{
53 if (s)
Chaoren Lin7f951142015-05-28 21:19:31 +000054 {
55 if (s[0] == '?')
56 return Mangled::eManglingSchemeMSVC;
57 if (s[0] == '_' && s[1] == 'Z')
58 return Mangled::eManglingSchemeItanium;
59 }
60 return Mangled::eManglingSchemeNone;
61}
62
63static inline bool
64cstring_is_mangled(const char *s)
65{
66 return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
Greg Clayton5e0c5e82012-07-18 20:47:40 +000067}
68
Jason Molendaaff1b352014-10-10 23:07:36 +000069static const ConstString &
Greg Claytonddaf6a72015-07-08 22:32:23 +000070get_demangled_name_without_arguments (ConstString mangled, ConstString demangled)
Jason Molendaaff1b352014-10-10 23:07:36 +000071{
72 // This pair is <mangled name, demangled name without function arguments>
73 static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args;
74
75 // Need to have the mangled & demangled names we're currently examining as statics
76 // so we can return a const ref to them at the end of the func if we don't have
77 // anything better.
78 static ConstString g_last_mangled;
79 static ConstString g_last_demangled;
80
Jason Molendaaff1b352014-10-10 23:07:36 +000081 if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled)
82 {
83 return g_most_recent_mangled_to_name_sans_args.second;
84 }
85
86 g_last_demangled = demangled;
87 g_last_mangled = mangled;
88
89 const char *mangled_name_cstr = mangled.GetCString();
Jason Molendaaff1b352014-10-10 23:07:36 +000090
91 if (demangled && mangled_name_cstr && mangled_name_cstr[0])
92 {
93 if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
94 (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name
95 mangled_name_cstr[2] != 'G' && // avoid guard variables
96 mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back)
97 {
Jim Inghamaa816b82015-09-02 01:59:14 +000098 CPlusPlusLanguage::MethodName cxx_method (demangled);
Tamas Berghammer5aa27e12015-07-24 08:54:22 +000099 if (!cxx_method.GetBasename().empty())
Jason Molendaaff1b352014-10-10 23:07:36 +0000100 {
Tamas Berghammer5aa27e12015-07-24 08:54:22 +0000101 std::string shortname;
102 if (!cxx_method.GetContext().empty())
103 shortname = cxx_method.GetContext().str() + "::";
Jason Molendaaff1b352014-10-10 23:07:36 +0000104 shortname += cxx_method.GetBasename().str();
105 ConstString result(shortname.c_str());
106 g_most_recent_mangled_to_name_sans_args.first = mangled;
107 g_most_recent_mangled_to_name_sans_args.second = result;
108 return g_most_recent_mangled_to_name_sans_args.second;
109 }
110 }
111 }
112
113 if (demangled)
114 return g_last_demangled;
115 return g_last_mangled;
116}
117
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118#pragma mark Mangled
119//----------------------------------------------------------------------
120// Default constructor
121//----------------------------------------------------------------------
122Mangled::Mangled () :
123 m_mangled(),
124 m_demangled()
125{
126}
127
128//----------------------------------------------------------------------
129// Constructor with an optional string and a boolean indicating if it is
130// the mangled version.
131//----------------------------------------------------------------------
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000132Mangled::Mangled (const ConstString &s, bool mangled) :
133 m_mangled(),
134 m_demangled()
135{
136 if (s)
137 SetValue(s, mangled);
138}
139
Greg Clayton037520e2012-07-18 23:18:10 +0000140Mangled::Mangled (const ConstString &s) :
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000141 m_mangled(),
142 m_demangled()
143{
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000144 if (s)
145 SetValue(s);
146}
147
148//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149// Destructor
150//----------------------------------------------------------------------
151Mangled::~Mangled ()
152{
153}
154
155//----------------------------------------------------------------------
156// Convert to pointer operator. This allows code to check any Mangled
157// objects to see if they contain anything valid using code such as:
158//
159// Mangled mangled(...);
160// if (mangled)
161// { ...
162//----------------------------------------------------------------------
163Mangled::operator void* () const
164{
165 return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
166}
167
168//----------------------------------------------------------------------
169// Logical NOT operator. This allows code to check any Mangled
170// objects to see if they are invalid using code such as:
171//
172// Mangled mangled(...);
173// if (!file_spec)
174// { ...
175//----------------------------------------------------------------------
176bool
177Mangled::operator! () const
178{
179 return !m_mangled;
180}
181
182//----------------------------------------------------------------------
183// Clear the mangled and demangled values.
184//----------------------------------------------------------------------
185void
186Mangled::Clear ()
187{
188 m_mangled.Clear();
189 m_demangled.Clear();
190}
191
192
193//----------------------------------------------------------------------
Bruce Mitchener58ef3912015-06-18 05:27:05 +0000194// Compare the string values.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195//----------------------------------------------------------------------
196int
197Mangled::Compare (const Mangled& a, const Mangled& b)
198{
Greg Claytonddaf6a72015-07-08 22:32:23 +0000199 return ConstString::Compare(a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000200}
201
202
203
204//----------------------------------------------------------------------
205// Set the string value in this objects. If "mangled" is true, then
206// the mangled named is set with the new value in "s", else the
207// demangled name is set.
208//----------------------------------------------------------------------
209void
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000210Mangled::SetValue (const ConstString &s, bool mangled)
211{
212 if (s)
213 {
214 if (mangled)
215 {
216 m_demangled.Clear();
217 m_mangled = s;
218 }
219 else
220 {
221 m_demangled = s;
222 m_mangled.Clear();
223 }
224 }
225 else
226 {
227 m_demangled.Clear();
228 m_mangled.Clear();
229 }
230}
231
232void
233Mangled::SetValue (const ConstString &name)
234{
235 if (name)
236 {
237 if (cstring_is_mangled(name.GetCString()))
238 {
239 m_demangled.Clear();
240 m_mangled = name;
241 }
242 else
243 {
244 m_demangled = name;
245 m_mangled.Clear();
246 }
247 }
248 else
249 {
250 m_demangled.Clear();
251 m_mangled.Clear();
252 }
253}
254
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255//----------------------------------------------------------------------
256// Generate the demangled name on demand using this accessor. Code in
257// this class will need to use this accessor if it wishes to decode
258// the demangled name. The result is cached and will be kept until a
259// new string value is supplied to this object, or until the end of the
260// object's lifetime.
261//----------------------------------------------------------------------
262const ConstString&
Greg Claytonddaf6a72015-07-08 22:32:23 +0000263Mangled::GetDemangledName (lldb::LanguageType language) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264{
265 // Check to make sure we have a valid mangled name and that we
266 // haven't already decoded our mangled name.
267 if (m_mangled && !m_demangled)
268 {
269 // We need to generate and cache the demangled name.
270 Timer scoped_timer (__PRETTY_FUNCTION__,
271 "Mangled::GetDemangledName (m_mangled = %s)",
272 m_mangled.GetCString());
273
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000274 // Don't bother running anything that isn't mangled
Chaoren Lin7f951142015-05-28 21:19:31 +0000275 const char *mangled_name = m_mangled.GetCString();
276 ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
277 if (mangling_scheme != eManglingSchemeNone &&
278 !m_mangled.GetMangledCounterpart(m_demangled))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279 {
Chaoren Lin7f951142015-05-28 21:19:31 +0000280 // We didn't already mangle this name, demangle it and if all goes well
281 // add it to our map.
282 char *demangled_name = nullptr;
283 switch (mangling_scheme)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284 {
Chaoren Lin7f951142015-05-28 21:19:31 +0000285 case eManglingSchemeMSVC:
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000286 {
Chaoren Lin7f951142015-05-28 21:19:31 +0000287#if defined(_MSC_VER)
288 const size_t demangled_length = 2048;
289 demangled_name = static_cast<char *>(::malloc(demangled_length));
290 ::ZeroMemory(demangled_name, demangled_length);
291 DWORD result = ::UnDecorateSymbolName(mangled_name, demangled_name, demangled_length,
292 UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected keywords
293 UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc keywords
294 UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
295 UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers
296 UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
297 );
298 if (result == 0)
299 {
300 free(demangled_name);
301 demangled_name = nullptr;
302 }
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000303#endif
Chaoren Lin7f951142015-05-28 21:19:31 +0000304 break;
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000305 }
Chaoren Lin7f951142015-05-28 21:19:31 +0000306 case eManglingSchemeItanium:
307 {
308#ifdef LLDB_USE_BUILTIN_DEMANGLER
309 // Try to use the fast-path demangler first for the
310 // performance win, falling back to the full demangler only
311 // when necessary
312 demangled_name = FastDemangle(mangled_name, m_mangled.GetLength());
313 if (!demangled_name)
314 demangled_name = __cxa_demangle(mangled_name, NULL, NULL, NULL);
315#else
316 demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
317#endif
318 break;
319 }
320 case eManglingSchemeNone:
321 break;
322 }
323 if (demangled_name)
324 {
325 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
326 free(demangled_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000327 }
328 }
Jason Molenda3f8688b2010-12-15 04:27:04 +0000329 if (!m_demangled)
330 {
331 // Set the demangled string to the empty string to indicate we
332 // tried to parse it once and failed.
333 m_demangled.SetCString("");
334 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000335 }
336
337 return m_demangled;
338}
339
Greg Clayton83c5cd92010-11-14 22:13:40 +0000340
Enrico Granatac1f705c2015-07-06 18:28:46 +0000341ConstString
Greg Claytonddaf6a72015-07-08 22:32:23 +0000342Mangled::GetDisplayDemangledName (lldb::LanguageType language) const
Enrico Granatac1f705c2015-07-06 18:28:46 +0000343{
Greg Claytonddaf6a72015-07-08 22:32:23 +0000344 return GetDemangledName(language);
Enrico Granatac1f705c2015-07-06 18:28:46 +0000345}
346
Greg Clayton83c5cd92010-11-14 22:13:40 +0000347bool
Greg Claytonddaf6a72015-07-08 22:32:23 +0000348Mangled::NameMatches (const RegularExpression& regex, lldb::LanguageType language) const
Greg Clayton83c5cd92010-11-14 22:13:40 +0000349{
350 if (m_mangled && regex.Execute (m_mangled.AsCString()))
351 return true;
Greg Claytonddaf6a72015-07-08 22:32:23 +0000352
353 ConstString demangled = GetDemangledName(language);
354 if (demangled && regex.Execute (demangled.AsCString()))
Greg Clayton83c5cd92010-11-14 22:13:40 +0000355 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//----------------------------------------------------------------------
Greg Claytonddaf6a72015-07-08 22:32:23 +0000362ConstString
363Mangled::GetName (lldb::LanguageType language, Mangled::NamePreference preference) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364{
Greg Claytonddaf6a72015-07-08 22:32:23 +0000365 ConstString demangled = GetDemangledName(language);
366
Jason Molendaaff1b352014-10-10 23:07:36 +0000367 if (preference == ePreferDemangledWithoutArguments)
368 {
Greg Claytonddaf6a72015-07-08 22:32:23 +0000369 return get_demangled_name_without_arguments (m_mangled, demangled);
Jason Molendaaff1b352014-10-10 23:07:36 +0000370 }
Greg Clayton87425432010-09-14 23:44:49 +0000371 if (preference == ePreferDemangled)
Jim Ingham08b87e02010-09-14 22:03:00 +0000372 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000373 // Call the accessor to make sure we get a demangled name in case
374 // it hasn't been demangled yet...
Greg Claytonddaf6a72015-07-08 22:32:23 +0000375 if (demangled)
376 return demangled;
Greg Clayton87425432010-09-14 23:44:49 +0000377 return m_mangled;
378 }
379 else
380 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000381 if (m_mangled)
382 return m_mangled;
Greg Claytonddaf6a72015-07-08 22:32:23 +0000383 return demangled;
Jim Ingham08b87e02010-09-14 22:03:00 +0000384 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385}
386
387//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388// Dump a Mangled object to stream "s". We don't force our
389// demangled name to be computed currently (we don't use the accessor).
390//----------------------------------------------------------------------
391void
392Mangled::Dump (Stream *s) const
393{
394 if (m_mangled)
395 {
396 *s << ", mangled = " << m_mangled;
397 }
398 if (m_demangled)
399 {
400 const char * demangled = m_demangled.AsCString();
401 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
402 }
403}
404
405//----------------------------------------------------------------------
406// Dumps a debug version of this string with extra object and state
407// information to stream "s".
408//----------------------------------------------------------------------
409void
410Mangled::DumpDebug (Stream *s) const
411{
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000412 s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void*) * 2),
413 static_cast<const void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414 m_mangled.DumpDebug(s);
415 s->Printf(", demangled = ");
416 m_demangled.DumpDebug(s);
417}
418
419//----------------------------------------------------------------------
420// Return the size in byte that this object takes in memory. The size
421// includes the size of the objects it owns, and not the strings that
422// it references because they are shared strings.
423//----------------------------------------------------------------------
424size_t
425Mangled::MemorySize () const
426{
427 return m_mangled.MemorySize() + m_demangled.MemorySize();
428}
429
Dawn Perchikbfd96182015-12-16 19:40:00 +0000430//----------------------------------------------------------------------
431// We "guess" the language because we can't determine a symbol's language
432// from it's name. For example, a Pascal symbol can be mangled using the
433// C++ Itanium scheme, and defined in a compilation unit within the same
434// module as other C++ units. In addition, different targets could have
435// different ways of mangling names from a given language, likewise the
436// compilation units within those targets.
437//----------------------------------------------------------------------
Greg Clayton94976f72015-01-23 23:18:53 +0000438lldb::LanguageType
Dawn Perchik1f93e862015-06-25 19:14:34 +0000439Mangled::GuessLanguage () const
Greg Clayton94976f72015-01-23 23:18:53 +0000440{
441 ConstString mangled = GetMangledName();
442 if (mangled)
443 {
Greg Claytonddaf6a72015-07-08 22:32:23 +0000444 if (GetDemangledName(lldb::eLanguageTypeUnknown))
Greg Clayton94976f72015-01-23 23:18:53 +0000445 {
Dawn Perchikbfd96182015-12-16 19:40:00 +0000446 const char *mangled_name = mangled.GetCString();
447 if (CPlusPlusLanguage::IsCPPMangledName(mangled_name))
Greg Clayton94976f72015-01-23 23:18:53 +0000448 return lldb::eLanguageTypeC_plus_plus;
Dawn Perchikbfd96182015-12-16 19:40:00 +0000449 else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name))
450 return lldb::eLanguageTypeObjC;
Greg Clayton94976f72015-01-23 23:18:53 +0000451 }
452 }
Dawn Perchikbfd96182015-12-16 19:40:00 +0000453 return lldb::eLanguageTypeUnknown;
Greg Clayton94976f72015-01-23 23:18:53 +0000454}
455
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456//----------------------------------------------------------------------
457// Dump OBJ to the supplied stream S.
458//----------------------------------------------------------------------
459Stream&
460operator << (Stream& s, const Mangled& obj)
461{
462 if (obj.GetMangledName())
463 s << "mangled = '" << obj.GetMangledName() << "'";
464
Greg Claytonddaf6a72015-07-08 22:32:23 +0000465 const ConstString& demangled = obj.GetDemangledName(lldb::eLanguageTypeUnknown);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466 if (demangled)
467 s << ", demangled = '" << demangled << '\'';
468 else
469 s << ", demangled = <error>";
470 return s;
471}