1 //===-- 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 10 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 18 // FreeBSD9-STABLE requires this to know about size_t in cxxabi.h 19 #include <cstddef> 20 #include <cxxabi.h> 21 #endif 22 23 24 #include "llvm/ADT/DenseMap.h" 25 26 #include "lldb/Core/ConstString.h" 27 #include "lldb/Core/Mangled.h" 28 #include "lldb/Core/RegularExpression.h" 29 #include "lldb/Core/Stream.h" 30 #include "lldb/Core/Timer.h" 31 #include <ctype.h> 32 #include <string.h> 33 #include <stdlib.h> 34 35 using namespace lldb_private; 36 37 static inline bool 38 cstring_is_mangled (const char *s) 39 { 40 if (s) 41 return s[0] == '_' && s[1] == 'Z'; 42 return false; 43 } 44 45 #pragma mark Mangled 46 //---------------------------------------------------------------------- 47 // Default constructor 48 //---------------------------------------------------------------------- 49 Mangled::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 //---------------------------------------------------------------------- 59 Mangled::Mangled (const ConstString &s, bool mangled) : 60 m_mangled(), 61 m_demangled() 62 { 63 if (s) 64 SetValue(s, mangled); 65 } 66 67 Mangled::Mangled (const ConstString &s) : 68 m_mangled(), 69 m_demangled() 70 { 71 if (s) 72 SetValue(s); 73 } 74 75 //---------------------------------------------------------------------- 76 // Destructor 77 //---------------------------------------------------------------------- 78 Mangled::~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 //---------------------------------------------------------------------- 90 Mangled::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 //---------------------------------------------------------------------- 103 bool 104 Mangled::operator! () const 105 { 106 return !m_mangled; 107 } 108 109 //---------------------------------------------------------------------- 110 // Clear the mangled and demangled values. 111 //---------------------------------------------------------------------- 112 void 113 Mangled::Clear () 114 { 115 m_mangled.Clear(); 116 m_demangled.Clear(); 117 } 118 119 120 //---------------------------------------------------------------------- 121 // Compare the the string values. 122 //---------------------------------------------------------------------- 123 int 124 Mangled::Compare (const Mangled& a, const Mangled& b) 125 { 126 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled)); 127 } 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 //---------------------------------------------------------------------- 136 void 137 Mangled::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 159 void 160 Mangled::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 183 //---------------------------------------------------------------------- 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 //---------------------------------------------------------------------- 190 const ConstString& 191 Mangled::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 202 // Don't bother running anything that isn't mangled 203 const char *mangled_cstr = m_mangled.GetCString(); 204 if (cstring_is_mangled(mangled_cstr)) 205 { 206 if (!m_mangled.GetMangledCounterpart(m_demangled)) 207 { 208 // We didn't already mangle this name, demangle it and if all goes well 209 // add it to our map. 210 #if defined(USE_BUILTIN_LIBCXXABI_DEMANGLER) 211 char *demangled_name = lldb_cxxabiv1::__cxa_demangle (mangled_cstr, NULL, NULL, NULL); 212 #else 213 char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL); 214 #endif 215 216 if (demangled_name) 217 { 218 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled); 219 free (demangled_name); 220 } 221 } 222 } 223 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 } 229 } 230 231 return m_demangled; 232 } 233 234 235 bool 236 Mangled::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 246 //---------------------------------------------------------------------- 247 // Get the demangled name if there is one, else return the mangled name. 248 //---------------------------------------------------------------------- 249 const ConstString& 250 Mangled::GetName (Mangled::NamePreference preference) const 251 { 252 if (preference == ePreferDemangled) 253 { 254 // 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; 258 return m_mangled; 259 } 260 else 261 { 262 if (m_mangled) 263 return m_mangled; 264 return GetDemangledName(); 265 } 266 } 267 268 //---------------------------------------------------------------------- 269 // 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 //---------------------------------------------------------------------- 272 void 273 Mangled::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 //---------------------------------------------------------------------- 290 void 291 Mangled::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 //---------------------------------------------------------------------- 304 size_t 305 Mangled::MemorySize () const 306 { 307 return m_mangled.MemorySize() + m_demangled.MemorySize(); 308 } 309 310 //---------------------------------------------------------------------- 311 // Dump OBJ to the supplied stream S. 312 //---------------------------------------------------------------------- 313 Stream& 314 operator << (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 } 326