📄 cplus-dem.c
字号:
Numeric conversion is ASCII dependent (FIXME). */static intdemangle_qualified (work, mangled, result, isfuncname, append) struct work_stuff *work; const char **mangled; string *result; int isfuncname; int append;{ int qualifiers; int namelength; int success = 1; const char *p; char num[2]; string temp; string_init (&temp); switch ((*mangled)[1]) { case '_': /* GNU mangled name with more than 9 classes. The count is preceded by an underscore (to distinguish it from the <= 9 case) and followed by an underscore. */ p = *mangled + 2; qualifiers = atoi (p); if (!isdigit (*p) || *p == '0') success = 0; /* Skip the digits. */ while (isdigit (*p)) ++p; if (*p != '_') success = 0; *mangled = p + 1; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* The count is in a single digit. */ num[0] = (*mangled)[1]; num[1] = '\0'; qualifiers = atoi (num); /* If there is an underscore after the digit, skip it. This is said to be for ARM-qualified names, but the ARM makes no mention of such an underscore. Perhaps cfront uses one. */ if ((*mangled)[2] == '_') { (*mangled)++; } (*mangled) += 2; break; case '0': default: success = 0; } if (!success) return success; /* Pick off the names and collect them in the temp buffer in the order in which they are found, separated by '::'. */ while (qualifiers-- > 0) { if (*mangled[0] == '_') *mangled = *mangled + 1; if (*mangled[0] == 't') { success = demangle_template(work, mangled, &temp, 0); if (!success) break; } else { namelength = consume_count (mangled); if (strlen (*mangled) < namelength) { /* Simple sanity check failed */ success = 0; break; } string_appendn (&temp, *mangled, namelength); *mangled += namelength; } if (qualifiers > 0) { string_appendn (&temp, "::", 2); } } /* If we are using the result as a function name, we need to append the appropriate '::' separated constructor or destructor name. We do this here because this is the most convenient place, where we already have a pointer to the name and the length of the name. */ if (isfuncname && (work->constructor & 1 || work->destructor & 1)) { string_appendn (&temp, "::", 2); if (work -> destructor & 1) { string_append (&temp, "~"); } string_appendn (&temp, (*mangled) - namelength, namelength); } /* Now either prepend the temp buffer to the result, or append it, depending upon the state of the append flag. */ if (append) { string_appends (result, &temp); } else { if (!STRING_EMPTY (result)) { string_appendn (&temp, "::", 2); } string_prepends (result, &temp); } string_delete (&temp); return (success);}/*LOCAL FUNCTION get_count -- convert an ascii count to integer, consuming tokensSYNOPSIS static int get_count (const char **type, int *count)DESCRIPTION Return 0 if no conversion is performed, 1 if a string is converted.*/static intget_count (type, count) const char **type; int *count;{ const char *p; int n; if (!isdigit (**type)) { return (0); } else { *count = **type - '0'; (*type)++; if (isdigit (**type)) { p = *type; n = *count; do { n *= 10; n += *p - '0'; p++; } while (isdigit (*p)); if (*p == '_') { *type = p + 1; *count = n; } } } return (1);}/* result will be initialised here; it will be freed on failure */static intdo_type (work, mangled, result) struct work_stuff *work; const char **mangled; string *result;{ int n; int done; int success; string decl; const char *remembered_type; int constp; int volatilep; string_init (&decl); string_init (result); done = 0; success = 1; while (success && !done) { int member; switch (**mangled) { /* A pointer type */ case 'P': case 'p': (*mangled)++; string_prepend (&decl, "*"); break; /* A reference type */ case 'R': (*mangled)++; string_prepend (&decl, "&"); break; /* An array */ case 'A': { const char *p = ++(*mangled); string_prepend (&decl, "("); string_append (&decl, ")["); /* Copy anything up until the next underscore (the size of the array). */ while (**mangled && **mangled != '_') ++(*mangled); if (**mangled == '_') { string_appendn (&decl, p, *mangled - p); string_append (&decl, "]"); *mangled += 1; } else success = 0; break; } /* A back reference to a previously seen type */ case 'T': (*mangled)++; if (!get_count (mangled, &n) || n >= work -> ntypes) { success = 0; } else { remembered_type = work -> typevec[n]; mangled = &remembered_type; } break; /* A function */ case 'F': (*mangled)++; if (!STRING_EMPTY (&decl) && decl.b[0] == '*') { string_prepend (&decl, "("); string_append (&decl, ")"); } /* After picking off the function args, we expect to either find the function return type (preceded by an '_') or the end of the string. */ if (!demangle_args (work, mangled, &decl) || (**mangled != '_' && **mangled != '\0')) { success = 0; } if (success && (**mangled == '_')) { (*mangled)++; } break; case 'M': case 'O': { constp = 0; volatilep = 0; member = **mangled == 'M'; (*mangled)++; if (!isdigit (**mangled)) { success = 0; break; } n = consume_count (mangled); if (strlen (*mangled) < n) { success = 0; break; } string_append (&decl, ")"); string_prepend (&decl, "::"); string_prependn (&decl, *mangled, n); string_prepend (&decl, "("); *mangled += n; if (member) { if (**mangled == 'C') { (*mangled)++; constp = 1; } if (**mangled == 'V') { (*mangled)++; volatilep = 1; } if (*(*mangled)++ != 'F') { success = 0; break; } } if ((member && !demangle_args (work, mangled, &decl)) || **mangled != '_') { success = 0; break; } (*mangled)++; if (! PRINT_ANSI_QUALIFIERS) { break; } if (constp) { APPEND_BLANK (&decl); string_append (&decl, "const"); } if (volatilep) { APPEND_BLANK (&decl); string_append (&decl, "volatile"); } break; } case 'G': (*mangled)++; break; case 'C': (*mangled)++;/* if ((*mangled)[1] == 'P') {*/ if (PRINT_ANSI_QUALIFIERS) { if (!STRING_EMPTY (&decl)) { string_prepend (&decl, " "); } string_prepend (&decl, "const"); } break;/* }*/ /* fall through */ default: done = 1; break; } } switch (**mangled) { /* A qualified name, such as "Outer::Inner". */ case 'Q': success = demangle_qualified (work, mangled, result, 0, 1); break; default: success = demangle_fund_type (work, mangled, result); break; } if (success) { if (!STRING_EMPTY (&decl)) { string_append (result, " "); string_appends (result, &decl); } } else { string_delete (result); } string_delete (&decl); return (success);}/* Given a pointer to a type string that represents a fundamental type argument (int, long, unsigned int, etc) in TYPE, a pointer to the string in which the demangled output is being built in RESULT, and the WORK structure, decode the types and add them to the result. For example: "Ci" => "const int" "Sl" => "signed long" "CUs" => "const unsigned short" */static intdemangle_fund_type (work, mangled, result) struct work_stuff *work; const char **mangled; string *result;{ int done = 0; int success = 1; /* First pick off any type qualifiers. There can be more than one. */ while (!done) { switch (**mangled) { case 'C': (*mangled)++; if (PRINT_ANSI_QUALIFIERS) { APPEND_BLANK (result); string_append (result, "const"); } break; case 'U': (*mangled)++; APPEND_BLANK (result); string_append (result, "unsigned"); break; case 'S': /* signed char only */ (*mangled)++; APPEND_BLANK (result); string_append (result, "signed"); break; case 'V': (*mangled)++; if (PRINT_ANSI_QUALIFIERS) { APPEND_BLANK (result); string_append (result, "volatile"); } break; default: done = 1; break; } } /* Now pick off the fundamental type. There can be only one. */ switch (**mangled) { case '\0': case '_': break; case 'v': (*mangled)++; APPEND_BLANK (result); string_append (result, "void"); break; case 'x': (*mangled)++; APPEND_BLANK (result); string_append (result, "long long"); break; case 'l': (*mangled)++; APPEND_BLANK (result); string_append (result, "long"); break; case 'i': (*mangled)++; APPEND_BLANK (result); string_append (result, "int"); break; case 's': (*mangled)++; APPEND_BLANK (result); string_append (result, "short"); break; case 'b': (*mangled)++; APPEND_BLANK (result); string_append (result, "bool"); break; case 'c': (*mangled)++; APPEND_BLANK (result); string_append (result, "char"); break; case 'w': (*mangled)++; APPEND_BLANK (result); string_append (result, "wchar_t"); break; case 'r': (*mangled)++; APPEND_BLANK (result); string_append (result, "long double"); break; case 'd': (*mangled)++; APPEND_BLANK (result); string_append (result, "double"); break; case 'f': (*mangled)++; APPEND_BLANK (result); string_append (result, "float"); break; case 'G': (*mangled)++; if (!isdigit (**mangled)) { success = 0; break; } /* fall through */ /* An explicit type, such as "6mytype" or "7integer" */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': APPEND_BLANK (result); if (!demangle_class_name (work, mangled, result)) { --result->p; success = 0; } break; case 't': success = demangle_template(work,mangled, result, 0); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -