📄 method.c
字号:
return; if (decl == global_namespace) return; context = CP_DECL_CONTEXT (decl); /* try to issue a K type, and if we can't continue the normal path */ if (!(ktypelist && issue_ktype (context))) { /* For a template type parameter, we want to output an 'Xn' rather than 'T' or some such. */ if (TREE_CODE (context) == TEMPLATE_TYPE_PARM || TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM) build_mangled_name_for_type (context); else { if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') context = TYPE_NAME (context); build_overload_nested_name (context); } } if (TREE_CODE (decl) == FUNCTION_DECL) { tree name = DECL_ASSEMBLER_NAME (decl); char *label; ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), static_labelno); static_labelno++; if (numeric_output_need_bar) OB_PUTC ('_'); icat (strlen (label)); OB_PUTCP (label); numeric_output_need_bar = 1; } else if (TREE_CODE (decl) == NAMESPACE_DECL) build_overload_identifier (DECL_NAME (decl)); else /* TYPE_DECL */ build_overload_identifier (decl);}/* Output the decimal representation of I. If I > 9, the decimal representation is preceeded and followed by an underscore. */static voidbuild_underscore_int (i) int i;{ if (i > 9) OB_PUTC ('_'); icat (i); if (i > 9) OB_PUTC ('_');}static voidbuild_overload_scope_ref (value) tree value;{ OB_PUTC2 ('Q', '2'); numeric_output_need_bar = 0; build_mangled_name_for_type (TREE_OPERAND (value, 0)); build_overload_identifier (TREE_OPERAND (value, 1));}/* Encoding for an INTEGER_CST value. */static voidbuild_overload_int (value, in_template) tree value; int in_template;{ if (in_template && TREE_CODE (value) != INTEGER_CST) { if (TREE_CODE (value) == SCOPE_REF) { build_overload_scope_ref (value); return; } OB_PUTC ('E'); numeric_output_need_bar = 0; if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (value)))) { int i; int operands = tree_code_length[(int) TREE_CODE (value)]; tree id; char* name; id = ansi_opname [(int) TREE_CODE (value)]; my_friendly_assert (id != NULL_TREE, 0); name = IDENTIFIER_POINTER (id); if (name[0] != '_' || name[1] != '_') /* On some erroneous inputs, we can get here with VALUE a LOOKUP_EXPR. In that case, the NAME will be the identifier for "<invalid operator>". We must survive this routine in order to issue a sensible error message, so we fall through to the case below. */ goto bad_value; for (i = 0; i < operands; ++i) { tree operand; enum tree_code tc; /* We just outputted either the `E' or the name of the operator. */ numeric_output_need_bar = 0; if (i != 0) /* Skip the leading underscores. */ OB_PUTCP (name + 2); operand = TREE_OPERAND (value, i); tc = TREE_CODE (operand); if (TREE_CODE_CLASS (tc) == 't') /* We can get here with sizeof, e.g.: template <class T> void f(A<sizeof(T)>); */ build_mangled_name_for_type (operand); else if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (tc))) build_overload_int (operand, in_template); else build_overload_value (TREE_TYPE (operand), operand, in_template); } } else { /* We don't ever want this output, but it's inconvenient not to be able to build the string. This should cause assembler errors we'll notice. */ static int n; bad_value: sprintf (digit_buffer, " *%d", n++); OB_PUTCP (digit_buffer); } OB_PUTC ('W'); numeric_output_need_bar = 0; return; } my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243); if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT) { if (TREE_INT_CST_HIGH (value) != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1))) { /* need to print a DImode value in decimal */ dicat (TREE_INT_CST_LOW (value), TREE_INT_CST_HIGH (value)); numeric_output_need_bar = 1; return; } /* else fall through to print in smaller mode */ } /* Wordsize or smaller */ icat (TREE_INT_CST_LOW (value)); numeric_output_need_bar = 1;}/* Output S followed by a representation of the TEMPLATE_PARM_INDEX supplied in INDEX. */static void build_mangled_template_parm_index (s, index) char* s; tree index;{ OB_PUTCP (s); build_underscore_int (TEMPLATE_PARM_IDX (index)); /* We use the LEVEL, not the ORIG_LEVEL, because the mangling is a representation of the function from the point of view of its type. */ build_underscore_int (TEMPLATE_PARM_LEVEL (index));}/* Mangling for C9X integer types (and Cygnus extensions for 128-bit and other types) is based on the letter "I" followed by the hex representations of the bitsize for the type in question. For encodings that result in larger than two digits, a leading and trailing underscore is added. Thus: int1_t = 001 = I01 int8_t = 008 = I08 int16_t = 010 = I10 int24_t = 018 = I18 int32_t = 020 = I20 int64_t = 040 = I40 int80_t = 050 = I50 int128_t = 080 = I80 int256_t = 100 = I_100_ int512_t = 200 = I_200_ Given an integer in decimal format, mangle according to this scheme. */#if HOST_BITS_PER_WIDE_INT >= 64static voidbuild_mangled_C9x_name (bits) int bits;{ char mangled[10] = ""; if (bits > 255) sprintf (mangled, "I_%x_", bits); else sprintf (mangled, "I%.2x", bits); OB_PUTCP (mangled);}#endifstatic voidbuild_overload_value (type, value, in_template) tree type, value; int in_template;{ my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0); while (TREE_CODE (value) == NON_LVALUE_EXPR || TREE_CODE (value) == NOP_EXPR) value = TREE_OPERAND (value, 0); if (numeric_output_need_bar) { OB_PUTC ('_'); numeric_output_need_bar = 0; } if (TREE_CODE (value) == TEMPLATE_PARM_INDEX) { build_mangled_template_parm_index ("Y", value); return; } if (TYPE_PTRMEM_P (type)) { if (TREE_CODE (value) != PTRMEM_CST) /* We should have already rejected this pointer to member, since it is not a constant. */ my_friendly_abort (0); /* Get the actual FIELD_DECL. */ value = PTRMEM_CST_MEMBER (value); my_friendly_assert (TREE_CODE (value) == FIELD_DECL, 0); /* Output the name of the field. */ build_overload_identifier (DECL_NAME (value)); return; } switch (TREE_CODE (type)) { case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: { build_overload_int (value, in_template); return; } case REAL_TYPE: { REAL_VALUE_TYPE val; char *bufp = digit_buffer; pedwarn ("ANSI C++ forbids floating-point template arguments"); my_friendly_assert (TREE_CODE (value) == REAL_CST, 244); val = TREE_REAL_CST (value); if (REAL_VALUE_ISNAN (val)) { sprintf (bufp, "NaN"); } else { if (REAL_VALUE_NEGATIVE (val)) { val = REAL_VALUE_NEGATE (val); *bufp++ = 'm'; } if (REAL_VALUE_ISINF (val)) { sprintf (bufp, "Infinity"); } else { REAL_VALUE_TO_DECIMAL (val, "%.20e", bufp); bufp = (char *) index (bufp, 'e'); if (!bufp) strcat (digit_buffer, "e0"); else { char *p; bufp++; if (*bufp == '-') { *bufp++ = 'm'; } p = bufp; if (*p == '+') p++; while (*p == '0') p++; if (*p == 0) { *bufp++ = '0'; *bufp = 0; } else if (p != bufp) { while (*p) *bufp++ = *p++; *bufp = 0; } }#ifdef NO_DOT_IN_LABEL bufp = (char *) index (bufp, '.'); if (bufp) *bufp = '_';#endif } } OB_PUTCP (digit_buffer); numeric_output_need_bar = 1; return; } case POINTER_TYPE: if (TREE_CODE (value) == INTEGER_CST) { build_overload_int (value, in_template); return; } else if (TREE_CODE (value) == TEMPLATE_PARM_INDEX) { build_mangled_template_parm_index ("", value); numeric_output_need_bar = 1; return; } value = TREE_OPERAND (value, 0); /* Fall through. */ case REFERENCE_TYPE: if (TREE_CODE (value) == VAR_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 245); build_overload_identifier (DECL_ASSEMBLER_NAME (value)); return; } else if (TREE_CODE (value) == FUNCTION_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 246); build_overload_identifier (DECL_ASSEMBLER_NAME (value)); return; } else if (TREE_CODE (value) == SCOPE_REF) build_overload_scope_ref (value); else my_friendly_abort (71); break; /* not really needed */ case RECORD_TYPE: { tree delta; tree idx; tree pfn; tree delta2; my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 0); /* We'll get a ADDR_EXPR of a SCOPE_REF here if we're mangling, an instantiation of something like: template <class T, void (T::*fp)()> class C {}; template <class T> C<T, &T::f> x(); We mangle the return type of the function, and that contains template parameters. */ if (TREE_CODE (value) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (value, 0)) == SCOPE_REF) { build_overload_scope_ref (TREE_OPERAND (value, 0)); break; } my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0); expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2); build_overload_int (delta, in_template); OB_PUTC ('_'); build_overload_int (idx, in_template); OB_PUTC ('_'); if (pfn) { numeric_output_need_bar = 0; build_overload_identifier (DECL_ASSEMBLER_NAME (PTRMEM_CST_MEMBER (value))); } else { OB_PUTC ('i'); build_overload_int (delta2, in_template); } } break; default: sorry ("conversion of %s as template parameter", tree_code_name [(int) TREE_CODE (type)]); my_friendly_abort (72); }}/* Add encodings for the declaration of template template parameters. PARMLIST must be a TREE_VEC. */static voidbuild_template_template_parm_names (parmlist) tree parmlist;{ int i, nparms; my_friendly_assert (TREE_CODE (parmlist) == TREE_VEC, 246.5); nparms = TREE_VEC_LENGTH (parmlist); icat (nparms); for (i = 0; i < nparms; i++) { tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i)); if (TREE_CODE (parm) == TYPE_DECL) { /* This parameter is a type. */ OB_PUTC ('Z'); } else if (TREE_CODE (parm) == TEMPLATE_DECL) { /* This parameter is a template. */ OB_PUTC ('z'); build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm)); } else /* It's a PARM_DECL. */ build_mangled_name_for_type (TREE_TYPE (parm)); }}/* Add encodings for the vector of template parameters in PARMLIST, given the vector of arguments to be substituted in ARGLIST. */static voidbuild_template_parm_names (parmlist, arglist) tree parmlist; tree arglist;{ int i, nparms; tree inner_args = innermost_args (arglist); nparms = TREE_VEC_LENGTH (parmlist); icat (nparms); for (i = 0; i < nparms; i++) { tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i)); tree arg = TREE_VEC_ELT (inner_args, i); if (TREE_CODE (parm) == TYPE_DECL) { /* This parameter is a type. */ OB_PUTC ('Z'); build_mangled_name_for_type (arg); } else if (TREE_CODE (parm) == TEMPLATE_DECL) { /* This parameter is a template. */ if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) /* Output parameter declaration, argument index and level. */ build_mangled_name_for_type (arg); else { /* A TEMPLATE_DECL node, output the parameter declaration and template name */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -