1 //===-- Mangled.cpp ---------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
16 #include "llvm/ADT/DenseMap.h"
18 #include "lldb/Core/ConstString.h"
19 #include "lldb/Core/Mangled.h"
20 #include "lldb/Core/RegularExpression.h"
21 #include "lldb/Core/Stream.h"
22 #include "lldb/Core/Timer.h"
27 using namespace lldb_private;
30 cstring_is_mangled (const char *s)
33 return s[0] == '_' && s[1] == 'Z';
38 //----------------------------------------------------------------------
39 // Default constructor
40 //----------------------------------------------------------------------
47 //----------------------------------------------------------------------
48 // Constructor with an optional string and a boolean indicating if it is
49 // the mangled version.
50 //----------------------------------------------------------------------
51 Mangled::Mangled (const ConstString &s, bool mangled) :
59 Mangled::Mangled (const ConstString &s) :
67 //----------------------------------------------------------------------
69 //----------------------------------------------------------------------
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:
78 // Mangled mangled(...);
81 //----------------------------------------------------------------------
82 Mangled::operator void* () const
84 return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
87 //----------------------------------------------------------------------
88 // Logical NOT operator. This allows code to check any Mangled
89 // objects to see if they are invalid using code such as:
91 // Mangled mangled(...);
94 //----------------------------------------------------------------------
96 Mangled::operator! () const
101 //----------------------------------------------------------------------
102 // Clear the mangled and demangled values.
103 //----------------------------------------------------------------------
112 //----------------------------------------------------------------------
113 // Compare the the string values.
114 //----------------------------------------------------------------------
116 Mangled::Compare (const Mangled& a, const Mangled& b)
118 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled));
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 //----------------------------------------------------------------------
129 Mangled::SetValue (const ConstString &s, bool mangled)
152 Mangled::SetValue (const ConstString &name)
156 if (cstring_is_mangled(name.GetCString()))
175 //----------------------------------------------------------------------
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 //----------------------------------------------------------------------
183 Mangled::GetDemangledName () const
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)
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());
194 // Don't bother running anything that isn't mangled
195 const char *mangled_cstr = m_mangled.GetCString();
196 if (cstring_is_mangled(mangled_cstr))
198 if (!m_mangled.GetMangledCounterpart(m_demangled))
200 // We didn't already mangle this name, demangle it and if all goes well
201 // add it to our map.
202 char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
206 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
207 free (demangled_name);
213 // Set the demangled string to the empty string to indicate we
214 // tried to parse it once and failed.
215 m_demangled.SetCString("");
224 Mangled::NameMatches (const RegularExpression& regex) const
226 if (m_mangled && regex.Execute (m_mangled.AsCString()))
229 if (GetDemangledName() && regex.Execute (m_demangled.AsCString()))
234 //----------------------------------------------------------------------
235 // Get the demangled name if there is one, else return the mangled name.
236 //----------------------------------------------------------------------
238 Mangled::GetName (Mangled::NamePreference preference) const
240 if (preference == ePreferDemangled)
242 // Call the accessor to make sure we get a demangled name in case
243 // it hasn't been demangled yet...
244 if (GetDemangledName())
252 return GetDemangledName();
256 //----------------------------------------------------------------------
257 // 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 //----------------------------------------------------------------------
261 Mangled::Dump (Stream *s) const
265 *s << ", mangled = " << m_mangled;
269 const char * demangled = m_demangled.AsCString();
270 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
274 //----------------------------------------------------------------------
275 // Dumps a debug version of this string with extra object and state
276 // information to stream "s".
277 //----------------------------------------------------------------------
279 Mangled::DumpDebug (Stream *s) const
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);
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 //----------------------------------------------------------------------
293 Mangled::MemorySize () const
295 return m_mangled.MemorySize() + m_demangled.MemorySize();
298 //----------------------------------------------------------------------
299 // Dump OBJ to the supplied stream S.
300 //----------------------------------------------------------------------
302 operator << (Stream& s, const Mangled& obj)
304 if (obj.GetMangledName())
305 s << "mangled = '" << obj.GetMangledName() << "'";
307 const ConstString& demangled = obj.GetDemangledName();
309 s << ", demangled = '" << demangled << '\'';
311 s << ", demangled = <error>";