blob: 4852436bb96064fa32181158c5399e6ac6526b7e [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
Filipe Cabecinhasdd393952012-09-11 18:11:12 +000018// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
19#include <cstddef>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include <cxxabi.h>
Greg Claytone9982672012-08-06 15:55:38 +000021#endif
22
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023
Greg Claytone41e5892010-09-03 23:26:12 +000024#include "llvm/ADT/DenseMap.h"
25
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Core/ConstString.h"
27#include "lldb/Core/Mangled.h"
Greg Clayton83c5cd92010-11-14 22:13:40 +000028#include "lldb/Core/RegularExpression.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Core/Stream.h"
30#include "lldb/Core/Timer.h"
Eli Friedman88966972010-06-09 08:50:27 +000031#include <ctype.h>
32#include <string.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033
34using namespace lldb_private;
35
Greg Clayton5e0c5e82012-07-18 20:47:40 +000036static inline bool
37cstring_is_mangled (const char *s)
38{
39 if (s)
40 return s[0] == '_' && s[1] == 'Z';
41 return false;
42}
43
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044#pragma mark Mangled
45//----------------------------------------------------------------------
46// Default constructor
47//----------------------------------------------------------------------
48Mangled::Mangled () :
49 m_mangled(),
50 m_demangled()
51{
52}
53
54//----------------------------------------------------------------------
55// Constructor with an optional string and a boolean indicating if it is
56// the mangled version.
57//----------------------------------------------------------------------
Greg Clayton5e0c5e82012-07-18 20:47:40 +000058Mangled::Mangled (const ConstString &s, bool mangled) :
59 m_mangled(),
60 m_demangled()
61{
62 if (s)
63 SetValue(s, mangled);
64}
65
Greg Clayton037520e2012-07-18 23:18:10 +000066Mangled::Mangled (const ConstString &s) :
Greg Clayton5e0c5e82012-07-18 20:47:40 +000067 m_mangled(),
68 m_demangled()
69{
Greg Clayton5e0c5e82012-07-18 20:47:40 +000070 if (s)
71 SetValue(s);
72}
73
74//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075// Destructor
76//----------------------------------------------------------------------
77Mangled::~Mangled ()
78{
79}
80
81//----------------------------------------------------------------------
82// Convert to pointer operator. This allows code to check any Mangled
83// objects to see if they contain anything valid using code such as:
84//
85// Mangled mangled(...);
86// if (mangled)
87// { ...
88//----------------------------------------------------------------------
89Mangled::operator void* () const
90{
91 return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
92}
93
94//----------------------------------------------------------------------
95// Logical NOT operator. This allows code to check any Mangled
96// objects to see if they are invalid using code such as:
97//
98// Mangled mangled(...);
99// if (!file_spec)
100// { ...
101//----------------------------------------------------------------------
102bool
103Mangled::operator! () const
104{
105 return !m_mangled;
106}
107
108//----------------------------------------------------------------------
109// Clear the mangled and demangled values.
110//----------------------------------------------------------------------
111void
112Mangled::Clear ()
113{
114 m_mangled.Clear();
115 m_demangled.Clear();
116}
117
118
119//----------------------------------------------------------------------
120// Compare the the string values.
121//----------------------------------------------------------------------
122int
123Mangled::Compare (const Mangled& a, const Mangled& b)
124{
Jim Ingham89bf5e92010-09-15 00:13:44 +0000125 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126}
127
128
129
130//----------------------------------------------------------------------
131// Set the string value in this objects. If "mangled" is true, then
132// the mangled named is set with the new value in "s", else the
133// demangled name is set.
134//----------------------------------------------------------------------
135void
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000136Mangled::SetValue (const ConstString &s, bool mangled)
137{
138 if (s)
139 {
140 if (mangled)
141 {
142 m_demangled.Clear();
143 m_mangled = s;
144 }
145 else
146 {
147 m_demangled = s;
148 m_mangled.Clear();
149 }
150 }
151 else
152 {
153 m_demangled.Clear();
154 m_mangled.Clear();
155 }
156}
157
158void
159Mangled::SetValue (const ConstString &name)
160{
161 if (name)
162 {
163 if (cstring_is_mangled(name.GetCString()))
164 {
165 m_demangled.Clear();
166 m_mangled = name;
167 }
168 else
169 {
170 m_demangled = name;
171 m_mangled.Clear();
172 }
173 }
174 else
175 {
176 m_demangled.Clear();
177 m_mangled.Clear();
178 }
179}
180
181
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182//----------------------------------------------------------------------
183// Generate the demangled name on demand using this accessor. Code in
184// this class will need to use this accessor if it wishes to decode
185// the demangled name. The result is cached and will be kept until a
186// new string value is supplied to this object, or until the end of the
187// object's lifetime.
188//----------------------------------------------------------------------
189const ConstString&
190Mangled::GetDemangledName () const
191{
192 // Check to make sure we have a valid mangled name and that we
193 // haven't already decoded our mangled name.
194 if (m_mangled && !m_demangled)
195 {
196 // We need to generate and cache the demangled name.
197 Timer scoped_timer (__PRETTY_FUNCTION__,
198 "Mangled::GetDemangledName (m_mangled = %s)",
199 m_mangled.GetCString());
200
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000201 // Don't bother running anything that isn't mangled
202 const char *mangled_cstr = m_mangled.GetCString();
203 if (cstring_is_mangled(mangled_cstr))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000204 {
Greg Claytonc3ae1ce2011-06-09 22:34:34 +0000205 if (!m_mangled.GetMangledCounterpart(m_demangled))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206 {
Greg Claytone41e5892010-09-03 23:26:12 +0000207 // We didn't already mangle this name, demangle it and if all goes well
208 // add it to our map.
Greg Claytone9982672012-08-06 15:55:38 +0000209#if defined(USE_BUILTIN_LIBCXXABI_DEMANGLER)
210 char *demangled_name = lldb_cxxabiv1::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
211#else
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000212 char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
Greg Claytone9982672012-08-06 15:55:38 +0000213#endif
Greg Claytone41e5892010-09-03 23:26:12 +0000214
215 if (demangled_name)
216 {
Greg Claytonc3ae1ce2011-06-09 22:34:34 +0000217 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
Greg Claytone41e5892010-09-03 23:26:12 +0000218 free (demangled_name);
219 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220 }
221 }
Jason Molenda3f8688b2010-12-15 04:27:04 +0000222 if (!m_demangled)
223 {
224 // Set the demangled string to the empty string to indicate we
225 // tried to parse it once and failed.
226 m_demangled.SetCString("");
227 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228 }
229
230 return m_demangled;
231}
232
Greg Clayton83c5cd92010-11-14 22:13:40 +0000233
234bool
235Mangled::NameMatches (const RegularExpression& regex) const
236{
237 if (m_mangled && regex.Execute (m_mangled.AsCString()))
238 return true;
239
240 if (GetDemangledName() && regex.Execute (m_demangled.AsCString()))
241 return true;
242 return false;
243}
244
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245//----------------------------------------------------------------------
246// Get the demangled name if there is one, else return the mangled name.
247//----------------------------------------------------------------------
248const ConstString&
Jim Ingham08b87e02010-09-14 22:03:00 +0000249Mangled::GetName (Mangled::NamePreference preference) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250{
Greg Clayton87425432010-09-14 23:44:49 +0000251 if (preference == ePreferDemangled)
Jim Ingham08b87e02010-09-14 22:03:00 +0000252 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000253 // Call the accessor to make sure we get a demangled name in case
254 // it hasn't been demangled yet...
255 if (GetDemangledName())
256 return m_demangled;
Greg Clayton87425432010-09-14 23:44:49 +0000257 return m_mangled;
258 }
259 else
260 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000261 if (m_mangled)
262 return m_mangled;
263 return GetDemangledName();
Jim Ingham08b87e02010-09-14 22:03:00 +0000264 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000265}
266
267//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268// Dump a Mangled object to stream "s". We don't force our
269// demangled name to be computed currently (we don't use the accessor).
270//----------------------------------------------------------------------
271void
272Mangled::Dump (Stream *s) const
273{
274 if (m_mangled)
275 {
276 *s << ", mangled = " << m_mangled;
277 }
278 if (m_demangled)
279 {
280 const char * demangled = m_demangled.AsCString();
281 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
282 }
283}
284
285//----------------------------------------------------------------------
286// Dumps a debug version of this string with extra object and state
287// information to stream "s".
288//----------------------------------------------------------------------
289void
290Mangled::DumpDebug (Stream *s) const
291{
292 s->Printf("%*p: Mangled mangled = ", (int)sizeof(void*) * 2, this);
293 m_mangled.DumpDebug(s);
294 s->Printf(", demangled = ");
295 m_demangled.DumpDebug(s);
296}
297
298//----------------------------------------------------------------------
299// Return the size in byte that this object takes in memory. The size
300// includes the size of the objects it owns, and not the strings that
301// it references because they are shared strings.
302//----------------------------------------------------------------------
303size_t
304Mangled::MemorySize () const
305{
306 return m_mangled.MemorySize() + m_demangled.MemorySize();
307}
308
309//----------------------------------------------------------------------
310// Dump OBJ to the supplied stream S.
311//----------------------------------------------------------------------
312Stream&
313operator << (Stream& s, const Mangled& obj)
314{
315 if (obj.GetMangledName())
316 s << "mangled = '" << obj.GetMangledName() << "'";
317
318 const ConstString& demangled = obj.GetDemangledName();
319 if (demangled)
320 s << ", demangled = '" << demangled << '\'';
321 else
322 s << ", demangled = <error>";
323 return s;
324}