1 //===-- Mangled.cpp ---------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "lldb/Core/Mangled.h"
13 #include "lldb/Host/windows/windows.h"
16 #pragma comment(lib, "dbghelp.lib")
19 #include "lldb/Core/RichManglingContext.h"
20 #include "lldb/Utility/ConstString.h"
21 #include "lldb/Utility/Log.h"
22 #include "lldb/Utility/Logging.h"
23 #include "lldb/Utility/RegularExpression.h"
24 #include "lldb/Utility/Stream.h"
25 #include "lldb/Utility/Timer.h"
26 #include "lldb/lldb-enumerations.h"
28 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
29 #include "Plugins/Language/ObjC/ObjCLanguage.h"
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/Demangle/Demangle.h"
33 #include "llvm/Support/Compiler.h"
41 using namespace lldb_private;
44 static DWORD safeUndecorateName(const char *Mangled, char *Demangled,
45 DWORD DemangledLength) {
47 std::lock_guard<std::mutex> Lock(M);
48 return ::UnDecorateSymbolName(
49 Mangled, Demangled, DemangledLength,
50 UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected
52 UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall,
54 UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
55 UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc
57 UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
62 static inline Mangled::ManglingScheme cstring_mangling_scheme(const char *s) {
65 return Mangled::eManglingSchemeMSVC;
66 if (s[0] == '_' && s[1] == 'Z')
67 return Mangled::eManglingSchemeItanium;
69 return Mangled::eManglingSchemeNone;
72 static inline bool cstring_is_mangled(const char *s) {
73 return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
76 static const ConstString &
77 get_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;
83 // Need to have the mangled & demangled names we're currently examining as
84 // statics so we can return a const ref to them at the end of the func if we
85 // don't have anything better.
86 static ConstString g_last_mangled;
87 static ConstString g_last_demangled;
89 if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled) {
90 return g_most_recent_mangled_to_name_sans_args.second;
93 g_last_demangled = demangled;
94 g_last_mangled = mangled;
96 const char *mangled_name_cstr = mangled.GetCString();
98 if (demangled && mangled_name_cstr && mangled_name_cstr[0]) {
99 if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
100 (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
101 // typeinfo structure, and typeinfo
103 mangled_name_cstr[2] != 'G' && // avoid guard variables
104 mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually
105 // handle eSymbolTypeData, we will want
108 CPlusPlusLanguage::MethodName cxx_method(demangled);
109 if (!cxx_method.GetBasename().empty()) {
110 std::string shortname;
111 if (!cxx_method.GetContext().empty())
112 shortname = cxx_method.GetContext().str() + "::";
113 shortname += cxx_method.GetBasename().str();
114 ConstString result(shortname.c_str());
115 g_most_recent_mangled_to_name_sans_args.first = mangled;
116 g_most_recent_mangled_to_name_sans_args.second = result;
117 return g_most_recent_mangled_to_name_sans_args.second;
123 return g_last_demangled;
124 return g_last_mangled;
128 //----------------------------------------------------------------------
129 // Default constructor
130 //----------------------------------------------------------------------
131 Mangled::Mangled() : m_mangled(), m_demangled() {}
133 //----------------------------------------------------------------------
134 // Constructor with an optional string and a boolean indicating if it is the
136 //----------------------------------------------------------------------
137 Mangled::Mangled(const ConstString &s, bool mangled)
138 : m_mangled(), m_demangled() {
140 SetValue(s, mangled);
143 Mangled::Mangled(llvm::StringRef name, bool is_mangled) {
145 SetValue(ConstString(name), is_mangled);
148 Mangled::Mangled(const ConstString &s) : m_mangled(), m_demangled() {
153 Mangled::Mangled(llvm::StringRef name) {
155 SetValue(ConstString(name));
158 //----------------------------------------------------------------------
160 //----------------------------------------------------------------------
161 Mangled::~Mangled() {}
163 //----------------------------------------------------------------------
164 // Convert to pointer operator. This allows code to check any Mangled objects
165 // to see if they contain anything valid using code such as:
167 // Mangled mangled(...);
170 //----------------------------------------------------------------------
171 Mangled::operator void *() const {
172 return (m_mangled) ? const_cast<Mangled *>(this) : NULL;
175 //----------------------------------------------------------------------
176 // Logical NOT operator. This allows code to check any Mangled objects to see
177 // if they are invalid using code such as:
179 // Mangled mangled(...);
182 //----------------------------------------------------------------------
183 bool Mangled::operator!() const { return !m_mangled; }
185 //----------------------------------------------------------------------
186 // Clear the mangled and demangled values.
187 //----------------------------------------------------------------------
188 void Mangled::Clear() {
193 //----------------------------------------------------------------------
194 // Compare the string values.
195 //----------------------------------------------------------------------
196 int Mangled::Compare(const Mangled &a, const Mangled &b) {
197 return ConstString::Compare(
198 a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled),
199 b.GetName(lldb::eLanguageTypeUnknown, ePreferMangled));
202 //----------------------------------------------------------------------
203 // Set the string value in this objects. If "mangled" is true, then the mangled
204 // named is set with the new value in "s", else the demangled name is set.
205 //----------------------------------------------------------------------
206 void Mangled::SetValue(const ConstString &s, bool mangled) {
221 void Mangled::SetValue(const ConstString &name) {
223 if (cstring_is_mangled(name.GetCString())) {
236 //----------------------------------------------------------------------
237 // Local helpers for different demangling implementations.
238 //----------------------------------------------------------------------
239 static char *GetMSVCDemangledStr(const char *M) {
240 #if defined(_MSC_VER)
241 const size_t demangled_length = 2048;
242 char *demangled_cstr = static_cast<char *>(::malloc(demangled_length));
243 ::ZeroMemory(demangled_cstr, demangled_length);
244 DWORD result = safeUndecorateName(M, demangled_cstr, demangled_length);
246 if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) {
247 if (demangled_cstr && demangled_cstr[0])
248 log->Printf("demangled msvc: %s -> \"%s\"", M, demangled_cstr);
250 log->Printf("demangled msvc: %s -> error: 0x%lu", M, result);
254 return demangled_cstr;
256 ::free(demangled_cstr);
264 static char *GetItaniumDemangledStr(const char *M) {
265 char *demangled_cstr = nullptr;
267 llvm::ItaniumPartialDemangler ipd;
268 bool err = ipd.partialDemangle(M);
270 // Default buffer and size (will realloc in case it's too small).
271 size_t demangled_size = 80;
272 demangled_cstr = static_cast<char *>(std::malloc(demangled_size));
273 demangled_cstr = ipd.finishDemangle(demangled_cstr, &demangled_size);
275 assert(demangled_cstr &&
276 "finishDemangle must always succeed if partialDemangle did");
277 assert(demangled_cstr[demangled_size - 1] == '\0' &&
278 "Expected demangled_size to return length including trailing null");
281 if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) {
283 log->Printf("demangled itanium: %s -> \"%s\"", M, demangled_cstr);
285 log->Printf("demangled itanium: %s -> error: failed to demangle", M);
288 return demangled_cstr;
291 //----------------------------------------------------------------------
292 // Explicit demangling for scheduled requests during batch processing. This
293 // makes use of ItaniumPartialDemangler's rich demangle info
294 //----------------------------------------------------------------------
295 bool Mangled::DemangleWithRichManglingInfo(
296 RichManglingContext &context, SkipMangledNameFn *skip_mangled_name) {
297 // We need to generate and cache the demangled name.
298 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
299 Timer scoped_timer(func_cat,
300 "Mangled::DemangleWithRichNameIndexInfo (m_mangled = %s)",
301 m_mangled.GetCString());
303 // Others are not meant to arrive here. ObjC names or C's main() for example
304 // have their names stored in m_demangled, while m_mangled is empty.
307 // Check whether or not we are interested in this name at all.
308 ManglingScheme scheme = cstring_mangling_scheme(m_mangled.GetCString());
309 if (skip_mangled_name && skip_mangled_name(m_mangled.GetStringRef(), scheme))
313 case eManglingSchemeNone:
314 // The current mangled_name_filter would allow llvm_unreachable here.
317 case eManglingSchemeItanium:
318 // We want the rich mangling info here, so we don't care whether or not
319 // there is a demangled string in the pool already.
320 if (context.FromItaniumName(m_mangled)) {
321 // If we got an info, we have a name. Copy to string pool and connect the
322 // counterparts to accelerate later access in GetDemangledName().
323 context.ParseFullName();
324 m_demangled.SetStringWithMangledCounterpart(context.GetBufferRef(),
328 m_demangled.SetCString("");
332 case eManglingSchemeMSVC: {
333 // We have no rich mangling for MSVC-mangled names yet, so first try to
334 // demangle it if necessary.
335 if (!m_demangled && !m_mangled.GetMangledCounterpart(m_demangled)) {
336 if (char *d = GetMSVCDemangledStr(m_mangled.GetCString())) {
337 // If we got an info, we have a name. Copy to string pool and connect
338 // the counterparts to accelerate later access in GetDemangledName().
339 m_demangled.SetStringWithMangledCounterpart(llvm::StringRef(d),
343 m_demangled.SetCString("");
347 if (m_demangled.IsEmpty()) {
348 // Cannot demangle it, so don't try parsing.
351 // Demangled successfully, we can try and parse it with
352 // CPlusPlusLanguage::MethodName.
353 return context.FromCxxMethodName(m_demangled);
357 llvm_unreachable("Fully covered switch above!");
360 //----------------------------------------------------------------------
361 // Generate the demangled name on demand using this accessor. Code in this
362 // class will need to use this accessor if it wishes to decode the demangled
363 // name. The result is cached and will be kept until a new string value is
364 // supplied to this object, or until the end of the object's lifetime.
365 //----------------------------------------------------------------------
367 Mangled::GetDemangledName(lldb::LanguageType language) const {
368 // Check to make sure we have a valid mangled name and that we haven't
369 // already decoded our mangled name.
370 if (m_mangled && m_demangled.IsNull()) {
371 // We need to generate and cache the demangled name.
372 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
373 Timer scoped_timer(func_cat, "Mangled::GetDemangledName (m_mangled = %s)",
374 m_mangled.GetCString());
376 // Don't bother running anything that isn't mangled
377 const char *mangled_name = m_mangled.GetCString();
378 ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
379 if (mangling_scheme != eManglingSchemeNone &&
380 !m_mangled.GetMangledCounterpart(m_demangled)) {
381 // We didn't already mangle this name, demangle it and if all goes well
382 // add it to our map.
383 char *demangled_name = nullptr;
384 switch (mangling_scheme) {
385 case eManglingSchemeMSVC:
386 demangled_name = GetMSVCDemangledStr(mangled_name);
388 case eManglingSchemeItanium: {
389 demangled_name = GetItaniumDemangledStr(mangled_name);
392 case eManglingSchemeNone:
393 llvm_unreachable("eManglingSchemeNone was handled already");
395 if (demangled_name) {
396 m_demangled.SetStringWithMangledCounterpart(
397 llvm::StringRef(demangled_name), m_mangled);
398 free(demangled_name);
401 if (m_demangled.IsNull()) {
402 // Set the demangled string to the empty string to indicate we tried to
403 // parse it once and failed.
404 m_demangled.SetCString("");
412 Mangled::GetDisplayDemangledName(lldb::LanguageType language) const {
413 return GetDemangledName(language);
416 bool Mangled::NameMatches(const RegularExpression ®ex,
417 lldb::LanguageType language) const {
418 if (m_mangled && regex.Execute(m_mangled.AsCString()))
421 ConstString demangled = GetDemangledName(language);
422 return demangled && regex.Execute(demangled.AsCString());
425 //----------------------------------------------------------------------
426 // Get the demangled name if there is one, else return the mangled name.
427 //----------------------------------------------------------------------
428 ConstString Mangled::GetName(lldb::LanguageType language,
429 Mangled::NamePreference preference) const {
430 if (preference == ePreferMangled && m_mangled)
433 ConstString demangled = GetDemangledName(language);
435 if (preference == ePreferDemangledWithoutArguments) {
436 return get_demangled_name_without_arguments(m_mangled, demangled);
438 if (preference == ePreferDemangled) {
439 // Call the accessor to make sure we get a demangled name in case it hasn't
440 // been demangled yet...
448 //----------------------------------------------------------------------
449 // Dump a Mangled object to stream "s". We don't force our demangled name to be
450 // computed currently (we don't use the accessor).
451 //----------------------------------------------------------------------
452 void Mangled::Dump(Stream *s) const {
454 *s << ", mangled = " << m_mangled;
457 const char *demangled = m_demangled.AsCString();
458 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
462 //----------------------------------------------------------------------
463 // Dumps a debug version of this string with extra object and state information
465 //----------------------------------------------------------------------
466 void Mangled::DumpDebug(Stream *s) const {
467 s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void *) * 2),
468 static_cast<const void *>(this));
469 m_mangled.DumpDebug(s);
470 s->Printf(", demangled = ");
471 m_demangled.DumpDebug(s);
474 //----------------------------------------------------------------------
475 // Return the size in byte that this object takes in memory. The size includes
476 // the size of the objects it owns, and not the strings that it references
477 // because they are shared strings.
478 //----------------------------------------------------------------------
479 size_t Mangled::MemorySize() const {
480 return m_mangled.MemorySize() + m_demangled.MemorySize();
483 //----------------------------------------------------------------------
484 // We "guess" the language because we can't determine a symbol's language from
485 // it's name. For example, a Pascal symbol can be mangled using the C++
486 // Itanium scheme, and defined in a compilation unit within the same module as
487 // other C++ units. In addition, different targets could have different ways
488 // of mangling names from a given language, likewise the compilation units
489 // within those targets.
490 //----------------------------------------------------------------------
491 lldb::LanguageType Mangled::GuessLanguage() const {
492 ConstString mangled = GetMangledName();
494 if (GetDemangledName(lldb::eLanguageTypeUnknown)) {
495 const char *mangled_name = mangled.GetCString();
496 if (CPlusPlusLanguage::IsCPPMangledName(mangled_name))
497 return lldb::eLanguageTypeC_plus_plus;
498 else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name))
499 return lldb::eLanguageTypeObjC;
502 // ObjC names aren't really mangled, so they won't necessarily be in the
503 // mangled name slot.
504 ConstString demangled_name = GetDemangledName(lldb::eLanguageTypeUnknown);
506 && ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString()))
507 return lldb::eLanguageTypeObjC;
510 return lldb::eLanguageTypeUnknown;
513 //----------------------------------------------------------------------
514 // Dump OBJ to the supplied stream S.
515 //----------------------------------------------------------------------
516 Stream &operator<<(Stream &s, const Mangled &obj) {
517 if (obj.GetMangledName())
518 s << "mangled = '" << obj.GetMangledName() << "'";
520 const ConstString &demangled =
521 obj.GetDemangledName(lldb::eLanguageTypeUnknown);
523 s << ", demangled = '" << demangled << '\'';
525 s << ", demangled = <error>";