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