📄 cp-method.c
字号:
char *last_space; dump_type (TREE_VALUE (parmtypes), &p); last_space = (char *)obstack_next_free (&scratch_obstack); while (last_space[-1] == ' ') last_space--; scratch_obstack.next_free = last_space; if (TREE_PURPOSE (parmtypes)) { scratch_error_offset = obstack_object_size (&scratch_obstack); OB_PUTS (" (= "); dump_init (TREE_PURPOSE (parmtypes)); OB_PUTC (')'); } OB_PUTC2 (',', ' '); parmtypes = TREE_CHAIN (parmtypes); } in_parmlist--; } if (parmtypes) { if (spaces) scratch_obstack.next_free = obstack_next_free (&scratch_obstack)-spaces; } else OB_PUTS ("..."); OB_PUTC (')'); if (print_ret_type_p && ! IDENTIFIER_TYPENAME_P (name)) dump_type_suffix (TREE_TYPE (fntype), &p); if (TREE_CODE (fntype) == METHOD_TYPE) dump_readonly_or_volatile (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype)))); OB_FINISH (); return (char *)obstack_base (&scratch_obstack);}/* Same, but handtype a _TYPE. */char *type_as_string (typ) tree typ;{ int p = 0; OB_INIT (); dump_type(typ,&p); OB_FINISH (); return (char *)obstack_base (&scratch_obstack);}/* A cross between type_as_string and fndecl_as_string. */char *decl_as_string (decl) tree decl;{ OB_INIT (); dump_decl(decl); OB_FINISH (); return (char *)obstack_base (&scratch_obstack);}/* Move inline function definitions out of structure so that they can be processed normally. CNAME is the name of the class we are working from, METHOD_LIST is the list of method lists of the structure. We delete friend methods here, after saving away their inline function definitions (if any). */voiddo_inline_function_hair (type, friend_list) tree type, friend_list;{ tree method = TYPE_METHODS (type); if (method && TREE_CODE (method) == TREE_VEC) { if (TREE_VEC_ELT (method, 0)) method = TREE_VEC_ELT (method, 0); else method = TREE_VEC_ELT (method, 1); } while (method) { /* Do inline member functions. */ struct pending_inline *info = DECL_PENDING_INLINE_INFO (method); if (info) { tree args; my_friendly_assert (info->fndecl == method, 238); args = DECL_ARGUMENTS (method); while (args) { DECL_CONTEXT (args) = method; args = TREE_CHAIN (args); } /* Allow this decl to be seen in global scope */ IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (method)) = method; } method = TREE_CHAIN (method); } while (friend_list) { tree fndecl = TREE_VALUE (friend_list); struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl); if (info) { tree args; my_friendly_assert (info->fndecl == fndecl, 239); args = DECL_ARGUMENTS (fndecl); while (args) { DECL_CONTEXT (args) = fndecl; args = TREE_CHAIN (args); } /* Allow this decl to be seen in global scope */ IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (fndecl)) = fndecl; } friend_list = TREE_CHAIN (friend_list); }}/* Report an argument type mismatch between the best declared function we could find and the current argument list that we have. */voidreport_type_mismatch (cp, parmtypes, name_kind, err_name) struct candidate *cp; tree parmtypes; char *name_kind, *err_name;{ int i = cp->u.bad_arg; tree ttf, tta; char *tmp_firstobj; switch (i) { case -4: my_friendly_assert (TREE_CODE (cp->function) == TEMPLATE_DECL, 240); error ("type unification failed for function template `%s'", err_name); return; case -3: if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (parmtypes)))) error ("call to const %s `%s' with non-const object", name_kind, err_name); else error ("call to non-const %s `%s' with const object", name_kind, err_name); return; case -2: error ("too few arguments for %s `%s'", name_kind, err_name); return; case -1: error ("too many arguments for %s `%s'", name_kind, err_name); return; case 0: if (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE) { /* Happens when we have an ambiguous base class. */ my_friendly_assert (get_binfo (DECL_CLASS_CONTEXT (cp->function), TREE_TYPE (TREE_TYPE (TREE_VALUE (parmtypes))), 1) == error_mark_node, 241); return; } } ttf = TYPE_ARG_TYPES (TREE_TYPE (cp->function)); tta = parmtypes; while (i-- > 0) { ttf = TREE_CHAIN (ttf); tta = TREE_CHAIN (tta); } OB_INIT (); OB_PUTS ("bad argument "); sprintf (digit_buffer, "%d", cp->u.bad_arg - (TREE_CODE (TREE_TYPE (cp->function)) == METHOD_TYPE)); OB_PUTCP (digit_buffer); OB_PUTS (" for function `"); tmp_firstobj = scratch_firstobj; scratch_firstobj = 0; fndecl_as_string (0, cp->function, 0); scratch_firstobj = tmp_firstobj; /* We know that the last char written is next_free-1. */ ((char *) obstack_next_free (&scratch_obstack))[-1] = '\''; OB_PUTS (" (type was "); /* Reset `i' so that type printing routines do the right thing. */ if (tta) { enum tree_code code = TREE_CODE (TREE_TYPE (TREE_VALUE (tta))); if (code == ERROR_MARK) OB_PUTS ("(failed type instantiation)"); else { i = (code == FUNCTION_TYPE || code == METHOD_TYPE); dump_type (TREE_TYPE (TREE_VALUE (tta)), &i); } } else OB_PUTS ("void"); OB_PUTC (')'); OB_FINISH (); tmp_firstobj = (char *)alloca (obstack_object_size (&scratch_obstack)); bcopy (obstack_base (&scratch_obstack), tmp_firstobj, obstack_object_size (&scratch_obstack)); error (tmp_firstobj);}/* Here is where overload code starts. *//* Array of types seen so far in top-level call to `build_overload_name'. Allocated and deallocated by caller. */static tree *typevec;/* Number of types interned by `build_overload_name' so far. */static int maxtype;/* Number of occurrences of last type seen. */static int nrepeats;/* Nonzero if we should not try folding parameter types. */static int nofold;#define ALLOCATE_TYPEVEC(PARMTYPES) \ do { maxtype = 0, nrepeats = 0; \ typevec = (tree *)alloca (list_length (PARMTYPES) * sizeof (tree)); } while (0)#define DEALLOCATE_TYPEVEC(PARMTYPES) \ do { tree t = (PARMTYPES); \ while (t) { TREE_USED (TREE_VALUE (t)) = 0; t = TREE_CHAIN (t); } \ } while (0)/* Code to concatenate an asciified integer to a string. */static#ifdef __GNUC____inline#endifvoidicat (i) int i;{ if (i < 0) { OB_PUTC ('m'); i = -i; } if (i < 10) OB_PUTC ('0' + i); else { icat (i / 10); OB_PUTC ('0' + (i % 10)); }}static#ifdef __GNUC____inline#endifvoidflush_repeats (type) tree type;{ int tindex = 0; while (typevec[tindex] != type) tindex++; if (nrepeats > 1) { OB_PUTC ('N'); icat (nrepeats); if (nrepeats > 9) OB_PUTC ('_'); } else OB_PUTC ('T'); nrepeats = 0; icat (tindex); if (tindex > 9) OB_PUTC ('_');}static void build_overload_identifier ();static voidbuild_overload_nested_name (context) tree context;{ /* We use DECL_NAME here, because pushtag now sets the DECL_ASSEMBLER_NAME. */ tree name = DECL_NAME (context); if (DECL_CONTEXT (context)) { context = DECL_CONTEXT (context); if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') context = TYPE_NAME (context); build_overload_nested_name (context); } build_overload_identifier (name);}static voidbuild_overload_value (type, value) tree type, value;{ while (TREE_CODE (value) == NON_LVALUE_EXPR) value = TREE_OPERAND (value, 0); my_friendly_assert (TREE_CODE (type) == PARM_DECL, 242); type = TREE_TYPE (type); switch (TREE_CODE (type)) { case INTEGER_TYPE: case ENUMERAL_TYPE: { my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243); if (TYPE_PRECISION (value) == 2 * HOST_BITS_PER_WIDE_INT) { if (tree_int_cst_lt (value, integer_zero_node)) { OB_PUTC ('m'); value = build_int_2 (~ TREE_INT_CST_LOW (value), - TREE_INT_CST_HIGH (value)); } 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 */ sorry ("conversion of long long as PT parameter"); } /* else fall through to print in smaller mode */ } /* Wordsize or smaller */ icat (TREE_INT_CST_LOW (value)); return; }#ifndef REAL_IS_NOT_DOUBLE case REAL_TYPE: { REAL_VALUE_TYPE val; char *bufp = digit_buffer; extern char *index (); my_friendly_assert (TREE_CODE (value) == REAL_CST, 244); val = TREE_REAL_CST (value); if (val < 0) { val = -val; *bufp++ = 'm'; } sprintf (bufp, "%e", val); 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; } } OB_PUTCP (digit_buffer); return; }#endif case POINTER_TYPE: value = TREE_OPERAND (value, 0); if (TREE_CODE (value) == VAR_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 245); build_overload_identifier (DECL_NAME (value)); return; } else if (TREE_CODE (value) == FUNCTION_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 246); build_overload_identifier (DECL_NAME (value)); return; } else my_friendly_abort (71); break; /* not really needed */ default: sorry ("conversion of %s as PT parameter", tree_code_name [(int) TREE_CODE (type)]); my_friendly_abort (72); }}static voidbuild_overload_identifier (name) tree name;{ if (IDENTIFIER_TEMPLATE (name)) { tree template, parmlist, arglist, tname; int i, nparms; template = IDENTIFIER_TEMPLATE (name); arglist = TREE_VALUE (template); template = TREE_PURPOSE (template); tname = DECL_NAME (template); parmlist = DECL_ARGUMENTS (template); nparms = TREE_VEC_LENGTH (parmlist); OB_PUTC ('t'); icat (IDENTIFIER_LENGTH (tname)); OB_PUTID (tname); icat (nparms); for (i = 0; i < nparms; i++) { tree parm = TREE_VEC_ELT (parmlist, i); tree arg = TREE_VEC_ELT (arglist, i); if (TREE_CODE (parm) == IDENTIFIER_NODE) { /* This parameter is a type. */ OB_PUTC ('Z'); build_overload_name (arg, 0, 0); } else { /* It's a PARM_DECL. */ build_overload_name (TREE_TYPE (parm), 0, 0); build_overload_value (parm, arg); } } } else { icat (IDENTIFIER_LENGTH (name)); OB_PUTID (name); }}/* 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 (); if (just_one = (TREE_CODE (parmtypes) != TREE_LIST)) { parmtype = parmtypes; goto only_one; } while (parmtypes) { parmtype = TREE_VALUE (parmtypes); only_one: if (! nofold) { if (! just_one) /* Every argument gets counted. */ typevec[maxtype++] = parmtype; if (TREE_USED (parmtype)) { if (! just_one && parmtype == typevec[maxtype-2]) nrepeats++; else { if (nrepeats) flush_repeats (parmtype); if (! just_one && TREE_CHAIN (parmtypes) && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes))) nrepeats++; else { int tindex = 0; while (typevec[tindex] != parmtype) tindex++; OB_PUTC ('T'); icat (tindex);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -