25 using llvm::itanium_demangle::OutputBuffer;
26 using llvm::itanium_demangle::StringView;
46 const char *parseMangle(OutputBuffer *Demangled);
59 const char *parseMangle(OutputBuffer *Demangled,
const char *Mangled);
71 const char *decodeNumber(
const char *Mangled,
unsigned long &
Ret);
84 const char *decodeBackrefPos(
const char *Mangled,
long &
Ret);
94 const char *decodeBackref(
const char *Mangled,
const char *&
Ret);
106 const char *parseSymbolBackref(OutputBuffer *Demangled,
const char *Mangled);
117 const char *parseTypeBackref(
const char *Mangled);
126 bool isSymbolName(
const char *Mangled);
137 const char *parseIdentifier(OutputBuffer *Demangled,
const char *Mangled);
150 const char *parseLName(OutputBuffer *Demangled,
const char *Mangled,
162 const char *parseQualified(OutputBuffer *Demangled,
const char *Mangled);
172 const char *
parseType(
const char *Mangled);
182 const char *Demangler::decodeNumber(
const char *Mangled,
unsigned long &
Ret) {
184 if (Mangled ==
nullptr || !std::isdigit(*Mangled))
187 unsigned long Val = 0;
190 unsigned long Digit = Mangled[0] -
'0';
196 Val = Val * 10 + Digit;
198 }
while (std::isdigit(*Mangled));
200 if (*Mangled ==
'\0')
207 const char *Demangler::decodeBackrefPos(
const char *Mangled,
long &
Ret) {
209 if (Mangled ==
nullptr || !std::isalpha(*Mangled))
222 unsigned long Val = 0;
224 while (std::isalpha(*Mangled)) {
231 if (Mangled[0] >=
'a' && Mangled[0] <=
'z') {
232 Val += Mangled[0] -
'a';
239 Val += Mangled[0] -
'A';
246 const char *Demangler::decodeBackref(
const char *Mangled,
const char *&
Ret) {
247 assert(Mangled !=
nullptr && *Mangled ==
'Q' &&
"Invalid back reference!");
251 const char *Qpos = Mangled;
255 Mangled = decodeBackrefPos(Mangled, RefPos);
256 if (Mangled ==
nullptr)
259 if (RefPos > Qpos - Str)
268 const char *Demangler::parseSymbolBackref(OutputBuffer *Demangled,
269 const char *Mangled) {
278 Mangled = decodeBackref(Mangled, Backref);
281 Backref = decodeNumber(Backref, Len);
282 if (Backref ==
nullptr || strlen(Backref) < Len)
285 Backref = parseLName(Demangled, Backref, Len);
286 if (Backref ==
nullptr)
292 const char *Demangler::parseTypeBackref(
const char *Mangled) {
301 if (Mangled - Str >= LastBackref)
304 int SaveRefPos = LastBackref;
305 LastBackref = Mangled - Str;
308 Mangled = decodeBackref(Mangled, Backref);
311 if (Backref ==
nullptr)
317 LastBackref = SaveRefPos;
319 if (Backref ==
nullptr)
325 bool Demangler::isSymbolName(
const char *Mangled) {
327 const char *Qref = Mangled;
329 if (std::isdigit(*Mangled))
337 Mangled = decodeBackrefPos(Mangled + 1,
Ret);
338 if (Mangled ==
nullptr ||
Ret > Qref - Str)
341 return std::isdigit(Qref[-
Ret]);
344 const char *Demangler::parseMangle(OutputBuffer *Demangled,
345 const char *Mangled) {
357 Mangled = parseQualified(Demangled, Mangled);
359 if (Mangled !=
nullptr) {
371 const char *Demangler::parseQualified(OutputBuffer *Demangled,
372 const char *Mangled) {
388 size_t NotFirst =
false;
391 if (*Mangled ==
'0') {
394 while (*Mangled ==
'0');
403 Mangled = parseIdentifier(Demangled, Mangled);
405 }
while (Mangled && isSymbolName(Mangled));
410 const char *Demangler::parseIdentifier(OutputBuffer *Demangled,
411 const char *Mangled) {
414 if (Mangled ==
nullptr || *Mangled ==
'\0')
418 return parseSymbolBackref(Demangled, Mangled);
422 const char *Endptr = decodeNumber(Mangled, Len);
424 if (Endptr ==
nullptr || Len == 0)
427 if (strlen(Endptr) < Len)
437 if (Len >= 4 && Mangled[0] ==
'_' && Mangled[1] ==
'_' && Mangled[2] ==
'S') {
438 const char *NumPtr = Mangled + 3;
439 while (NumPtr < (Mangled + Len) && std::isdigit(*NumPtr))
442 if (Mangled + Len == NumPtr) {
445 return parseIdentifier(Demangled, Mangled);
451 return parseLName(Demangled, Mangled, Len);
455 if (*Mangled ==
'\0')
475 return parseTypeBackref(Mangled);
482 const char *Demangler::parseLName(OutputBuffer *Demangled,
const char *Mangled,
486 if (strncmp(Mangled,
"__initZ", Len + 1) == 0) {
488 Demangled->prepend(
"initializer for ");
489 Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
493 if (strncmp(Mangled,
"__vtblZ", Len + 1) == 0) {
495 Demangled->prepend(
"vtable for ");
496 Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
503 if (strncmp(Mangled,
"__ClassZ", Len + 1) == 0) {
505 Demangled->prepend(
"ClassInfo for ");
506 Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
513 if (strncmp(Mangled,
"__InterfaceZ", Len + 1) == 0) {
515 Demangled->prepend(
"Interface for ");
516 Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
523 if (strncmp(Mangled,
"__ModuleInfoZ", Len + 1) == 0) {
525 Demangled->prepend(
"ModuleInfo for ");
526 Demangled->setCurrentPosition(Demangled->getCurrentPosition() - 1);
533 *Demangled << StringView(Mangled, Len);
540 : Str(Mangled), LastBackref(strlen(Mangled)) {}
542 const char *Demangler::parseMangle(OutputBuffer *Demangled) {
543 return parseMangle(Demangled, this->Str);
547 if (MangledName ==
nullptr || strncmp(MangledName,
"_D", 2) != 0)
550 OutputBuffer Demangled;
554 if (strcmp(MangledName,
"_Dmain") == 0) {
555 Demangled <<
"D main";
559 MangledName =
D.parseMangle(&Demangled);
562 if (MangledName ==
nullptr || *MangledName !=
'\0') {
563 std::free(Demangled.getBuffer());
570 if (Demangled.getCurrentPosition() > 0) {
572 Demangled.setCurrentPosition(Demangled.getCurrentPosition() - 1);
573 return Demangled.getBuffer();
576 std::free(Demangled.getBuffer());