📄 etoa_decode.c
字号:
goto end_of_routine; } /* if */ do { n = n*10 + (*p - '0'); if (n > dctl->input_id_len) { /* Bad number. */ bad_mangled_name(dctl); n = dctl->input_id_len; goto end_of_routine; } /* if */ p++; } while (isdigit((unsigned char)*p));end_of_routine: *num = n; return p;} /* get_length */static char *get_number(char *p, unsigned long *num, a_decode_control_block_ptr dctl)/*Accumulate a number starting at position p and return its value in *num.Return a pointer to the character position following the number.*/{ unsigned long n = 0; if (!isdigit((unsigned char)*p)) { bad_mangled_name(dctl); goto end_of_routine; } /* if */ do { n = n*10 + (*p - '0'); p++; } while (isdigit((unsigned char)*p));end_of_routine: *num = n; return p;} /* get_number */static char *get_single_digit_number(char *p, unsigned long *num, a_decode_control_block_ptr dctl)/*Accumulate a number starting at position p and return its value in *num.The number is a single digit. Return a pointer to the character positionfollowing the number.*/{ *num = 0; if (!isdigit((unsigned char)*p)) { bad_mangled_name(dctl); goto end_of_routine; } /* if */ *num = (*p - '0'); p++;end_of_routine: return p;} /* get_single_digit_number */static char *get_length_with_optional_underscore( char *p, unsigned long *num, a_decode_control_block_ptr dctl)/*Accumulate a number starting at position p and return its value in *num.If the number has more than one digit, it is followed by an underscore.(Or, in a newer representation, surrounded by underscores.)Return a pointer to the character position following the number.*/{ if (*p == '_') { /* New encoding (not from cfront) -- the length is surrounded by underscores whether it's a single digit or several digits, e.g., "L_10_1234567890". */ p++; /* Multi-digit number followed by underscore. */ p = get_length(p, num, dctl); p = advance_past_underscore(p, dctl); } else if (isdigit((unsigned char)p[0]) && isdigit((unsigned char)p[1]) && (dctl->end_of_constant == NULL || p+2 < dctl->end_of_constant) && p[2] == '_') { /* The cfront version -- a multi-digit length is followed by an underscore, e.g., "L10_1234567890". This doesn't work well because something like "L11", intended to have a one-digit length, can be made ambiguous by following it by a "_" for some other reason. (That's resolved in most cases by the check against end_of_constant.) So this form is not used in new cases where that can come up, e.g., nontype template arguments for functions. In any case, interpret "multi-digit" as "2-digit" and don't look further for the underscore. */ /* Multi-digit number followed by underscore. */ p = get_length(p, num, dctl); p = advance_past_underscore(p, dctl); } else { /* Single-digit number not followed by underscore. */ p = get_single_digit_number(p, num, dctl); } /* if */ return p;} /* get_length_with_optional_underscore */static a_boolean is_immediate_type_qualifier(char *p)/*Return TRUE if the encoding pointed to is one that indicates typequalification.*/{ a_boolean is_type_qual = FALSE; if (*p == 'C' || *p == 'V') { /* This is a type qualifier. */ is_type_qual = TRUE; } /* if */ return is_type_qual;} /* is_immediate_type_qualifier */static void write_template_parameter_name(unsigned long depth, unsigned long position, a_boolean nontype, a_decode_control_block_ptr dctl)/*Output a representation of a template parameter with depth and positionas indicated. It's a nontype parameter if nontype is TRUE.*/{ char buffer[100]; char letter = '\0'; if (nontype) { /* Nontype parameter. */ /* Use a code letter for the first few levels, then the depth number. */ if (depth == 1) { letter = 'N'; } else if (depth == 2) { letter = 'O'; } else if (depth == 3) { letter = 'P'; } /* if */ if (letter != '\0') { (void)sprintf(buffer, "%c%lu", letter, position); } else { (void)sprintf(buffer, "N_%lu_%lu", depth, position); } /* if */ } else { /* Normal type parameter. */ /* Use a code letter for the first few levels, then the depth number. */ if (depth == 1) { letter = 'T'; } else if (depth == 2) { letter = 'U'; } else if (depth == 3) { letter = 'V'; } /* if */ if (letter != '\0') { (void)sprintf(buffer, "%c%lu", letter, position); } else { (void)sprintf(buffer, "T_%lu_%lu", depth, position); } /* if */ } /* if */ write_id_str(buffer, dctl);} /* write_template_parameter_name */static char *demangle_template_parameter_name( char *ptr, a_boolean nontype, a_decode_control_block_ptr dctl)/*Demangle a template parameter name at the indicated location. The parameteris a nontype parameter if nontype is TRUE. Return a pointer to the characterposition following what was demangled.*/{ char *p = ptr; unsigned long position, depth = 1; /* This comes up with the modern mangling for template functions. Form is "ZnZ" or "Zn_mZ", where n is the parameter number and m is the depth number (1 if not specified). */ p++; /* Advance past the "Z". */ /* Get the position number. */ p = get_number(p, &position, dctl); if (*p == '_' && p[1] != '_') { /* Form including depth ("Zn_mZ"). */ p++; p = get_number(p, &depth, dctl); } /* if */ /* Output the template parameter name. */ write_template_parameter_name(depth, position, nontype, dctl); if (p[0] == '_' && p[1] == '_' && p[2] == 't' && p[3] == 'm' && p[4] == '_' && p[5] == '_') { /* A template template parameter followed by a template argument list. */ p = demangle_template_arguments(p+6, /*partial_spec=*/FALSE, (a_template_param_block_ptr)NULL, dctl); } /* if */ /* Check for the final "Z". This appears in the mangling to avoid ambiguities when the template parameter is followed by something whose encoding begins with a digit, e.g., a class name. */ if (*p != 'Z') { bad_mangled_name(dctl); } else { p++; } /* if */ return p;} /* demangle_template_parameter_name */static char *demangle_constant(char *ptr, a_decode_control_block_ptr dctl)/*Demangle a constant (e.g., a nontype template class argument) beginning atptr, and output the demangled form. Return a pointer to the characterposition following what was demangled.*/{ char *p = ptr, *type = NULL, *index; unsigned long nchars; /* A constant has a form like CiL15 <-- integer constant 5 ^-- Literal constant representation. ^--- Length of literal constant. ^---- L indicates literal constant; c indicates address of variable, etc. ^^----- Type of template argument, with "const" added. A template parameter constant or a constant expression does not have the initial "C" and type. */ if (*p == 'C') { /* Advance past the type. */ type = p; dctl->suppress_id_output++; p = demangle_type(p, dctl); dctl->suppress_id_output--; } /* if */ /* The next thing has one of the following forms: 3abc Address of "abc". L211 Literal constant; length ("2") followed by the characters of the constant ("11"). LM0_L2n1_1j Pointer-to-member-function constant; the three parts correspond to the triplet of values in the __mptr data structure. Z1Z Template parameter. Opl2Z1ZZ2ZO Expression. */ if (isdigit((unsigned char)*p)) { /* A name preceded by its length, e.g., "3abc". Put out "&name". */ write_id_ch('&', dctl); /* Process the length and name. */ p = demangle_name_with_preceding_length(p, /*allow_member=*/TRUE, (a_template_param_block_ptr)NULL, dctl); } else if (*p == 'L') { if (p[1] != 'M') { /* Normal literal constant. Form is something like L3n12 encoding for -12 ^^^---- Characters of constant. Some characters get remapped: n --> - p --> + d --> . ^------- Length of constant. Output is (type)constant That is, the literal constant preceded by a cast to the right type. */ /* See if the type is bool. */ a_boolean is_bool = (type+2 == p && *(type+1) == 'b'), is_nonzero; /* If the type is bool, don't put out the cast. */ if (!is_bool) { write_id_ch('(', dctl); /* Start at type+1 to avoid the "C" for const. */ (void)demangle_type(type+1, dctl); write_id_ch(')', dctl); } /* if */ p++; /* Advance past the "L". */ /* Get the length of the constant. */ p = get_length_with_optional_underscore(p, &nchars, dctl); /* Process the characters of the literal constant. */ is_nonzero = FALSE; for (; nchars > 0; nchars--, p++) { /* Remap characters where necessary. */ char ch = *p; switch (ch) { case '\0': case '_': /* Ran off end of string. */ bad_mangled_name(dctl); goto end_of_routine; case 'p': ch = '+'; break; case 'n': ch = '-'; break; case 'd': ch = '.'; break; } /* switch */ if (is_bool) { /* For the bool case, just keep track of whether the constant is non-zero; true or false will be output later. */ if (ch != '0') is_nonzero = TRUE; } else { /* Normal (non-bool) case. Output the character of the constant. */ write_id_ch(ch, dctl); } /* if */ } /* for */ if (is_bool) { /* For bool, output true or false. */ write_id_str((char *)(is_nonzero ? "true" : "false"), dctl); } /* if */ } else { /* Pointer-to-member-function. The form of the constant is LM0_L2n1_1j Non-virtual function LM0_L11_0 Virtual function LM0_L10_0 Null pointer The three parts match the three components of the __mptr structure: (delta, index, function or offset). The index is -1 for a non-virtual function, 0 for a null pointer, and greater than 0 for a virtual function. The index is represented like an integer constant (see above). For virtual functions, the last component is always "0" even if the offset is not zero. */ /* Advance past the "LM". */ p += 2; /* Advance over the first component, ignoring it. */ while (isdigit((unsigned char)*p)) p++; p = advance_past_underscore(p, dctl); /* The index component should be next. */ if (*p != 'L') { bad_mangled_name(dctl); goto end_of_routine; } /* if */ p++; /* Get the index length. */ /* Note that get_length_with_optional_underscore is not used because this is an ambiguous situation: an underscore follows the index value, and there's no way to tell if it's the multi-digit indicator for the length or the separator between fields. */ if (*p == '_') { /* New-form encoding, no ambiguity. */ p = get_length_with_optional_underscore(p, &nchars, dctl); } else { p = get_single_digit_number(p, &nchars, dctl); } /* if */ /* Remember the start of the index. */ index = p; /* Skip the rest of the index. */ while (isdigit((unsigned char)*p) || (*p == 'n')) p++; p = advance_past_underscore(p, dctl); /* If the index number starts with 'n', this is a non-virtual function. */ if (*index == 'n') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -