22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Demangle/Demangle.h"
24 #include "llvm/Support/Compiler.h"
35 return Mangled::GetManglingScheme(s) != Mangled::eManglingSchemeNone;
40 Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef
const name) {
42 return Mangled::eManglingSchemeNone;
44 if (name.startswith(
"?"))
45 return Mangled::eManglingSchemeMSVC;
47 if (name.startswith(
"_R"))
48 return Mangled::eManglingSchemeRustV0;
50 if (name.startswith(
"_D"))
51 return Mangled::eManglingSchemeD;
53 if (name.startswith(
"_Z"))
54 return Mangled::eManglingSchemeItanium;
57 if (name.startswith(
"___Z"))
58 return Mangled::eManglingSchemeItanium;
60 return Mangled::eManglingSchemeNone;
63 Mangled::Mangled(
ConstString s) : m_mangled(), m_demangled() {
68 Mangled::Mangled(llvm::StringRef name) {
79 Mangled::operator bool()
const {
return m_mangled || m_demangled; }
82 void Mangled::Clear() {
90 b.GetName(ePreferMangled));
95 void Mangled::SetValue(
ConstString s,
bool mangled) {
127 char *demangled_cstr = llvm::microsoftDemangle(
128 M,
nullptr,
nullptr,
nullptr,
nullptr,
129 llvm::MSDemangleFlags(
130 llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention |
131 llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType));
133 if (
Log *log =
GetLog(LLDBLog::Demangle)) {
134 if (demangled_cstr && demangled_cstr[0])
135 LLDB_LOGF(log,
"demangled msvc: %s -> \"%s\"", M, demangled_cstr);
137 LLDB_LOGF(log,
"demangled msvc: %s -> error", M);
140 return demangled_cstr;
144 char *demangled_cstr =
nullptr;
146 llvm::ItaniumPartialDemangler ipd;
147 bool err = ipd.partialDemangle(M);
150 size_t demangled_size = 80;
151 demangled_cstr =
static_cast<char *
>(std::malloc(demangled_size));
152 demangled_cstr = ipd.finishDemangle(demangled_cstr, &demangled_size);
154 assert(demangled_cstr &&
155 "finishDemangle must always succeed if partialDemangle did");
156 assert(demangled_cstr[demangled_size - 1] ==
'\0' &&
157 "Expected demangled_size to return length including trailing null");
160 if (
Log *log =
GetLog(LLDBLog::Demangle)) {
162 LLDB_LOGF(log,
"demangled itanium: %s -> \"%s\"", M, demangled_cstr);
164 LLDB_LOGF(log,
"demangled itanium: %s -> error: failed to demangle", M);
167 return demangled_cstr;
171 char *demangled_cstr = llvm::rustDemangle(M);
173 if (
Log *log =
GetLog(LLDBLog::Demangle)) {
174 if (demangled_cstr && demangled_cstr[0])
175 LLDB_LOG(log,
"demangled rustv0: {0} -> \"{1}\"", M, demangled_cstr);
177 LLDB_LOG(log,
"demangled rustv0: {0} -> error: failed to demangle", M);
180 return demangled_cstr;
184 char *demangled_cstr = llvm::dlangDemangle(M);
186 if (
Log *log =
GetLog(LLDBLog::Demangle)) {
187 if (demangled_cstr && demangled_cstr[0])
188 LLDB_LOG(log,
"demangled dlang: {0} -> \"{1}\"", M, demangled_cstr);
190 LLDB_LOG(log,
"demangled dlang: {0} -> error: failed to demangle", M);
193 return demangled_cstr;
199 SkipMangledNameFn *skip_mangled_name) {
205 ManglingScheme scheme = GetManglingScheme(m_mangled.GetStringRef());
206 if (skip_mangled_name && skip_mangled_name(m_mangled.GetStringRef(), scheme))
210 case eManglingSchemeNone:
214 case eManglingSchemeItanium:
219 case eManglingSchemeMSVC: {
222 if (!m_demangled && !m_mangled.GetMangledCounterpart(m_demangled)) {
227 m_demangled.SetStringWithMangledCounterpart(llvm::StringRef(d),
231 m_demangled.SetCString(
"");
235 if (m_demangled.IsEmpty()) {
245 case eManglingSchemeRustV0:
246 case eManglingSchemeD:
250 llvm_unreachable(
"Fully covered switch above!");
260 if (m_mangled && m_demangled.IsNull()) {
262 const char *mangled_name = m_mangled.
GetCString();
263 ManglingScheme mangling_scheme =
264 GetManglingScheme(m_mangled.GetStringRef());
265 if (mangling_scheme != eManglingSchemeNone &&
266 !m_mangled.GetMangledCounterpart(m_demangled)) {
269 char *demangled_name =
nullptr;
270 switch (mangling_scheme) {
271 case eManglingSchemeMSVC:
274 case eManglingSchemeItanium: {
278 case eManglingSchemeRustV0:
281 case eManglingSchemeD:
284 case eManglingSchemeNone:
285 llvm_unreachable(
"eManglingSchemeNone was handled already");
287 if (demangled_name) {
288 m_demangled.SetStringWithMangledCounterpart(
289 llvm::StringRef(demangled_name), m_mangled);
290 free(demangled_name);
293 if (m_demangled.IsNull()) {
296 m_demangled.SetCString(
"");
303 ConstString Mangled::GetDisplayDemangledName()
const {
304 return GetDemangledName();
308 if (m_mangled && regex.
Execute(m_mangled.GetStringRef()))
317 if (preference == ePreferMangled && m_mangled)
324 if (preference == ePreferDemangledWithoutArguments) {
325 if (
Language *lang = Language::FindPlugin(GuessLanguage())) {
326 return lang->GetDemangledFunctionNameWithoutArguments(*
this);
329 if (preference == ePreferDemangled) {
339 void Mangled::Dump(
Stream *s)
const {
341 *s <<
", mangled = " << m_mangled;
344 const char *demangled = m_demangled.
AsCString();
345 s->
Printf(
", demangled = %s", demangled[0] ? demangled :
"<error>");
351 void Mangled::DumpDebug(
Stream *s)
const {
352 s->
Printf(
"%*p: Mangled mangled = ",
static_cast<int>(
sizeof(
void *) * 2),
353 static_cast<const void *
>(
this));
354 m_mangled.DumpDebug(s);
355 s->
Printf(
", demangled = ");
356 m_demangled.DumpDebug(s);
362 size_t Mangled::MemorySize()
const {
363 return m_mangled.MemorySize() + m_demangled.MemorySize();
375 Language::ForEach([
this, &result](
Language *l) {
377 result = l->GetLanguageType();
387 if (obj.GetMangledName())
388 s <<
"mangled = '" << obj.GetMangledName() <<
"'";
392 s <<
", demangled = '" << demangled <<
'\'';
394 s <<
", demangled = <error>";
434 m_demangled.SetString(strtab.
Get(data.
GetU32(offset_ptr)));
438 m_mangled.SetString(strtab.
Get(data.
GetU32(offset_ptr)));
442 m_mangled.SetString(strtab.
Get(data.
GetU32(offset_ptr)));
443 m_demangled.SetString(strtab.
Get(data.
GetU32(offset_ptr)));
483 if (!(m_mangled.GetMangledCounterpart(s) && s == m_demangled))
486 }
else if (m_demangled) {
489 file.AppendU8(encoding);
494 file.AppendU32(strtab.
Add(m_demangled));
497 file.AppendU32(strtab.
Add(m_mangled));
500 file.AppendU32(strtab.
Add(m_mangled));
501 file.AppendU32(strtab.
Add(m_demangled));