📄 edg-decode.c
字号:
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, (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') { /* Non-virtual function. */ /* The third component is a name preceded by its length, e.g., "1f". Put out "&A::f", where "A" is the class type retrieved from the type. */ write_id_ch('&', dctl); /* Start at type+2 to skip the "C" for const and the "M" for pointer-to-member. */ (void)demangle_type_name(type+2, dctl); write_id_str("::", dctl); /* Demangle the length and name. */ p = demangle_name_with_preceding_length(p, (a_template_param_block_ptr)NULL, dctl); } else { /* Not a non-virtual function. The encoding for the third component should be simply "0". */ if (*p != '0') { bad_mangled_name(dctl); goto end_of_routine; } /* if */ p++; if (nchars == 1 && *index == '0') { /* Null pointer constant. Output "(type)0", that is, a zero cast to the pointer-to-member type. */ write_id_ch('(', dctl); (void)demangle_type(type, dctl); write_id_str(")0", dctl); } else { /* Virtual function. This case can't really be demangled properly, because the mangled name doesn't have enough information. Output "&A::virtual-function-n". */ write_id_ch('&', dctl); /* Start at type+2 to skip the "C" for const and the "M" for pointer-to-member. */ (void)demangle_type_name(type+2, dctl); write_id_str("::", dctl); write_id_str("virtual-function-", dctl); /* Write the index number. */ for (; nchars > 0; nchars--, index++) write_id_ch(*index, dctl); } /* if */ } /* if */ } /* if */ } else if (*p == 'Z') { /* A template parameter. */ p = demangle_template_parameter_name(p, /*nontype=*/TRUE, dctl); } else if (*p == 'O') { /* An operation. */ p = demangle_operation(p, dctl); } else { /* The constant starts with something unexpected. */ bad_mangled_name(dctl); } /* if */end_of_routine: return p;} /* demangle_constant */static char *demangle_operation(char *ptr, a_decode_control_block_ptr dctl)/*Demangle an operation in a constant expression (these come up in templatearguments and array sizes, in template function parameter lists) beginningat ptr, and output the demangled form. Return a pointer to the characterposition following what was demangled.*/{ char *p = ptr, *operator_str; int op_length; unsigned long num_operands; a_boolean takes_type; /* An operation has the form Opl2Z1ZZ2ZO <-- "Z1 + Z2", Z1/Z2 indicating nontype template parameters. ^---- "O" to end the operation encoding.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -