⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 method.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 4 页
字号:
	    }	}    }  else    {      if (numeric_output_need_bar)	{	  OB_PUTC ('_');	  numeric_output_need_bar = 0;	}      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 ();  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))	    {	      flush_repeats (parmtype);	      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 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);	    int i = 1;	    if (TREE_CODE (name) == TYPE_DECL)	      {		tree context = name;		/* If DECL_ASSEMBLER_NAME has been set properly, use it. */		if (DECL_ASSEMBLER_NAME (context) != DECL_NAME (context))		  {		    OB_PUTID (DECL_ASSEMBLER_NAME (context));		    break;		  }		while (DECL_CONTEXT (context))		  {		    i += 1;		    context = DECL_CONTEXT (context);		    if (TREE_CODE_CLASS (TREE_CODE (context)) == 't')		      context = TYPE_NAME (context);		  }		name = DECL_NAME (name);	      }	    my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 248);	    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 (TYPE_MAIN_DECL (parmtype));	      }	    else	      build_overload_identifier (name);	    break;	  }	case UNKNOWN_TYPE:	  /* This will take some work.  */	  OB_PUTC ('?');	  break;	case TEMPLATE_TYPE_PARM:	case TEMPLATE_CONST_PARM:        case UNINSTANTIATED_P_TYPE:	  /* 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;	    sprintf (digit_buffer, " *%d", n++);	    OB_PUTCP (digit_buffer);	  }	  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);}treebuild_static_name (basetype, name)  tree basetype, name;{  char *basename  = build_overload_name (basetype, 1, 1);  char *buf = (char *) alloca (IDENTIFIER_LENGTH (name)			       + sizeof (STATIC_NAME_FORMAT)			       + strlen (basename));  sprintf (buf, STATIC_NAME_FORMAT, basename, IDENTIFIER_POINTER (name));  return get_identifier (buf);}  /* Generate an identifier that encodes the (ANSI) exception TYPE. *//* This should be part of `ansi_opname', or at least be defined by the std.  */#define EXCEPTION_NAME_PREFIX "__ex"#define EXCEPTION_NAME_LENGTH 4treecplus_exception_name (type)     tree type;{  OB_INIT ();  OB_PUTS (EXCEPTION_NAME_PREFIX);  return get_identifier (build_overload_name (type, 0, 1));}/* Change the name of a function definition so that it may be   overloaded. NAME is the name of the function to overload,   PARMS is the parameter list (which determines what name the   final function obtains).   FOR_METHOD is 1 if this overload is being performed   for a method, rather than a function type.  It is 2 if   this overload is being performed for a constructor.  */treebuild_decl_overload (dname, parms, for_method)     tree dname;     tree parms;     int for_method;{  char *name = IDENTIFIER_POINTER (dname);  /* member operators new and delete look like methods at this point.  */  if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST)    {      if (dname == ansi_opname[(int) DELETE_EXPR])	return get_identifier ("__builtin_delete");      else if (dname == ansi_opname[(int) VEC_DELETE_EXPR])	return get_identifier ("__builtin_vec_delete");      else if (TREE_CHAIN (parms) == void_list_node)	{	  if (dname == ansi_opname[(int) NEW_EXPR])	    return get_identifier ("__builtin_new");	  else if (dname == ansi_opname[(int) VEC_NEW_EXPR])	    return get_identifier ("__builtin_vec_new");	}    }  OB_INIT ();  if (for_method != 2)    OB_PUTCP (name);  /* Otherwise, we can divine that this is a constructor,     and figure out its name without any extra encoding.  */  OB_PUTC2 ('_', '_');  if (for_method)    {#if 0      /* We can get away without doing this.  */      OB_PUTC ('M');#endif      {	tree this_type = TREE_VALUE (parms);	if (TREE_CODE (this_type) == RECORD_TYPE)  /* a signature pointer */	  parms = temp_tree_cons (NULL_TREE, SIGNATURE_TYPE (this_type),				  TREE_CHAIN (parms));	else	  parms = temp_tree_cons (NULL_TREE, TREE_TYPE (this_type),				  TREE_CHAIN (parms));      }    }  else    OB_PUTC ('F');  if (parms == NULL_TREE)    OB_PUTC2 ('e', '\0');  else if (parms == void_list_node)    OB_PUTC2 ('v', '\0');  else    {      ALLOCATE_TYPEVEC (parms);      nofold = 0;      if (for_method)	{	  build_overload_name (TREE_VALUE (parms), 0, 0);	  typevec[maxtype++] = TREE_VALUE (parms);	  TREE_USED (TREE_VALUE (parms)) = 1;	  if (TREE_CHAIN (parms))	    build_overload_name (TREE_CHAIN (parms), 0, 1);	  else	    OB_PUTC2 ('e', '\0');	}      else	build_overload_name (parms, 0, 1);      DEALLOCATE_TYPEVEC (parms);    }  {    tree n = get_identifier (obstack_base (&scratch_obstack));    if (IDENTIFIER_OPNAME_P (dname))      IDENTIFIER_OPNAME_P (n) = 1;    return n;  }}/* Build an overload name for the type expression TYPE.  */treebuild_typename_overload (type)     tree type;{  tree id;  OB_INIT ();  OB_PUTID (ansi_opname[(int) TYPE_EXPR]);  nofold = 1;  build_overload_name (type, 0, 1);  id = get_identifier (obstack_base (&scratch_obstack));  IDENTIFIER_OPNAME_P (id) = 1;#if 0  IDENTIFIER_GLOBAL_VALUE (id) = TYPE_NAME (type);#endif  TREE_TYPE (id) = type;  return id;}#ifndef NO_DOLLAR_IN_LABEL#define T_DESC_FORMAT "TD$"#define I_DESC_FORMAT "ID$"#define M_DESC_FORMAT "MD$"#else#if !defined(NO_DOT_IN_LABEL)#define T_DESC_FORMAT "TD."#define I_DESC_FORMAT "ID."#define M_DESC_FORMAT "MD."#else#define T_DESC_FORMAT "__t_desc_"#define I_DESC_FORMAT "__i_desc_"#define M_DESC_FORMAT "__m_desc_"#endif#endif/* Build an overload name for the type expression TYPE.  */treebuild_t_desc_overload (type)     tree type;{  OB_INIT ();  OB_PUTS (T_DESC_FORMAT);  nofold = 1;#if 0  /* Use a different format if the type isn't defined yet.  */  if (TYPE_SIZE (type) == NULL_TREE)    {      char *p;      int changed;      for (p = tname; *p; p++)	if (isupper (*p))	  {	    changed = 1;	    *p = tolower (*p);	  }      /* If there's no change, we have an inappropriate T_DESC_FORMAT.  */      my_friendly_assert (changed != 0, 249);    }#endif  build_overload_name (type, 0, 1);  return get_identifier (obstack_base (&scratch_obstack));}/* Top-level interface to explicit overload requests. Allow NAME   to be overloaded. Error if NAME is already declared for the current   scope. Warning if function is redundantly overloaded. */voiddeclare_overloaded (name)     tree name;{#ifdef NO_AUTO_OVERLOAD  if (is_overloaded (name))    warning ("function `%s' already declared overloaded",	     IDENTIFIER_POINTER (name));  else if (IDENTIFIER_GLOBAL_VALUE (name))    error ("overloading function `%s' that is already defined",	   IDENTIFIER_POINTER (name));  else    {      TREE_OVERLOADED (name) = 1;      IDENTIFIER_GLOBAL_VALUE (name) = build_tree_list (name, NULL_TREE);      TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name)) = unknown_type_node;    }#else  if (current_lang_name == lang_name_cplusplus)    {      if (0)	warning ("functions are implicitly overloaded in C++");    }  else if (current_lang_name == lang_name_c)    error ("overloading function `%s' cannot be done in C language context");  else    my_friendly_abort (76);#endif}#ifdef NO_AUTO_OVERLOAD/* Check to see if NAME is overloaded. For first approximation,   check to see if its TREE_OVERLOADED is set.  This is used on   IDENTIFIER nodes.  */intis_overloaded (name)     tree name;{  /* @@ */  return (TREE_OVERLOADED (name)	  && (! IDENTIFIER_CLASS_VALUE (name) || current_class_type == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -