📄 etoa_decode.c
字号:
s = ">"; } else if (start_of_id_is("ls", ptr)) { s = "<<"; } else if (start_of_id_is("rs", ptr)) { s = ">>"; } else if (start_of_id_is("eq", ptr)) { s = "=="; } else if (start_of_id_is("ne", ptr)) { s = "!="; } else if (start_of_id_is("le", ptr)) { s = "<="; } else if (start_of_id_is("ge", ptr)) { s = ">="; } else if (start_of_id_is("aa", ptr)) { s = "&&"; } else if (start_of_id_is("oo", ptr)) { s = "||"; } else if (start_of_id_is("pp", ptr)) { s = "++"; } else if (start_of_id_is("mm", ptr)) { s = "--"; } else if (start_of_id_is("cm", ptr)) { s = ","; } else if (start_of_id_is("rm", ptr)) { s = "->*"; } else if (start_of_id_is("rf", ptr)) { s = "->"; } else if (start_of_id_is("cl", ptr)) { s = "()"; } else if (start_of_id_is("vc", ptr)) { s = "[]"; } else if (start_of_id_is("qs", ptr)) { s = "?"; } else if (start_of_id_is("cs", ptr)) { s = "cast"; *takes_type = TRUE; } else if (start_of_id_is("sz", ptr)) { s = "sizeof("; *takes_type = TRUE; } else if (start_of_id_is("af", ptr)) { s = "__alignof__("; *takes_type = TRUE; } else if (start_of_id_is("uu", ptr)) { s = "__uuidof("; *takes_type = TRUE; } else { s = NULL; } /* if */ *mangled_length = len; return s;} /* demangle_operator */static a_boolean is_operator_function_name(char *ptr, char **demangled_name, int *mangled_length)/*Examine the string beginning at ptr to see if it is the mangled name foran operator function. If so, return TRUE and set *demangled_name tothe demangled form, and *mangled_length to the length of the mangled form.*/{ char *s, *end_ptr; int len; a_boolean takes_type; /* Get the operator name.*/ s = demangle_operator(ptr, &len, &takes_type); if (s != NULL) { /* Make sure we took the whole name and nothing more. */ end_ptr = ptr + len; if (*end_ptr == '\0' || (end_ptr[0] == '_' && end_ptr[1] == '_')) { /* Okay. */ } else { s = NULL; } /* if */ } /* if */ *demangled_name = s; *mangled_length = len; return (s != NULL);} /* is_operator_function_name */static void note_specialization(char *ptr, a_template_param_block_ptr temp_par_info)/*Note the fact that a specialization indication has been encountered at ptrwhile scanning a mangled name. temp_par_info, if non-NULL, points toa block of information related to template parameter processing.*/{ if (temp_par_info != NULL) { if (temp_par_info->set_final_specialization) { /* Remember the location of the last specialization seen. */ temp_par_info->final_specialization = ptr; } else if (temp_par_info->actual_template_args_until_final_specialization&& ptr == temp_par_info->final_specialization) { /* Stop doing the special processing for specializations when the final specialization is reached. */ temp_par_info->actual_template_args_until_final_specialization = FALSE; } /* if */ } /* if */} /* note_specialization */static char get_char(char *ptr, char *base_ptr, unsigned long nchars)/*Get and return the character pointed to by ptr. However, if nchars isnon-zero, the string from which the character is to be extracted startsat base_ptr and has length nchars. An attempt to get a character pastthe end of the string returns a null character.*/{ char ch; if (nchars > 0 && ptr >= base_ptr+nchars) { ch = '\0'; } else { ch = *ptr; } /* if */ return ch;} /* get_char */static char *demangle_name(char *ptr, unsigned long nchars, a_boolean stop_on_underscores, unsigned long *nchars_left, char *mclass, a_template_param_block_ptr temp_par_info, a_decode_control_block_ptr dctl)/*Demangle the name at ptr and output the demangled form. Return a pointerto the character position following what was demangled. A "name" isusually just a string of alphanumeric characters. However, names ofconstructors, destructors, and operator functions require specialhandling, as do template entity names. nchars indicates the numberof characters in the name, or is zero if the name is open-ended(it's ended by a null or double underscore). A double underscoreends the name if stop_on_underscores is TRUE (though some sequencesbeginning with two underscores, e.g., "__pt", end the name even ifstop_on_underscores is FALSE). If nchars_left is non-NULL, noerror is issued if too few characters are taken to satisfy nchars;the count of remaining characters is placed in *nchars_left.mclass, when non-NULL, points to the mangled form of the class ofwhich this name is a member. When it's non-NULL, constructor anddestructor names will be put out in the proper form (otherwise,they are left in their original forms). When temp_par_info != NULL,it points to a block that controls output of extra information ontemplate parameters.*/{ char *p, *end_ptr = NULL; a_boolean is_special_name = FALSE, is_pt, is_partial_spec = FALSE; a_boolean partial_spec_output_suppressed = FALSE; char *demangled_name; int mangled_length; if (nchars_left != NULL) *nchars_left = 0; /* See if the name is special in some way. */ if ((nchars == 0 || nchars >= 3) && ptr[0] == '_' && ptr[1] == '_') { /* Name beginning with two underscores. */ p = ptr + 2; if (start_of_id_is("ct", p)) { /* Constructor. */ end_ptr = p + 2; if (mclass == NULL) { /* The mangled name for the class is not provided, so handle this as a normal name. */ } else { /* Output the class name for the constructor name. */ is_special_name = TRUE; (void)full_demangle_type_name(mclass, /*base_name_only=*/TRUE, /*temp_par_info=*/ (a_template_param_block_ptr)NULL, dctl); } /* if */ } else if (start_of_id_is("dt", p)) { /* Destructor. */ end_ptr = p + 2; if (mclass == NULL) { /* The mangled name for the class is not provided, so handle this as a normal name. */ } else { /* Output ~class-name for the destructor name. */ is_special_name = TRUE; write_id_ch('~', dctl); (void)full_demangle_type_name(mclass, /*base_name_only=*/TRUE, /*temp_par_info=*/ (a_template_param_block_ptr)NULL, dctl); } /* if */ } else if (start_of_id_is("op", p)) { /* Conversion function. Name looks like __opi__... where the part after "op" encodes the type (e.g., "opi" is "operator int"). */ is_special_name = TRUE; write_id_str("operator ", dctl); end_ptr = demangle_type(p+2, dctl); } else if (is_operator_function_name(p, &demangled_name, &mangled_length)) { /* Operator function. */ is_special_name = TRUE; write_id_str("operator ", dctl); write_id_str(demangled_name, dctl); end_ptr = p + mangled_length; } else if (nchars != 0 && start_of_id_is("N", p)) { /* __Nxxxx: unnamed namespace name. Put out "<unnamed>" and ignore the characters after "__N". For nested unnamed namespaces there is no number after the "__N". */ is_special_name = TRUE; write_id_str("<unnamed>", dctl); end_ptr = p + nchars - 2; } else { /* Something unrecognized. */ } /* if */ } /* if */ /* Here, end_ptr non-null means the end of the string has been found already (because the name is special in some way). */ if (end_ptr == NULL) { /* Not a special name. Find the end of the string and set end_ptr. Also look for template-related things that terminate the name earlier. */ for (p = ptr; ; p++) { char ch = get_char(p, ptr, nchars); /* Stop at the end of the string (real, or as indicated by nchars). */ if (ch == '\0') break; /* Stop on a double underscore, but not one at the start of the string. More than 2 underscores in a row does not terminate the string, so that something like the name for "void f_()" (i.e., "f___Fv") can be demangled successfully. */ if (ch == '_' && p != ptr && get_char(p+1, ptr, nchars) == '_' && get_char(p+2, ptr, nchars) != '_' && /* When stop_on_underscores is FALSE, stop only on "__tm", "__ps", "__pt", or "__S". Double underscores can appear in the middle of some names, e.g., member names used as template arguments. */ (stop_on_underscores || (get_char(p+2, ptr, nchars) == 't' && get_char(p+3, ptr, nchars) == 'm') || (get_char(p+2, ptr, nchars) == 'p' && get_char(p+3, ptr, nchars) == 's') || (get_char(p+2, ptr, nchars) == 'p' && get_char(p+3, ptr, nchars) == 't') || get_char(p+2, ptr, nchars) == 'S')) { break; } /* if */ } /* for */ end_ptr = p; } /* if */ /* Here, end_ptr indicates the character after the end of the initial part of the name. */ if (!is_special_name) { /* Output the characters of the base name. */ for (p = ptr; p < end_ptr; p++) write_id_ch(*p, dctl); } /* if */ /* If there's a template argument list for a partial specialization (beginning with "__ps__"), process it. */ if ((nchars == 0 || (end_ptr-ptr+6) < nchars) && start_of_id_is("__ps__", end_ptr)) { /* Write the arguments. This first argument list gives the arguments that appear in the partial specialization declaration: template <class T, class U> struct A { ... }; template <class T> struct A<T *, int> { ... }; ^^^^^^^^this argument list This first argument list will be followed by another argument list that gives the arguments according to the partial specialization. For A<int *, int> according to the example above, the second argument list is <int>. The second argument list is scanned but not put out, except when argument correspondences are output. */ end_ptr = demangle_template_arguments(end_ptr+6, /*partial_spec=*/TRUE, temp_par_info, dctl); note_specialization(end_ptr, temp_par_info); is_partial_spec = TRUE; } /* if */ /* If there's a specialization indication ("__S"), ignore it. */ if (get_char(end_ptr, ptr, nchars) == '_' && get_char(end_ptr+1, ptr, nchars) == '_' && get_char(end_ptr+2, ptr, nchars) == 'S') { note_specialization(end_ptr, temp_par_info); end_ptr += 3; } /* if */ /* If there's a template argument list (beginning with "__pt__" or "__tm__"), process it. */ if ((nchars == 0 || (end_ptr-ptr+6) < nchars) && ((is_pt = start_of_id_is("__pt__", end_ptr)) || start_of_id_is("__tm__", end_ptr))) { /* The "__pt__ form indicates an old-style mangled template name. */ if (is_pt && temp_par_info != NULL ) { temp_par_info->use_old_form_for_template_output = TRUE; } /* if */ /* For the second argument list of a partial specialization, process the argument list but suppress output. */ if (is_partial_spec && temp_par_info != NULL && !temp_par_info->output_only_correspondences) { dctl->suppress_id_output++; partial_spec_output_suppressed = TRUE; } /* if */ /* Write the arguments. */#if ENABLE_GNU_LIKE_OUTPUT /* But not if we are printing an implicit Ctor/Dtor name! */ if (temp_par_info != NULL && temp_par_info->base_name_only) dctl->suppress_id_output++;#endif end_ptr = demangle_template_arguments(end_ptr+6, /*partial_spec=*/FALSE, temp_par_info, dctl);#if ENABLE_GNU_LIKE_OUTPUT if (temp_par_info != NULL && temp_par_info->base_name_only) dctl->suppress_id_output--;#endif if (partial_spec_output_suppressed) dctl->suppress_id_output--; /* If there's a(nother) specialization indication ("__S"), ignore it. */ if (get_char(end_ptr, ptr, nchars) == '_' && get_char(end_ptr+1, ptr, nchars) == '_' && get_char(end_ptr+2, ptr, nchars) == 'S') { note_specialization(end_ptr, temp_par_info); end_ptr += 3; } /* if */ } /* if */ /* Check that we took exactly the characters we should have. */ if (((nchars != 0) ? (end_ptr-ptr == nchars) : (*end_ptr == '\0')) || (stop_on_underscores && get_char(end_ptr, ptr, nchars) == '_' && get_char(end_ptr+1, ptr, nchars) == '_')) { /* Okay. */ } else if (nchars_left != NULL) { /* Return the count of characters not taken. */ *nchars_left = nchars-(end_ptr-ptr); } else { bad_mangled_name(dctl); } /* if */ return end_ptr;} /* demangle_name */static char *demangle_function_local_indication( char *ptr, unsigned long nchars, a_decode_control_block_ptr dctl)/*Demangle the function name and block number in a function-local indication: __L2__f__Fv ^-- returned pointer points here ^------- mangled function name ^---------- block number within function (ptr points here on entry)ptr points to the character after the "__L". If nchars is non-zero, itindicates the length of the string, starting from ptr. Return a pointerto the character following the mangled function name. Output a functionindication like "f(void)::".*/{ char *p = ptr; unsigned long block_number;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -