26using llvm::itanium_demangle::OutputBuffer;
27using llvm::itanium_demangle::starts_with;
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(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(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(std::string_view &Mangled) {
308 if (
Mangled.data() - Str.data() >= LastBackref) {
313 int SaveRefPos = LastBackref;
314 LastBackref =
Mangled.data() - Str.data();
317 std::string_view Backref;
318 if (!decodeBackref(Mangled, Backref)) {
324 if (Backref.empty()) {
333 LastBackref = SaveRefPos;
339bool Demangler::isSymbolName(std::string_view Mangled) {
341 const char *Qref =
Mangled.data();
343 if (std::isdigit(
Mangled.front()))
352 bool Valid = decodeBackrefPos(Mangled, Ret);
353 if (!Valid || Ret > Qref - Str.data())
356 return std::isdigit(Qref[-Ret]);
360 std::string_view &Mangled) {
372 parseQualified(Demangled, Mangled);
387 std::string_view &Mangled) {
403 size_t NotFirst =
false;
418 parseIdentifier(Demangled, Mangled);
419 }
while (!
Mangled.empty() && isSymbolName(Mangled));
423 std::string_view &Mangled) {
430 return parseSymbolBackref(Demangled, Mangled);
435 decodeNumber(Mangled, Len);
441 if (!Len ||
Mangled.length() < Len) {
452 const size_t SuffixLen =
Mangled.length() -
Len;
453 std::string_view
P =
Mangled.substr(3);
454 while (
P.length() > SuffixLen && std::isdigit(
P.front()))
456 if (
P.length() == SuffixLen) {
459 return parseIdentifier(Demangled, Mangled);
465 parseLName(Demangled, Mangled, Len);
468bool Demangler::parseType(std::string_view &Mangled) {
491 parseTypeBackref(Mangled);
501void Demangler::parseLName(
OutputBuffer *Demangled, std::string_view &Mangled,
507 Demangled->
prepend(
"initializer for ");
514 Demangled->
prepend(
"vtable for ");
524 Demangled->
prepend(
"ClassInfo for ");
534 Demangled->
prepend(
"Interface for ");
544 Demangled->
prepend(
"ModuleInfo for ");
552 *Demangled <<
Mangled.substr(0, Len);
556Demangler::Demangler(std::string_view Mangled)
557 : Str(Mangled), LastBackref(Mangled.length()) {}
559const char *Demangler::parseMangle(OutputBuffer *Demangled) {
560 std::string_view M(this->Str);
561 parseMangle(Demangled, M);
566 if (MangledName.empty() || !
starts_with(MangledName,
"_D"))
569 OutputBuffer Demangled;
570 if (MangledName ==
"_Dmain") {
571 Demangled <<
"D main";
575 const char *M =
D.parseMangle(&Demangled);
578 if (M ==
nullptr || *M !=
'\0') {
579 std::free(Demangled.getBuffer());
586 if (Demangled.getCurrentPosition() > 0) {
588 Demangled.setCurrentPosition(Demangled.getCurrentPosition() - 1);
589 return Demangled.getBuffer();
592 std::free(Demangled.getBuffer());
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
itanium_demangle::ManglingParser< DefaultAllocator > Demangler
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OutputBuffer & prepend(std::string_view R)
void setCurrentPosition(size_t NewPos)
size_t getCurrentPosition() const
This is an optimization pass for GlobalISel generic memory operations.
char * dlangDemangle(std::string_view MangledName)
Type * parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, const SlotMapping *Slots=nullptr)
Parse a type in the given string.