blob: 7bb58ff24a2fe5a01b337bcfc0cc1e1bafc21d70 [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
11#if defined(__APPLE__)
12#define USE_BUILTIN_LIBCXXABI_DEMANGLER 1
13#endif
14
15#if defined(USE_BUILTIN_LIBCXXABI_DEMANGLER)
16#include "lldb/Core/cxa_demangle.h"
17#else
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include <cxxabi.h>
Greg Claytone9982672012-08-06 15:55:38 +000019#endif
20
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021
Greg Claytone41e5892010-09-03 23:26:12 +000022#include "llvm/ADT/DenseMap.h"
23
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Core/ConstString.h"
25#include "lldb/Core/Mangled.h"
Greg Clayton83c5cd92010-11-14 22:13:40 +000026#include "lldb/Core/RegularExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Core/Stream.h"
28#include "lldb/Core/Timer.h"
Eli Friedman88966972010-06-09 08:50:27 +000029#include <ctype.h>
30#include <string.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
32using namespace lldb_private;
33
Greg Clayton5e0c5e82012-07-18 20:47:40 +000034static inline bool
35cstring_is_mangled (const char *s)
36{
37 if (s)
38 return s[0] == '_' && s[1] == 'Z';
39 return false;
40}
41
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042#pragma mark Mangled
43//----------------------------------------------------------------------
44// Default constructor
45//----------------------------------------------------------------------
46Mangled::Mangled () :
47 m_mangled(),
48 m_demangled()
49{
50}
51
52//----------------------------------------------------------------------
53// Constructor with an optional string and a boolean indicating if it is
54// the mangled version.
55//----------------------------------------------------------------------
Greg Clayton5e0c5e82012-07-18 20:47:40 +000056Mangled::Mangled (const ConstString &s, bool mangled) :
57 m_mangled(),
58 m_demangled()
59{
60 if (s)
61 SetValue(s, mangled);
62}
63
Greg Clayton037520e2012-07-18 23:18:10 +000064Mangled::Mangled (const ConstString &s) :
Greg Clayton5e0c5e82012-07-18 20:47:40 +000065 m_mangled(),
66 m_demangled()
67{
Greg Clayton5e0c5e82012-07-18 20:47:40 +000068 if (s)
69 SetValue(s);
70}
71
72//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073// Destructor
74//----------------------------------------------------------------------
75Mangled::~Mangled ()
76{
77}
78
79//----------------------------------------------------------------------
80// Convert to pointer operator. This allows code to check any Mangled
81// objects to see if they contain anything valid using code such as:
82//
83// Mangled mangled(...);
84// if (mangled)
85// { ...
86//----------------------------------------------------------------------
87Mangled::operator void* () const
88{
89 return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
90}
91
92//----------------------------------------------------------------------
93// Logical NOT operator. This allows code to check any Mangled
94// objects to see if they are invalid using code such as:
95//
96// Mangled mangled(...);
97// if (!file_spec)
98// { ...
99//----------------------------------------------------------------------
100bool
101Mangled::operator! () const
102{
103 return !m_mangled;
104}
105
106//----------------------------------------------------------------------
107// Clear the mangled and demangled values.
108//----------------------------------------------------------------------
109void
110Mangled::Clear ()
111{
112 m_mangled.Clear();
113 m_demangled.Clear();
114}
115
116
117//----------------------------------------------------------------------
118// Compare the the string values.
119//----------------------------------------------------------------------
120int
121Mangled::Compare (const Mangled& a, const Mangled& b)
122{
Jim Ingham89bf5e92010-09-15 00:13:44 +0000123 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000124}
125
126
127
128//----------------------------------------------------------------------
129// Set the string value in this objects. If "mangled" is true, then
130// the mangled named is set with the new value in "s", else the
131// demangled name is set.
132//----------------------------------------------------------------------
133void
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000134Mangled::SetValue (const ConstString &s, bool mangled)
135{
136 if (s)
137 {
138 if (mangled)
139 {
140 m_demangled.Clear();
141 m_mangled = s;
142 }
143 else
144 {
145 m_demangled = s;
146 m_mangled.Clear();
147 }
148 }
149 else
150 {
151 m_demangled.Clear();
152 m_mangled.Clear();
153 }
154}
155
156void
157Mangled::SetValue (const ConstString &name)
158{
159 if (name)
160 {
161 if (cstring_is_mangled(name.GetCString()))
162 {
163 m_demangled.Clear();
164 m_mangled = name;
165 }
166 else
167 {
168 m_demangled = name;
169 m_mangled.Clear();
170 }
171 }
172 else
173 {
174 m_demangled.Clear();
175 m_mangled.Clear();
176 }
177}
178
179
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180//----------------------------------------------------------------------
181// Generate the demangled name on demand using this accessor. Code in
182// this class will need to use this accessor if it wishes to decode
183// the demangled name. The result is cached and will be kept until a
184// new string value is supplied to this object, or until the end of the
185// object's lifetime.
186//----------------------------------------------------------------------
187const ConstString&
188Mangled::GetDemangledName () const
189{
190 // Check to make sure we have a valid mangled name and that we
191 // haven't already decoded our mangled name.
192 if (m_mangled && !m_demangled)
193 {
194 // We need to generate and cache the demangled name.
195 Timer scoped_timer (__PRETTY_FUNCTION__,
196 "Mangled::GetDemangledName (m_mangled = %s)",
197 m_mangled.GetCString());
198
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000199 // Don't bother running anything that isn't mangled
200 const char *mangled_cstr = m_mangled.GetCString();
201 if (cstring_is_mangled(mangled_cstr))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000202 {
Greg Claytonc3ae1ce2011-06-09 22:34:34 +0000203 if (!m_mangled.GetMangledCounterpart(m_demangled))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 {
Greg Claytone41e5892010-09-03 23:26:12 +0000205 // We didn't already mangle this name, demangle it and if all goes well
206 // add it to our map.
Greg Claytone9982672012-08-06 15:55:38 +0000207#if defined(USE_BUILTIN_LIBCXXABI_DEMANGLER)
208 char *demangled_name = lldb_cxxabiv1::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
209#else
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000210 char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
Greg Claytone9982672012-08-06 15:55:38 +0000211#endif
Greg Claytone41e5892010-09-03 23:26:12 +0000212
213 if (demangled_name)
214 {
Greg Claytonc3ae1ce2011-06-09 22:34:34 +0000215 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
Greg Claytone41e5892010-09-03 23:26:12 +0000216 free (demangled_name);
217 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218 }
219 }
Jason Molenda3f8688b2010-12-15 04:27:04 +0000220 if (!m_demangled)
221 {
222 // Set the demangled string to the empty string to indicate we
223 // tried to parse it once and failed.
224 m_demangled.SetCString("");
225 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 }
227
228 return m_demangled;
229}
230
Greg Clayton83c5cd92010-11-14 22:13:40 +0000231
232bool
233Mangled::NameMatches (const RegularExpression& regex) const
234{
235 if (m_mangled && regex.Execute (m_mangled.AsCString()))
236 return true;
237
238 if (GetDemangledName() && regex.Execute (m_demangled.AsCString()))
239 return true;
240 return false;
241}
242
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243//----------------------------------------------------------------------
244// Get the demangled name if there is one, else return the mangled name.
245//----------------------------------------------------------------------
246const ConstString&
Jim Ingham08b87e02010-09-14 22:03:00 +0000247Mangled::GetName (Mangled::NamePreference preference) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248{
Greg Clayton87425432010-09-14 23:44:49 +0000249 if (preference == ePreferDemangled)
Jim Ingham08b87e02010-09-14 22:03:00 +0000250 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000251 // Call the accessor to make sure we get a demangled name in case
252 // it hasn't been demangled yet...
253 if (GetDemangledName())
254 return m_demangled;
Greg Clayton87425432010-09-14 23:44:49 +0000255 return m_mangled;
256 }
257 else
258 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000259 if (m_mangled)
260 return m_mangled;
261 return GetDemangledName();
Jim Ingham08b87e02010-09-14 22:03:00 +0000262 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000263}
264
265//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266// Dump a Mangled object to stream "s". We don't force our
267// demangled name to be computed currently (we don't use the accessor).
268//----------------------------------------------------------------------
269void
270Mangled::Dump (Stream *s) const
271{
272 if (m_mangled)
273 {
274 *s << ", mangled = " << m_mangled;
275 }
276 if (m_demangled)
277 {
278 const char * demangled = m_demangled.AsCString();
279 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
280 }
281}
282
283//----------------------------------------------------------------------
284// Dumps a debug version of this string with extra object and state
285// information to stream "s".
286//----------------------------------------------------------------------
287void
288Mangled::DumpDebug (Stream *s) const
289{
290 s->Printf("%*p: Mangled mangled = ", (int)sizeof(void*) * 2, this);
291 m_mangled.DumpDebug(s);
292 s->Printf(", demangled = ");
293 m_demangled.DumpDebug(s);
294}
295
296//----------------------------------------------------------------------
297// Return the size in byte that this object takes in memory. The size
298// includes the size of the objects it owns, and not the strings that
299// it references because they are shared strings.
300//----------------------------------------------------------------------
301size_t
302Mangled::MemorySize () const
303{
304 return m_mangled.MemorySize() + m_demangled.MemorySize();
305}
306
307//----------------------------------------------------------------------
308// Dump OBJ to the supplied stream S.
309//----------------------------------------------------------------------
310Stream&
311operator << (Stream& s, const Mangled& obj)
312{
313 if (obj.GetMangledName())
314 s << "mangled = '" << obj.GetMangledName() << "'";
315
316 const ConstString& demangled = obj.GetDemangledName();
317 if (demangled)
318 s << ", demangled = '" << demangled << '\'';
319 else
320 s << ", demangled = <error>";
321 return s;
322}