25using llvm::itanium_demangle::OutputBuffer;
26using llvm::itanium_demangle::StringView;
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);
182const 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';
193 if (Val > (std::numeric_limits<unsigned int>::max() - Digit) / 10)
196 Val = Val * 10 + Digit;
198 }
while (std::isdigit(*Mangled));
200 if (*Mangled ==
'\0')
207const 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)) {
226 if (Val > (std::numeric_limits<unsigned long>::max() - 25) / 26)
231 if (Mangled[0] >=
'a' && Mangled[0] <=
'z') {
232 Val += Mangled[0] -
'a';
239 Val += Mangled[0] -
'A';
246const 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)
268const 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)
292const 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)
325bool 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]);
344const char *Demangler::parseMangle(
OutputBuffer *Demangled,
345 const char *Mangled) {
357 Mangled = parseQualified(Demangled, Mangled);
359 if (Mangled !=
nullptr) {
371const 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));
410const 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);
454const char *Demangler::parseType(
const char *Mangled) {
455 if (*Mangled ==
'\0')
475 return parseTypeBackref(Mangled);
482const char *Demangler::parseLName(
OutputBuffer *Demangled,
const char *Mangled,
486 if (strncmp(Mangled,
"__initZ", Len + 1) == 0) {
488 Demangled->
prepend(
"initializer for ");
493 if (strncmp(Mangled,
"__vtblZ", Len + 1) == 0) {
495 Demangled->
prepend(
"vtable for ");
503 if (strncmp(Mangled,
"__ClassZ", Len + 1) == 0) {
505 Demangled->
prepend(
"ClassInfo for ");
513 if (strncmp(Mangled,
"__InterfaceZ", Len + 1) == 0) {
515 Demangled->
prepend(
"Interface for ");
523 if (strncmp(Mangled,
"__ModuleInfoZ", Len + 1) == 0) {
525 Demangled->
prepend(
"ModuleInfo for ");
539Demangler::Demangler(
const char *Mangled)
540 : Str(Mangled), LastBackref(strlen(Mangled)) {}
542const char *Demangler::parseMangle(OutputBuffer *Demangled) {
543 return parseMangle(Demangled, this->Str);
547 if (MangledName ==
nullptr || strncmp(MangledName,
"_D", 2) != 0)
550 OutputBuffer Demangled;
551 if (strcmp(MangledName,
"_Dmain") == 0) {
552 Demangled <<
"D main";
556 MangledName =
D.parseMangle(&Demangled);
559 if (MangledName ==
nullptr || *MangledName !=
'\0') {
560 std::free(Demangled.getBuffer());
567 if (Demangled.getCurrentPosition() > 0) {
569 Demangled.setCurrentPosition(Demangled.getCurrentPosition() - 1);
570 return Demangled.getBuffer();
573 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(StringView R)
void setCurrentPosition(size_t NewPos)
size_t getCurrentPosition() const
This is an optimization pass for GlobalISel generic memory operations.
char * dlangDemangle(const char *MangledName)
Type * parseType(StringRef Asm, SMDiagnostic &Err, const Module &M, const SlotMapping *Slots=nullptr)
Parse a type in the given string.