// The demangler entry point. bool Demangle(const char *mangled, char *out, int out_size) { State state; InitState(&state, mangled, out, out_size); return (ParseMangledName(&state) && state.overflowed == false && RemainingLength(&state) == 0); }
// <expr-primary> ::= L <type> <(value) number> E // ::= L <type> <(value) float> E // ::= L <mangled-name> E // // A bug in g++'s C++ ABI version 2 (-fabi-version=2). // ::= LZ <encoding> E static bool ParseExprPrimary(State *state) { State copy = *state; if (ParseChar(state, 'L') && ParseType(state) && ParseNumber(state) && ParseChar(state, 'E')) { return true; } *state = copy; if (ParseChar(state, 'L') && ParseType(state) && ParseFloatNumber(state) && ParseChar(state, 'E')) { return true; } *state = copy; if (ParseChar(state, 'L') && ParseMangledName(state) && ParseChar(state, 'E')) { return true; } *state = copy; if (ParseTwoChar(state, "LZ") && ParseEncoding(state) && ParseChar(state, 'E')) { return true; } *state = copy; return false; }
// The demangler entry point. int gimli_demangle(const char *mangled, char *out, int out_size) { State state; #ifdef __MACH__ /* skip leading '_' that is present on this platform */ mangled++; #endif InitState(&state, mangled, out, out_size); return (ParseMangledName(&state) && state.overflowed == false && RemainingLength(&state) == 0); }
// Parse <mangled-name>, optionally followed by either a function-clone suffix // or version suffix. Returns true only if all of "mangled_cur" was consumed. static bool ParseTopLevelMangledName(State *state) { if (ParseMangledName(state)) { if (state->mangled_cur[0] != '\0') { // Drop trailing function clone suffix, if any. if (IsFunctionCloneSuffix(state->mangled_cur)) { return true; } // Append trailing version suffix if any. // ex. _Z3foo@@GLIBCXX_3.4 if (state->mangled_cur[0] == '@') { MaybeAppend(state, state->mangled_cur); return true; } return false; // Unconsumed suffix. } return true; } return false; }