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 // FreeBSD9-STABLE requires this to know about size_t in cxxabi.h 12 #include <cstddef> 13 #include <cxxabi.h> 14 15 16 #include "llvm/ADT/DenseMap.h" 17 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" 23 #include <ctype.h> 24 #include <string.h> 25 #include <stdlib.h> 26 27 using namespace lldb_private; 28 29 static inline bool 30 cstring_is_mangled (const char *s) 31 { 32 if (s) 33 return s[0] == '_' && s[1] == 'Z'; 34 return false; 35 } 36 37 #pragma mark Mangled 38 //---------------------------------------------------------------------- 39 // Default constructor 40 //---------------------------------------------------------------------- 41 Mangled::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 //---------------------------------------------------------------------- 51 Mangled::Mangled (const ConstString &s, bool mangled) : 52 m_mangled(), 53 m_demangled() 54 { 55 if (s) 56 SetValue(s, mangled); 57 } 58 59 Mangled::Mangled (const ConstString &s) : 60 m_mangled(), 61 m_demangled() 62 { 63 if (s) 64 SetValue(s); 65 } 66 67 //---------------------------------------------------------------------- 68 // Destructor 69 //---------------------------------------------------------------------- 70 Mangled::~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 //---------------------------------------------------------------------- 82 Mangled::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 //---------------------------------------------------------------------- 95 bool 96 Mangled::operator! () const 97 { 98 return !m_mangled; 99 } 100 101 //---------------------------------------------------------------------- 102 // Clear the mangled and demangled values. 103 //---------------------------------------------------------------------- 104 void 105 Mangled::Clear () 106 { 107 m_mangled.Clear(); 108 m_demangled.Clear(); 109 } 110 111 112 //---------------------------------------------------------------------- 113 // Compare the the string values. 114 //---------------------------------------------------------------------- 115 int 116 Mangled::Compare (const Mangled& a, const Mangled& b) 117 { 118 return ConstString::Compare(a.GetName(ePreferMangled), a.GetName(ePreferMangled)); 119 } 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 //---------------------------------------------------------------------- 128 void 129 Mangled::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 151 void 152 Mangled::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 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 //---------------------------------------------------------------------- 182 const ConstString& 183 Mangled::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 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)) 197 { 198 if (!m_mangled.GetMangledCounterpart(m_demangled)) 199 { 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); 203 204 if (demangled_name) 205 { 206 m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled); 207 free (demangled_name); 208 } 209 } 210 } 211 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 } 217 } 218 219 return m_demangled; 220 } 221 222 223 bool 224 Mangled::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 234 //---------------------------------------------------------------------- 235 // Get the demangled name if there is one, else return the mangled name. 236 //---------------------------------------------------------------------- 237 const ConstString& 238 Mangled::GetName (Mangled::NamePreference preference) const 239 { 240 if (preference == ePreferDemangled) 241 { 242 // 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; 246 return m_mangled; 247 } 248 else 249 { 250 if (m_mangled) 251 return m_mangled; 252 return GetDemangledName(); 253 } 254 } 255 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 //---------------------------------------------------------------------- 260 void 261 Mangled::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 //---------------------------------------------------------------------- 278 void 279 Mangled::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 //---------------------------------------------------------------------- 292 size_t 293 Mangled::MemorySize () const 294 { 295 return m_mangled.MemorySize() + m_demangled.MemorySize(); 296 } 297 298 //---------------------------------------------------------------------- 299 // Dump OBJ to the supplied stream S. 300 //---------------------------------------------------------------------- 301 Stream& 302 operator << (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 } 314