📄 cplus-dem.c
字号:
string *));static intdemangle_real_value PARAMS ((struct work_stuff *, const char **, string *));static voiddemangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int, string *));static voidrecursively_demangle PARAMS ((struct work_stuff *, const char **, string *, int));static voidgrow_vect PARAMS ((void **, size_t *, size_t, int));/* Translate count to integer, consuming tokens in the process. Conversion terminates on the first non-digit character. Trying to consume something that isn't a count results in no consumption of input and a return of -1. Overflow consumes the rest of the digits, and returns -1. */static intconsume_count (type) const char **type;{ int count = 0; if (! ISDIGIT ((unsigned char)**type)) return -1; while (ISDIGIT ((unsigned char)**type)) { count *= 10; /* Check for overflow. We assume that count is represented using two's-complement; no power of two is divisible by ten, so if an overflow occurs when multiplying by ten, the result will not be a multiple of ten. */ if ((count % 10) != 0) { while (ISDIGIT ((unsigned char) **type)) (*type)++; return -1; } count += **type - '0'; (*type)++; } return (count);}/* Like consume_count, but for counts that are preceded and followed by '_' if they are greater than 10. Also, -1 is returned for failure, since 0 can be a valid value. */static intconsume_count_with_underscores (mangled) const char **mangled;{ int idx; if (**mangled == '_') { (*mangled)++; if (!ISDIGIT ((unsigned char)**mangled)) return -1; idx = consume_count (mangled); if (**mangled != '_') /* The trailing underscore was missing. */ return -1; (*mangled)++; } else { if (**mangled < '0' || **mangled > '9') return -1; idx = **mangled - '0'; (*mangled)++; } return idx;}/* C is the code for a type-qualifier. Return the TYPE_QUAL corresponding to this qualifier. */static intcode_for_qualifier (c) int c;{ switch (c) { case 'C': return TYPE_QUAL_CONST; case 'V': return TYPE_QUAL_VOLATILE; case 'u': return TYPE_QUAL_RESTRICT; default: break; } /* C was an invalid qualifier. */ return TYPE_UNQUALIFIED;}/* Return the string corresponding to the qualifiers given by TYPE_QUALS. */static const char*qualifier_string (type_quals) int type_quals;{ switch (type_quals) { case TYPE_UNQUALIFIED: return ""; case TYPE_QUAL_CONST: return "const"; case TYPE_QUAL_VOLATILE: return "volatile"; case TYPE_QUAL_RESTRICT: return "__restrict"; case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE: return "const volatile"; case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT: return "const __restrict"; case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: return "volatile __restrict"; case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: return "const volatile __restrict"; default: break; } /* TYPE_QUALS was an invalid qualifier set. */ abort ();}/* C is the code for a type-qualifier. Return the string corresponding to this qualifier. This function should only be called with a valid qualifier code. */static const char*demangle_qualifier (c) int c;{ return qualifier_string (code_for_qualifier (c));}intcplus_demangle_opname (opname, result, options) const char *opname; char *result; int options;{ int len, len1, ret; string type; struct work_stuff work[1]; const char *tem; len = strlen(opname); result[0] = '\0'; ret = 0; memset ((char *) work, 0, sizeof (work)); work->options = options; if (opname[0] == '_' && opname[1] == '_' && opname[2] == 'o' && opname[3] == 'p') { /* ANSI. */ /* type conversion operator. */ tem = opname + 4; if (do_type (work, &tem, &type)) { strcat (result, "operator "); strncat (result, type.b, type.p - type.b); string_delete (&type); ret = 1; } } else if (opname[0] == '_' && opname[1] == '_' && ISLOWER((unsigned char)opname[2]) && ISLOWER((unsigned char)opname[3])) { if (opname[4] == '\0') { /* Operator. */ size_t i; for (i = 0; i < ARRAY_SIZE (optable); i++) { if (strlen (optable[i].in) == 2 && memcmp (optable[i].in, opname + 2, 2) == 0) { strcat (result, "operator"); strcat (result, optable[i].out); ret = 1; break; } } } else { if (opname[2] == 'a' && opname[5] == '\0') { /* Assignment. */ size_t i; for (i = 0; i < ARRAY_SIZE (optable); i++) { if (strlen (optable[i].in) == 3 && memcmp (optable[i].in, opname + 2, 3) == 0) { strcat (result, "operator"); strcat (result, optable[i].out); ret = 1; break; } } } } } else if (len >= 3 && opname[0] == 'o' && opname[1] == 'p' && strchr (cplus_markers, opname[2]) != NULL) { /* see if it's an assignment expression */ if (len >= 10 /* op$assign_ */ && memcmp (opname + 3, "assign_", 7) == 0) { size_t i; for (i = 0; i < ARRAY_SIZE (optable); i++) { len1 = len - 10; if ((int) strlen (optable[i].in) == len1 && memcmp (optable[i].in, opname + 10, len1) == 0) { strcat (result, "operator"); strcat (result, optable[i].out); strcat (result, "="); ret = 1; break; } } } else { size_t i; for (i = 0; i < ARRAY_SIZE (optable); i++) { len1 = len - 3; if ((int) strlen (optable[i].in) == len1 && memcmp (optable[i].in, opname + 3, len1) == 0) { strcat (result, "operator"); strcat (result, optable[i].out); ret = 1; break; } } } } else if (len >= 5 && memcmp (opname, "type", 4) == 0 && strchr (cplus_markers, opname[4]) != NULL) { /* type conversion operator */ tem = opname + 5; if (do_type (work, &tem, &type)) { strcat (result, "operator "); strncat (result, type.b, type.p - type.b); string_delete (&type); ret = 1; } } squangle_mop_up (work); return ret;}/* Takes operator name as e.g. "++" and returns mangled operator name (e.g. "postincrement_expr"), or NULL if not found. If OPTIONS & DMGL_ANSI == 1, return the ANSI name; if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */const char *cplus_mangle_opname (opname, options) const char *opname; int options;{ size_t i; int len; len = strlen (opname); for (i = 0; i < ARRAY_SIZE (optable); i++) { if ((int) strlen (optable[i].out) == len && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI) && memcmp (optable[i].out, opname, len) == 0) return optable[i].in; } return (0);}/* Add a routine to set the demangling style to be sure it is valid and allow for any demangler initialization that maybe necessary. */enum demangling_stylescplus_demangle_set_style (style) enum demangling_styles style;{ struct demangler_engine *demangler = libiberty_demanglers; for (; demangler->demangling_style != unknown_demangling; ++demangler) if (style == demangler->demangling_style) { current_demangling_style = style; return current_demangling_style; } return unknown_demangling;}/* Do string name to style translation */enum demangling_stylescplus_demangle_name_to_style (name) const char *name;{ struct demangler_engine *demangler = libiberty_demanglers; for (; demangler->demangling_style != unknown_demangling; ++demangler) if (strcmp (name, demangler->demangling_style_name) == 0) return demangler->demangling_style; return unknown_demangling;}/* char *cplus_demangle (const char *mangled, int options) If MANGLED is a mangled function name produced by GNU C++, then a pointer to a malloced string giving a C++ representation of the name will be returned; otherwise NULL will be returned. It is the caller's responsibility to free the string which is returned. The OPTIONS arg may contain one or more of the following bits: DMGL_ANSI ANSI qualifiers such as `const' and `void' are included. DMGL_PARAMS Function parameters are included. For example, cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)" cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)" cplus_demangle ("foo__1Ai", 0) => "A::foo" cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)" cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)" cplus_demangle ("foo__1Afe", 0) => "A::foo" Note that any leading underscores, or other such characters prepended by the compilation system, are presumed to have already been stripped from MANGLED. */char *cplus_demangle (mangled, options) const char *mangled; int options;{ char *ret; struct work_stuff work[1]; memset ((char *) work, 0, sizeof (work)); work->options = options; if ((work->options & DMGL_STYLE_MASK) == 0) work->options |= (int) current_demangling_style & DMGL_STYLE_MASK; /* The V3 ABI demangling is implemented elsewhere. */ if (GNU_V3_DEMANGLING || AUTO_DEMANGLING) { ret = cplus_demangle_v3 (mangled); if (ret || GNU_V3_DEMANGLING) return ret; } if (GNAT_DEMANGLING) return ada_demangle(mangled,options); if (EDG_DEMANGLING) { ret = edg_demangle(mangled,options); if (ret) { return (ret); } } ret = internal_cplus_demangle (work, mangled); squangle_mop_up (work); return (ret);}/* Assuming *OLD_VECT points to an array of *SIZE objects of size ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects, updating *OLD_VECT and *SIZE as necessary. */static voidgrow_vect (old_vect, size, min_size, element_size) void **old_vect; size_t *size; size_t min_size; int element_size;{ if (*size < min_size) { *size *= 2; if (*size < min_size) *size = min_size; *old_vect = xrealloc (*old_vect, *size * element_size); }}/* Demangle ada names: 1. Discard final __{DIGIT}+ or ${DIGIT}+ 2. Convert other instances of embedded "__" to `.'. 3. Discard leading _ada_. 4. Remove everything after first ___ if it is followed by 'X'. 5. Put symbols that should be suppressed in <...> brackets. The resulting string is valid until the next call of ada_demangle. */static char *ada_demangle (mangled, option) const char *mangled; int option ATTRIBUTE_UNUSED;{ int i, j; int len0; const char* p; char *demangled = NULL; int at_start_name; int changed; char *demangling_buffer = NULL; size_t demangling_buffer_size = 0; changed = 0; if (strncmp (mangled, "_ada_", 5) == 0) { mangled += 5; changed = 1; } if (mangled[0] == '_' || mangled[0] == '<') goto Suppress; p = strstr (mangled, "___"); if (p == NULL) len0 = strlen (mangled); else { if (p[3] == 'X') { len0 = p - mangled; changed = 1; } else goto Suppress; } /* Make demangled big enough for possible expansion by operator name. */ grow_vect ((void **) &(demangling_buffer), &demangling_buffer_size, 2 * len0 + 1, sizeof (char)); demangled = demangling_buffer; if (ISDIGIT ((unsigned char) mangled[len0 - 1])) { for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1) ; if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_') { len0 = i - 1; changed = 1; } else if (mangled[i] == '$') { len0 = i; changed = 1; } } for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]); i += 1, j += 1) demangled[j] = mangled[i]; at_start_name = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -