blob: 376c16387b705ec77a503d2447fc495a563a1ebd [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
Filipe Cabecinhasdd393952012-09-11 18:11:12 +000010// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
11#include <cstddef>
Hafiz Abid Qadeerf6ee79c2016-12-15 15:00:41 +000012#if defined(_WIN32)
Zachary Turnera45fa2c2015-01-14 18:34:43 +000013#include "lldb/Host/windows/windows.h"
Hafiz Abid Qadeerf6ee79c2016-12-15 15:00:41 +000014#include <dbghelp.h>
Leny Kholodovca951202015-07-02 15:54:13 +000015#pragma comment(lib, "dbghelp.lib")
Virgile Bellod0c5c772013-09-18 08:09:31 +000016#endif
Greg Claytone9982672012-08-06 15:55:38 +000017
Greg Clayton19c8e782013-10-30 18:42:59 +000018#ifdef LLDB_USE_BUILTIN_DEMANGLER
Kate Stonee2b21862014-07-22 17:03:38 +000019// Provide a fast-path demangler implemented in FastDemangle.cpp until it can
20// replace the existing C++ demangler with a complete implementation
Rafael Espindola9aa7d662016-09-07 16:14:00 +000021#include "llvm/Demangle/Demangle.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000022#include "lldb/Core/FastDemangle.h"
Pavel Labath0e947eb2016-08-26 09:47:58 +000023#else
24#include <cxxabi.h>
Greg Clayton19c8e782013-10-30 18:42:59 +000025#endif
26
Greg Claytone41e5892010-09-03 23:26:12 +000027#include "llvm/ADT/DenseMap.h"
28
Kate Stoneb9c1b512016-09-06 20:57:50 +000029#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
30#include "Plugins/Language/ObjC/ObjCLanguage.h"
Greg Clayton4141c7a2016-05-27 00:17:18 +000031#include "lldb/Core/Log.h"
32#include "lldb/Core/Logging.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Core/Mangled.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Core/Timer.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000035#include "lldb/Utility/ConstString.h"
36#include "lldb/Utility/RegularExpression.h"
37#include "lldb/Utility/Stream.h"
Eli Friedman88966972010-06-09 08:50:27 +000038#include <ctype.h>
Daniel Maleac91e4ab2013-05-31 20:21:38 +000039#include <stdlib.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000040#include <string.h>
Jason Molendaaff1b352014-10-10 23:07:36 +000041
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042using namespace lldb_private;
43
Zachary Turner1f6a8d32017-02-28 20:29:20 +000044#if defined(_MSC_VER)
45static DWORD safeUndecorateName(const char* Mangled, char *Demangled, DWORD DemangledLength) {
46 static std::mutex M;
47 std::lock_guard<std::mutex> Lock(M);
48 return ::UnDecorateSymbolName(
49 Mangled, Demangled, DemangledLength,
50 UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected
51 // keywords
52 UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall,
53 // etc keywords
54 UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
55 UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc
56 // specifiers
57 UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
58 );
59}
60#endif
61
Kate Stoneb9c1b512016-09-06 20:57:50 +000062static inline Mangled::ManglingScheme cstring_mangling_scheme(const char *s) {
63 if (s) {
64 if (s[0] == '?')
65 return Mangled::eManglingSchemeMSVC;
66 if (s[0] == '_' && s[1] == 'Z')
67 return Mangled::eManglingSchemeItanium;
68 }
69 return Mangled::eManglingSchemeNone;
Chaoren Lin7f951142015-05-28 21:19:31 +000070}
71
Kate Stoneb9c1b512016-09-06 20:57:50 +000072static inline bool cstring_is_mangled(const char *s) {
73 return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
Greg Clayton5e0c5e82012-07-18 20:47:40 +000074}
75
Jason Molendaaff1b352014-10-10 23:07:36 +000076static const ConstString &
Kate Stoneb9c1b512016-09-06 20:57:50 +000077get_demangled_name_without_arguments(ConstString mangled,
78 ConstString demangled) {
79 // This pair is <mangled name, demangled name without function arguments>
80 static std::pair<ConstString, ConstString>
81 g_most_recent_mangled_to_name_sans_args;
Jason Molendaaff1b352014-10-10 23:07:36 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083 // Need to have the mangled & demangled names we're currently examining as
84 // statics
85 // so we can return a const ref to them at the end of the func if we don't
86 // have
87 // anything better.
88 static ConstString g_last_mangled;
89 static ConstString g_last_demangled;
Jason Molendaaff1b352014-10-10 23:07:36 +000090
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled) {
92 return g_most_recent_mangled_to_name_sans_args.second;
93 }
94
95 g_last_demangled = demangled;
96 g_last_mangled = mangled;
97
98 const char *mangled_name_cstr = mangled.GetCString();
99
100 if (demangled && mangled_name_cstr && mangled_name_cstr[0]) {
101 if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
102 (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
103 // typeinfo structure, and typeinfo
104 // mangled_name
105 mangled_name_cstr[2] != 'G' && // avoid guard variables
106 mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually
107 // handle eSymbolTypeData, we will want
108 // this back)
Jason Molendaaff1b352014-10-10 23:07:36 +0000109 {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 CPlusPlusLanguage::MethodName cxx_method(demangled);
111 if (!cxx_method.GetBasename().empty()) {
112 std::string shortname;
113 if (!cxx_method.GetContext().empty())
114 shortname = cxx_method.GetContext().str() + "::";
115 shortname += cxx_method.GetBasename().str();
116 ConstString result(shortname.c_str());
117 g_most_recent_mangled_to_name_sans_args.first = mangled;
118 g_most_recent_mangled_to_name_sans_args.second = result;
Jason Molendaaff1b352014-10-10 23:07:36 +0000119 return g_most_recent_mangled_to_name_sans_args.second;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 }
Jason Molendaaff1b352014-10-10 23:07:36 +0000121 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122 }
Jason Molendaaff1b352014-10-10 23:07:36 +0000123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 if (demangled)
125 return g_last_demangled;
126 return g_last_mangled;
Jason Molendaaff1b352014-10-10 23:07:36 +0000127}
128
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129#pragma mark Mangled
130//----------------------------------------------------------------------
131// Default constructor
132//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133Mangled::Mangled() : m_mangled(), m_demangled() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000134
135//----------------------------------------------------------------------
136// Constructor with an optional string and a boolean indicating if it is
137// the mangled version.
138//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139Mangled::Mangled(const ConstString &s, bool mangled)
140 : m_mangled(), m_demangled() {
141 if (s)
142 SetValue(s, mangled);
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000143}
144
Zachary Turner97d2c402016-10-05 23:40:23 +0000145Mangled::Mangled(llvm::StringRef name, bool is_mangled) {
146 if (!name.empty())
147 SetValue(ConstString(name), is_mangled);
148}
149
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150Mangled::Mangled(const ConstString &s) : m_mangled(), m_demangled() {
151 if (s)
152 SetValue(s);
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000153}
154
Zachary Turner97d2c402016-10-05 23:40:23 +0000155Mangled::Mangled(llvm::StringRef name) {
156 if (!name.empty())
157 SetValue(ConstString(name));
158}
159
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000160//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161// Destructor
162//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163Mangled::~Mangled() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000164
165//----------------------------------------------------------------------
166// Convert to pointer operator. This allows code to check any Mangled
167// objects to see if they contain anything valid using code such as:
168//
169// Mangled mangled(...);
170// if (mangled)
171// { ...
172//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173Mangled::operator void *() const {
174 return (m_mangled) ? const_cast<Mangled *>(this) : NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175}
176
177//----------------------------------------------------------------------
178// Logical NOT operator. This allows code to check any Mangled
179// objects to see if they are invalid using code such as:
180//
181// Mangled mangled(...);
182// if (!file_spec)
183// { ...
184//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185bool Mangled::operator!() const { return !m_mangled; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186
187//----------------------------------------------------------------------
188// Clear the mangled and demangled values.
189//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190void Mangled::Clear() {
191 m_mangled.Clear();
192 m_demangled.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000193}
194
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195//----------------------------------------------------------------------
Bruce Mitchener58ef3912015-06-18 05:27:05 +0000196// Compare the string values.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000197//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198int Mangled::Compare(const Mangled &a, const Mangled &b) {
199 return ConstString::Compare(
200 a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled),
201 a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000202}
203
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204//----------------------------------------------------------------------
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//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209void Mangled::SetValue(const ConstString &s, bool mangled) {
210 if (s) {
211 if (mangled) {
212 m_demangled.Clear();
213 m_mangled = s;
214 } else {
215 m_demangled = s;
216 m_mangled.Clear();
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000217 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218 } else {
219 m_demangled.Clear();
220 m_mangled.Clear();
221 }
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000222}
223
Kate Stoneb9c1b512016-09-06 20:57:50 +0000224void Mangled::SetValue(const ConstString &name) {
225 if (name) {
226 if (cstring_is_mangled(name.GetCString())) {
227 m_demangled.Clear();
228 m_mangled = name;
229 } else {
230 m_demangled = name;
231 m_mangled.Clear();
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000232 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 } else {
234 m_demangled.Clear();
235 m_mangled.Clear();
236 }
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000237}
238
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239//----------------------------------------------------------------------
240// Generate the demangled name on demand using this accessor. Code in
241// this class will need to use this accessor if it wishes to decode
242// the demangled name. The result is cached and will be kept until a
243// new string value is supplied to this object, or until the end of the
244// object's lifetime.
245//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246const ConstString &
247Mangled::GetDemangledName(lldb::LanguageType language) const {
248 // Check to make sure we have a valid mangled name and that we
249 // haven't already decoded our mangled name.
250 if (m_mangled && !m_demangled) {
251 // We need to generate and cache the demangled name.
252 Timer scoped_timer(LLVM_PRETTY_FUNCTION,
253 "Mangled::GetDemangledName (m_mangled = %s)",
254 m_mangled.GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255
Kate Stoneb9c1b512016-09-06 20:57:50 +0000256 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE);
Greg Clayton4141c7a2016-05-27 00:17:18 +0000257
Kate Stoneb9c1b512016-09-06 20:57:50 +0000258 // Don't bother running anything that isn't mangled
259 const char *mangled_name = m_mangled.GetCString();
260 ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
261 if (mangling_scheme != eManglingSchemeNone &&
262 !m_mangled.GetMangledCounterpart(m_demangled)) {
263 // We didn't already mangle this name, demangle it and if all goes well
264 // add it to our map.
265 char *demangled_name = nullptr;
266 switch (mangling_scheme) {
267 case eManglingSchemeMSVC: {
Chaoren Lin7f951142015-05-28 21:19:31 +0000268#if defined(_MSC_VER)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000269 if (log)
270 log->Printf("demangle msvc: %s", mangled_name);
271 const size_t demangled_length = 2048;
272 demangled_name = static_cast<char *>(::malloc(demangled_length));
273 ::ZeroMemory(demangled_name, demangled_length);
Zachary Turner1f6a8d32017-02-28 20:29:20 +0000274 DWORD result = safeUndecorateName(mangled_name, demangled_name, demangled_length);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000275 if (log) {
276 if (demangled_name && demangled_name[0])
277 log->Printf("demangled msvc: %s -> \"%s\"", mangled_name,
278 demangled_name);
279 else
Zachary Turner5a8ad4592016-10-05 17:07:34 +0000280 log->Printf("demangled msvc: %s -> error: 0x%lu", mangled_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281 result);
282 }
Greg Clayton4141c7a2016-05-27 00:17:18 +0000283
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 if (result == 0) {
285 free(demangled_name);
286 demangled_name = nullptr;
287 }
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000288#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000289 break;
290 }
291 case eManglingSchemeItanium: {
Chaoren Lin7f951142015-05-28 21:19:31 +0000292#ifdef LLDB_USE_BUILTIN_DEMANGLER
Kate Stoneb9c1b512016-09-06 20:57:50 +0000293 if (log)
294 log->Printf("demangle itanium: %s", mangled_name);
295 // Try to use the fast-path demangler first for the
296 // performance win, falling back to the full demangler only
297 // when necessary
298 demangled_name = FastDemangle(mangled_name, m_mangled.GetLength());
299 if (!demangled_name)
Rafael Espindola9aa7d662016-09-07 16:14:00 +0000300 demangled_name =
301 llvm::itaniumDemangle(mangled_name, NULL, NULL, NULL);
Chaoren Lin7f951142015-05-28 21:19:31 +0000302#else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000303 demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
Chaoren Lin7f951142015-05-28 21:19:31 +0000304#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000305 if (log) {
306 if (demangled_name)
307 log->Printf("demangled itanium: %s -> \"%s\"", mangled_name,
308 demangled_name);
309 else
310 log->Printf("demangled itanium: %s -> error: failed to demangle",
311 mangled_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000313 break;
314 }
315 case eManglingSchemeNone:
316 break;
317 }
318 if (demangled_name) {
319 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
320 free(demangled_name);
321 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000322 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000323 if (!m_demangled) {
324 // Set the demangled string to the empty string to indicate we
325 // tried to parse it once and failed.
326 m_demangled.SetCString("");
327 }
328 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000329
Kate Stoneb9c1b512016-09-06 20:57:50 +0000330 return m_demangled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000331}
332
Enrico Granatac1f705c2015-07-06 18:28:46 +0000333ConstString
Kate Stoneb9c1b512016-09-06 20:57:50 +0000334Mangled::GetDisplayDemangledName(lldb::LanguageType language) const {
335 return GetDemangledName(language);
Enrico Granatac1f705c2015-07-06 18:28:46 +0000336}
337
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338bool Mangled::NameMatches(const RegularExpression &regex,
339 lldb::LanguageType language) const {
340 if (m_mangled && regex.Execute(m_mangled.AsCString()))
341 return true;
Greg Claytonddaf6a72015-07-08 22:32:23 +0000342
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343 ConstString demangled = GetDemangledName(language);
344 if (demangled && regex.Execute(demangled.AsCString()))
345 return true;
346 return false;
Greg Clayton83c5cd92010-11-14 22:13:40 +0000347}
348
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349//----------------------------------------------------------------------
350// Get the demangled name if there is one, else return the mangled name.
351//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000352ConstString Mangled::GetName(lldb::LanguageType language,
353 Mangled::NamePreference preference) const {
354 if (preference == ePreferMangled && m_mangled)
355 return m_mangled;
Greg Clayton3feddff2015-12-17 01:00:50 +0000356
Kate Stoneb9c1b512016-09-06 20:57:50 +0000357 ConstString demangled = GetDemangledName(language);
Greg Claytonddaf6a72015-07-08 22:32:23 +0000358
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359 if (preference == ePreferDemangledWithoutArguments) {
360 return get_demangled_name_without_arguments(m_mangled, demangled);
361 }
362 if (preference == ePreferDemangled) {
363 // Call the accessor to make sure we get a demangled name in case
364 // it hasn't been demangled yet...
365 if (demangled)
366 return demangled;
367 return m_mangled;
368 }
369 return demangled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370}
371
372//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000373// Dump a Mangled object to stream "s". We don't force our
374// demangled name to be computed currently (we don't use the accessor).
375//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000376void Mangled::Dump(Stream *s) const {
377 if (m_mangled) {
378 *s << ", mangled = " << m_mangled;
379 }
380 if (m_demangled) {
381 const char *demangled = m_demangled.AsCString();
382 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
383 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384}
385
386//----------------------------------------------------------------------
387// Dumps a debug version of this string with extra object and state
388// information to stream "s".
389//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390void Mangled::DumpDebug(Stream *s) const {
391 s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void *) * 2),
392 static_cast<const void *>(this));
393 m_mangled.DumpDebug(s);
394 s->Printf(", demangled = ");
395 m_demangled.DumpDebug(s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396}
397
398//----------------------------------------------------------------------
399// Return the size in byte that this object takes in memory. The size
400// includes the size of the objects it owns, and not the strings that
401// it references because they are shared strings.
402//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000403size_t Mangled::MemorySize() const {
404 return m_mangled.MemorySize() + m_demangled.MemorySize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000405}
406
Dawn Perchikbfd96182015-12-16 19:40:00 +0000407//----------------------------------------------------------------------
408// We "guess" the language because we can't determine a symbol's language
409// from it's name. For example, a Pascal symbol can be mangled using the
410// C++ Itanium scheme, and defined in a compilation unit within the same
411// module as other C++ units. In addition, different targets could have
412// different ways of mangling names from a given language, likewise the
413// compilation units within those targets.
414//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415lldb::LanguageType Mangled::GuessLanguage() const {
416 ConstString mangled = GetMangledName();
417 if (mangled) {
418 if (GetDemangledName(lldb::eLanguageTypeUnknown)) {
419 const char *mangled_name = mangled.GetCString();
420 if (CPlusPlusLanguage::IsCPPMangledName(mangled_name))
421 return lldb::eLanguageTypeC_plus_plus;
422 else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name))
423 return lldb::eLanguageTypeObjC;
Greg Clayton94976f72015-01-23 23:18:53 +0000424 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000425 }
426 return lldb::eLanguageTypeUnknown;
Greg Clayton94976f72015-01-23 23:18:53 +0000427}
428
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429//----------------------------------------------------------------------
430// Dump OBJ to the supplied stream S.
431//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432Stream &operator<<(Stream &s, const Mangled &obj) {
433 if (obj.GetMangledName())
434 s << "mangled = '" << obj.GetMangledName() << "'";
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435
Kate Stoneb9c1b512016-09-06 20:57:50 +0000436 const ConstString &demangled =
437 obj.GetDemangledName(lldb::eLanguageTypeUnknown);
438 if (demangled)
439 s << ", demangled = '" << demangled << '\'';
440 else
441 s << ", demangled = <error>";
442 return s;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443}