| 697 | } |
| 698 | |
| 699 | DFHACK_EXPORT std::string cxx_demangle(const std::string &mangled_name, std::string *status_out) |
| 700 | { |
| 701 | #ifdef __GNUC__ |
| 702 | int status; |
| 703 | char *demangled = abi::__cxa_demangle(mangled_name.c_str(), nullptr, nullptr, &status); |
| 704 | std::string out; |
| 705 | if (demangled) { |
| 706 | out = demangled; |
| 707 | free(demangled); |
| 708 | } |
| 709 | if (status_out) { |
| 710 | if (status == 0) *status_out = "success"; |
| 711 | else if (status == -1) *status_out = "memory allocation failure"; |
| 712 | else if (status == -2) *status_out = "invalid mangled name"; |
| 713 | else if (status == -3) *status_out = "invalid arguments"; |
| 714 | else *status_out = "unknown error"; |
| 715 | } |
| 716 | return out; |
| 717 | #elif defined(_WIN32) |
| 718 | const char* mangled_cstr = mangled_name.c_str(); |
| 719 | |
| 720 | char demangledBuf[MAX_SYM_NAME]; |
| 721 | DWORD flags = UNDNAME_NAME_ONLY; |
| 722 | |
| 723 | if (mangled_cstr[0] == '.') { |
| 724 | // Symbol is a type, demangle as such |
| 725 | // Flag is actually "UNDNAME_TYPE_ONLY", but hasn't been renamed for this method yet. |
| 726 | flags |= UNDNAME_NO_ARGUMENTS; |
| 727 | mangled_cstr++; |
| 728 | } |
| 729 | |
| 730 | DWORD res = UnDecorateSymbolName(mangled_cstr, (char*)&demangledBuf, MAX_SYM_NAME, flags); |
| 731 | |
| 732 | std::string out; |
| 733 | if (res == 0) { |
| 734 | // Demangling failed |
| 735 | *status_out = "demangling failed"; |
| 736 | return out; |
| 737 | } |
| 738 | if (demangledBuf[0] == '?') { |
| 739 | // Wine failed to demangle symbol |
| 740 | *status_out = "wine demangling failed"; |
| 741 | return out; |
| 742 | } |
| 743 | out = (char*)&demangledBuf; |
| 744 | return out; |
| 745 | #else |
| 746 | #error Platform does not support symbol demangling |
| 747 | #endif |
| 748 | } |