blob: 00a90a7eb39e71c6b1cb66b866dda6ca61f238d5 [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>
Chaoren Lin7f951142015-05-28 21:19:31 +000016#define LLDB_USE_BUILTIN_DEMANGLER
Colin Riley61979cc2013-11-20 15:19:08 +000017#elif defined (__FreeBSD__)
Greg Clayton19c8e782013-10-30 18:42:59 +000018#define LLDB_USE_BUILTIN_DEMANGLER
19#else
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include <cxxabi.h>
Virgile Bellod0c5c772013-09-18 08:09:31 +000021#endif
Greg Claytone9982672012-08-06 15:55:38 +000022
Greg Clayton19c8e782013-10-30 18:42:59 +000023#ifdef LLDB_USE_BUILTIN_DEMANGLER
24
Kate Stonee2b21862014-07-22 17:03:38 +000025// Provide a fast-path demangler implemented in FastDemangle.cpp until it can
26// replace the existing C++ demangler with a complete implementation
Chaoren Lin7f951142015-05-28 21:19:31 +000027#include "lldb/Core/FastDemangle.h"
28#include "lldb/Core/CxaDemangle.h"
Ying Chenb6762732015-05-28 21:06:36 +000029
Greg Clayton19c8e782013-10-30 18:42:59 +000030#endif
31
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032
Greg Claytone41e5892010-09-03 23:26:12 +000033#include "llvm/ADT/DenseMap.h"
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Core/ConstString.h"
36#include "lldb/Core/Mangled.h"
Greg Clayton83c5cd92010-11-14 22:13:40 +000037#include "lldb/Core/RegularExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038#include "lldb/Core/Stream.h"
39#include "lldb/Core/Timer.h"
Jason Molendaaff1b352014-10-10 23:07:36 +000040#include "lldb/Target/CPPLanguageRuntime.h"
Eli Friedman88966972010-06-09 08:50:27 +000041#include <ctype.h>
42#include <string.h>
Daniel Maleac91e4ab2013-05-31 20:21:38 +000043#include <stdlib.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044
Jason Molendaaff1b352014-10-10 23:07:36 +000045
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046using namespace lldb_private;
47
Chaoren Lin7f951142015-05-28 21:19:31 +000048static inline Mangled::ManglingScheme
49cstring_mangling_scheme(const char *s)
Greg Clayton5e0c5e82012-07-18 20:47:40 +000050{
51 if (s)
Chaoren Lin7f951142015-05-28 21:19:31 +000052 {
53 if (s[0] == '?')
54 return Mangled::eManglingSchemeMSVC;
55 if (s[0] == '_' && s[1] == 'Z')
56 return Mangled::eManglingSchemeItanium;
57 }
58 return Mangled::eManglingSchemeNone;
59}
60
61static inline bool
62cstring_is_mangled(const char *s)
63{
64 return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
Greg Clayton5e0c5e82012-07-18 20:47:40 +000065}
66
Jason Molendaaff1b352014-10-10 23:07:36 +000067static const ConstString &
68get_demangled_name_without_arguments (const Mangled *obj)
69{
70 // This pair is <mangled name, demangled name without function arguments>
71 static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args;
72
73 // Need to have the mangled & demangled names we're currently examining as statics
74 // so we can return a const ref to them at the end of the func if we don't have
75 // anything better.
76 static ConstString g_last_mangled;
77 static ConstString g_last_demangled;
78
79 ConstString mangled = obj->GetMangledName ();
80 ConstString demangled = obj->GetDemangledName ();
81
82 if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled)
83 {
84 return g_most_recent_mangled_to_name_sans_args.second;
85 }
86
87 g_last_demangled = demangled;
88 g_last_mangled = mangled;
89
90 const char *mangled_name_cstr = mangled.GetCString();
Jason Molendaaff1b352014-10-10 23:07:36 +000091
92 if (demangled && mangled_name_cstr && mangled_name_cstr[0])
93 {
94 if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
95 (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name
96 mangled_name_cstr[2] != 'G' && // avoid guard variables
97 mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back)
98 {
99 CPPLanguageRuntime::MethodName cxx_method (demangled);
100 if (!cxx_method.GetBasename().empty() && !cxx_method.GetContext().empty())
101 {
102 std::string shortname = cxx_method.GetContext().str();
103 shortname += "::";
104 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{
Jim Ingham89bf5e92010-09-15 00:13:44 +0000199 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(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&
263Mangled::GetDemangledName () const
264{
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
341bool
342Mangled::NameMatches (const RegularExpression& regex) const
343{
344 if (m_mangled && regex.Execute (m_mangled.AsCString()))
345 return true;
346
347 if (GetDemangledName() && regex.Execute (m_demangled.AsCString()))
348 return true;
349 return false;
350}
351
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352//----------------------------------------------------------------------
353// Get the demangled name if there is one, else return the mangled name.
354//----------------------------------------------------------------------
355const ConstString&
Jim Ingham08b87e02010-09-14 22:03:00 +0000356Mangled::GetName (Mangled::NamePreference preference) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000357{
Jason Molendaaff1b352014-10-10 23:07:36 +0000358 if (preference == ePreferDemangledWithoutArguments)
359 {
360 // Call the accessor to make sure we get a demangled name in case
361 // it hasn't been demangled yet...
362 GetDemangledName();
363
364 return get_demangled_name_without_arguments (this);
365 }
Greg Clayton87425432010-09-14 23:44:49 +0000366 if (preference == ePreferDemangled)
Jim Ingham08b87e02010-09-14 22:03:00 +0000367 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000368 // Call the accessor to make sure we get a demangled name in case
369 // it hasn't been demangled yet...
370 if (GetDemangledName())
371 return m_demangled;
Greg Clayton87425432010-09-14 23:44:49 +0000372 return m_mangled;
373 }
374 else
375 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000376 if (m_mangled)
377 return m_mangled;
378 return GetDemangledName();
Jim Ingham08b87e02010-09-14 22:03:00 +0000379 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380}
381
382//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383// Dump a Mangled object to stream "s". We don't force our
384// demangled name to be computed currently (we don't use the accessor).
385//----------------------------------------------------------------------
386void
387Mangled::Dump (Stream *s) const
388{
389 if (m_mangled)
390 {
391 *s << ", mangled = " << m_mangled;
392 }
393 if (m_demangled)
394 {
395 const char * demangled = m_demangled.AsCString();
396 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
397 }
398}
399
400//----------------------------------------------------------------------
401// Dumps a debug version of this string with extra object and state
402// information to stream "s".
403//----------------------------------------------------------------------
404void
405Mangled::DumpDebug (Stream *s) const
406{
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000407 s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void*) * 2),
408 static_cast<const void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000409 m_mangled.DumpDebug(s);
410 s->Printf(", demangled = ");
411 m_demangled.DumpDebug(s);
412}
413
414//----------------------------------------------------------------------
415// Return the size in byte that this object takes in memory. The size
416// includes the size of the objects it owns, and not the strings that
417// it references because they are shared strings.
418//----------------------------------------------------------------------
419size_t
420Mangled::MemorySize () const
421{
422 return m_mangled.MemorySize() + m_demangled.MemorySize();
423}
424
Greg Clayton94976f72015-01-23 23:18:53 +0000425lldb::LanguageType
Dawn Perchik1f93e862015-06-25 19:14:34 +0000426Mangled::GuessLanguage () const
Greg Clayton94976f72015-01-23 23:18:53 +0000427{
428 ConstString mangled = GetMangledName();
429 if (mangled)
430 {
431 if (GetDemangledName())
432 {
433 if (cstring_is_mangled(mangled.GetCString()))
434 return lldb::eLanguageTypeC_plus_plus;
435 }
436 }
437 return lldb::eLanguageTypeUnknown;
438}
439
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440//----------------------------------------------------------------------
441// Dump OBJ to the supplied stream S.
442//----------------------------------------------------------------------
443Stream&
444operator << (Stream& s, const Mangled& obj)
445{
446 if (obj.GetMangledName())
447 s << "mangled = '" << obj.GetMangledName() << "'";
448
449 const ConstString& demangled = obj.GetDemangledName();
450 if (demangled)
451 s << ", demangled = '" << demangled << '\'';
452 else
453 s << ", demangled = <error>";
454 return s;
455}