📄 edg-decode.c
字号:
^^^----- Second operand. ^^^-------- First operand. ^----------- Count of operands. ^^------------ Operation, using same encoding as for operator function names. ^-------------- "O" for operation. */ p++; /* Advance past the "O". */ /* Decode the operator name, e.g., "pl" is "+". */ operator_str = demangle_operator(p, &op_length, &takes_type); if (operator_str == NULL) { bad_mangled_name(dctl); } else { p += op_length; /* Put parentheses around the operation. */ write_id_ch('(', dctl); /* For a cast, sizeof, or __ALIGNOF__, get the type. */ if (takes_type) { if (strcmp(operator_str, "cast") == 0) { write_id_ch('(', dctl); operator_str = ""; } else { write_id_str(operator_str, dctl); } /* if */ p = demangle_type(p, dctl); write_id_ch(')', dctl); } /* if */ /* Get the count of operands. */ p = get_single_digit_number(p, &num_operands, dctl); /* sizeof and __ALIGNOF__ take zero operands. */ if (num_operands != 0) { if (num_operands == 1) { /* Unary operator -- operator comes first. */ write_id_str(operator_str, dctl); } /* if */ /* Process the first operand. */ p = demangle_constant(p, dctl); if (num_operands > 1) { /* Binary and ternary operators -- operator comes after first operand. */ write_id_str(operator_str, dctl); /* Process the second operand. */ p = demangle_constant(p, dctl); if (num_operands > 2) { /* Ternary operand -- "?". */ write_id_ch(':', dctl); /* Process the third operand. */ p = demangle_constant(p, dctl); } /* if */ } /* if */ } /* if */ write_id_ch(')', dctl); /* Check for the final "O". */ if (*p != 'O') { bad_mangled_name(dctl); } else { p++; } /* if */ } /* if */ return p;} /* demangle_operation */static void clear_template_param_block(a_template_param_block_ptr tpbp)/*Clear the fields of the indicated template parameter block.*/{ tpbp->nesting_level = 0; tpbp->final_specialization = NULL; tpbp->set_final_specialization = FALSE; tpbp->actual_template_args_until_final_specialization = FALSE; tpbp->output_only_correspondences = FALSE; tpbp->first_correspondence = FALSE; tpbp->use_old_form_for_template_output = FALSE; tpbp->base_name_only = FALSE;} /* clear_template_param_block */static char *demangle_template_arguments( char *ptr, a_boolean partial_spec, a_template_param_block_ptr temp_par_info, a_decode_control_block_ptr dctl)/*Demangle the template class arguments beginning at ptr and output thedemangled form. Return a pointer to the character position following what wasdemangled. ptr points to just past the "__tm__", "__ps__", or "__pt__"string. partial_spec is TRUE if this is a partial-specializationparameter list ("__ps__"). When temp_par_info != NULL, it points to ablock that controls output of extra information on template parameters.*/{ char *p = ptr, *arg_base; unsigned long nchars, position; a_boolean nontype, skipped, unskipped; if (temp_par_info != NULL && !partial_spec) temp_par_info->nesting_level++; /* A template argument list looks like __tm__3_ii ^^---- Argument types. ^------- Size of argument types, including the underscore. ^------- ptr points here. For the first argument list of a partial specialization, "__tm__" is replaced by "__ps__". For old-form mangling of templates, "__tm__" is replaced by "__pt__". */ write_id_ch('<', dctl); /* Scan the size. */ p = get_length(p, &nchars, dctl); arg_base = p; p = advance_past_underscore(p, dctl); /* Loop to process the arguments. */ for (position = 1;; position++) { if (dctl->err_in_id) break; /* Avoid infinite loops on errors. */ if (*p == '\0' || *p == '_') { /* We ran off the end of the string. */ bad_mangled_name(dctl); break; } /* if */ /* "X" identifies the beginning of a nontype argument. */ nontype = (*p == 'X'); skipped = unskipped = FALSE; if (!partial_spec && temp_par_info != NULL && !temp_par_info->use_old_form_for_template_output && !temp_par_info->actual_template_args_until_final_specialization) { /* Doing something special: writing out the template parameter name. */ if (temp_par_info->output_only_correspondences) { /* This is the second pass, which writes out parameter/argument correspondences, e.g., "T1=int". Output has been suppressed in general, and is turned on briefly here. */ dctl->suppress_id_output--; unskipped = TRUE; /* Put out a comma between entries and a left bracket preceding the first entry. */ if (temp_par_info->first_correspondence) { write_id_str(" [with ", dctl); temp_par_info->first_correspondence = FALSE; } else { write_id_str(", ", dctl); } /* if */ } /* if */ /* Write the template parameter name. */ write_template_parameter_name(temp_par_info->nesting_level, position, nontype, dctl); if (temp_par_info->output_only_correspondences) { /* This is the second pass, to write out correspondences, so put the argument value out after the parameter name. */ write_id_ch('=', dctl); } else { /* This is the first pass. The argument value is skipped. In the second pass, its value will be written out. */ /* We still have to scan over the argument value, but suppress output. */ dctl->suppress_id_output++; skipped = TRUE; } /* if */ } /* if */ /* Write the argument value. */ if (nontype) { /* Nontype argument. */ char *saved_end_of_constant = dctl->end_of_constant; p++; /* Advance past the "X". */ /* Note the end position of the constant. This is used to decide that certain lengths are implausible as a way to resolve ambiguities. */ dctl->end_of_constant = arg_base + nchars; p = demangle_constant(p, dctl); dctl->end_of_constant = saved_end_of_constant; } else { /* Type argument. */ p = demangle_type(p, dctl); } /* if */ if (skipped) dctl->suppress_id_output--; if (unskipped) dctl->suppress_id_output++; /* Stop after the last argument. */ if ((p - arg_base) >= nchars) break; write_id_str(", ", dctl); } /* for */ write_id_ch('>', dctl); return p;} /* demangle_template_arguments */static char *demangle_operator(char *ptr, int *mangled_length, a_boolean *takes_type)/*Examine the first few characters at ptr to see if they are an encoding foran operator (e.g., "pl" for plus). If so, return a pointer to a string forthe operator (e.g., "+"), set *mangled_length to the number of charactersin the encoding, and *takes_type to TRUE if the operator takes a typemodifier (e.g., cast). If the first few characters are not an operatorencoding, return NULL.*/{ char *s; int len = 2; *takes_type = FALSE; /* The length-3 codes are tested first to avoid taking their first two letters as one of the length-2 codes. */ if (start_of_id_is("apl", ptr)) { s = "+="; len = 3; } else if (start_of_id_is("ami", ptr)) { s = "-="; len = 3; } else if (start_of_id_is("amu", ptr)) { s = "*="; len = 3; } else if (start_of_id_is("adv", ptr)) { s = "/="; len = 3; } else if (start_of_id_is("amd", ptr)) { s = "%="; len = 3; } else if (start_of_id_is("aer", ptr)) { s = "^="; len = 3; } else if (start_of_id_is("aad", ptr)) { s = "&="; len = 3; } else if (start_of_id_is("aor", ptr)) { s = "|="; len = 3; } else if (start_of_id_is("ars", ptr)) { s = ">>="; len = 3; } else if (start_of_id_is("als", ptr)) { s = "<<="; len = 3; } else if (start_of_id_is("nwa", ptr)) { s = "new[]"; len = 3; } else if (start_of_id_is("dla", ptr)) { s = "delete[]"; len = 3; } else if (start_of_id_is("nw", ptr)) { s = "new"; } else if (start_of_id_is("dl", ptr)) { s = "delete"; } else if (start_of_id_is("pl", ptr)) { s = "+"; } else if (start_of_id_is("mi", ptr)) { s = "-"; } else if (start_of_id_is("ml", ptr)) { s = "*"; } else if (start_of_id_is("dv", ptr)) { s = "/"; } else if (start_of_id_is("md", ptr)) { s = "%"; } else if (start_of_id_is("er", ptr)) { s = "^"; } else if (start_of_id_is("ad", ptr)) { s = "&"; } else if (start_of_id_is("or", ptr)) { s = "|"; } else if (start_of_id_is("co", ptr)) { s = "~"; } else if (start_of_id_is("nt", ptr)) { s = "!"; } else if (start_of_id_is("as", ptr)) { s = "="; } else if (start_of_id_is("lt", ptr)) { s = "<"; } else if (start_of_id_is("gt", ptr)) { 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);} /* demangle_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 to
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -