]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/Mangled.cpp
Merge bmake-20170510
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / Mangled.cpp
1 //===-- 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
10 // FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
11 #include <cstddef>
12 #if defined(_WIN32)
13 #include "lldb/Host/windows/windows.h"
14 #include <dbghelp.h>
15 #pragma comment(lib, "dbghelp.lib")
16 #endif
17
18 #ifdef LLDB_USE_BUILTIN_DEMANGLER
19 // Provide a fast-path demangler implemented in FastDemangle.cpp until it can
20 // replace the existing C++ demangler with a complete implementation
21 #include "llvm/Demangle/Demangle.h"
22 #include "lldb/Core/FastDemangle.h"
23 #else
24 #include <cxxabi.h>
25 #endif
26
27 #include "llvm/ADT/DenseMap.h"
28
29 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
30 #include "Plugins/Language/ObjC/ObjCLanguage.h"
31 #include "lldb/Core/ConstString.h"
32 #include "lldb/Core/Log.h"
33 #include "lldb/Core/Logging.h"
34 #include "lldb/Core/Mangled.h"
35 #include "lldb/Core/RegularExpression.h"
36 #include "lldb/Core/Stream.h"
37 #include "lldb/Core/Timer.h"
38 #include <ctype.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 using namespace lldb_private;
43
44 static inline Mangled::ManglingScheme cstring_mangling_scheme(const char *s) {
45   if (s) {
46     if (s[0] == '?')
47       return Mangled::eManglingSchemeMSVC;
48     if (s[0] == '_' && s[1] == 'Z')
49       return Mangled::eManglingSchemeItanium;
50   }
51   return Mangled::eManglingSchemeNone;
52 }
53
54 static inline bool cstring_is_mangled(const char *s) {
55   return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
56 }
57
58 static const ConstString &
59 get_demangled_name_without_arguments(ConstString mangled,
60                                      ConstString demangled) {
61   // This pair is <mangled name, demangled name without function arguments>
62   static std::pair<ConstString, ConstString>
63       g_most_recent_mangled_to_name_sans_args;
64
65   // Need to have the mangled & demangled names we're currently examining as
66   // statics
67   // so we can return a const ref to them at the end of the func if we don't
68   // have
69   // anything better.
70   static ConstString g_last_mangled;
71   static ConstString g_last_demangled;
72
73   if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled) {
74     return g_most_recent_mangled_to_name_sans_args.second;
75   }
76
77   g_last_demangled = demangled;
78   g_last_mangled = mangled;
79
80   const char *mangled_name_cstr = mangled.GetCString();
81
82   if (demangled && mangled_name_cstr && mangled_name_cstr[0]) {
83     if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
84         (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
85                                         // typeinfo structure, and typeinfo
86                                         // mangled_name
87          mangled_name_cstr[2] != 'G' && // avoid guard variables
88          mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually
89                                        // handle eSymbolTypeData, we will want
90                                        // this back)
91     {
92       CPlusPlusLanguage::MethodName cxx_method(demangled);
93       if (!cxx_method.GetBasename().empty()) {
94         std::string shortname;
95         if (!cxx_method.GetContext().empty())
96           shortname = cxx_method.GetContext().str() + "::";
97         shortname += cxx_method.GetBasename().str();
98         ConstString result(shortname.c_str());
99         g_most_recent_mangled_to_name_sans_args.first = mangled;
100         g_most_recent_mangled_to_name_sans_args.second = result;
101         return g_most_recent_mangled_to_name_sans_args.second;
102       }
103     }
104   }
105
106   if (demangled)
107     return g_last_demangled;
108   return g_last_mangled;
109 }
110
111 #pragma mark Mangled
112 //----------------------------------------------------------------------
113 // Default constructor
114 //----------------------------------------------------------------------
115 Mangled::Mangled() : m_mangled(), m_demangled() {}
116
117 //----------------------------------------------------------------------
118 // Constructor with an optional string and a boolean indicating if it is
119 // the mangled version.
120 //----------------------------------------------------------------------
121 Mangled::Mangled(const ConstString &s, bool mangled)
122     : m_mangled(), m_demangled() {
123   if (s)
124     SetValue(s, mangled);
125 }
126
127 Mangled::Mangled(llvm::StringRef name, bool is_mangled) {
128   if (!name.empty())
129     SetValue(ConstString(name), is_mangled);
130 }
131
132 Mangled::Mangled(const ConstString &s) : m_mangled(), m_demangled() {
133   if (s)
134     SetValue(s);
135 }
136
137 Mangled::Mangled(llvm::StringRef name) {
138   if (!name.empty())
139     SetValue(ConstString(name));
140 }
141
142 //----------------------------------------------------------------------
143 // Destructor
144 //----------------------------------------------------------------------
145 Mangled::~Mangled() {}
146
147 //----------------------------------------------------------------------
148 // Convert to pointer operator. This allows code to check any Mangled
149 // objects to see if they contain anything valid using code such as:
150 //
151 //  Mangled mangled(...);
152 //  if (mangled)
153 //  { ...
154 //----------------------------------------------------------------------
155 Mangled::operator void *() const {
156   return (m_mangled) ? const_cast<Mangled *>(this) : NULL;
157 }
158
159 //----------------------------------------------------------------------
160 // Logical NOT operator. This allows code to check any Mangled
161 // objects to see if they are invalid using code such as:
162 //
163 //  Mangled mangled(...);
164 //  if (!file_spec)
165 //  { ...
166 //----------------------------------------------------------------------
167 bool Mangled::operator!() const { return !m_mangled; }
168
169 //----------------------------------------------------------------------
170 // Clear the mangled and demangled values.
171 //----------------------------------------------------------------------
172 void Mangled::Clear() {
173   m_mangled.Clear();
174   m_demangled.Clear();
175 }
176
177 //----------------------------------------------------------------------
178 // Compare the string values.
179 //----------------------------------------------------------------------
180 int Mangled::Compare(const Mangled &a, const Mangled &b) {
181   return ConstString::Compare(
182       a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled),
183       a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled));
184 }
185
186 //----------------------------------------------------------------------
187 // Set the string value in this objects. If "mangled" is true, then
188 // the mangled named is set with the new value in "s", else the
189 // demangled name is set.
190 //----------------------------------------------------------------------
191 void Mangled::SetValue(const ConstString &s, bool mangled) {
192   if (s) {
193     if (mangled) {
194       m_demangled.Clear();
195       m_mangled = s;
196     } else {
197       m_demangled = s;
198       m_mangled.Clear();
199     }
200   } else {
201     m_demangled.Clear();
202     m_mangled.Clear();
203   }
204 }
205
206 void Mangled::SetValue(const ConstString &name) {
207   if (name) {
208     if (cstring_is_mangled(name.GetCString())) {
209       m_demangled.Clear();
210       m_mangled = name;
211     } else {
212       m_demangled = name;
213       m_mangled.Clear();
214     }
215   } else {
216     m_demangled.Clear();
217     m_mangled.Clear();
218   }
219 }
220
221 //----------------------------------------------------------------------
222 // Generate the demangled name on demand using this accessor. Code in
223 // this class will need to use this accessor if it wishes to decode
224 // the demangled name. The result is cached and will be kept until a
225 // new string value is supplied to this object, or until the end of the
226 // object's lifetime.
227 //----------------------------------------------------------------------
228 const ConstString &
229 Mangled::GetDemangledName(lldb::LanguageType language) const {
230   // Check to make sure we have a valid mangled name and that we
231   // haven't already decoded our mangled name.
232   if (m_mangled && !m_demangled) {
233     // We need to generate and cache the demangled name.
234     Timer scoped_timer(LLVM_PRETTY_FUNCTION,
235                        "Mangled::GetDemangledName (m_mangled = %s)",
236                        m_mangled.GetCString());
237
238     Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE);
239
240     // Don't bother running anything that isn't mangled
241     const char *mangled_name = m_mangled.GetCString();
242     ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
243     if (mangling_scheme != eManglingSchemeNone &&
244         !m_mangled.GetMangledCounterpart(m_demangled)) {
245       // We didn't already mangle this name, demangle it and if all goes well
246       // add it to our map.
247       char *demangled_name = nullptr;
248       switch (mangling_scheme) {
249       case eManglingSchemeMSVC: {
250 #if defined(_MSC_VER)
251         if (log)
252           log->Printf("demangle msvc: %s", mangled_name);
253         const size_t demangled_length = 2048;
254         demangled_name = static_cast<char *>(::malloc(demangled_length));
255         ::ZeroMemory(demangled_name, demangled_length);
256         DWORD result = ::UnDecorateSymbolName(
257             mangled_name, demangled_name, demangled_length,
258             UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected
259                                            // keywords
260                 UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall,
261                                                  // etc keywords
262                 UNDNAME_NO_THROW_SIGNATURES |    // Strip throw() specifications
263                 UNDNAME_NO_MEMBER_TYPE |         // Strip virtual, static, etc
264                                                  // specifiers
265                 UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
266             );
267         if (log) {
268           if (demangled_name && demangled_name[0])
269             log->Printf("demangled msvc: %s -> \"%s\"", mangled_name,
270                         demangled_name);
271           else
272             log->Printf("demangled msvc: %s -> error: 0x%lu", mangled_name,
273                         result);
274         }
275
276         if (result == 0) {
277           free(demangled_name);
278           demangled_name = nullptr;
279         }
280 #endif
281         break;
282       }
283       case eManglingSchemeItanium: {
284 #ifdef LLDB_USE_BUILTIN_DEMANGLER
285         if (log)
286           log->Printf("demangle itanium: %s", mangled_name);
287         // Try to use the fast-path demangler first for the
288         // performance win, falling back to the full demangler only
289         // when necessary
290         demangled_name = FastDemangle(mangled_name, m_mangled.GetLength());
291         if (!demangled_name)
292           demangled_name =
293               llvm::itaniumDemangle(mangled_name, NULL, NULL, NULL);
294 #else
295         demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
296 #endif
297         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);
304         }
305         break;
306       }
307       case eManglingSchemeNone:
308         break;
309       }
310       if (demangled_name) {
311         m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
312         free(demangled_name);
313       }
314     }
315     if (!m_demangled) {
316       // Set the demangled string to the empty string to indicate we
317       // tried to parse it once and failed.
318       m_demangled.SetCString("");
319     }
320   }
321
322   return m_demangled;
323 }
324
325 ConstString
326 Mangled::GetDisplayDemangledName(lldb::LanguageType language) const {
327   return GetDemangledName(language);
328 }
329
330 bool Mangled::NameMatches(const RegularExpression &regex,
331                           lldb::LanguageType language) const {
332   if (m_mangled && regex.Execute(m_mangled.AsCString()))
333     return true;
334
335   ConstString demangled = GetDemangledName(language);
336   if (demangled && regex.Execute(demangled.AsCString()))
337     return true;
338   return false;
339 }
340
341 //----------------------------------------------------------------------
342 // Get the demangled name if there is one, else return the mangled name.
343 //----------------------------------------------------------------------
344 ConstString Mangled::GetName(lldb::LanguageType language,
345                              Mangled::NamePreference preference) const {
346   if (preference == ePreferMangled && m_mangled)
347     return m_mangled;
348
349   ConstString demangled = GetDemangledName(language);
350
351   if (preference == ePreferDemangledWithoutArguments) {
352     return get_demangled_name_without_arguments(m_mangled, demangled);
353   }
354   if (preference == ePreferDemangled) {
355     // Call the accessor to make sure we get a demangled name in case
356     // it hasn't been demangled yet...
357     if (demangled)
358       return demangled;
359     return m_mangled;
360   }
361   return demangled;
362 }
363
364 //----------------------------------------------------------------------
365 // Dump a Mangled object to stream "s". We don't force our
366 // demangled name to be computed currently (we don't use the accessor).
367 //----------------------------------------------------------------------
368 void 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   }
376 }
377
378 //----------------------------------------------------------------------
379 // Dumps a debug version of this string with extra object and state
380 // information to stream "s".
381 //----------------------------------------------------------------------
382 void 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);
388 }
389
390 //----------------------------------------------------------------------
391 // Return the size in byte that this object takes in memory. The size
392 // includes the size of the objects it owns, and not the strings that
393 // it references because they are shared strings.
394 //----------------------------------------------------------------------
395 size_t Mangled::MemorySize() const {
396   return m_mangled.MemorySize() + m_demangled.MemorySize();
397 }
398
399 //----------------------------------------------------------------------
400 // We "guess" the language because we can't determine a symbol's language
401 // from it's name.  For example, a Pascal symbol can be mangled using the
402 // C++ Itanium scheme, and defined in a compilation unit within the same
403 // module as other C++ units.  In addition, different targets could have
404 // different ways of mangling names from a given language, likewise the
405 // compilation units within those targets.
406 //----------------------------------------------------------------------
407 lldb::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;
416     }
417   }
418   return lldb::eLanguageTypeUnknown;
419 }
420
421 //----------------------------------------------------------------------
422 // Dump OBJ to the supplied stream S.
423 //----------------------------------------------------------------------
424 Stream &operator<<(Stream &s, const Mangled &obj) {
425   if (obj.GetMangledName())
426     s << "mangled = '" << obj.GetMangledName() << "'";
427
428   const ConstString &demangled =
429       obj.GetDemangledName(lldb::eLanguageTypeUnknown);
430   if (demangled)
431     s << ", demangled = '" << demangled << '\'';
432   else
433     s << ", demangled = <error>";
434   return s;
435 }