blob: b8a43be10fbc64c617713947c6367ca626078a73 [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
Zachary Turner2f3df612017-04-06 21:28:29 +000010#include "lldb/Core/Mangled.h"
11
Hafiz Abid Qadeerf6ee79c2016-12-15 15:00:41 +000012#if defined(_WIN32)
Zachary Turneraaea8ee2017-06-23 23:55:32 +000013#include "lldb/Host/windows/windows.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000014
Hafiz Abid Qadeerf6ee79c2016-12-15 15:00:41 +000015#include <dbghelp.h>
Leny Kholodovca951202015-07-02 15:54:13 +000016#pragma comment(lib, "dbghelp.lib")
Virgile Bellod0c5c772013-09-18 08:09:31 +000017#endif
Greg Claytone9982672012-08-06 15:55:38 +000018
Zachary Turnerbf9a7732017-02-02 21:39:50 +000019#include "lldb/Utility/ConstString.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000020#include "lldb/Utility/Log.h"
21#include "lldb/Utility/Logging.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000022#include "lldb/Utility/RegularExpression.h"
23#include "lldb/Utility/Stream.h"
Pavel Labath38d06322017-06-29 14:32:17 +000024#include "lldb/Utility/Timer.h"
Stefan Granitz2f842d62018-07-25 15:19:04 +000025#include "lldb/lldb-enumerations.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000026
27#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
28#include "Plugins/Language/ObjC/ObjCLanguage.h"
29
Stefan Granitz2f842d62018-07-25 15:19:04 +000030#include "llvm/ADT/StringRef.h"
31#include "llvm/Demangle/Demangle.h"
32#include "llvm/Support/Compiler.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000033
Stefan Granitz2f842d62018-07-25 15:19:04 +000034#include <mutex>
35#include <string>
36#include <utility>
Zachary Turner2f3df612017-04-06 21:28:29 +000037
Daniel Maleac91e4ab2013-05-31 20:21:38 +000038#include <stdlib.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000039#include <string.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040using namespace lldb_private;
41
Zachary Turner1f6a8d32017-02-28 20:29:20 +000042#if defined(_MSC_VER)
Zachary Turner31897182017-02-28 20:30:31 +000043static DWORD safeUndecorateName(const char *Mangled, char *Demangled,
44 DWORD DemangledLength) {
Zachary Turner1f6a8d32017-02-28 20:29:20 +000045 static std::mutex M;
46 std::lock_guard<std::mutex> Lock(M);
47 return ::UnDecorateSymbolName(
Zachary Turner31897182017-02-28 20:30:31 +000048 Mangled, Demangled, DemangledLength,
49 UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected
50 // keywords
51 UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall,
52 // etc keywords
53 UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
54 UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc
55 // specifiers
56 UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
57 );
Zachary Turner1f6a8d32017-02-28 20:29:20 +000058}
59#endif
60
Kate Stoneb9c1b512016-09-06 20:57:50 +000061static inline Mangled::ManglingScheme cstring_mangling_scheme(const char *s) {
62 if (s) {
63 if (s[0] == '?')
64 return Mangled::eManglingSchemeMSVC;
65 if (s[0] == '_' && s[1] == 'Z')
66 return Mangled::eManglingSchemeItanium;
67 }
68 return Mangled::eManglingSchemeNone;
Chaoren Lin7f951142015-05-28 21:19:31 +000069}
70
Kate Stoneb9c1b512016-09-06 20:57:50 +000071static inline bool cstring_is_mangled(const char *s) {
72 return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
Greg Clayton5e0c5e82012-07-18 20:47:40 +000073}
74
Jason Molendaaff1b352014-10-10 23:07:36 +000075static const ConstString &
Kate Stoneb9c1b512016-09-06 20:57:50 +000076get_demangled_name_without_arguments(ConstString mangled,
77 ConstString demangled) {
78 // This pair is <mangled name, demangled name without function arguments>
79 static std::pair<ConstString, ConstString>
80 g_most_recent_mangled_to_name_sans_args;
Jason Molendaaff1b352014-10-10 23:07:36 +000081
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 // Need to have the mangled & demangled names we're currently examining as
Adrian Prantl05097242018-04-30 16:49:04 +000083 // statics so we can return a const ref to them at the end of the func if we
84 // don't have anything better.
Kate Stoneb9c1b512016-09-06 20:57:50 +000085 static ConstString g_last_mangled;
86 static ConstString g_last_demangled;
Jason Molendaaff1b352014-10-10 23:07:36 +000087
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled) {
89 return g_most_recent_mangled_to_name_sans_args.second;
90 }
91
92 g_last_demangled = demangled;
93 g_last_mangled = mangled;
94
95 const char *mangled_name_cstr = mangled.GetCString();
96
97 if (demangled && mangled_name_cstr && mangled_name_cstr[0]) {
98 if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
99 (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
100 // typeinfo structure, and typeinfo
101 // mangled_name
102 mangled_name_cstr[2] != 'G' && // avoid guard variables
103 mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually
104 // handle eSymbolTypeData, we will want
105 // this back)
Jason Molendaaff1b352014-10-10 23:07:36 +0000106 {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107 CPlusPlusLanguage::MethodName cxx_method(demangled);
108 if (!cxx_method.GetBasename().empty()) {
109 std::string shortname;
110 if (!cxx_method.GetContext().empty())
111 shortname = cxx_method.GetContext().str() + "::";
112 shortname += cxx_method.GetBasename().str();
113 ConstString result(shortname.c_str());
114 g_most_recent_mangled_to_name_sans_args.first = mangled;
115 g_most_recent_mangled_to_name_sans_args.second = result;
Jason Molendaaff1b352014-10-10 23:07:36 +0000116 return g_most_recent_mangled_to_name_sans_args.second;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117 }
Jason Molendaaff1b352014-10-10 23:07:36 +0000118 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 }
Jason Molendaaff1b352014-10-10 23:07:36 +0000120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121 if (demangled)
122 return g_last_demangled;
123 return g_last_mangled;
Jason Molendaaff1b352014-10-10 23:07:36 +0000124}
125
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126#pragma mark Mangled
127//----------------------------------------------------------------------
128// Default constructor
129//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130Mangled::Mangled() : m_mangled(), m_demangled() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000131
132//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000133// Constructor with an optional string and a boolean indicating if it is the
134// mangled version.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000135//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136Mangled::Mangled(const ConstString &s, bool mangled)
137 : m_mangled(), m_demangled() {
138 if (s)
139 SetValue(s, mangled);
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000140}
141
Zachary Turner97d2c402016-10-05 23:40:23 +0000142Mangled::Mangled(llvm::StringRef name, bool is_mangled) {
143 if (!name.empty())
144 SetValue(ConstString(name), is_mangled);
145}
146
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147Mangled::Mangled(const ConstString &s) : m_mangled(), m_demangled() {
148 if (s)
149 SetValue(s);
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000150}
151
Zachary Turner97d2c402016-10-05 23:40:23 +0000152Mangled::Mangled(llvm::StringRef name) {
153 if (!name.empty())
154 SetValue(ConstString(name));
155}
156
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000157//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158// Destructor
159//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160Mangled::~Mangled() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161
162//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000163// Convert to pointer operator. This allows code to check any Mangled objects
164// to see if they contain anything valid using code such as:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000165//
166// Mangled mangled(...);
167// if (mangled)
168// { ...
169//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170Mangled::operator void *() const {
171 return (m_mangled) ? const_cast<Mangled *>(this) : NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172}
173
174//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000175// Logical NOT operator. This allows code to check any Mangled objects to see
176// if they are invalid using code such as:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000177//
178// Mangled mangled(...);
179// if (!file_spec)
180// { ...
181//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182bool Mangled::operator!() const { return !m_mangled; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183
184//----------------------------------------------------------------------
185// Clear the mangled and demangled values.
186//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000187void Mangled::Clear() {
188 m_mangled.Clear();
189 m_demangled.Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000190}
191
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000192//----------------------------------------------------------------------
Bruce Mitchener58ef3912015-06-18 05:27:05 +0000193// Compare the string values.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000194//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195int Mangled::Compare(const Mangled &a, const Mangled &b) {
196 return ConstString::Compare(
197 a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled),
Stefan Granitzc238ca22018-08-06 14:15:21 +0000198 b.GetName(lldb::eLanguageTypeUnknown, ePreferMangled));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199}
200
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000202// Set the string value in this objects. If "mangled" is true, then the mangled
203// named is set with the new value in "s", else the demangled name is set.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205void Mangled::SetValue(const ConstString &s, bool mangled) {
206 if (s) {
207 if (mangled) {
208 m_demangled.Clear();
209 m_mangled = s;
210 } else {
211 m_demangled = s;
212 m_mangled.Clear();
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000213 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 } else {
215 m_demangled.Clear();
216 m_mangled.Clear();
217 }
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000218}
219
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220void Mangled::SetValue(const ConstString &name) {
221 if (name) {
222 if (cstring_is_mangled(name.GetCString())) {
223 m_demangled.Clear();
224 m_mangled = name;
225 } else {
226 m_demangled = name;
227 m_mangled.Clear();
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000228 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229 } else {
230 m_demangled.Clear();
231 m_mangled.Clear();
232 }
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000233}
234
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000236// Generate the demangled name on demand using this accessor. Code in this
237// class will need to use this accessor if it wishes to decode the demangled
238// name. The result is cached and will be kept until a new string value is
239// supplied to this object, or until the end of the object's lifetime.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241const ConstString &
242Mangled::GetDemangledName(lldb::LanguageType language) const {
Adrian Prantl05097242018-04-30 16:49:04 +0000243 // Check to make sure we have a valid mangled name and that we haven't
244 // already decoded our mangled name.
Stefan Granitz4af5a832018-08-06 14:15:17 +0000245 if (m_mangled && m_demangled.IsNull()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246 // We need to generate and cache the demangled name.
Pavel Labathf9d16472017-05-15 13:02:37 +0000247 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
248 Timer scoped_timer(func_cat, "Mangled::GetDemangledName (m_mangled = %s)",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249 m_mangled.GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250
Kate Stoneb9c1b512016-09-06 20:57:50 +0000251 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE);
Greg Clayton4141c7a2016-05-27 00:17:18 +0000252
Kate Stoneb9c1b512016-09-06 20:57:50 +0000253 // Don't bother running anything that isn't mangled
254 const char *mangled_name = m_mangled.GetCString();
255 ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
256 if (mangling_scheme != eManglingSchemeNone &&
257 !m_mangled.GetMangledCounterpart(m_demangled)) {
258 // We didn't already mangle this name, demangle it and if all goes well
259 // add it to our map.
260 char *demangled_name = nullptr;
261 switch (mangling_scheme) {
262 case eManglingSchemeMSVC: {
Chaoren Lin7f951142015-05-28 21:19:31 +0000263#if defined(_MSC_VER)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264 if (log)
265 log->Printf("demangle msvc: %s", mangled_name);
266 const size_t demangled_length = 2048;
267 demangled_name = static_cast<char *>(::malloc(demangled_length));
268 ::ZeroMemory(demangled_name, demangled_length);
Zachary Turner31897182017-02-28 20:30:31 +0000269 DWORD result =
270 safeUndecorateName(mangled_name, demangled_name, demangled_length);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271 if (log) {
272 if (demangled_name && demangled_name[0])
273 log->Printf("demangled msvc: %s -> \"%s\"", mangled_name,
274 demangled_name);
275 else
Zachary Turner5a8ad4592016-10-05 17:07:34 +0000276 log->Printf("demangled msvc: %s -> error: 0x%lu", mangled_name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277 result);
278 }
Greg Clayton4141c7a2016-05-27 00:17:18 +0000279
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280 if (result == 0) {
281 free(demangled_name);
282 demangled_name = nullptr;
283 }
Ying Chenfd6c7ad2015-05-28 21:06:33 +0000284#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285 break;
286 }
287 case eManglingSchemeItanium: {
Stefan Granitz2f842d62018-07-25 15:19:04 +0000288 llvm::ItaniumPartialDemangler IPD;
289 bool demangle_err = IPD.partialDemangle(mangled_name);
290 if (!demangle_err) {
291 // Default buffer and size (realloc is used in case it's too small).
292 size_t demangled_size = 80;
293 demangled_name = static_cast<char *>(::malloc(demangled_size));
294 demangled_name = IPD.finishDemangle(demangled_name, &demangled_size);
295 }
296
Kate Stoneb9c1b512016-09-06 20:57:50 +0000297 if (log) {
298 if (demangled_name)
299 log->Printf("demangled itanium: %s -> \"%s\"", mangled_name,
300 demangled_name);
301 else
302 log->Printf("demangled itanium: %s -> error: failed to demangle",
303 mangled_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000304 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000305 break;
306 }
307 case eManglingSchemeNone:
308 break;
309 }
310 if (demangled_name) {
Pavel Labath19a357a2018-08-06 08:27:59 +0000311 m_demangled.SetStringWithMangledCounterpart(demangled_name, m_mangled);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000312 free(demangled_name);
313 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000314 }
Stefan Granitz4af5a832018-08-06 14:15:17 +0000315 if (m_demangled.IsNull()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000316 // Set the demangled string to the empty string to indicate we tried to
317 // parse it once and failed.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 m_demangled.SetCString("");
319 }
320 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321
Kate Stoneb9c1b512016-09-06 20:57:50 +0000322 return m_demangled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000323}
324
Enrico Granatac1f705c2015-07-06 18:28:46 +0000325ConstString
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326Mangled::GetDisplayDemangledName(lldb::LanguageType language) const {
327 return GetDemangledName(language);
Enrico Granatac1f705c2015-07-06 18:28:46 +0000328}
329
Kate Stoneb9c1b512016-09-06 20:57:50 +0000330bool Mangled::NameMatches(const RegularExpression &regex,
331 lldb::LanguageType language) const {
332 if (m_mangled && regex.Execute(m_mangled.AsCString()))
333 return true;
Greg Claytonddaf6a72015-07-08 22:32:23 +0000334
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335 ConstString demangled = GetDemangledName(language);
336 if (demangled && regex.Execute(demangled.AsCString()))
337 return true;
338 return false;
Greg Clayton83c5cd92010-11-14 22:13:40 +0000339}
340
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341//----------------------------------------------------------------------
342// Get the demangled name if there is one, else return the mangled name.
343//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344ConstString Mangled::GetName(lldb::LanguageType language,
345 Mangled::NamePreference preference) const {
346 if (preference == ePreferMangled && m_mangled)
347 return m_mangled;
Greg Clayton3feddff2015-12-17 01:00:50 +0000348
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349 ConstString demangled = GetDemangledName(language);
Greg Claytonddaf6a72015-07-08 22:32:23 +0000350
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351 if (preference == ePreferDemangledWithoutArguments) {
352 return get_demangled_name_without_arguments(m_mangled, demangled);
353 }
354 if (preference == ePreferDemangled) {
Adrian Prantl05097242018-04-30 16:49:04 +0000355 // Call the accessor to make sure we get a demangled name in case it hasn't
356 // been demangled yet...
Kate Stoneb9c1b512016-09-06 20:57:50 +0000357 if (demangled)
358 return demangled;
359 return m_mangled;
360 }
361 return demangled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000362}
363
364//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000365// Dump a Mangled object to stream "s". We don't force our demangled name to be
366// computed currently (we don't use the accessor).
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368void Mangled::Dump(Stream *s) const {
369 if (m_mangled) {
370 *s << ", mangled = " << m_mangled;
371 }
372 if (m_demangled) {
373 const char *demangled = m_demangled.AsCString();
374 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
375 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376}
377
378//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000379// Dumps a debug version of this string with extra object and state information
380// to stream "s".
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382void Mangled::DumpDebug(Stream *s) const {
383 s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void *) * 2),
384 static_cast<const void *>(this));
385 m_mangled.DumpDebug(s);
386 s->Printf(", demangled = ");
387 m_demangled.DumpDebug(s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000388}
389
390//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000391// Return the size in byte that this object takes in memory. The size includes
392// the size of the objects it owns, and not the strings that it references
393// because they are shared strings.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395size_t Mangled::MemorySize() const {
396 return m_mangled.MemorySize() + m_demangled.MemorySize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397}
398
Dawn Perchikbfd96182015-12-16 19:40:00 +0000399//----------------------------------------------------------------------
Adrian Prantl05097242018-04-30 16:49:04 +0000400// We "guess" the language because we can't determine a symbol's language from
401// it's name. For example, a Pascal symbol can be mangled using the C++
402// Itanium scheme, and defined in a compilation unit within the same module as
403// other C++ units. In addition, different targets could have different ways
404// of mangling names from a given language, likewise the compilation units
405// within those targets.
Dawn Perchikbfd96182015-12-16 19:40:00 +0000406//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000407lldb::LanguageType Mangled::GuessLanguage() const {
408 ConstString mangled = GetMangledName();
409 if (mangled) {
410 if (GetDemangledName(lldb::eLanguageTypeUnknown)) {
411 const char *mangled_name = mangled.GetCString();
412 if (CPlusPlusLanguage::IsCPPMangledName(mangled_name))
413 return lldb::eLanguageTypeC_plus_plus;
414 else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name))
415 return lldb::eLanguageTypeObjC;
Greg Clayton94976f72015-01-23 23:18:53 +0000416 }
Jim Inghambdbdd222017-04-12 00:19:54 +0000417 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000418 // ObjC names aren't really mangled, so they won't necessarily be in the
Jim Inghambdbdd222017-04-12 00:19:54 +0000419 // mangled name slot.
420 ConstString demangled_name = GetDemangledName(lldb::eLanguageTypeUnknown);
421 if (demangled_name
422 && ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString()))
423 return lldb::eLanguageTypeObjC;
424
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}