method.c
来自「GCC编译器源代码」· C语言 代码 · 共 2,227 行 · 第 1/4 页
C
2,227 行
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 (TREE_TYPE (type)) == METHOD_TYPE && TREE_CODE (value) != ADDR_EXPR) { if (TREE_CODE (value) == CONSTRUCTOR) { /* This is dangerous code, crack built up pointer to members. */ tree args = CONSTRUCTOR_ELTS (value); tree a1 = TREE_VALUE (args); tree a2 = TREE_VALUE (TREE_CHAIN (args)); tree a3 = CONSTRUCTOR_ELTS (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)))); a3 = TREE_VALUE (a3); STRIP_NOPS (a3); if (TREE_CODE (a1) == INTEGER_CST && TREE_CODE (a2) == INTEGER_CST) { build_overload_int (a1, in_template); OB_PUTC ('_'); build_overload_int (a2, in_template); OB_PUTC ('_'); if (TREE_CODE (a3) == ADDR_EXPR) { a3 = TREE_OPERAND (a3, 0); if (TREE_CODE (a3) == FUNCTION_DECL) { numeric_output_need_bar = 0; build_overload_identifier (DECL_ASSEMBLER_NAME (a3)); return; } } else if (TREE_CODE (a3) == INTEGER_CST) { OB_PUTC ('i'); build_overload_int (a3, in_template); numeric_output_need_bar = 1; return; } } } sorry ("template instantiation with pointer to method that is too complex"); return; } if (TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == TEMPLATE_CONST_PARM) { build_overload_int (value, in_template); numeric_output_need_bar = 1; return; } value = TREE_OPERAND (value, 0); 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 my_friendly_abort (71); break; /* not really needed */ default: sorry ("conversion of %s as template parameter", tree_code_name [(int) TREE_CODE (type)]); my_friendly_abort (72); }}/* 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; 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 (arglist, i); if (TREE_CODE (parm) == TYPE_DECL) { /* This parameter is a type. */ OB_PUTC ('Z'); build_overload_name (arg, 0, 0); } else { parm = tsubst (parm, arglist, TREE_VEC_LENGTH (arglist), NULL_TREE); /* It's a PARM_DECL. */ build_overload_name (TREE_TYPE (parm), 0, 0); build_overload_value (parm, arg, uses_template_parms (arglist)); } } }static voidbuild_overload_identifier (name) tree name;{ if (TREE_CODE (name) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (name)) && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)) && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)))) { tree template, parmlist, arglist, tname; template = CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)); arglist = TREE_VALUE (template); template = TREE_PURPOSE (template); tname = DECL_NAME (template); parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template); OB_PUTC ('t'); icat (IDENTIFIER_LENGTH (tname)); OB_PUTID (tname); build_template_parm_names (parmlist, arglist); } else { if (TREE_CODE (name) == TYPE_DECL) name = DECL_NAME (name); if (numeric_output_need_bar) { OB_PUTC ('_'); numeric_output_need_bar = 0; } icat (IDENTIFIER_LENGTH (name)); OB_PUTID (name); }}/* Given DECL, either a class TYPE, TYPE_DECL or FUNCTION_DECL, produce the mangling for it. Used by build_overload_name and build_static_name. */static voidbuild_qualified_name (decl) tree decl;{ tree context; int i = 1; if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't') decl = TYPE_NAME (decl); /* If DECL_ASSEMBLER_NAME has been set properly, use it. */ if (TREE_CODE (decl) == TYPE_DECL && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)) { OB_PUTID (DECL_ASSEMBLER_NAME (decl)); return; } context = decl; while (DECL_CONTEXT (context)) { i += 1; context = DECL_CONTEXT (context); if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') context = TYPE_NAME (context); } if (i > 1) { OB_PUTC ('Q'); if (i > 9) OB_PUTC ('_'); icat (i); if (i > 9) OB_PUTC ('_'); numeric_output_need_bar = 0; } build_overload_nested_name (decl);}/* Given a list of parameters in PARMTYPES, create an unambiguous overload string. Should distinguish any type that C (or C++) can distinguish. I.e., pointers to functions are treated correctly. Caller must deal with whether a final `e' goes on the end or not. Any default conversions must take place before this function is called. BEGIN and END control initialization and finalization of the obstack where we build the string. */char *build_overload_name (parmtypes, begin, end) tree parmtypes; int begin, end;{ int just_one; tree parmtype; if (begin) OB_INIT (); numeric_output_need_bar = 0; if ((just_one = (TREE_CODE (parmtypes) != TREE_LIST))) { parmtype = parmtypes; goto only_one; } while (parmtypes) { parmtype = TREE_VALUE (parmtypes); only_one: if (! nofold && ! just_one) { /* Every argument gets counted. */ typevec[maxtype++] = parmtype; if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2]) { nrepeats++; goto next; } if (nrepeats) flush_repeats (typevec[maxtype-2]); if (TREE_USED (parmtype)) {#if 0 /* We can turn this on at some point when we want improved symbol mangling. */ nrepeats++;#else /* This is bug compatible with 2.7.x */ flush_repeats (parmtype);#endif goto next; } /* Only cache types which take more than one character. */ if (parmtype != TYPE_MAIN_VARIANT (parmtype) || (TREE_CODE (parmtype) != INTEGER_TYPE && TREE_CODE (parmtype) != REAL_TYPE)) TREE_USED (parmtype) = 1; } if (TYPE_PTRMEMFUNC_P (parmtype)) parmtype = TYPE_PTRMEMFUNC_FN_TYPE (parmtype); if (TREE_READONLY (parmtype)) OB_PUTC ('C'); if (TREE_CODE (parmtype) == INTEGER_TYPE && TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype))) OB_PUTC ('U'); if (TYPE_VOLATILE (parmtype)) OB_PUTC ('V'); switch (TREE_CODE (parmtype)) { case OFFSET_TYPE: OB_PUTC ('O'); build_overload_name (TYPE_OFFSET_BASETYPE (parmtype), 0, 0); OB_PUTC ('_'); build_overload_name (TREE_TYPE (parmtype), 0, 0); break; case REFERENCE_TYPE: OB_PUTC ('R'); goto more; case ARRAY_TYPE:#if PARM_CAN_BE_ARRAY_TYPE { tree length; OB_PUTC ('A'); if (TYPE_DOMAIN (parmtype) == NULL_TREE) error ("pointer or reference to array of unknown bound in parm type"); else { length = array_type_nelts (parmtype); if (TREE_CODE (length) == INTEGER_CST) icat (TREE_INT_CST_LOW (length) + 1); } OB_PUTC ('_'); goto more; }#else OB_PUTC ('P'); goto more;#endif case POINTER_TYPE: OB_PUTC ('P'); more: build_overload_name (TREE_TYPE (parmtype), 0, 0); break; case FUNCTION_TYPE: case METHOD_TYPE: { tree firstarg = TYPE_ARG_TYPES (parmtype); /* Otherwise have to implement reentrant typevecs, unmark and remark types, etc. */ int old_nofold = nofold; nofold = 1; if (nrepeats) flush_repeats (typevec[maxtype-1]); /* @@ It may be possible to pass a function type in which is not preceded by a 'P'. */ if (TREE_CODE (parmtype) == FUNCTION_TYPE) { OB_PUTC ('F'); if (firstarg == NULL_TREE) OB_PUTC ('e'); else if (firstarg == void_list_node) OB_PUTC ('v'); else build_overload_name (firstarg, 0, 0); } else { int constp = TYPE_READONLY (TREE_TYPE (TREE_VALUE (firstarg))); int volatilep = TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (firstarg))); OB_PUTC ('M'); firstarg = TREE_CHAIN (firstarg); build_overload_name (TYPE_METHOD_BASETYPE (parmtype), 0, 0); if (constp) OB_PUTC ('C'); if (volatilep) OB_PUTC ('V'); /* For cfront 2.0 compatibility. */ OB_PUTC ('F'); if (firstarg == NULL_TREE) OB_PUTC ('e'); else if (firstarg == void_list_node) OB_PUTC ('v'); else build_overload_name (firstarg, 0, 0); } /* Separate args from return type. */ OB_PUTC ('_'); build_overload_name (TREE_TYPE (parmtype), 0, 0); nofold = old_nofold; break; } case INTEGER_TYPE: parmtype = TYPE_MAIN_VARIANT (parmtype); if (parmtype == integer_type_node || parmtype == unsigned_type_node) OB_PUTC ('i'); else if (parmtype == long_integer_type_node || parmtype == long_unsigned_type_node) OB_PUTC ('l'); else if (parmtype == short_integer_type_node || parmtype == short_unsigned_type_node) OB_PUTC ('s'); else if (parmtype == signed_char_type_node) { OB_PUTC ('S'); OB_PUTC ('c'); } else if (parmtype == char_type_node || parmtype == unsigned_char_type_node) OB_PUTC ('c'); else if (parmtype == wchar_type_node) OB_PUTC ('w'); else if (parmtype == long_long_integer_type_node || parmtype == long_long_unsigned_type_node) OB_PUTC ('x');#if 0 /* it would seem there is no way to enter these in source code, yet. (mrs) */ else if (parmtype == long_long_long_integer_type_node || parmtype == long_long_long_unsigned_type_node) OB_PUTC ('q');#endif else my_friendly_abort (73); break; case BOOLEAN_TYPE: OB_PUTC ('b'); break; case REAL_TYPE: parmtype = TYPE_MAIN_VARIANT (parmtype); if (parmtype == long_double_type_node) OB_PUTC ('r'); else if (parmtype == double_type_node) OB_PUTC ('d'); else if (parmtype == float_type_node) OB_PUTC ('f'); else my_friendly_abort (74); break; case COMPLEX_TYPE: OB_PUTC ('J'); build_overload_name (TREE_TYPE (parmtype), 0, 0); break; case VOID_TYPE: if (! just_one) {#if 0 extern tree void_list_node; /* See if anybody is wasting memory. */ my_friendly_assert (parmtypes == void_list_node, 247);#endif /* This is the end of a parameter list. */ if (end) OB_FINISH (); return (char *)obstack_base (&scratch_obstack); } OB_PUTC ('v'); break; case ERROR_MARK: /* not right, but nothing is anyway */ break; /* have to do these */ case UNION_TYPE: case RECORD_TYPE: if (! just_one) /* Make this type signature look incompatible with AT&T. */ OB_PUTC ('G'); goto common; case ENUMERAL_TYPE: common: { tree name = TYPE_NAME (parmtype); if (TREE_CODE (name) == IDENTIFIER_NODE) { build_overload_identifier (TYPE_NAME (parmtype)); break; } my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 248); build_qualified_name (name); break; } case UNKNOWN_TYPE: /* We can get here if __null is defined to have type ({unkown type}*), which it is if -ansi is not used. Treat this like 'void*'. */ OB_PUTC ('v'); break; case TEMPLATE_TYPE_PARM: OB_PUTC ('X'); build_underscore_int (TEMPLATE_TYPE_IDX (parmtype)); build_underscore_int (TEMPLATE_TYPE_LEVEL (parmtype)); break; case TYPENAME_TYPE: /* When mangling the type of a function template whose declaration looks like: template <class T> void foo(typename T::U) we have to mangle these. */ build_qualified_name (parmtype); break; default: my_friendly_abort (75); } next: if (just_one) break; parmtypes = TREE_CHAIN (parmtypes); } if (! just_one) { if (nrepeats) flush_repeats (typevec[maxtype-1]); /* To get here, parms must end with `...'. */ OB_PUTC ('e'); } if (end) OB_FINISH (); return (char *)obstack_base (&scratch_obstack);}/* Produce the mangling for a variable named NAME in CONTEXT, which can be either a class TYPE or a FUNCTION_DECL. */treebuild_static_name (context, name) tree context, name;{ OB_INIT (); numeric_output_need_bar = 0;#ifdef JOINER OB_PUTC ('_'); build_qualified_name (context); OB_PUTC (JOINER);#else OB_PUTS ("__static_"); build_qualified_name (context); OB_PUTC ('_');#endif OB_PUTID (name); OB_FINISH (); return get_identifier ((char *)obstack_base (&scratch_obstack));}static tree build_decl_overload_real (dname, parms, ret_type, tparms, targs, for_method) tree dname; tree parms; tree ret_type;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?