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 #include <cxxabi.h> 19 #endif 20 21 22 #include "llvm/ADT/DenseMap.h" 23 24 #include "lldb/Core/ConstString.h" 25 #include "lldb/Core/Mangled.h" 26 #include "lldb/Core/RegularExpression.h" 27 #include "lldb/Core/Stream.h" 28 #include "lldb/Core/Timer.h" 29 #include <ctype.h> 30 #include <string.h> 31 32 using namespace lldb_private; 33 34 static inline bool 35 cstring_is_mangled (const char *s) 36 { 37 if (s) 38 return s[0] == '_' && s[1] == 'Z'; 39 return false; 40 } 41 42 #pragma mark Mangled 43 //---------------------------------------------------------------------- 44 // Default constructor 45 //---------------------------------------------------------------------- 46 Mangled::Mangled () : 47 m_mangled(), 48 m_demangled() 49 { 50 } 51 52 //---------------------------------------------------------------------- 53 // Constructor with an optional string and a boolean indicating if it is 54 // the mangled version. 55 //---------------------------------------------------------------------- 56 Mangled::Mangled (const ConstString &s, bool mangled) : 57 m_mangled(), 58 m_demangled() 59 { 60 if (s) 61 SetValue(s, mangled); 62 } 63 64 Mangled::Mangled (const ConstString &s) : 65 m_mangled(), 66 m_demangled() 67 { 68 if (s) 69 SetValue(s); 70 } 71 72 //---------------------------------------------------------------------- 73 // Destructor 74 //---------------------------------------------------------------------- 75 Mangled::~Mangled () 76 { 77 } 78 79 //---------------------------------------------------------------------- 80 // Convert to pointer operator. This allows code to check any Mangled 81 // objects to see if they contain anything valid using code such as: 82 // 83 // Mangled mangled(...); 84 // if (mangled) 85 // { ... 86 //---------------------------------------------------------------------- 87 Mangled::operator void* () const 88 { 89 return (m_mangled) ? const_cast<Mangled*>(this) : NULL; 90 } 91 92 //---------------------------------------------------------------------- 93 // Logical NOT operator. This allows code to check any Mangled 94 // objects to see if they are invalid using code such as: 95 // 96 // Mangled mangled(...); 97 // if (!file_spec) 98 // { ... 99 //---------------------------------------------------------------------- 100 bool 101 Mangled::operator! () const 102 { 103 return !m_mangled; 104 } 105 106 //---------------------------------------------------------------------- 107 // Clear the mangled and demangled values. 108 //---------------------------------------------------------------------- 109 void 110 Mangled::Clear () 111 { 112 m_mangled.Clear(); 113 m_demangled.Clear(); 114 } 115 116 117 //---------------------------------------------------------------------- 118 // Compare the the string values. 119 //---------------------------------------------------------------------- 120 int 121 Mangled::Compare (const Mangled& a, const Mangled& b) 122 { 123 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled)); 124 } 125 126 127 128 //---------------------------------------------------------------------- 129 // Set the string value in this objects. If "mangled" is true, then 130 // the mangled named is set with the new value in "s", else the 131 // demangled name is set. 132 //---------------------------------------------------------------------- 133 void 134 Mangled::SetValue (const ConstString &s, bool mangled) 135 { 136 if (s) 137 { 138 if (mangled) 139 { 140 m_demangled.Clear(); 141 m_mangled = s; 142 } 143 else 144 { 145 m_demangled = s; 146 m_mangled.Clear(); 147 } 148 } 149 else 150 { 151 m_demangled.Clear(); 152 m_mangled.Clear(); 153 } 154 } 155 156 void 157 Mangled::SetValue (const ConstString &name) 158 { 159 if (name) 160 { 161 if (cstring_is_mangled(name.GetCString())) 162 { 163 m_demangled.Clear(); 164 m_mangled = name; 165 } 166 else 167 { 168 m_demangled = name; 169 m_mangled.Clear(); 170 } 171 } 172 else 173 { 174 m_demangled.Clear(); 175 m_mangled.Clear(); 176 } 177 } 178 179 180 //---------------------------------------------------------------------- 181 // Generate the demangled name on demand using this accessor. Code in 182 // this class will need to use this accessor if it wishes to decode 183 // the demangled name. The result is cached and will be kept until a 184 // new string value is supplied to this object, or until the end of the 185 // object's lifetime. 186 //---------------------------------------------------------------------- 187 const ConstString& 188 Mangled::GetDemangledName () const 189 { 190 // Check to make sure we have a valid mangled name and that we 191 // haven't already decoded our mangled name. 192 if (m_mangled && !m_demangled) 193 { 194 // We need to generate and cache the demangled name. 195 Timer scoped_timer (__PRETTY_FUNCTION__, 196 "Mangled::GetDemangledName (m_mangled = %s)", 197 m_mangled.GetCString()); 198 199 // Don't bother running anything that isn't mangled 200 const char *mangled_cstr = m_mangled.GetCString(); 201 if (cstring_is_mangled(mangled_cstr)) 202 { 203 if (!m_mangled.GetMangledCounterpart(m_demangled)) 204 { 205 // We didn't already mangle this name, demangle it and if all goes well 206 // add it to our map. 207 #if defined(USE_BUILTIN_LIBCXXABI_DEMANGLER) 208 char *demangled_name = lldb_cxxabiv1::__cxa_demangle (mangled_cstr, NULL, NULL, NULL); 209 #else 210 char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL); 211 #endif 212 213 if (demangled_name) 214 { 215 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled); 216 free (demangled_name); 217 } 218 } 219 } 220 if (!m_demangled) 221 { 222 // Set the demangled string to the empty string to indicate we 223 // tried to parse it once and failed. 224 m_demangled.SetCString(""); 225 } 226 } 227 228 return m_demangled; 229 } 230 231 232 bool 233 Mangled::NameMatches (const RegularExpression& regex) const 234 { 235 if (m_mangled && regex.Execute (m_mangled.AsCString())) 236 return true; 237 238 if (GetDemangledName() && regex.Execute (m_demangled.AsCString())) 239 return true; 240 return false; 241 } 242 243 //---------------------------------------------------------------------- 244 // Get the demangled name if there is one, else return the mangled name. 245 //---------------------------------------------------------------------- 246 const ConstString& 247 Mangled::GetName (Mangled::NamePreference preference) const 248 { 249 if (preference == ePreferDemangled) 250 { 251 // Call the accessor to make sure we get a demangled name in case 252 // it hasn't been demangled yet... 253 if (GetDemangledName()) 254 return m_demangled; 255 return m_mangled; 256 } 257 else 258 { 259 if (m_mangled) 260 return m_mangled; 261 return GetDemangledName(); 262 } 263 } 264 265 //---------------------------------------------------------------------- 266 // Dump a Mangled object to stream "s". We don't force our 267 // demangled name to be computed currently (we don't use the accessor). 268 //---------------------------------------------------------------------- 269 void 270 Mangled::Dump (Stream *s) const 271 { 272 if (m_mangled) 273 { 274 *s << ", mangled = " << m_mangled; 275 } 276 if (m_demangled) 277 { 278 const char * demangled = m_demangled.AsCString(); 279 s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>"); 280 } 281 } 282 283 //---------------------------------------------------------------------- 284 // Dumps a debug version of this string with extra object and state 285 // information to stream "s". 286 //---------------------------------------------------------------------- 287 void 288 Mangled::DumpDebug (Stream *s) const 289 { 290 s->Printf("%*p: Mangled mangled = ", (int)sizeof(void*) * 2, this); 291 m_mangled.DumpDebug(s); 292 s->Printf(", demangled = "); 293 m_demangled.DumpDebug(s); 294 } 295 296 //---------------------------------------------------------------------- 297 // Return the size in byte that this object takes in memory. The size 298 // includes the size of the objects it owns, and not the strings that 299 // it references because they are shared strings. 300 //---------------------------------------------------------------------- 301 size_t 302 Mangled::MemorySize () const 303 { 304 return m_mangled.MemorySize() + m_demangled.MemorySize(); 305 } 306 307 //---------------------------------------------------------------------- 308 // Dump OBJ to the supplied stream S. 309 //---------------------------------------------------------------------- 310 Stream& 311 operator << (Stream& s, const Mangled& obj) 312 { 313 if (obj.GetMangledName()) 314 s << "mangled = '" << obj.GetMangledName() << "'"; 315 316 const ConstString& demangled = obj.GetDemangledName(); 317 if (demangled) 318 s << ", demangled = '" << demangled << '\''; 319 else 320 s << ", demangled = <error>"; 321 return s; 322 } 323