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

📄 cp-method.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		      if (tindex > 9)			OB_PUTC ('_');		    }		}	      goto next;	    }	  if (nrepeats)	    flush_repeats (typevec[maxtype-2]);	  if (! just_one	      /* Only cache types which take more than one character.  */	      && (parmtype != TYPE_MAIN_VARIANT (parmtype)		  || (TREE_CODE (parmtype) != INTEGER_TYPE		      && TREE_CODE (parmtype) != REAL_TYPE)))	    TREE_USED (parmtype) = 1;	}      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 ("parameter type with unspecified array bounds invalid");		icat (1);	      }	    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 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;		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');		icat (i);		build_overload_nested_name (TYPE_NAME (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);}/* 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);  if (dname == ansi_opname[(int) NEW_EXPR]      && parms != NULL_TREE      && TREE_CODE (parms) == TREE_LIST      && TREE_VALUE (parms) == sizetype      && TREE_CHAIN (parms) == void_list_node)    return get_identifier ("__builtin_new");  else if (dname == ansi_opname[(int) DELETE_EXPR]	   && parms != NULL_TREE	   && TREE_CODE (parms) == TREE_LIST	   && TREE_VALUE (parms) == ptr_type_node	   && TREE_CHAIN (parms) == void_list_node)    return get_identifier ("__builtin_delete");  else if (dname == ansi_opname[(int) DELETE_EXPR]	   && parms != NULL_TREE	   && TREE_CODE (parms) == TREE_LIST	   && TREE_VALUE (parms) == ptr_type_node	   && TREE_CHAIN (parms) != NULL_TREE	   && TREE_CODE (TREE_CHAIN (parms)) == TREE_LIST	   && TREE_VALUE (TREE_CHAIN (parms)) == sizetype	   && TREE_CHAIN (TREE_CHAIN (parms)) == void_list_node)    return get_identifier ("__builtin_delete");  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      parms = temp_tree_cons (NULL_TREE, TREE_TYPE (TREE_VALUE (parms)), 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);    }  return get_identifier (obstack_base (&scratch_obstack));}/* Build an overload name for the type expression TYPE.  */treebuild_typename_overload (type)     tree type;{  OB_INIT ();  OB_PUTID (ansi_opname[(int) TYPE_EXPR]);#if 0  /* We can get away without doing this--it really gets     overloaded later.  */  OB_PUTC2 ('_', '_');  OB_PUTC ('M');#endif  nofold = 1;  build_overload_name (type, 0, 1);  return get_identifier (obstack_base (&scratch_obstack));}#define T_DESC_FORMAT "TD$"#define I_DESC_FORMAT "ID$"#define M_DESC_FORMAT "MD$"/* 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)	  && ! IDENTIFIER_LOCAL_VALUE (name));}#endif/* Given a tree_code CODE, and some arguments (at least one),   attempt to use an overloaded operator on the arguments.   For unary operators, only the first argument need be checked.   For binary operators, both arguments may need to be checked.   Member functions can convert class references to class pointers,   for one-level deep indirection.  More than that is not supported.   Operators [](), ()(), and ->() must be member functions.   We call function call building calls with nonzero complain if   they are our only hope.  This is true when we see a vanilla operator   applied to something of aggregate type.  If this fails, we are free to   return `error_mark_node', because we will have reported the error.   Operators NEW and DELETE overload in funny ways: operator new takes   a single `size' parameter, and operator delete takes a pointer to the   storage being deleted.  When overloading these operators, success is   assumed.  If there is a failure, report an error message and return   `error_mark_node'.  *//* NOSTRICT */treebuild_opfncall (code, flags, xarg1, xarg2, arg3)     enum tree_code code;     int flags;     tree xarg1, xarg2, arg3;{  tree rval = 0;  tree arg1, arg2;  tree type1, type2, fnname;  tree fields1 = 0, parms = 0;  tree global_fn;  int try_second;  int binary_is_unary;  if (xarg1 == error_mark_node)    return error_mark_node;  if (code == COND_EXPR)    {      if (TREE_CODE (xarg2) == ERROR_MARK	  || TREE_CODE (arg3) == ERROR_MARK)	return error_mark_node;    }  if (code == COMPONENT_REF)    if (TREE_CODE (TREE_TYPE (xarg1)) == POINTER_TYPE)      return rval;  /* First, see if we can work with the first argument */  type1 = TREE_TYPE (xarg1);  /* Some tree codes have length > 1, but we really only want to     overload them if their first argument has a user defined type.  */  switch (code)    {    case PREINCREMENT_EXPR:      code = POSTINCREMENT_EXPR;      binary_is_unary = 1;

⌨️ 快捷键说明

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