📄 cplus-dem.c
字号:
we are not prepared for, it must be an error. */ success = 0; } break; } if (AUTO_DEMANGLING || GNU_DEMANGLING) { if (success && expect_func) { func_done = 1; success = demangle_args (work, mangled, declp); } } } if (success && !func_done) { if (AUTO_DEMANGLING || GNU_DEMANGLING) { /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and bar__3fooi is 'foo::bar(int)'. We get here when we find the first case, and need to ensure that the '(void)' gets added to the current declp. Note that with ARM, the first case represents the name of a static data member 'foo::bar', which is in the current declp, so we leave it alone. */ success = demangle_args (work, mangled, declp); } } if (success && work -> static_type && PRINT_ARG_TYPES) { string_append (declp, " static"); } if (success && work -> const_type && PRINT_ARG_TYPES) { string_append (declp, " const"); } return (success);}#if 0static intdemangle_method_args (work, mangled, declp) struct work_stuff *work; CONST char **mangled; string *declp;{ int success = 0; if (work -> static_type) { string_append (declp, *mangled + 1); *mangled += strlen (*mangled); success = 1; } else { success = demangle_args (work, mangled, declp); } return (success);}#endifstatic intdemangle_template (work, mangled, declp) struct work_stuff *work; CONST char **mangled; string *declp;{ int i; string tname; string trawname; int is_pointer; int is_real; int is_integral; int r; int need_comma = 0; int success = 0; int done; CONST char *old_p; int symbol_len; string temp; (*mangled)++; string_init (&tname); string_init (&trawname); /* get template name */ if (!get_count (mangled, &r)) { return (0); } string_appendn (&tname, *mangled, r); string_appendn (&trawname, *mangled, r); string_appendn (&trawname, "", 1); *mangled += r; string_append (&tname, "<"); /* get size of template parameter list */ if (!get_count (mangled, &r)) { return (0); } for (i = 0; i < r; i++) { if (need_comma) { string_append (&tname, ", "); } /* Z for type parameters */ if (**mangled == 'Z') { (*mangled)++; success = do_type (work, mangled, &temp); string_appendn (&temp, "", 1); if (success) { string_append (&tname, temp.b); } string_delete(&temp); if (!success) { break; } } else { /* otherwise, value parameter */ old_p = *mangled; is_pointer = 0; is_real = 0; is_integral = 0; done = 0; success = do_type (work, mangled, &temp); string_appendn (&temp, "", 1); if (success) { string_append (&tname, temp.b); } string_delete(&temp); if (!success) { break; } string_append (&tname, "="); while (*old_p && !done) { switch (*old_p) { case 'P': case 'R': done = is_pointer = 1; break; case 'C': /* const */ case 'S': /* explicitly signed [char] */ case 'U': /* unsigned */ case 'V': /* volatile */ case 'F': /* function */ case 'M': /* member function */ case 'O': /* ??? */ old_p++; continue; case 'Q': /* repetition of following */ case 'T': /* remembered type */ abort (); break; case 'v': /* void */ abort (); break; case 'x': /* long long */ case 'l': /* long */ case 'i': /* int */ case 's': /* short */ case 'c': /* char */ case 'w': /* wchar_t */ done = is_integral = 1; break; case 'r': /* long double */ case 'd': /* double */ case 'f': /* float */ done = is_real = 1; break; default: abort (); } } if (is_integral) { if (**mangled == 'm') { string_appendn (&tname, "-", 1); (*mangled)++; } while (isdigit (**mangled)) { string_appendn (&tname, *mangled, 1); (*mangled)++; } } else if (is_real) { if (**mangled == 'm') { string_appendn (&tname, "-", 1); (*mangled)++; } while (isdigit (**mangled)) { string_appendn (&tname, *mangled, 1); (*mangled)++; } if (**mangled == '.') /* fraction */ { string_appendn (&tname, ".", 1); (*mangled)++; while (isdigit (**mangled)) { string_appendn (&tname, *mangled, 1); (*mangled)++; } } if (**mangled == 'e') /* exponent */ { string_appendn (&tname, "e", 1); (*mangled)++; while (isdigit (**mangled)) { string_appendn (&tname, *mangled, 1); (*mangled)++; } } } else if (is_pointer) { if (!get_count (mangled, &symbol_len)) { success = 0; break; } string_appendn (&tname, *mangled, symbol_len); *mangled += symbol_len; } } need_comma = 1; } string_append (&tname, ">::"); if (work -> destructor) { string_append (&tname, "~"); } if (work -> constructor || work -> destructor) { string_append (&tname, trawname.b); } string_delete(&trawname); if (!success) { string_delete(&tname); } else { string_prepend (declp, tname.b); string_delete (&tname); if (work -> static_type) { string_append (declp, *mangled + 1); *mangled += strlen (*mangled); success = 1; } else { success = demangle_args (work, mangled, declp); } } return (success);}/*LOCAL FUNCTION demangle_class -- demangle a mangled class sequenceSYNOPSIS static int demangle_class (struct work_stuff *work, const char **mangled, strint *declp)DESCRIPTION DECLP points to the buffer into which demangling is being done. *MANGLED points to the current token to be demangled. On input, it points to a mangled class (I.E. "3foo", "13verylongclass", etc.) On exit, it points to the next token after the mangled class on success, or the first unconsumed token on failure. If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then we are demangling a constructor or destructor. In this case we prepend "class::class" or "class::~class" to DECLP. Otherwise, we prepend "class::" to the current DECLP. Reset the constructor/destructor flags once they have been "consumed". This allows demangle_class to be called later during the same demangling, to do normal class demangling. Returns 1 if demangling is successful, 0 otherwise.*/static intdemangle_class (work, mangled, declp) struct work_stuff *work; CONST char **mangled; string *declp;{ int n; int success = 0; n = consume_count (mangled); if (strlen (*mangled) >= n) { if (work -> constructor || work -> destructor) { string_prependn (declp, *mangled, n); if (work -> destructor) { string_prepend (declp, "~"); } work -> constructor = work -> destructor = 0; } string_prepend (declp, "::"); string_prependn (declp, *mangled, n); *mangled += n; success = 1; } return (success);}/*LOCAL FUNCTION demangle_prefix -- consume the mangled name prefix and find signatureSYNOPSIS static int demangle_prefix (struct work_stuff *work, const char **mangled, string *declp);DESCRIPTION Consume and demangle the prefix of the mangled name. DECLP points to the string buffer into which demangled output is placed. On entry, the buffer is empty. On exit it contains the root function name, the demangled operator name, or in some special cases either nothing or the completely demangled result. MANGLED points to the current pointer into the mangled name. As each token of the mangled name is consumed, it is updated. Upon entry the current mangled name pointer points to the first character of the mangled name. Upon exit, it should point to the first character of the signature if demangling was successful, or to the first unconsumed character if demangling of the prefix was unsuccessful. Returns 1 on success, 0 otherwise. */static intdemangle_prefix (work, mangled, declp) struct work_stuff *work; CONST char **mangled; string *declp;{ int success = 1; CONST char *scan; int i;/* This block of code is a reduction in strength time optimization of: scan = strstr (*mangled, "__"); */ { scan = *mangled; do { scan = strchr (scan, '_'); } while (scan != NULL && *++scan != '_'); if (scan != NULL) --scan; } if (scan != NULL) { /* We found a sequence of two or more '_', ensure that we start at the last pair in the sequence. */ i = strspn (scan, "_"); if (i > 2) { scan += (i - 2); } } if (scan == NULL) { success = 0; } else if (work -> static_type) { if (!isdigit (scan[0]) && (scan[0] != 't')) { success = 0; } } else if ((scan == *mangled) && (isdigit (scan[2]) || (scan[2] == 'Q'))) { /* A GNU style constructor starts with "__<digit>" or "__Q". */ work -> constructor = 1; *mangled = scan + 2; } else if ((scan == *mangled) && !isdigit (scan[2]) && (scan[2] != 't')) { /* Mangled name starts with "__". Skip over any leading '_' characters, then find the next "__" that separates the prefix from the signature. */ if (!(CFRONT_DEMANGLING || LUCID_DEMANGLING) || (cfront_special (work, mangled, declp) == 0)) { while (*scan == '_') { scan++; } if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) { /* No separator (I.E. "__not_mangled"), or empty signature (I.E. "__not_mangled_either__") */ success = 0; } else { demangle_function_name (work, mangled, declp, scan); } } } else if (*(scan + 2) != '\0') { /* Mangled name does not start with "__" but does have one somewhere in there with non empty stuff after it. Looks like a global function name. */ demangle_function_name (work, mangled, declp, scan); } else { /* Doesn't look like a mangled name */ success = 0; } return (success);}/*LOCAL FUNCTION gnu_special -- special handling of gnu mangled stringsSYNOPSIS static int gnu_special (struct work_stuff *work, const char **mangled, string *declp);DESCRIPTION Process some special GNU style mangling forms that don't fit the normal pattern. For example: _$_3foo (destructor for class foo) _vt$foo (foo virtual table) _vt$foo$bar (foo::bar virtual table) _3foo$varname (static data member) */static intgnu_special (work, mangled, declp) struct work_stuff *work; CONST char **mangled; string *declp;{ int n; int success = 1; CONST char *p; if ((*mangled)[0] == '_' && strchr (cplus_markers, (*mangled)[1]) != NULL && (*mangled)[2] == '_') { /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */ (*mangled) += 3; work -> destructor = 1; } else if ((*mangled)[0] == '_' && (*mangled)[1] == 'v' && (*mangled)[2] == 't' && strchr (cplus_markers, (*mangled)[3]) != NULL) { /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>" and create the decl. Note that we consume the entire mangled input string, which means that demangle_signature has no work to do. */ (*mangled) += 4; while (**mangled != '\0') { n = strcspn (*mangled, cplus_markers); string_appendn (declp, *mangled, n); (*mangled) += n; if (**mangled != '\0') { string_append (declp, "::"); (*mangled)++; } } string_append (declp, " virtual table"); } else if ((*mangled)[0] == '_' && isdigit ((*mangled)[1]) && (p = strpbrk (*mangled, cplus_markers)) != NULL) { /* static data member, "_3foo$varname" for example */ (*mangled)++; p++; n = consume_count (mangled); string_appendn (declp, *mangled, n); string_append (declp, "::"); n = strlen (p); string_appendn (declp, p, n); (*mangled) = p + n; } else { success = 0; } return (success);}/*LOCAL FUNCTION cfront_special -- special handling of cfront/lucid mangled stringsSYNOPSIS static int cfront_special (struct work_stuff *work, const char **mangled, string *declp);DESCRIPTION Process some special cfront style mangling forms that don't fit the normal pattern. For example: __vtbl__3foo (foo virtual table) __vtbl__3foo__3bar (bar::foo virtual table) */static intcfront_special (work, mangled, declp) struct work_stuff *work; CONST char **mangled; string *declp;{ int n; int i; int success = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -