📄 cplus-dem.c
字号:
if (is_type) { if (remember) bindex = register_Btype (work); start = *mangled; /* get template name */ if (**mangled == 'z') { int idx; (*mangled)++; (*mangled)++; idx = consume_count_with_underscores (mangled); if (idx == -1 || (work->tmpl_argvec && idx >= work->ntmpl_args) || consume_count_with_underscores (mangled) == -1) return (0); if (work->tmpl_argvec) { string_append (tname, work->tmpl_argvec[idx]); if (trawname) string_append (trawname, work->tmpl_argvec[idx]); } else { string_append_template_idx (tname, idx); if (trawname) string_append_template_idx (trawname, idx); } } else { if ((r = consume_count (mangled)) <= 0 || (int) strlen (*mangled) < r) { return (0); } is_java_array = (work -> options & DMGL_JAVA) && strncmp (*mangled, "JArray1Z", 8) == 0; if (! is_java_array) { string_appendn (tname, *mangled, r); } if (trawname) string_appendn (trawname, *mangled, r); *mangled += r; } } if (!is_java_array) string_append (tname, "<"); /* get size of template parameter list */ if (!get_count (mangled, &r)) { return (0); } if (!is_type) { /* Create an array for saving the template argument values. */ work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *)); work->ntmpl_args = r; for (i = 0; i < r; i++) work->tmpl_argvec[i] = 0; } for (i = 0; i < r; i++) { if (need_comma) { string_append (tname, ", "); } /* Z for type parameters */ if (**mangled == 'Z') { (*mangled)++; /* temp is initialized in do_type */ success = do_type (work, mangled, &temp); if (success) { string_appends (tname, &temp); if (!is_type) { /* Save the template argument. */ int len = temp.p - temp.b; work->tmpl_argvec[i] = xmalloc (len + 1); memcpy (work->tmpl_argvec[i], temp.b, len); work->tmpl_argvec[i][len] = '\0'; } } string_delete(&temp); if (!success) { break; } } /* z for template parameters */ else if (**mangled == 'z') { int r2; (*mangled)++; success = demangle_template_template_parm (work, mangled, tname); if (success && (r2 = consume_count (mangled)) > 0 && (int) strlen (*mangled) >= r2) { string_append (tname, " "); string_appendn (tname, *mangled, r2); if (!is_type) { /* Save the template argument. */ int len = r2; work->tmpl_argvec[i] = xmalloc (len + 1); memcpy (work->tmpl_argvec[i], *mangled, len); work->tmpl_argvec[i][len] = '\0'; } *mangled += r2; } if (!success) { break; } } else { string param; string* s; /* otherwise, value parameter */ /* temp is initialized in do_type */ success = do_type (work, mangled, &temp); string_delete(&temp); if (!success) break; if (!is_type) { s = ¶m; string_init (s); } else s = tname; success = demangle_template_value_parm (work, mangled, s, (type_kind_t) success); if (!success) { if (!is_type) string_delete (s); success = 0; break; } if (!is_type) { int len = s->p - s->b; work->tmpl_argvec[i] = xmalloc (len + 1); memcpy (work->tmpl_argvec[i], s->b, len); work->tmpl_argvec[i][len] = '\0'; string_appends (tname, s); string_delete (s); } } need_comma = 1; } if (is_java_array) { string_append (tname, "[]"); } else { if (tname->p[-1] == '>') string_append (tname, " "); string_append (tname, ">"); } if (is_type && remember) remember_Btype (work, tname->b, LEN_STRING (tname), bindex); /* if (work -> static_type) { string_append (declp, *mangled + 1); *mangled += strlen (*mangled); success = 1; } else { success = demangle_args (work, mangled, declp); } } */ return (success);}static intarm_pt (work, mangled, n, anchor, args) struct work_stuff *work; const char *mangled; int n; const char **anchor, **args;{ /* Check if ARM template with "__pt__" in it ("parameterized type") */ /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */ if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__"))) { int len; *args = *anchor + 6; len = consume_count (args); if (len == -1) return 0; if (*args + len == mangled + n && **args == '_') { ++*args; return 1; } } if (AUTO_DEMANGLING || EDG_DEMANGLING) { if ((*anchor = mystrstr (mangled, "__tm__")) || (*anchor = mystrstr (mangled, "__ps__")) || (*anchor = mystrstr (mangled, "__pt__"))) { int len; *args = *anchor + 6; len = consume_count (args); if (len == -1) return 0; if (*args + len == mangled + n && **args == '_') { ++*args; return 1; } } else if ((*anchor = mystrstr (mangled, "__S"))) { int len; *args = *anchor + 3; len = consume_count (args); if (len == -1) return 0; if (*args + len == mangled + n && **args == '_') { ++*args; return 1; } } } return 0;}static voiddemangle_arm_hp_template (work, mangled, n, declp) struct work_stuff *work; const char **mangled; int n; string *declp;{ const char *p; const char *args; const char *e = *mangled + n; string arg; /* Check for HP aCC template spec: classXt1t2 where t1, t2 are template args */ if (HP_DEMANGLING && ((*mangled)[n] == 'X')) { char *start_spec_args = NULL; /* First check for and omit template specialization pseudo-arguments, such as in "Spec<#1,#1.*>" */ start_spec_args = strchr (*mangled, '<'); if (start_spec_args && (start_spec_args - *mangled < n)) string_appendn (declp, *mangled, start_spec_args - *mangled); else string_appendn (declp, *mangled, n); (*mangled) += n + 1; string_init (&arg); if (work->temp_start == -1) /* non-recursive call */ work->temp_start = declp->p - declp->b; string_append (declp, "<"); while (1) { string_clear (&arg); switch (**mangled) { case 'T': /* 'T' signals a type parameter */ (*mangled)++; if (!do_type (work, mangled, &arg)) goto hpacc_template_args_done; break; case 'U': case 'S': /* 'U' or 'S' signals an integral value */ if (!do_hpacc_template_const_value (work, mangled, &arg)) goto hpacc_template_args_done; break; case 'A': /* 'A' signals a named constant expression (literal) */ if (!do_hpacc_template_literal (work, mangled, &arg)) goto hpacc_template_args_done; break; default: /* Today, 1997-09-03, we have only the above types of template parameters */ /* FIXME: maybe this should fail and return null */ goto hpacc_template_args_done; } string_appends (declp, &arg); /* Check if we're at the end of template args. 0 if at end of static member of template class, _ if done with template args for a function */ if ((**mangled == '\000') || (**mangled == '_')) break; else string_append (declp, ","); } hpacc_template_args_done: string_append (declp, ">"); string_delete (&arg); if (**mangled == '_') (*mangled)++; return; } /* ARM template? (Also handles HP cfront extensions) */ else if (arm_pt (work, *mangled, n, &p, &args)) { string type_str; string_init (&arg); string_appendn (declp, *mangled, p - *mangled); if (work->temp_start == -1) /* non-recursive call */ work->temp_start = declp->p - declp->b; string_append (declp, "<"); /* should do error checking here */ while (args < e) { string_clear (&arg); /* Check for type or literal here */ switch (*args) { /* HP cfront extensions to ARM for template args */ /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */ /* FIXME: We handle only numeric literals for HP cfront */ case 'X': /* A typed constant value follows */ args++; if (!do_type (work, &args, &type_str)) goto cfront_template_args_done; string_append (&arg, "("); string_appends (&arg, &type_str); string_append (&arg, ")"); if (*args != 'L') goto cfront_template_args_done; args++; /* Now snarf a literal value following 'L' */ if (!snarf_numeric_literal (&args, &arg)) goto cfront_template_args_done; break; case 'L': /* Snarf a literal following 'L' */ args++; if (!snarf_numeric_literal (&args, &arg)) goto cfront_template_args_done; break; default: /* Not handling other HP cfront stuff */ if (!do_type (work, &args, &arg)) goto cfront_template_args_done; } string_appends (declp, &arg); string_append (declp, ","); } cfront_template_args_done: string_delete (&arg); if (args >= e) --declp->p; /* remove extra comma */ string_append (declp, ">"); } else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 && (*mangled)[9] == 'N' && (*mangled)[8] == (*mangled)[10] && strchr (cplus_markers, (*mangled)[8])) { /* A member of the anonymous namespace. */ string_append (declp, "{anonymous}"); } else { if (work->temp_start == -1) /* non-recursive call only */ work->temp_start = 0; /* disable in recursive calls */ string_appendn (declp, *mangled, n); } *mangled += n;}/* Extract a class name, possibly a template with arguments, from the mangled string; qualifiers, local class indicators, etc. have already been dealt with */static intdemangle_class_name (work, mangled, declp) struct work_stuff *work; const char **mangled; string *declp;{ int n; int success = 0; n = consume_count (mangled); if (n == -1) return 0; if ((int) strlen (*mangled) >= n) { demangle_arm_hp_template (work, mangled, n, declp); success = 1; } 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 success = 0; int btype; string class_name; char *save_class_name_end = 0; string_init (&class_name); btype = register_Btype (work); if (demangle_class_name (work, mangled, &class_name)) { save_class_name_end = class_name.p; if ((work->constructor & 1) || (work->destructor & 1)) { /* adjust so we don't include template args */ if (work->temp_start && (work->temp_start != -1)) { class_name.p = class_name.b + work->temp_start; } string_prepends (declp, &class_name); if (work -> destructor & 1) { string_prepend (declp, "~"); work -> destructor -= 1; } else { work -> constructor -= 1; } } class_name.p = save_class_name_end; remember_Ktype (work, class_name.b, LEN_STRING(&class_name)); remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype); string_prepend (declp, SCOPE_STRING (work)); string_prepends (declp, &class_name); success = 1; } string_delete (&class_name); return (success);}/* Called when there's a "__" in the mangled name, with `scan' pointing to the rightmost guess. Find the correct "__"-sequence where the function name ends and the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -