📄 cplus-dem.c
字号:
while (work -> ntypes > 0) { i = --(work -> ntypes); if (work -> typevec[i] != NULL) { free (work -> typevec[i]); work -> typevec[i] = NULL; } }}/* Process the argument list part of the signature, after any class spec has been consumed, as well as the first 'F' character (if any). For example: "__als__3fooRT0" => process "RT0" "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i" DECLP must be already initialised, usually non-empty. It won't be freed on failure. Note that g++ differs significantly from cfront and lucid style mangling with regards to references to previously seen types. For example, given the source fragment: class foo { public: foo::foo (int, foo &ia, int, foo &ib, int, foo &ic); }; foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } g++ produces the names: __3fooiRT0iT2iT2 foo__FiR3fooiT1iT1 while lcc (and presumably cfront as well) produces: foo__FiR3fooT1T2T1T2 __ct__3fooFiR3fooT1T2T1T2 Note that g++ bases it's type numbers starting at zero and counts all previously seen types, while lucid/cfront bases it's type numbers starting at one and only considers types after it has seen the 'F' character indicating the start of the function args. For lucid/cfront style, we account for this difference by discarding any previously seen types when we see the 'F' character, and subtracting one from the type number reference. */static intdemangle_args (work, mangled, declp) struct work_stuff *work; CONST char **mangled; string *declp;{ string arg; int need_comma = 0; int r; int t; CONST char *tem; char temptype; if (PRINT_ARG_TYPES) { string_append (declp, "("); if (**mangled == '\0') { string_append (declp, "void"); } } while (**mangled != '_' && **mangled != '\0' && **mangled != 'e') { if ((**mangled == 'N') || (**mangled == 'T')) { temptype = *(*mangled)++; if (temptype == 'N') { if (!get_count (mangled, &r)) { return (0); } } else { r = 1; } if (!get_count (mangled, &t)) { return (0); } if (LUCID_DEMANGLING || CFRONT_DEMANGLING) { t--; } /* Validate the type index. Protect against illegal indices from malformed type strings. */ if ((t < 0) || (t >= work -> ntypes)) { return (0); } while (--r >= 0) { tem = work -> typevec[t]; if (need_comma && PRINT_ARG_TYPES) { string_append (declp, ", "); } if (!do_arg (work, &tem, &arg)) { return (0); } if (PRINT_ARG_TYPES) { string_appends (declp, &arg); } string_delete (&arg); need_comma = 1; } } else { if (need_comma & PRINT_ARG_TYPES) { string_append (declp, ", "); } if (!do_arg (work, mangled, &arg)) { return (0); } if (PRINT_ARG_TYPES) { string_appends (declp, &arg); } string_delete (&arg); need_comma = 1; } } if (**mangled == 'e') { (*mangled)++; if (PRINT_ARG_TYPES) { if (need_comma) { string_append (declp, ","); } string_append (declp, "..."); } } if (PRINT_ARG_TYPES) { string_append (declp, ")"); } return (1);}static voiddemangle_function_name (work, mangled, declp, scan) struct work_stuff *work; CONST char **mangled; string *declp; CONST char *scan;{ int i; int len; string type; CONST char *tem; string_appendn (declp, (*mangled), scan - (*mangled)); string_need (declp, 1); *(declp -> p) = '\0'; /* Consume the function name, including the "__" separating the name from the signature. We are guaranteed that SCAN points to the separator. */ (*mangled) = scan + 2; if (LUCID_DEMANGLING || CFRONT_DEMANGLING) { /* See if we have an ARM style constructor or destructor operator. If so, then just record it, clear the decl, and return. We can't build the actual constructor/destructor decl until later, when we recover the class name from the signature. */ if (strcmp (declp -> b, "__ct") == 0) { work -> constructor = 1; string_clear (declp); return; } else if (strcmp (declp -> b, "__dt") == 0) { work -> destructor = 1; string_clear (declp); return; } } if (declp->p - declp->b >= 3 && declp->b[0] == 'o' && declp->b[1] == 'p' && strchr (cplus_markers, declp->b[2]) != NULL) { /* see if it's an assignment expression */ if (declp->p - declp->b >= 10 /* op$assign_ */ && memcmp (declp->b + 3, "assign_", 7) == 0) { for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) { len = declp->p - declp->b - 10; if (strlen (optable[i].in) == len && memcmp (optable[i].in, declp->b + 10, len) == 0) { string_clear (declp); string_append (declp, "operator"); string_append (declp, optable[i].out); string_append (declp, "="); break; } } } else { for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) { int len = declp->p - declp->b - 3; if (strlen (optable[i].in) == len && memcmp (optable[i].in, declp->b + 3, len) == 0) { string_clear (declp); string_append (declp, "operator"); string_append (declp, optable[i].out); break; } } } } else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type$", 5) == 0) { /* type conversion operator */ tem = declp->b + 5; if (do_type (work, &tem, &type)) { string_clear (declp); string_append (declp, "operator "); string_appends (declp, &type); string_delete (&type); } } else if (declp->b[2] == 'o' && declp->b[3] == 'p') { /* ANSI. */ /* type conversion operator. */ tem = declp->b + 4; if (do_type (work, &tem, &type)) { string_clear (declp); string_append (declp, "operator "); string_appends (declp, &type); string_delete (&type); } } else if (declp->b[0] == '_' && declp->b[1] == '_' && declp->b[2] >= 'a' && declp->b[2] <= 'z' && declp->b[3] >= 'a' && declp->b[3] <= 'z') { if (declp->b[4] == '\0') { /* Operator. */ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) { if (strlen (optable[i].in) == 2 && memcmp (optable[i].in, declp->b + 2, 2) == 0) { string_clear (declp); string_append (declp, "operator"); string_append (declp, optable[i].out); break; } } } else { if (declp->b[2] == 'a' && declp->b[5] == '\0') { /* Assignment. */ for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) { if (strlen (optable[i].in) == 3 && memcmp (optable[i].in, declp->b + 2, 3) == 0) { string_clear (declp); string_append (declp, "operator"); string_append (declp, optable[i].out); break; } } } } }}/* a mini string-handling package */static voidstring_need (s, n) string *s; int n;{ int tem; if (s->b == NULL) { if (n < 32) { n = 32; } s->p = s->b = xmalloc (n); s->e = s->b + n; } else if (s->e - s->p < n) { tem = s->p - s->b; n += tem; n *= 2; s->b = xrealloc (s->b, n); s->p = s->b + tem; s->e = s->b + n; }}static voidstring_delete (s) string *s;{ if (s->b != NULL) { free (s->b); s->b = s->e = s->p = NULL; }}static voidstring_init (s) string *s;{ s->b = s->p = s->e = NULL;}static void string_clear (s) string *s;{ s->p = s->b;}#if 0static intstring_empty (s) string *s;{ return (s->b == s->p);}#endifstatic voidstring_append (p, s) string *p; CONST char *s;{ int n; if (s == NULL || *s == '\0') return; n = strlen (s); string_need (p, n); memcpy (p->p, s, n); p->p += n;}static voidstring_appends (p, s) string *p, *s;{ int n; if (s->b != s->p) { n = s->p - s->b; string_need (p, n); memcpy (p->p, s->b, n); p->p += n; }}static voidstring_appendn (p, s, n) string *p; CONST char *s; int n;{ if (n != 0) { string_need (p, n); memcpy (p->p, s, n); p->p += n; }}static voidstring_prepend (p, s) string *p; CONST char *s;{ if (s != NULL && *s != '\0') { string_prependn (p, s, strlen (s)); }}#if 0static voidstring_prepends (p, s) string *p, *s;{ if (s->b != s->p) { string_prependn (p, s->b, s->p - s->b); }}#endifstatic voidstring_prependn (p, s, n) string *p; CONST char *s; int n;{ char *q; if (n != 0) { string_need (p, n); for (q = p->p - 1; q >= p->b; q--) { q[n] = q[0]; } memcpy (p->b, s, n); p->p += n; }}/* To generate a standalone demangler program for testing purposes, just compile and link this file with -DMAIN. When run, it demangles each command line arg, or each stdin string, and prints the result on stdout. */#ifdef MAINstatic voiddemangle_it (mangled_name) char *mangled_name;{ char *result; result = cplus_demangle (mangled_name, DMGL_PARAMS | DMGL_ANSI); if (result == NULL) { printf ("%s\n", mangled_name); } else { printf ("%s\n", result); free (result); }}char *xmalloc (size) long size;{ char * newmem; if ((newmem = (char *) malloc ((int) size)) == NULL) { fprintf (stderr, "\nCan't allocate %u bytes\n", size); exit (1); } return (newmem);}char *xrealloc (oldmem, size) char * oldmem; long size;{ char * newmem; if ((newmem = (char *) realloc ((char *) oldmem, (int) size)) == NULL) { fprintf (stderr, "\nCan't reallocate %u bytes\n", size); exit (1); } return (newmem);}main (argc, argv) int argc; char **argv;{ char mangled_name[128]; char *result; int c; extern char *optarg; extern int optind; while ((c = getopt (argc, argv, "s:?")) != EOF) { switch (c) { case '?': fprintf (stderr, "usage: demangle [-s style] [arg1 [arg2]] ...\n"); fprintf (stderr, "style = { gnu, lucid, cfront }\n"); fprintf (stderr, "reads args from stdin if none supplied\n"); exit (0); break; case 's': if (strcmp (optarg, "gnu") == 0) { current_demangling_style = gnu_demangling; } else if (strcmp (optarg, "lucid") == 0) { current_demangling_style = lucid_demangling; } else if (strcmp (optarg, "cfront") == 0) { current_demangling_style = cfront_demangling; } else { fprintf (stderr, "unknown demangling style `%s'\n", optarg); exit (1); } break; } } if (optind < argc) { for ( ; optind < argc; optind++) { demangle_it (argv[optind]); } } else { while (gets (mangled_name)) { demangle_it (mangled_name); } } exit (0);}#endif /* main */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -