26using llvm::itanium_demangle::OutputBuffer;
27using llvm::itanium_demangle::starts_with;
47 const char *parseMangle(OutputBuffer *Demangled);
58 void parseMangle(OutputBuffer *Demangled, std::string_view &Mangled);
68 void decodeNumber(std::string_view &Mangled,
unsigned long &Ret);
81 bool decodeBackrefPos(std::string_view &Mangled,
long &Ret);
91 bool decodeBackref(std::string_view &Mangled, std::string_view &Ret);
101 void parseSymbolBackref(OutputBuffer *Demangled, std::string_view &Mangled);
110 void parseTypeBackref(OutputBuffer *Demangled, std::string_view &Mangled);
119 bool isSymbolName(std::string_view Mangled);
128 void parseIdentifier(OutputBuffer *Demangled, std::string_view &Mangled);
139 void parseLName(OutputBuffer *Demangled, std::string_view &Mangled,
149 void parseQualified(OutputBuffer *Demangled, std::string_view &Mangled);
159 bool parseType(OutputBuffer *Demangled, std::string_view &Mangled);
162 const std::string_view Str;
169void Demangler::decodeNumber(std::string_view &Mangled,
unsigned long &Ret) {
176 if (!std::isdigit(
Mangled.front())) {
181 unsigned long Val = 0;
184 unsigned long Digit =
Mangled[0] -
'0';
187 if (Val > (std::numeric_limits<unsigned int>::max() - Digit) / 10) {
192 Val = Val * 10 + Digit;
204bool Demangler::decodeBackrefPos(std::string_view &Mangled,
long &Ret) {
220 unsigned long Val = 0;
224 if (Val > (std::numeric_limits<unsigned long>::max() - 25) / 26)
229 if (Mangled[0] >=
'a' && Mangled[0] <=
'z') {
246bool Demangler::decodeBackref(std::string_view &Mangled,
247 std::string_view &Ret) {
249 "Invalid back reference!");
253 const char *Qpos =
Mangled.data();
257 if (!decodeBackrefPos(Mangled, RefPos)) {
262 if (RefPos > Qpos - Str.data()) {
273void Demangler::parseSymbolBackref(OutputBuffer *Demangled,
274 std::string_view &Mangled) {
282 std::string_view Backref;
283 if (!decodeBackref(Mangled, Backref)) {
289 decodeNumber(Backref, Len);
290 if (Backref.empty() || Backref.length() < Len) {
295 parseLName(Demangled, Backref, Len);
300void Demangler::parseTypeBackref(OutputBuffer *Demangled,
301 std::string_view &Mangled) {
309 if (
Mangled.data() - Str.data() >= LastBackref) {
314 int SaveRefPos = LastBackref;
315 LastBackref =
Mangled.data() - Str.data();
318 std::string_view Backref;
319 if (!decodeBackref(Mangled, Backref)) {
325 if (Backref.empty()) {
334 LastBackref = SaveRefPos;
340bool Demangler::isSymbolName(std::string_view Mangled) {
342 const char *Qref =
Mangled.data();
344 if (std::isdigit(
Mangled.front()))
353 bool Valid = decodeBackrefPos(Mangled, Ret);
354 if (!Valid || Ret > Qref - Str.data())
357 return std::isdigit(Qref[-Ret]);
360void Demangler::parseMangle(OutputBuffer *Demangled,
361 std::string_view &Mangled) {
373 parseQualified(Demangled, Mangled);
384 OutputBuffer TypeBuf;
392 Demangled->
insert(TypeLen,
" ", 1);
399void Demangler::parseQualified(OutputBuffer *Demangled,
400 std::string_view &Mangled) {
416 size_t NotFirst =
false;
431 parseIdentifier(Demangled, Mangled);
432 }
while (!
Mangled.empty() && isSymbolName(Mangled));
435void Demangler::parseIdentifier(OutputBuffer *Demangled,
436 std::string_view &Mangled) {
443 return parseSymbolBackref(Demangled, Mangled);
448 decodeNumber(Mangled, Len);
454 if (!Len ||
Mangled.length() < Len) {
465 const size_t SuffixLen =
Mangled.length() -
Len;
466 std::string_view
P =
Mangled.substr(3);
467 while (
P.length() > SuffixLen && std::isdigit(
P.front()))
469 if (
P.length() == SuffixLen) {
472 return parseIdentifier(Demangled, Mangled);
478 parseLName(Demangled, Mangled, Len);
481bool Demangler::parseType(OutputBuffer *Demangled, std::string_view &Mangled) {
502 *Demangled <<
"void";
507 *Demangled <<
"char";
511 *Demangled <<
"bool";
515 *Demangled <<
"creal";
519 *Demangled <<
"double";
523 *Demangled <<
"real";
527 *Demangled <<
"float";
531 *Demangled <<
"byte";
535 *Demangled <<
"ubyte";
539 *Demangled <<
"ireal";
543 *Demangled <<
"uint";
547 *Demangled <<
"long";
551 *Demangled <<
"ulong";
558 *Demangled <<
"ifloat";
562 *Demangled <<
"idouble";
566 *Demangled <<
"cfloat";
570 *Demangled <<
"cdouble";
574 *Demangled <<
"short";
578 *Demangled <<
"ushort";
582 *Demangled <<
"wchar";
586 *Demangled <<
"dchar";
593 if (Mangled[1] ==
'i') {
595 *Demangled <<
"cent";
598 if (Mangled[1] ==
'k') {
600 *Demangled <<
"ucent";
610 if (Mangled[1] ==
'n') {
612 *Demangled <<
"noreturn";
620 parseTypeBackref(Demangled, Mangled);
630void Demangler::parseLName(OutputBuffer *Demangled, std::string_view &Mangled,
636 Demangled->
prepend(
"initializer for ");
643 Demangled->
prepend(
"vtable for ");
653 Demangled->
prepend(
"ClassInfo for ");
663 Demangled->
prepend(
"Interface for ");
673 Demangled->
prepend(
"ModuleInfo for ");
681 *Demangled <<
Mangled.substr(0, Len);
685Demangler::Demangler(std::string_view Mangled)
686 : Str(Mangled), LastBackref(Mangled.length()) {}
688const char *Demangler::parseMangle(
OutputBuffer *Demangled) {
689 std::string_view M(this->Str);
690 parseMangle(Demangled, M);
695 if (MangledName.empty() || !
starts_with(MangledName,
"_D"))
699 if (MangledName ==
"_Dmain") {
700 Demangled <<
"D main";
703 Demangler
D(MangledName);
704 const char *M =
D.parseMangle(&Demangled);
707 if (M ==
nullptr || *M !=
'\0') {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
itanium_demangle::ManglingParser< DefaultAllocator > Demangler
OutputBuffer & prepend(std::string_view R)
void setCurrentPosition(size_t NewPos)
size_t getCurrentPosition() const
void insert(size_t Pos, const char *S, size_t N)
@ Valid
The data is already valid.
This is an optimization pass for GlobalISel generic memory operations.
DEMANGLE_ABI char * dlangDemangle(std::string_view MangledName)
LLVM_ABI Type * parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, const SlotMapping *Slots=nullptr)
Parse a type in the given string.