blob: 37812e0956c0403d4e060f1989759e012b42c82d [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>
Daniel Maleae376a652013-05-31 19:24:53 +000033#include <cstdlib>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034
35using namespace lldb_private;
36
Greg Clayton5e0c5e82012-07-18 20:47:40 +000037static inline bool
38cstring_is_mangled (const char *s)
39{
40 if (s)
41 return s[0] == '_' && s[1] == 'Z';
42 return false;
43}
44
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045#pragma mark Mangled
46//----------------------------------------------------------------------
47// Default constructor
48//----------------------------------------------------------------------
49Mangled::Mangled () :
50 m_mangled(),
51 m_demangled()
52{
53}
54
55//----------------------------------------------------------------------
56// Constructor with an optional string and a boolean indicating if it is
57// the mangled version.
58//----------------------------------------------------------------------
Greg Clayton5e0c5e82012-07-18 20:47:40 +000059Mangled::Mangled (const ConstString &s, bool mangled) :
60 m_mangled(),
61 m_demangled()
62{
63 if (s)
64 SetValue(s, mangled);
65}
66
Greg Clayton037520e2012-07-18 23:18:10 +000067Mangled::Mangled (const ConstString &s) :
Greg Clayton5e0c5e82012-07-18 20:47:40 +000068 m_mangled(),
69 m_demangled()
70{
Greg Clayton5e0c5e82012-07-18 20:47:40 +000071 if (s)
72 SetValue(s);
73}
74
75//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076// Destructor
77//----------------------------------------------------------------------
78Mangled::~Mangled ()
79{
80}
81
82//----------------------------------------------------------------------
83// Convert to pointer operator. This allows code to check any Mangled
84// objects to see if they contain anything valid using code such as:
85//
86// Mangled mangled(...);
87// if (mangled)
88// { ...
89//----------------------------------------------------------------------
90Mangled::operator void* () const
91{
92 return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
93}
94
95//----------------------------------------------------------------------
96// Logical NOT operator. This allows code to check any Mangled
97// objects to see if they are invalid using code such as:
98//
99// Mangled mangled(...);
100// if (!file_spec)
101// { ...
102//----------------------------------------------------------------------
103bool
104Mangled::operator! () const
105{
106 return !m_mangled;
107}
108
109//----------------------------------------------------------------------
110// Clear the mangled and demangled values.
111//----------------------------------------------------------------------
112void
113Mangled::Clear ()
114{
115 m_mangled.Clear();
116 m_demangled.Clear();
117}
118
119
120//----------------------------------------------------------------------
121// Compare the the string values.
122//----------------------------------------------------------------------
123int
124Mangled::Compare (const Mangled& a, const Mangled& b)
125{
Jim Ingham89bf5e92010-09-15 00:13:44 +0000126 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127}
128
129
130
131//----------------------------------------------------------------------
132// Set the string value in this objects. If "mangled" is true, then
133// the mangled named is set with the new value in "s", else the
134// demangled name is set.
135//----------------------------------------------------------------------
136void
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000137Mangled::SetValue (const ConstString &s, bool mangled)
138{
139 if (s)
140 {
141 if (mangled)
142 {
143 m_demangled.Clear();
144 m_mangled = s;
145 }
146 else
147 {
148 m_demangled = s;
149 m_mangled.Clear();
150 }
151 }
152 else
153 {
154 m_demangled.Clear();
155 m_mangled.Clear();
156 }
157}
158
159void
160Mangled::SetValue (const ConstString &name)
161{
162 if (name)
163 {
164 if (cstring_is_mangled(name.GetCString()))
165 {
166 m_demangled.Clear();
167 m_mangled = name;
168 }
169 else
170 {
171 m_demangled = name;
172 m_mangled.Clear();
173 }
174 }
175 else
176 {
177 m_demangled.Clear();
178 m_mangled.Clear();
179 }
180}
181
182
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183//----------------------------------------------------------------------
184// Generate the demangled name on demand using this accessor. Code in
185// this class will need to use this accessor if it wishes to decode
186// the demangled name. The result is cached and will be kept until a
187// new string value is supplied to this object, or until the end of the
188// object's lifetime.
189//----------------------------------------------------------------------
190const ConstString&
191Mangled::GetDemangledName () const
192{
193 // Check to make sure we have a valid mangled name and that we
194 // haven't already decoded our mangled name.
195 if (m_mangled && !m_demangled)
196 {
197 // We need to generate and cache the demangled name.
198 Timer scoped_timer (__PRETTY_FUNCTION__,
199 "Mangled::GetDemangledName (m_mangled = %s)",
200 m_mangled.GetCString());
201
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000202 // Don't bother running anything that isn't mangled
203 const char *mangled_cstr = m_mangled.GetCString();
204 if (cstring_is_mangled(mangled_cstr))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205 {
Greg Claytonc3ae1ce2011-06-09 22:34:34 +0000206 if (!m_mangled.GetMangledCounterpart(m_demangled))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207 {
Greg Claytone41e5892010-09-03 23:26:12 +0000208 // We didn't already mangle this name, demangle it and if all goes well
209 // add it to our map.
Greg Claytone9982672012-08-06 15:55:38 +0000210#if defined(USE_BUILTIN_LIBCXXABI_DEMANGLER)
211 char *demangled_name = lldb_cxxabiv1::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
212#else
Greg Clayton5e0c5e82012-07-18 20:47:40 +0000213 char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
Greg Claytone9982672012-08-06 15:55:38 +0000214#endif
Greg Claytone41e5892010-09-03 23:26:12 +0000215
216 if (demangled_name)
217 {
Greg Claytonc3ae1ce2011-06-09 22:34:34 +0000218 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
Greg Claytone41e5892010-09-03 23:26:12 +0000219 free (demangled_name);
220 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221 }
222 }
Jason Molenda3f8688b2010-12-15 04:27:04 +0000223 if (!m_demangled)
224 {
225 // Set the demangled string to the empty string to indicate we
226 // tried to parse it once and failed.
227 m_demangled.SetCString("");
228 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229 }
230
231 return m_demangled;
232}
233
Greg Clayton83c5cd92010-11-14 22:13:40 +0000234
235bool
236Mangled::NameMatches (const RegularExpression& regex) const
237{
238 if (m_mangled && regex.Execute (m_mangled.AsCString()))
239 return true;
240
241 if (GetDemangledName() && regex.Execute (m_demangled.AsCString()))
242 return true;
243 return false;
244}
245
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246//----------------------------------------------------------------------
247// Get the demangled name if there is one, else return the mangled name.
248//----------------------------------------------------------------------
249const ConstString&
Jim Ingham08b87e02010-09-14 22:03:00 +0000250Mangled::GetName (Mangled::NamePreference preference) const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251{
Greg Clayton87425432010-09-14 23:44:49 +0000252 if (preference == ePreferDemangled)
Jim Ingham08b87e02010-09-14 22:03:00 +0000253 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000254 // Call the accessor to make sure we get a demangled name in case
255 // it hasn't been demangled yet...
256 if (GetDemangledName())
257 return m_demangled;
Greg Clayton87425432010-09-14 23:44:49 +0000258 return m_mangled;
259 }
260 else
261 {
Greg Claytond0b89f82010-09-14 23:48:44 +0000262 if (m_mangled)
263 return m_mangled;
264 return GetDemangledName();
Jim Ingham08b87e02010-09-14 22:03:00 +0000265 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266}
267
268//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000269// Dump a Mangled object to stream "s". We don't force our
270// demangled name to be computed currently (we don't use the accessor).
271//----------------------------------------------------------------------
272void
273Mangled::Dump (Stream *s) const
274{
275 if (m_mangled)
276 {
277 *s << ", mangled = " << m_mangled;
278 }
279 if (m_demangled)
280 {
281 const char * demangled = m_demangled.AsCString();
282 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
283 }
284}
285
286//----------------------------------------------------------------------
287// Dumps a debug version of this string with extra object and state
288// information to stream "s".
289//----------------------------------------------------------------------
290void
291Mangled::DumpDebug (Stream *s) const
292{
293 s->Printf("%*p: Mangled mangled = ", (int)sizeof(void*) * 2, this);
294 m_mangled.DumpDebug(s);
295 s->Printf(", demangled = ");
296 m_demangled.DumpDebug(s);
297}
298
299//----------------------------------------------------------------------
300// Return the size in byte that this object takes in memory. The size
301// includes the size of the objects it owns, and not the strings that
302// it references because they are shared strings.
303//----------------------------------------------------------------------
304size_t
305Mangled::MemorySize () const
306{
307 return m_mangled.MemorySize() + m_demangled.MemorySize();
308}
309
310//----------------------------------------------------------------------
311// Dump OBJ to the supplied stream S.
312//----------------------------------------------------------------------
313Stream&
314operator << (Stream& s, const Mangled& obj)
315{
316 if (obj.GetMangledName())
317 s << "mangled = '" << obj.GetMangledName() << "'";
318
319 const ConstString& demangled = obj.GetDemangledName();
320 if (demangled)
321 s << ", demangled = '" << demangled << '\'';
322 else
323 s << ", demangled = <error>";
324 return s;
325}