blob: 4655eb131a6c9d5a341174fc580e028c46e8647b [file] [log] [blame]
Chris Lattner24943d22010-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 Claytone8c020c2012-08-06 15:55:38 +000010
Filipe Cabecinhas4e17f302012-09-11 18:11:12 +000011// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
12#include <cstddef>
Chris Lattner24943d22010-06-08 16:52:24 +000013#include <cxxabi.h>
Greg Claytone8c020c2012-08-06 15:55:38 +000014
Chris Lattner24943d22010-06-08 16:52:24 +000015
Greg Claytone33bdd32010-09-03 23:26:12 +000016#include "llvm/ADT/DenseMap.h"
17
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Core/ConstString.h"
19#include "lldb/Core/Mangled.h"
Greg Clayton3bc52d02010-11-14 22:13:40 +000020#include "lldb/Core/RegularExpression.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/Stream.h"
22#include "lldb/Core/Timer.h"
Eli Friedmana4083262010-06-09 08:50:27 +000023#include <ctype.h>
24#include <string.h>
Daniel Maleaae8c27b2013-05-31 20:21:38 +000025#include <stdlib.h>
Chris Lattner24943d22010-06-08 16:52:24 +000026
27using namespace lldb_private;
28
Greg Clayton9b98ffd2012-07-18 20:47:40 +000029static inline bool
30cstring_is_mangled (const char *s)
31{
32 if (s)
33 return s[0] == '_' && s[1] == 'Z';
34 return false;
35}
36
Chris Lattner24943d22010-06-08 16:52:24 +000037#pragma mark Mangled
38//----------------------------------------------------------------------
39// Default constructor
40//----------------------------------------------------------------------
41Mangled::Mangled () :
42 m_mangled(),
43 m_demangled()
44{
45}
46
47//----------------------------------------------------------------------
48// Constructor with an optional string and a boolean indicating if it is
49// the mangled version.
50//----------------------------------------------------------------------
Greg Clayton9b98ffd2012-07-18 20:47:40 +000051Mangled::Mangled (const ConstString &s, bool mangled) :
52 m_mangled(),
53 m_demangled()
54{
55 if (s)
56 SetValue(s, mangled);
57}
58
Greg Claytonc0240042012-07-18 23:18:10 +000059Mangled::Mangled (const ConstString &s) :
Greg Clayton9b98ffd2012-07-18 20:47:40 +000060 m_mangled(),
61 m_demangled()
62{
Greg Clayton9b98ffd2012-07-18 20:47:40 +000063 if (s)
64 SetValue(s);
65}
66
67//----------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +000068// Destructor
69//----------------------------------------------------------------------
70Mangled::~Mangled ()
71{
72}
73
74//----------------------------------------------------------------------
75// Convert to pointer operator. This allows code to check any Mangled
76// objects to see if they contain anything valid using code such as:
77//
78// Mangled mangled(...);
79// if (mangled)
80// { ...
81//----------------------------------------------------------------------
82Mangled::operator void* () const
83{
84 return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
85}
86
87//----------------------------------------------------------------------
88// Logical NOT operator. This allows code to check any Mangled
89// objects to see if they are invalid using code such as:
90//
91// Mangled mangled(...);
92// if (!file_spec)
93// { ...
94//----------------------------------------------------------------------
95bool
96Mangled::operator! () const
97{
98 return !m_mangled;
99}
100
101//----------------------------------------------------------------------
102// Clear the mangled and demangled values.
103//----------------------------------------------------------------------
104void
105Mangled::Clear ()
106{
107 m_mangled.Clear();
108 m_demangled.Clear();
109}
110
111
112//----------------------------------------------------------------------
113// Compare the the string values.
114//----------------------------------------------------------------------
115int
116Mangled::Compare (const Mangled& a, const Mangled& b)
117{
Jim Inghambeea0522010-09-15 00:13:44 +0000118 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled));
Chris Lattner24943d22010-06-08 16:52:24 +0000119}
120
121
122
123//----------------------------------------------------------------------
124// Set the string value in this objects. If "mangled" is true, then
125// the mangled named is set with the new value in "s", else the
126// demangled name is set.
127//----------------------------------------------------------------------
128void
Greg Clayton9b98ffd2012-07-18 20:47:40 +0000129Mangled::SetValue (const ConstString &s, bool mangled)
130{
131 if (s)
132 {
133 if (mangled)
134 {
135 m_demangled.Clear();
136 m_mangled = s;
137 }
138 else
139 {
140 m_demangled = s;
141 m_mangled.Clear();
142 }
143 }
144 else
145 {
146 m_demangled.Clear();
147 m_mangled.Clear();
148 }
149}
150
151void
152Mangled::SetValue (const ConstString &name)
153{
154 if (name)
155 {
156 if (cstring_is_mangled(name.GetCString()))
157 {
158 m_demangled.Clear();
159 m_mangled = name;
160 }
161 else
162 {
163 m_demangled = name;
164 m_mangled.Clear();
165 }
166 }
167 else
168 {
169 m_demangled.Clear();
170 m_mangled.Clear();
171 }
172}
173
174
Chris Lattner24943d22010-06-08 16:52:24 +0000175//----------------------------------------------------------------------
176// Generate the demangled name on demand using this accessor. Code in
177// this class will need to use this accessor if it wishes to decode
178// the demangled name. The result is cached and will be kept until a
179// new string value is supplied to this object, or until the end of the
180// object's lifetime.
181//----------------------------------------------------------------------
182const ConstString&
183Mangled::GetDemangledName () const
184{
185 // Check to make sure we have a valid mangled name and that we
186 // haven't already decoded our mangled name.
187 if (m_mangled && !m_demangled)
188 {
189 // We need to generate and cache the demangled name.
190 Timer scoped_timer (__PRETTY_FUNCTION__,
191 "Mangled::GetDemangledName (m_mangled = %s)",
192 m_mangled.GetCString());
193
Greg Clayton9b98ffd2012-07-18 20:47:40 +0000194 // Don't bother running anything that isn't mangled
195 const char *mangled_cstr = m_mangled.GetCString();
196 if (cstring_is_mangled(mangled_cstr))
Chris Lattner24943d22010-06-08 16:52:24 +0000197 {
Greg Clayton9d479442011-06-09 22:34:34 +0000198 if (!m_mangled.GetMangledCounterpart(m_demangled))
Chris Lattner24943d22010-06-08 16:52:24 +0000199 {
Greg Claytone33bdd32010-09-03 23:26:12 +0000200 // We didn't already mangle this name, demangle it and if all goes well
201 // add it to our map.
Greg Clayton9b98ffd2012-07-18 20:47:40 +0000202 char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
Greg Claytone33bdd32010-09-03 23:26:12 +0000203
204 if (demangled_name)
205 {
Greg Clayton9d479442011-06-09 22:34:34 +0000206 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
Greg Claytone33bdd32010-09-03 23:26:12 +0000207 free (demangled_name);
208 }
Chris Lattner24943d22010-06-08 16:52:24 +0000209 }
210 }
Jason Molenda5d1ff142010-12-15 04:27:04 +0000211 if (!m_demangled)
212 {
213 // Set the demangled string to the empty string to indicate we
214 // tried to parse it once and failed.
215 m_demangled.SetCString("");
216 }
Chris Lattner24943d22010-06-08 16:52:24 +0000217 }
218
219 return m_demangled;
220}
221
Greg Clayton3bc52d02010-11-14 22:13:40 +0000222
223bool
224Mangled::NameMatches (const RegularExpression& regex) const
225{
226 if (m_mangled && regex.Execute (m_mangled.AsCString()))
227 return true;
228
229 if (GetDemangledName() && regex.Execute (m_demangled.AsCString()))
230 return true;
231 return false;
232}
233
Chris Lattner24943d22010-06-08 16:52:24 +0000234//----------------------------------------------------------------------
235// Get the demangled name if there is one, else return the mangled name.
236//----------------------------------------------------------------------
237const ConstString&
Jim Ingham17454cf2010-09-14 22:03:00 +0000238Mangled::GetName (Mangled::NamePreference preference) const
Chris Lattner24943d22010-06-08 16:52:24 +0000239{
Greg Clayton251de2a2010-09-14 23:44:49 +0000240 if (preference == ePreferDemangled)
Jim Ingham17454cf2010-09-14 22:03:00 +0000241 {
Greg Clayton02987822010-09-14 23:48:44 +0000242 // Call the accessor to make sure we get a demangled name in case
243 // it hasn't been demangled yet...
244 if (GetDemangledName())
245 return m_demangled;
Greg Clayton251de2a2010-09-14 23:44:49 +0000246 return m_mangled;
247 }
248 else
249 {
Greg Clayton02987822010-09-14 23:48:44 +0000250 if (m_mangled)
251 return m_mangled;
252 return GetDemangledName();
Jim Ingham17454cf2010-09-14 22:03:00 +0000253 }
Chris Lattner24943d22010-06-08 16:52:24 +0000254}
255
256//----------------------------------------------------------------------
Chris Lattner24943d22010-06-08 16:52:24 +0000257// Dump a Mangled object to stream "s". We don't force our
258// demangled name to be computed currently (we don't use the accessor).
259//----------------------------------------------------------------------
260void
261Mangled::Dump (Stream *s) const
262{
263 if (m_mangled)
264 {
265 *s << ", mangled = " << m_mangled;
266 }
267 if (m_demangled)
268 {
269 const char * demangled = m_demangled.AsCString();
270 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
271 }
272}
273
274//----------------------------------------------------------------------
275// Dumps a debug version of this string with extra object and state
276// information to stream "s".
277//----------------------------------------------------------------------
278void
279Mangled::DumpDebug (Stream *s) const
280{
281 s->Printf("%*p: Mangled mangled = ", (int)sizeof(void*) * 2, this);
282 m_mangled.DumpDebug(s);
283 s->Printf(", demangled = ");
284 m_demangled.DumpDebug(s);
285}
286
287//----------------------------------------------------------------------
288// Return the size in byte that this object takes in memory. The size
289// includes the size of the objects it owns, and not the strings that
290// it references because they are shared strings.
291//----------------------------------------------------------------------
292size_t
293Mangled::MemorySize () const
294{
295 return m_mangled.MemorySize() + m_demangled.MemorySize();
296}
297
298//----------------------------------------------------------------------
299// Dump OBJ to the supplied stream S.
300//----------------------------------------------------------------------
301Stream&
302operator << (Stream& s, const Mangled& obj)
303{
304 if (obj.GetMangledName())
305 s << "mangled = '" << obj.GetMangledName() << "'";
306
307 const ConstString& demangled = obj.GetDemangledName();
308 if (demangled)
309 s << ", demangled = '" << demangled << '\'';
310 else
311 s << ", demangled = <error>";
312 return s;
313}