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