📄 cplus-dem.c
字号:
while (i < len0) { at_start_name = 0; if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_') { demangled[j] = '.'; changed = at_start_name = 1; i += 2; j += 1; } else { demangled[j] = mangled[i]; i += 1; j += 1; } } demangled[j] = '\000'; for (i = 0; demangled[i] != '\0'; i += 1) if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ') goto Suppress; if (! changed) return NULL; else return demangled; Suppress: grow_vect ((void **) &(demangling_buffer), &demangling_buffer_size, strlen (mangled) + 3, sizeof (char)); demangled = demangling_buffer; if (mangled[0] == '<') strcpy (demangled, mangled); else sprintf (demangled, "<%s>", mangled); return demangled;}extern void decode_identifier(char *id, char *output_buffer, size_t output_buffer_size, int *err, int *buffer_overflow_err, size_t *required_buffer_size);static char *edg_demangle (mangled, option) const char *mangled; int option ATTRIBUTE_UNUSED;{ char *demangled_id = 0; int err; int buffer_overflow_err = 1; size_t buffer_size = 1024; while (buffer_overflow_err) { demangled_id = xrealloc(demangled_id, buffer_size); decode_identifier(mangled, demangled_id, (size_t) buffer_size, &err, &buffer_overflow_err, &buffer_size); } if (err) { free (demangled_id); return (char *)0; } return demangled_id;}/* This function performs most of what cplus_demangle use to do, but to be able to demangle a name with a B, K or n code, we need to have a longer term memory of what types have been seen. The original now intializes and cleans up the squangle code info, while internal calls go directly to this routine to avoid resetting that info. */static char *internal_cplus_demangle (work, mangled) struct work_stuff *work; const char *mangled;{ string decl; int success = 0; char *demangled = NULL; int s1, s2, s3, s4; s1 = work->constructor; s2 = work->destructor; s3 = work->static_type; s4 = work->type_quals; work->constructor = work->destructor = 0; work->type_quals = TYPE_UNQUALIFIED; work->dllimported = 0; if ((mangled != NULL) && (*mangled != '\0')) { string_init (&decl); /* First check to see if gnu style demangling is active and if the string to be demangled contains a CPLUS_MARKER. If so, attempt to recognize one of the gnu special forms rather than looking for a standard prefix. In particular, don't worry about whether there is a "__" string in the mangled string. Consider "_$_5__foo" for example. */ if ((AUTO_DEMANGLING || GNU_DEMANGLING)) { success = gnu_special (work, &mangled, &decl); } if (!success) { success = demangle_prefix (work, &mangled, &decl); } if (success && (*mangled != '\0')) { success = demangle_signature (work, &mangled, &decl); } if (work->constructor == 2) { string_prepend (&decl, "global constructors keyed to "); work->constructor = 0; } else if (work->destructor == 2) { string_prepend (&decl, "global destructors keyed to "); work->destructor = 0; } else if (work->dllimported == 1) { string_prepend (&decl, "import stub for "); work->dllimported = 0; } demangled = mop_up (work, &decl, success); } work->constructor = s1; work->destructor = s2; work->static_type = s3; work->type_quals = s4; return demangled;}/* Clear out and squangling related storage */static voidsquangle_mop_up (work) struct work_stuff *work;{ /* clean up the B and K type mangling types. */ forget_B_and_K_types (work); if (work -> btypevec != NULL) { free ((char *) work -> btypevec); } if (work -> ktypevec != NULL) { free ((char *) work -> ktypevec); }}/* Copy the work state and storage. */static voidwork_stuff_copy_to_from (to, from) struct work_stuff *to; struct work_stuff *from;{ int i; delete_work_stuff (to); /* Shallow-copy scalars. */ memcpy (to, from, sizeof (*to)); /* Deep-copy dynamic storage. */ if (from->typevec_size) to->typevec = (char **) xmalloc (from->typevec_size * sizeof (to->typevec[0])); for (i = 0; i < from->ntypes; i++) { int len = strlen (from->typevec[i]) + 1; to->typevec[i] = xmalloc (len); memcpy (to->typevec[i], from->typevec[i], len); } if (from->ksize) to->ktypevec = (char **) xmalloc (from->ksize * sizeof (to->ktypevec[0])); for (i = 0; i < from->numk; i++) { int len = strlen (from->ktypevec[i]) + 1; to->ktypevec[i] = xmalloc (len); memcpy (to->ktypevec[i], from->ktypevec[i], len); } if (from->bsize) to->btypevec = (char **) xmalloc (from->bsize * sizeof (to->btypevec[0])); for (i = 0; i < from->numb; i++) { int len = strlen (from->btypevec[i]) + 1; to->btypevec[i] = xmalloc (len); memcpy (to->btypevec[i], from->btypevec[i], len); } if (from->ntmpl_args) to->tmpl_argvec = xmalloc (from->ntmpl_args * sizeof (to->tmpl_argvec[0])); for (i = 0; i < from->ntmpl_args; i++) { int len = strlen (from->tmpl_argvec[i]) + 1; to->tmpl_argvec[i] = xmalloc (len); memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len); } if (from->previous_argument) { to->previous_argument = (string*) xmalloc (sizeof (string)); string_init (to->previous_argument); string_appends (to->previous_argument, from->previous_argument); }}/* Delete dynamic stuff in work_stuff that is not to be re-used. */static voiddelete_non_B_K_work_stuff (work) struct work_stuff *work;{ /* Discard the remembered types, if any. */ forget_types (work); if (work -> typevec != NULL) { free ((char *) work -> typevec); work -> typevec = NULL; work -> typevec_size = 0; } if (work->tmpl_argvec) { int i; for (i = 0; i < work->ntmpl_args; i++) if (work->tmpl_argvec[i]) free ((char*) work->tmpl_argvec[i]); free ((char*) work->tmpl_argvec); work->tmpl_argvec = NULL; } if (work->previous_argument) { string_delete (work->previous_argument); free ((char*) work->previous_argument); work->previous_argument = NULL; }}/* Delete all dynamic storage in work_stuff. */static voiddelete_work_stuff (work) struct work_stuff *work;{ delete_non_B_K_work_stuff (work); squangle_mop_up (work);}/* Clear out any mangled storage */static char *mop_up (work, declp, success) struct work_stuff *work; string *declp; int success;{ char *demangled = NULL; delete_non_B_K_work_stuff (work); /* If demangling was successful, ensure that the demangled string is null terminated and return it. Otherwise, free the demangling decl. */ if (!success) { string_delete (declp); } else { string_appendn (declp, "", 1); demangled = declp->b; } return (demangled);}/*LOCAL FUNCTION demangle_signature -- demangle the signature part of a mangled nameSYNOPSIS static int demangle_signature (struct work_stuff *work, const char **mangled, string *declp);DESCRIPTION Consume and demangle the signature portion of the mangled name. DECLP is the string where demangled output is being built. At entry it contains the demangled root name from the mangled name prefix. I.E. either a demangled operator name or the root function name. In some special cases, it may contain nothing. *MANGLED points to the current unconsumed location in the mangled name. As tokens are consumed and demangling is performed, the pointer is updated to continuously point at the next token to be consumed. Demangling GNU style mangled names is nasty because there is no explicit token that marks the start of the outermost function argument list. */static intdemangle_signature (work, mangled, declp) struct work_stuff *work; const char **mangled; string *declp;{ int success = 1; int func_done = 0; int expect_func = 0; int expect_return_type = 0; const char *oldmangled = NULL; string trawname; string tname; while (success && (**mangled != '\0')) { switch (**mangled) { case 'Q': oldmangled = *mangled; success = demangle_qualified (work, mangled, declp, 1, 0); if (success) remember_type (work, oldmangled, *mangled - oldmangled); if (AUTO_DEMANGLING || GNU_DEMANGLING) expect_func = 1; oldmangled = NULL; break; case 'K': oldmangled = *mangled; success = demangle_qualified (work, mangled, declp, 1, 0); if (AUTO_DEMANGLING || GNU_DEMANGLING) { expect_func = 1; } oldmangled = NULL; break; case 'S': /* Static member function */ if (oldmangled == NULL) { oldmangled = *mangled; } (*mangled)++; work -> static_type = 1; break; case 'C': case 'V': case 'u': work->type_quals |= code_for_qualifier (**mangled); /* a qualified member function */ if (oldmangled == NULL) oldmangled = *mangled; (*mangled)++; break; case 'L': /* Local class name follows after "Lnnn_" */ if (HP_DEMANGLING) { while (**mangled && (**mangled != '_')) (*mangled)++; if (!**mangled) success = 0; else (*mangled)++; } else success = 0; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (oldmangled == NULL) { oldmangled = *mangled; } work->temp_start = -1; /* uppermost call to demangle_class */ success = demangle_class (work, mangled, declp); if (success) { remember_type (work, oldmangled, *mangled - oldmangled); } if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING) { /* EDG and others will have the "F", so we let the loop cycle if we are looking at one. */ if (**mangled != 'F') expect_func = 1; } oldmangled = NULL; break; case 'B': { string s; success = do_type (work, mangled, &s); if (success) { string_append (&s, SCOPE_STRING (work)); string_prepends (declp, &s); } oldmangled = NULL; expect_func = 1; } break; case 'F': /* Function */ /* ARM/HP style demangling includes a specific 'F' character after the class name. For GNU style, it is just implied. So we can safely just consume any 'F' at this point and be compatible with either style. */ oldmangled = NULL; func_done = 1; (*mangled)++; /* For lucid/ARM/HP style we have to forget any types we might have remembered up to this point, since they were not argument types. GNU style considers all types seen as available for back references. See comment in demangle_args() */ if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) { forget_types (work); } success = demangle_args (work, mangled, declp); /* 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 (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_') { ++(*mangled); /* At this level, we do not care about the return type. */ success = do_type (work, mangled, &tname); string_delete (&tname); } break; case 't': /* G++ Template */ string_init(&trawname); string_init(&tname); if (oldmangled == NULL) { oldmangled = *mangled; } success = demangle_template (work, mangled, &tname, &trawname, 1, 1); if (success) { remember_type (work, oldmangled, *mangled - oldmangled); } string_append (&tname, SCOPE_STRING (work)); string_prepends(declp, &tname); if (work -> destructor & 1) { string_prepend (&trawname, "~"); string_appends (declp, &trawname); work->destructor -= 1; } if ((work->constructor & 1) || (work->destructor & 1)) { string_appends (declp, &trawname); work->constructor -= 1; } string_delete(&trawname); string_delete(&tname); oldmangled = NULL; expect_func = 1; break; case '_': if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -